|
| 1 | + |
| 2 | +:sectnums: |
| 3 | +:sectnumlevels: 5 |
| 4 | + |
| 5 | += pg_profile |
| 6 | + |
| 7 | +== Overview |
| 8 | +pg_profile is an extension tool for PostgreSQL database performance analysis. It is mainly used to collect resource-intensive activities in a target database, helping users gain in-depth insight into database runtime status, identify performance bottlenecks, and perform optimization. Its report is essentially a "delta analysis between two sample points", deriving the incremental load within the sampling interval, with sample point sequence numbers starting from 1. |
| 9 | + |
| 10 | +pg_profile hard-depends on two extensions: dblink and plpgsql (it is written entirely in SQL and PL/pgSQL and requires no external libraries or software). Additionally, it is recommended to install the pg_stat_statements extension to obtain SQL statement-level statistics in the reports. The version of pg_profile is strongly tied to the version of PostgreSQL, currently supporting up to PG 18. For the specific version support, please refer to the README in the official pg_profile github repository. |
| 11 | + |
| 12 | +Both the PG mode and Oracle compatibility mode of IvorySQL have been adapted for pg_profile. Note that in Oracle compatibility mode, before compiling pg_profile, you need to manually modify the control.tpl file in the extension source code to add a configuration item `pg_dialect = true`, otherwise the installation will fail. |
| 13 | + |
| 14 | +Project address: <https://github.com/zubkov-andrei/pg_profile> |
| 15 | + |
| 16 | +License: PostgreSQL License |
| 17 | + |
| 18 | +== Installation and Enabling |
| 19 | + |
| 20 | +=== Source Code Compilation |
| 21 | +To install pg_profile in IvorySQL's Oracle compatibility mode, you need to first modify the control.tpl file of pg_profile to add the `pg_dialect` configuration item: |
| 22 | +[literal] |
| 23 | +---- |
| 24 | +# pg_profile/control.tpl |
| 25 | +pg_dialect = true |
| 26 | +---- |
| 27 | + |
| 28 | +Perform source code compilation and installation: |
| 29 | +[literal] |
| 30 | +---- |
| 31 | +# Build and install pg_profile and its dependent extensions |
| 32 | +make -C contrib/dblink install |
| 33 | +make -C contrib/pg_stat_statements install |
| 34 | +make -C contrib/pg_profile install |
| 35 | +---- |
| 36 | + |
| 37 | +The installation artifacts are `pg_profile.control` and `pg_profile--4.11.sql`. In IvorySQL's Oracle compatibility mode, you can verify that the generated `pg_profile.control` file carries the `pg_dialect` declaration: |
| 38 | +[literal] |
| 39 | +---- |
| 40 | +default_version = '4.11' |
| 41 | +requires = 'dblink,plpgsql' |
| 42 | +superuser = false |
| 43 | +
|
| 44 | +pg_dialect = true |
| 45 | +---- |
| 46 | + |
| 47 | +=== Modify Configuration |
| 48 | +The pg_stat_statements that pg_profile depends on must be loaded at server startup via `shared_preload_libraries`. |
| 49 | + |
| 50 | +Edit `ivorysql.conf` and append `pg_stat_statements` to the end of the `shared_preload_libraries` configuration item: |
| 51 | +[literal] |
| 52 | +---- |
| 53 | +# ivorysql.conf |
| 54 | +shared_preload_libraries = 'liboracle_parser, ivorysql_ora, pg_stat_statements' |
| 55 | +---- |
| 56 | + |
| 57 | +=== Restart the Service |
| 58 | +[literal] |
| 59 | +---- |
| 60 | +pg_ctl -D $PGDATA restart |
| 61 | +---- |
| 62 | + |
| 63 | +=== Install the Extension |
| 64 | +The commands are identical in both PG mode and Oracle mode sessions: |
| 65 | +[literal] |
| 66 | +---- |
| 67 | +CREATE SCHEMA profile; |
| 68 | +CREATE SCHEMA dblink; |
| 69 | +CREATE SCHEMA statements; |
| 70 | +CREATE EXTENSION dblink SCHEMA dblink; |
| 71 | +CREATE EXTENSION pg_stat_statements SCHEMA statements; |
| 72 | +CREATE EXTENSION pg_profile SCHEMA profile; |
| 73 | +
|
| 74 | +SELECT extname, extversion FROM pg_extension WHERE extname = 'pg_profile'; |
| 75 | + extname | extversion |
| 76 | +------------+------------ |
| 77 | + pg_profile | 4.11 |
| 78 | +---- |
| 79 | + |
| 80 | +In Oracle compatibility mode, you can run the following query to confirm that the extension functions of pg_profile have been pinned to the PG syntax parser: |
| 81 | +[literal] |
| 82 | +---- |
| 83 | +SELECT proname, proconfig FROM pg_proc |
| 84 | +WHERE proname = 'take_sample' AND proconfig IS NOT NULL LIMIT 1; |
| 85 | + proname | proconfig |
| 86 | +-------------+------------------------------------------------------------- |
| 87 | + take_sample | {ivorysql.compatible_mode=pg,search_path=profile} |
| 88 | +---- |
| 89 | + |
| 90 | +== Usage Workflow |
| 91 | + |
| 92 | +=== Create Samples |
| 93 | +[literal] |
| 94 | +---- |
| 95 | +-- First sampling |
| 96 | +SELECT * FROM profile.take_sample(); |
| 97 | + server | result | elapsed |
| 98 | +--------+--------+------------- |
| 99 | + local | OK | 00:00:01.34 |
| 100 | +
|
| 101 | +-- ...after the business workload runs for a while, sample again |
| 102 | +SELECT * FROM profile.take_sample(); |
| 103 | +---- |
| 104 | + |
| 105 | +In production environments, periodic sampling via scheduled tasks is typically used (e.g., once every 30 minutes), which can be combined with pg_cron or an external crontab: |
| 106 | +[literal] |
| 107 | +---- |
| 108 | +*/30 * * * * psql -c 'SELECT profile.take_sample()' >/dev/null |
| 109 | +---- |
| 110 | + |
| 111 | +=== View Samples |
| 112 | +[literal] |
| 113 | +---- |
| 114 | +SELECT sample, sample_time, sizes_collected FROM profile.show_samples(); |
| 115 | + sample | sample_time | sizes_collected |
| 116 | +--------+------------------------+----------------- |
| 117 | + 1 | 2026-06-12 09:00:00+00 | t |
| 118 | + 2 | 2026-06-12 09:30:00+00 | t |
| 119 | +---- |
| 120 | + |
| 121 | +=== Generate Reports |
| 122 | +[literal] |
| 123 | +---- |
| 124 | +-- Generate the workload report between sample 1 and sample 2 (HTML text) |
| 125 | +\o report_1_2.html |
| 126 | +SELECT profile.get_report(1, 2); |
| 127 | +\o |
| 128 | +---- |
| 129 | + |
| 130 | +The above functions are invoked and produce identical results in an Oracle mode session (Oracle port/1521). |
| 131 | + |
| 132 | +== Notes |
| 133 | + |
| 134 | +=== Adaptation Description |
| 135 | +IvorySQL can directly install and use the pg_profile extension in PG mode. However, in Oracle compatibility mode, you need to add the `pg_dialect` configuration item to the control.tpl file of pg_profile at compile time to enable the PG syntax parser and avoid installation failure. |
| 136 | + |
| 137 | +=== Adaptation Boundary |
| 138 | +The `pg_dialect` adaptation mechanism protects *the extension's own code*; the SQL written in the caller's session is still parsed according to the session dialect. When calling pg_profile in an Oracle mode session, the user's own expressions in the statements must conform to Oracle mode syntax, for example: |
| 139 | +[literal] |
| 140 | +---- |
| 141 | +-- In an Oracle session: PG-style interval literals will cause an error during session parsing |
| 142 | +SELECT profile.set_server_size_sampling('local', current_time - interval '10 minute', ...); -- ERROR |
| 143 | +
|
| 144 | +-- Use a syntax acceptable to the session dialect, or perform management operations in a PG mode session |
| 145 | +---- |
0 commit comments