All Products
Search
Document Center

ApsaraDB RDS:Use the pg_profile extension to collect statistics on resource-intensive activities

Last Updated:Mar 28, 2026

The pg_profile extension collects snapshots of database activity statistics at scheduled intervals and generates HTML performance reports. Use it to identify resource-intensive SQL statements and optimize database performance on ApsaraDB RDS for PostgreSQL.

How it works

pg_profile uses a two-database architecture:

  • Server database: the database being monitored. It runs pg_stat_statements and pg_stat_kcache to expose query statistics.

  • Profile database: the database that manages monitoring. It connects to the server database, pulls statistics snapshots via dblink, and stores them locally. You generate performance reports from the profile database.

The profile database and server database can run on the same RDS instance or on separate instances.

Prerequisites

Before you begin, make sure you have:

Usage notes

  • pg_profile requires pg_stat_statements. Install it before pg_profile. Optionally, also install pg_stat_kcache to collect kernel-level I/O statistics.

  • Snapshots consume disk space. pg_profile includes an automatic cleanup mechanism—monitor disk usage and adjust retention settings as needed.

  • Each snapshot takes time to complete. Collect snapshots once or twice per hour.

Install and uninstall pg_profile

Run the following statements using a privileged account:

-- Install
CREATE EXTENSION pg_profile;

-- Uninstall
DROP EXTENSION pg_profile;

Set up monitoring

This section walks through setting up a server database named server and a profile database named profile on the same RDS instance. The same steps apply when the databases are on separate instances—only the connection parameters differ.

Set up the server database

Run the following statements using a privileged account.

  1. Create the server database.

    CREATE DATABASE server;
  2. Connect to the server database and install the required extensions.

    Both pg_stat_statements and pg_stat_kcache must be loaded at database startup. Add both to the shared_preload_libraries parameter before creating these extensions. pg_stat_kcache depends on pg_stat_statements, so both must be present in shared_preload_libraries. For instructions, see Set parameters.
    \c server
    CREATE EXTENSION pg_stat_statements;
    CREATE EXTENSION pg_stat_kcache;
  3. Verify the extensions are installed.

    \dx

    Expected output:

    Name                | Version |   Schema   |                              Description
    --------------------+---------+------------+------------------------------------------------------------------------
     pg_stat_kcache     | 2.2.1   | public     | Kernel statistics gathering
     pg_stat_statements | 1.9     | public     | track planning and execution statistics of all SQL statements executed
     ...

Set up the profile database

Run the following statements using a privileged account.

  1. Create the profile database.

    CREATE DATABASE profile;
  2. Connect to the profile database and install the required extensions.

    \c profile
    CREATE EXTENSION plpgsql;
    CREATE EXTENSION dblink;
    CREATE EXTENSION pg_profile;
  3. Verify the extensions are installed.

    \dx

    Expected output:

    Name        | Version |   Schema   |                         Description
    ------------+---------+------------+--------------------------------------------------------------
     dblink     | 1.2     | public     | connect to other PostgreSQL databases from within a database
     pg_profile | 4.0     | public     | PostgreSQL load profile repository and report builder
     plpgsql    | 1.0     | pg_catalog | PL/pgSQL procedural language
     ...

Register the server database connection

From the profile database, register the server database as a monitoring target. Run the following statement using a privileged account.

SELECT create_server('server', 'host=<host> dbname=server port=<port> user=<user> password=<password>');
ParameterExampleDescription
host127.0.0.1Endpoint of the RDS instance where the server database runs. See the table below for values by network topology.
dbnameserverName of the server database.
port3002Port of the RDS instance where the server database runs. Run SHOW PORT; to get the port.
usertest_userPrivileged account username for the server database instance.
passwordT123456!Password of the account.

`host` values by network topology:

TopologyValue for host
Same RDS instance127.0.0.1
Different instances, same virtual private cloud (VPC)Internal endpoint of the server database instance
Different instances, different VPCsPublic endpoint of the server database instance. The profile database instance must be configured with a NAT gateway and a public IP address.
To get the internal and public endpoints of an instance, see View and modify the endpoint and port number of an instance.

Expected output:

show_servers
---------------------------------------------------------------------------------------
 (local,"dbname=profile port=3002",t,)
 (server,"host=127.0.0.1 dbname=server port=3002 user=test_user password=****",t,)
(2 rows)
Creating a server connection also creates a local connection representing the profile database itself. You can see it in the output above.

Configure the profile database connection

After the local connection is created, configure its credentials. Run the following statement using a privileged account.

SELECT set_server_connstr('local','host=127.0.0.1 dbname=profile port=<port> user=<user> password=<password>');
ParameterExampleDescription
host127.0.0.1Set to 127.0.0.1.
dbnameprofileName of the profile database.
port3002Port of the profile database instance. Run SHOW PORT; to get the value.
usertest_userPrivileged account username for the profile database instance.
passwordT123456!Password of the account.

Collect snapshots and generate reports

Collect a snapshot

From the profile database, run take_sample() to collect a snapshot from all registered servers. Use a privileged account.

SELECT take_sample();

Expected output:

 take_sample
-------------------------
 (server,OK,00:00:00.52)
 (local,OK,00:00:00.51)
(2 rows)

Collect at least two snapshots before generating a report—the report covers the activity between two snapshot points.

View collected snapshots

SELECT * FROM show_samples('server');

Example output:

 sample |      sample_time       | sizes_collected | dbstats_reset | bgwrstats_reset | archstats_reset
--------+------------------------+-----------------+---------------+-----------------+-----------------
      1 | 2022-09-30 02:14:07+00 | t               |               |                 |
      2 | 2022-09-30 02:16:59+00 | t               |               |                 |
      3 | 2022-09-30 02:17:58+00 | t               |               |                 |

Generate a report

A report covers the activity between two snapshots—specify the start and end sample numbers.

Option 1: From psql in the profile database

\o report_2_3.html
SELECT get_report('server',2,3);

Option 2: From the command-line interface (CLI)

psql -Aqtc "SELECT profile.get_report('server',2,3)" \
  -o report_server_2_3.html \
  -d profile \
  -h <endpoint of the profile database instance> \
  -p 5432 \
  -U <privileged account of the profile database instance>

Both methods export the report as an HTML file to your local machine.

Automate snapshot collection

Use pg_cron to run take_sample() on a schedule. Collect snapshots once or twice per hour to capture meaningful intervals without generating excessive data.

What's next