Coder Social home page Coder Social logo

cybertec-postgresql / pg_show_plans Goto Github PK

View Code? Open in Web Editor NEW
185.0 15.0 23.0 101 KB

Show query plans of all currently running SQL statements

Home Page: https://www.cybertec-postgresql.com/en/products/pg-show-plans/

License: Other

Makefile 3.45% C 94.12% PLpgSQL 2.43%
postgresql-extension postgresql

pg_show_plans's Introduction

pg_show_plans

PostgreSQL extension that shows query plans of all the currently running SQL statements. Query plans can be shown in several formats, like JSON or YAML.

This extension creates a hash table within shared memory. The hash table is not resizable, thus, no new plans can be added once it has been filled up.

INSTALL

PostgreSQL versions 12 and newer are supported.

Install PostgreSQL before proceeding. Make sure to have pg_config binary, these are typically included in -dev and -devel packages.

git clone https://github.com/cybertec-postgresql/pg_show_plans.git
cd pg_show_plans
make
make install

Configure

Add pg_show_plans to shared_preload_libraries within postgresql.conf:

shared_preload_libraries = 'pg_show_plans'

Restart the server, and invoke CREATE EXTENSION pg_show_plans;:

postgresql=# CREATE EXTENSION pg_show_plans;
CREATE EXTENSION
postgresql=#

USAGE

To see the query plans:

testdb=# SELECT * FROM pg_show_plans;
  pid  | level | userid | dbid  |                                 plan
-------+-------+--------+-------+-----------------------------------------------------------------------
 11473 |     0 |     10 | 16384 | Function Scan on pg_show_plans  (cost=0.00..10.00 rows=1000 width=56)
 11504 |     0 |     10 | 16384 | Function Scan on print_item  (cost=0.25..10.25 rows=1000 width=524)
 11504 |     1 |     10 | 16384 | Result  (cost=0.00..0.01 rows=1 width=4)
(3 rows)

To get query plans and see the corresponding query expression:

testdb=# \x
Expanded display is on.
testdb=# SELECT * FROM pg_show_plans_q;
-[ RECORD 1 ]-----------------------------------------------------------------------------------------
pid   | 11473
level | 0
plan  | Sort  (cost=72.08..74.58 rows=1000 width=80)                                                  +
      |   Sort Key: pg_show_plans.pid, pg_show_plans.level                                            +
      |   ->  Hash Left Join  (cost=2.25..22.25 rows=1000 width=80)                                   +
      |         Hash Cond: (pg_show_plans.pid = s.pid)                                                +
      |         Join Filter: (pg_show_plans.level = 0)                                                +
      |         ->  Function Scan on pg_show_plans  (cost=0.00..10.00 rows=1000 width=48)             +
      |         ->  Hash  (cost=1.00..1.00 rows=100 width=44)                                         +
      |               ->  Function Scan on pg_stat_get_activity s  (cost=0.00..1.00 rows=100 width=44)
query | SELECT p.pid, p.level, p.plan, a.query FROM pg_show_plans p                                   +
      |    LEFT JOIN pg_stat_activity a                                                               +
      |    ON p.pid = a.pid AND p.level = 0 ORDER BY p.pid, p.level;
-[ RECORD 2 ]-----------------------------------------------------------------------------------------
pid   | 11517
level | 0
plan  | Function Scan on print_item  (cost=0.25..10.25 rows=1000 width=524)
query | SELECT * FROM print_item(1,20);
-[ RECORD 3 ]-----------------------------------------------------------------------------------------
pid   | 11517
level | 1
plan  | Result  (cost=0.00..0.01 rows=1 width=4)
query |

BENCHMARKS

pgbench -c 10 -j 3 -t 5000 -S plain PostgreSQL 16.1:

tps = 193655.084802 (without initial connection time)
tps = 200890.346014 (without initial connection time)
tps = 199931.223659 (without initial connection time)

pgbench -c 10 -j 3 -t 5000 -S PostgreSQL 16.1 with pg_show_plans version 2.1.0:

tps = 166564.507102 (without initial connection time)
tps = 172814.245424 (without initial connection time)
tps = 174658.455390 (without initial connection time)

In overall approximately 15% performance penalty.

REFERENCE

GUC Variables

  • pg_show_plans.plan_format = text: query plans output format, either of text, json, yaml, and xml.
  • pg_show_plans.max_plan_length = 16384: query plan maximal length in bytes. This value affects the amount of shared memory the extension asks for, the server may not start if the value is too high.
  • pg_show_plans.is_enabled = true: enable or disable the extension by assigning to this variable.

Default values are shown after '=' sign.

Views

  • pg_show_plans: defined as SELECT * FROM pg_show_plans(); for convenience.
  • pg_show_plans_q: same as pg_show_plans, but it has one more column with the corresponding query strings.

Functions

  • pg_show_plans(): show query plans:
    • pid: server process ID that runs the query.
    • level: query nest level. Top level is 0. For example, if you execute a simple select query, the level of this query's plan is 0. If you execute a function that invokes a select query, level 0 is the plan of the function and level 1 is the plan of the select query invoked by the function.
    • userid: user ID who runs the query.
    • dbid: database ID the query runs in.
    • plan: query plan.

pg_show_plans's People

Contributors

df7cb avatar kmoppel avatar kostiantyn-nemchenko avatar kovmir avatar laurenz avatar s-hironobu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pg_show_plans's Issues

queryid - pg_show_plans

Hi,

Would it make sense to add the queryid to the pg_show_plans view, so the executed query can be easily mapped to its execution stats found in pg_stat_statements ?

Would it be possible to hold the records/data a bit longer in the pg_show_plans view, so they could be collected by a external tool every minute for instance ?

Update the Readme to show how to create Makefile.global

The Readme shows these steps for building and installing the pg_show_plans extension:

$ tar xvfj postgresql-12.2.tar.bz2
$ cd postgresql-12.2/contrib
$ git clone https://github.com/cybertec-postgresql/pg_show_plans.git
$ cd pg_show_plans
$ make && make install

When I followed these steps, I saw these errors:

Makefile:16: ../../src/Makefile.global: No such file or directory
Makefile:17: /contrib/contrib-global.mk: No such file or directory

After some searching, I found a page describing Installing PostgreSQL from source and learned I needed to do this:

$ cd postgresql-12.2
$ ./configure --prefix=/usr/pgsql-12

where the path specified for prefix is the path to the postgresql instance on the server. Having done this, the missing files were created:

  • Makefile.global
  • Makefile.port -> ../src/makefiles/Makefile.linux

I could then proceed with the build and install

$ cd postgresql-12.2/contrib
$ git clone https://github.com/cybertec-postgresql/pg_show_plans.git
$ cd pg_show_plans
$ make
$ sudo make install

I suggest you update your Readme.md file to include the configure step.

I also suggest you also add an example wget command

$ wget https://ftp.postgresql.org/pub/source/v12.2/postgresql-12.2.tar.bz2
$ tar xvfj postgresql-12.2.tar.bz2

Thank you for making this tool available.

RPMs?

Are there any known sources of pre-built RPMs for this?

Thanks.

SpinLock Performance Decline

When pg_show_plans is enable, it brings the performance down seriously:

Stress testing tool:benchmark (200 Client)

  • before (shared_preload_libraries='')
    Measured tpmC = 315000
    Measured tpmTOTAL = 694000
  • after (shared_preload_libraries='pg_show_plans')
    Measured tpmC = 30400
    Measured tpmTOTAL = 70300

We print the call stack with 'pstack'

#0  0x00007f644ccd0b3b in do_futex_wait.constprop.1 () from /lib64/libpthread.so.0
#1  0x00007f644ccd0bcf in __new_sem_wait_slow.constprop.0 () from /lib64/libpthread.so.0
#2  0x00007f644ccd0c6b in sem_wait@@GLIBC_2.2.5 () from /lib64/libpthread.so.0
#3  0x0000000000707452 in PGSemaphoreLock (sema=0x7f53c6610c38) at pg_sema.c:327
#4  0x00000000007800ec in LWLockAcquire (lock=0x7f53c661e280, mode=mode@entry=LW_SHARED) at lwlock.c:1331
#5  0x00007f6441ddd4ec in entry_store (nested_level=0, plan=0x2d6d298 "Insert on bmsql_new_order  (cost=0.00..0.01 rows=1 width=12)\n  ->  Result  (cost=0.00..0.01 rows=1 width=12)") at pg_show_plans.c:555
#6  pgsp_ExecutorStart (queryDesc=<optimized out>, eflags=<optimized out>) at pg_show_plans.c:406
#7  0x0000000000792d46 in ProcessQuery (plan=<optimized out>, sourceText=0x2d36b78 "INSERT INTO bmsql_new_order (    no_o_id, no_d_id, no_w_id) VALUES ($1, $2, $3)", params=0x2d36c20, queryEnv=0x0, dest=0xa0cbe0 <donothingDR>, qc=0x7ffc98543370) at pquery.c:155
#8  0x0000000000792fb4 in PortalRunMulti (portal=portal@entry=0x2b84ac8, isTopLevel=isTopLevel@entry=true, setHoldSnapshot=setHoldSnapshot@entry=false, dest=0xa0cbe0 <donothingDR>, dest@entry=0x2af3298, altdest=0xa0cbe0 <donothingDR>, altdest@entry=0x2af3298, qc=qc@entry=0x7ffc98543370) at pquery.c:1269
#9  0x00000000007939cd in PortalRun (portal=portal@entry=0x2b84ac8, count=count@entry=1, isTopLevel=isTopLevel@entry=true, run_once=<optimized out>, dest=dest@entry=0x2af3298, altdest=altdest@entry=0x2af3298, qc=qc@entry=0x7ffc98543370) at pquery.c:783
#10 0x0000000000791482 in exec_execute_message (max_rows=1, portal_name=0x2af2e88 "") at postgres.c:2282
#11 PostgresMain (argc=<optimized out>, argv=argv@entry=0x2b22128, dbname=0x2b22028 "benchmarksql300", username=<optimized out>) at postgres.c:4506
#12 0x0000000000488208 in BackendRun (port=<optimized out>, port=<optimized out>) at postmaster.c:4988
#13 BackendStartup (port=0x2b19410) at postmaster.c:4672
#14 ServerLoop () at postmaster.c:1959
#15 0x000000000071a6f2 in PostmasterMain (argc=argc@entry=1, argv=argv@entry=0x2aed9a0) at postmaster.c:1495
#16 0x00000000004891ed in main (argc=1, argv=0x2aed9a0) at main.c:231
#0  0x00007f644b569a13 in __select_nocancel () from /lib64/libc.so.6
#1  0x00000000008eb91a in pg_usleep (microsec=<optimized out>) at pgsleep.c:56
#2  0x00000000007874d5 in perform_spin_delay (status=status@entry=0x7ffc98542480) at s_lock.c:138
#3  0x0000000000787610 in s_lock (lock=0x7f643c56d610 "", file=file@entry=0x7f6441dde040 "pg_show_plans.c", line=line@entry=349, func=func@entry=0x7f6441dde360 <__func__.26729> "pgsp_ExecutorStart") at s_lock.c:99
#4  0x00007f6441ddd68b in pgsp_ExecutorStart (queryDesc=0x2c02738, eflags=16) at pg_show_plans.c:349
#5  0x0000000000668ee0 in _SPI_pquery (tcount=1, fire_triggers=false, queryDesc=<optimized out>) at spi.c:2509
#6  _SPI_execute_plan (plan=plan@entry=0x2c59dd8, paramLI=0x2c026a8, snapshot=snapshot@entry=0x0, crosscheck_snapshot=crosscheck_snapshot@entry=0x0, read_only=read_only@entry=false, fire_triggers=fire_triggers@entry=false, tcount=tcount@entry=1) at spi.c:2288
#7  0x0000000000669334 in SPI_execute_snapshot (plan=plan@entry=0x2c59dd8, Values=Values@entry=0x7ffc985426f0, Nulls=Nulls@entry=0x7ffc985426b0 "   nX\177", snapshot=snapshot@entry=0x0, crosscheck_snapshot=crosscheck_snapshot@entry=0x0, read_only=read_only@entry=false, fire_triggers=fire_triggers@entry=false, tcount=tcount@entry=1) at spi.c:616
#8  0x000000000083f66a in ri_PerformCheck (riinfo=riinfo@entry=0x2bf8ee8, qkey=qkey@entry=0x7ffc98542970, qplan=0x2c59dd8, fk_rel=fk_rel@entry=0x7f644cf9f298, pk_rel=pk_rel@entry=0x7f644cf8af98, oldslot=oldslot@entry=0x0, newslot=newslot@entry=0x2d3e748, detectNewRows=detectNewRows@entry=false, expect_OK=expect_OK@entry=5) at ri_triggers.c:2277
#9  0x000000000083f913 in RI_FKey_check (trigdata=<optimized out>) at ri_triggers.c:392
#10 0x000000000060c09b in ExecCallTriggerFunc (trigdata=trigdata@entry=0x7ffc98542e20, tgindx=tgindx@entry=0, finfo=finfo@entry=0x2c79288, instr=instr@entry=0x0, per_tuple_context=per_tuple_context@entry=0x2c1f460) at trigger.c:2066
#11 0x000000000060cdce in AfterTriggerExecute (trigdesc=0x2c78d38, trigdesc=0x2c78d38, trig_tuple_slot2=0x0, trig_tuple_slot1=0x0, per_tuple_context=0x2c1f460, instr=0x0, finfo=0x2c79288, relInfo=0x2c78da8, event=0x2d63358, estate=0x2c78af8) at trigger.c:3955
#12 afterTriggerInvokeEvents (events=events@entry=0x2c68768, firing_id=6, estate=estate@entry=0x2c78af8, delete_ok=delete_ok@entry=false) at trigger.c:4169
#13 0x00000000006127c8 in AfterTriggerEndQuery (estate=estate@entry=0x2c78af8) at trigger.c:4505
#14 0x0000000000630417 in standard_ExecutorFinish (queryDesc=0x2d37600) at execMain.c:426
#15 0x00007f6441ddcf65 in pgsp_ExecutorFinish (queryDesc=0x2d37600) at pg_show_plans.c:493
#16 0x0000000000792d98 in ProcessQuery (plan=<optimized out>, sourceText=0x2d37398 "INSERT INTO bmsql_order_line (    ol_o_id, ol_d_id, ol_w_id, ol_number,     ol_i_id, ol_supply_w_id, ol_quantity,     ol_amount, ol_dist_info) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", params=0x2d374c0, queryEnv=0x0, dest=0xa0cbe0 <donothingDR>, qc=0x7ffc98543370) at pquery.c:194
#17 0x0000000000792fb4 in PortalRunMulti (portal=portal@entry=0x2b84ac8, isTopLevel=isTopLevel@entry=true, setHoldSnapshot=setHoldSnapshot@entry=false, dest=0xa0cbe0 <donothingDR>, dest@entry=0x2af3298, altdest=0xa0cbe0 <donothingDR>, altdest@entry=0x2af3298, qc=qc@entry=0x7ffc98543370) at pquery.c:1269
#18 0x00000000007939cd in PortalRun (portal=portal@entry=0x2b84ac8, count=count@entry=1, isTopLevel=isTopLevel@entry=true, run_once=<optimized out>, dest=dest@entry=0x2af3298, altdest=altdest@entry=0x2af3298, qc=qc@entry=0x7ffc98543370) at pquery.c:783
#19 0x0000000000791482 in exec_execute_message (max_rows=1, portal_name=0x2af2e88 "") at postgres.c:2282
#20 PostgresMain (argc=<optimized out>, argv=argv@entry=0x2b22128, dbname=0x2b22028 "benchmarksql300", username=<optimized out>) at postgres.c:4506
#21 0x0000000000488208 in BackendRun (port=<optimized out>, port=<optimized out>) at postmaster.c:4988
#22 BackendStartup (port=0x2b19410) at postmaster.c:4672
#23 ServerLoop () at postmaster.c:1959
#24 0x000000000071a6f2 in PostmasterMain (argc=argc@entry=1, argv=argv@entry=0x2aed9a0) at postmaster.c:1495
#25 0x00000000004891ed in main (argc=1, argv=0x2aed9a0) at main.c:231

and find that 'SpinLock' and 'LWLock' cause too many data-race

Query consumes transaction ID

hi,

when i used the follow sql: select * from pg_show_plans,and then i execute select txid_current(),i find current transaction id has increased by 2
postgres=# select txid_current();
txid_current
11057183
(1 row)

postgres=# select * from pg_show_plans ;
...

postgres=# select txid_current();
txid_current
11057185
(1 row)

Will this cause the transaction ID Wraparound quickly?

Control plan format using a GUC variable

Instead of having four functions to set plan format, it should rather be a single GUC variable with an assign hook to propagate the changes into shared memory. Query plan format is to be controlled via pg_show_plans.plan_format GUC variable.

Size of Hash table and warning querying catalog

Hi Team,

  1. When the server starts, pg_show_plans makes a hashtable on the shared-memory in order to temporarily store query plans. The hashtable size cannot be changed, so the plans are not stored if the hashtable is full.
    --- What is the size of the hashtable ? I see max_plan_length*max_connections is reserved, is the assumption correct or are these different ?

  2. We get below warning when query the catalog table:

postgres=# select pg_catalog.shobj_description(d.oid, 'pg_database') as "Description" FROM pg_catalog.pg_database d JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid ORDER BY 1;
WARNING: The 1th level plan could not be stored in the entry whose pid is 42363 because the entry could not find.
WARNING: The 1th level plan could not be stored in the entry whose pid is 42363 because the entry could not find.
WARNING: The 1th level plan could not be stored in the entry whose pid is 42363 because the entry could not find.
WARNING: The 1th level plan could not be stored in the entry whose pid is 42363 because the entry could not find.
                     Description 
--------------------------------------------------------
 default administrative connection database
 default template for new databases

Start Disabled GUC Option

As such troubleshooting / debugging is not always used and has a small performance impact, would be nice if the extension could start in disabled mode and one could enable it when the need arises with pg_show_plans_enable().
An alternative is of course to disable the extension from "shared_preload_libraries", but this requires server restart which might not work for all.

Explain is slow with tables having many columns

Hello,
working on an other extension using explain (to build a planid), I met this problem:
https://www.postgresql-archive.org/Explain-is-slow-with-tables-having-many-columns-td6047279.html#a6047280
https://www.postgresql-archive.org/Re-Explain-is-slow-with-tables-having-many-columns-td6047284.html

Did you think about storing the "Plan Tree" structured data in spite of explain text (explain being executed only when pg_show_plans is queried) ?

Thanks in advance for your answer, and thanks again for this very usefull tool !
Regards
PAscal

When I make a query, a transaction ID will be consumed

hi,
when i used the follow sql: select * from pg_show_plans,and then i execute select txid_current(),i find current transaction id has increased by 2
postgres=# select txid_current();
txid_current

 11057183

(1 row)

postgres=# select * from pg_show_plans ;
pid | level | userid | dbid | plan
-------+-------+--------+--------+-----------------------------------------------------------------------
20100 | 0 | 10 | 333744 | Function Scan on pg_show_plans (cost=0.00..10.00 rows=1000 width=56)
(1 row)

postgres=# select txid_current();
txid_current

 11057185

(1 row)

Will this cause the transaction ID Wraparound quickly?

Server crashes due to the lack of memory

This was raised on the pgsql-bugs list:
https://www.postgresql.org/message-id/flat/18308-f55e8ec2ee192cb5%40postgresql.org

There seem to be crashes with PostgreSQL 15.4 and pg_shao_plans with the query

select tc.table_schema, tc.table_name, 
       tc.constraint_type,tc.constraint_name, tc.is_deferrable,
       tc2.table_name as child_table,
       rc.unique_constraint_name as refer_key,
       case when rc.unique_constraint_name is not null then
            (select tc1.table_name 
               from information_schema.table_constraints tc1
              where tc1.constraint_name = rc.unique_constraint_name)
       end as ref_table,
       cc.check_clause,
       kc.column_name,
       kc.ordinal_position
  from information_schema.table_constraints tc
  left join information_schema.referential_constraints rc
    on tc.constraint_name = rc.constraint_name
  left join information_schema.check_constraints cc
    on tc.constraint_name = cc.constraint_name
  left join information_schema.key_column_usage kc
    on tc.constraint_name = kc.constraint_name
  left join LATERAL (
       select tc2.table_name, rc1.unique_constraint_name 
              from information_schema.referential_constraints rc1
              join information_schema.table_constraints tc2
                on rc1.constraint_name = tc2.constraint_name 
             where tc.constraint_name = rc1.unique_constraint_name
             ) tc2 on true
 where tc.table_name = 't1';

I didn't try to reproduce the error.

Can we make view pg_show_plans without extension?

Hi!
My solution:

CREATE OR REPLACE FUNCTION json_explain(
    query TEXT,
    params TEXT[] DEFAULT ARRAY[]::text[]
) RETURNS SETOF JSON AS $$
BEGIN
    RETURN QUERY
        EXECUTE 'EXPLAIN ('
                    || ARRAY_TO_STRING(ARRAY_APPEND(params, 'FORMAT JSON'), ',')
                    || ')'
        || query;
END
$$ LANGUAGE plpgsql;

--test
SELECT json_explain('SELECT * FROM pg_class', ARRAY['ANALYSE'])->0;

SELECT json_explain(query)->0, * FROM pg_stat_activity;

code review

I seems that norm_query variable is not used in entry_store(),
shouldn't :

	/* We postpone this pfree until we're out of the lock */
	if (norm_query)
		pfree(norm_query);

be modified ?

compile error

Bug Report

Version

  • PostgreSQL: 12.13
  • pg_show_plans: f123bfa

Step to reproduce the behavior

$ curl -sSL -o /tmp/pg_show_plans-master.zip https://github.com/cybertec-postgresql/pg_show_plans/archive/refs/heads/master.zip
$ unzip /tmp/pg_show_plans-master.zip -d /tmp/
Archive:  /tmp/pg_show_plans-master.zip
f123bfa57c13a88683135bedb9e2e72b135b9611
   creating: /tmp/pg_show_plans-master/
  inflating: /tmp/pg_show_plans-master/.gitignore
  inflating: /tmp/pg_show_plans-master/LICENCE
  inflating: /tmp/pg_show_plans-master/Makefile
  inflating: /tmp/pg_show_plans-master/README.md
  inflating: /tmp/pg_show_plans-master/pg_show_plans--1.0.sql
  inflating: /tmp/pg_show_plans-master/pg_show_plans.c
  inflating: /tmp/pg_show_plans-master/pg_show_plans.control
$ cd /tmp/pg_show_plans-master
$ make USE_PGXS=1 && make USE_PGXS=1 install

gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer -fPIC -I. -I./ -I/usr/include/postgresql/12/server -I/usr/include/postgresql/internal  -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2   -c -o pg_show_plans.o pg_show_plans.c
pg_show_plans.c: In function ‘_PG_init’:
pg_show_plans.c:175:7: error: ‘process_shared_preload_libraries_in_progress’ undeclared (first use in this function)
  175 |  if (!process_shared_preload_libraries_in_progress)
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pg_show_plans.c:175:7: note: each undeclared identifier is reported only once for each function it appears in
pg_show_plans.c: In function ‘pgsp_shmem_startup’:
pg_show_plans.c:245:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  245 |  bool    found; /* Does shared extension state structure exist? */
      |  ^~~~
pg_show_plans.c:248:13: error: ‘MaxConnections’ undeclared (first use in this function)
  248 |  pgsp_max = MaxConnections;
      |             ^~~~~~~~~~~~~~
pg_show_plans.c:282:7: error: ‘IsUnderPostmaster’ undeclared (first use in this function)
  282 |  if (!IsUnderPostmaster)
      |       ^~~~~~~~~~~~~~~~~
pg_show_plans.c: In function ‘pgsp_ExecutorStart’:
pg_show_plans.c:301:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  301 |  ExplainState *es = NewExplainState();
      |  ^~~~~~~~~~~~
pg_show_plans.c: In function ‘pgsp_ExecutorEnd’:
pg_show_plans.c:410:18: error: ‘MyProcPid’ undeclared (first use in this function); did you mean ‘MyProc’?
  410 |     delete_entry(MyProcPid);
      |                  ^~~~~~~~~
      |                  MyProc
pg_show_plans.c: In function ‘store_entry’:
pg_show_plans.c:455:12: error: ‘MyProcPid’ undeclared (first use in this function); did you mean ‘MyProc’?
  455 |  key.pid = MyProcPid;
      |            ^~~~~~~~~
      |            MyProc
pg_show_plans.c: In function ‘store_plan_into_entry’:
pg_show_plans.c:535:19: warning: implicit declaration of function ‘GetUserId’ [-Wimplicit-function-declaration]
  535 |   entry->userid = GetUserId();
      |                   ^~~~~~~~~
pg_show_plans.c:536:17: error: ‘MyDatabaseId’ undeclared (first use in this function)
  536 |   entry->dbid = MyDatabaseId;
      |                 ^~~~~~~~~~~~
pg_show_plans.c: In function ‘pg_show_plans’:
pg_show_plans.c:770:48: error: ‘work_mem’ undeclared (first use in this function)
  770 |  tupstore = tuplestore_begin_heap(true, false, work_mem);
      |                                                ^~~~~~~~
make: *** [<builtin>: pg_show_plans.o] Error 1

Install on mac with postgresql installed via brew

I installed postgresql via brew and then only installed the xcode commandline package (xcode-select --install). Installing this extension via make USE_PGXS=TRUE failed with

λ make  USE_PGXS=TRUE
clang -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -Wno-unused-command-line-argument -O2  -I. -I./ -I/usr/local/opt/postgresql@11/include/server -I/usr/local/opt/postgresql@11/include/internal -I/usr/local/Cellar/icu4c/64.2/include -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -I/usr/local/opt/[email protected]/include -I/usr/local/opt/readline/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2   -c -o pg_show_plans.o pg_show_plans.c
clang: warning: no such sysroot directory: '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk' [-Wmissing-sysroot]
In file included from pg_show_plans.c:11:
In file included from /usr/local/opt/postgresql@11/include/server/postgres.h:46:
/usr/local/opt/postgresql@11/include/server/c.h:59:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
         ^~~~~~~~~
1 error generated.

The fix was to overwrite the hardcoded (from the brew compile of PG) systroot: make USE_PGXS=TRUE PG_SYSROOT=$(xcrun --show-sdk-path)

see citusdata/cstore_fdw#207 (comment) for more details about the sysroot problem.

map pg_show_plans.plan display rules to pg_stat_activity.query's one.

Hello,

When using pg_show_plans joined with pg_stat_activity,
It appears that the query columns keeps its value even after the end of its transaction
(with status = Idle), but plan column is erased as soon as the query is finished and
commited.

Would it be possible to map pg_show_plans.plan column behavior to the pg_stat_activity.query one
(keeping actual plan value visible until a new plan is executed) ?

Thanks in advance for your feedback.
Regards
PAscal

pg_show_plans_disable() is reset by each new backend startup (autovacum included)

Hello,
pg_show_plans_disable() effect, is disabled after each new backend startup inside pgsp_shmem_startup(), that sets
pgsp->is_enable = true;

fix proposal:

	if (!found)
	{
		/* First time through ... */
#if PG_VERSION_NUM >= 90600
		pgsp->lock = &(GetNamedLWLockTranche("pg_show_plans"))->lock;
#else
		pgsp->lock = LWLockAssign();
#endif
		SpinLockInit(&pgsp->elock);
	}  <<< to move 
	/* Set the initial value to is_enable */
	pgsp->is_enable = true;
#if PG_VERSION_NUM >= 90500
	pgsp->plan_format = plan_format;
#endif


into

	if (!found)
	{
		/* First time through ... */
#if PG_VERSION_NUM >= 90600
		pgsp->lock = &(GetNamedLWLockTranche("pg_show_plans"))->lock;
#else
		pgsp->lock = LWLockAssign();
#endif
		SpinLockInit(&pgsp->elock);

	/* Set the initial value to is_enable */
	pgsp->is_enable = true;
#if PG_VERSION_NUM >= 90500
	pgsp->plan_format = plan_format;
#endif
	 }  <<< moved

regards
PAscal

pg_show_plans & logical replication slot

Hello,
after having installed the extension pg_show_plans (i can reproduce it when you want),
i face an error when creating logical replication slots.
i created a dedicated cluster for that :

1/ compile pg_show_plans on the server
2/ add shared_preload_libraries: pg_show_plans
3/ create extension pg_show_plans.

then, on the server :
postgres@stock(test)=# select * from pg_create_logical_replication_slot('slot1','pgoutput');
ERROR: cannot create logical replication slot in transaction that has performed writes
postgres@stock(test)=#

image
where 7910 is my own pid, it is my session.

if i remove the extension, stop/start cluster:
image

shared_preload_libraries is still set to pg_show_plans:
image

if i remove pg_show_plans from shared_preload_libraries
image

then i can create a logical replication slot:
image

I can test more if you want, just ask.

ps : pgsql 12.2
pg_show_plans 1.0
(i have the same problem on pg10 & pg11)

if you want to reproduce the error without pg_show_plans:
https://github.com/postgres/postgres/blob/master/contrib/test_decoding/expected/decoding_in_xact.out

my .psqlrc
psqlrc.zip

ps : for those who are blocked, you can still create replication slot using

pg_recvlogical

but for pg_squeeze no way.

segfault querying pg_settings

Greetings.
After installing pgsp, any query referencing pg_settings causes segmentation fault. Disabling pgsp via configuration attribute does not fix it, problem persists as long as pg_show_plans is present in shared_preload_libraries

The database info:

PostgreSQL 14.6 (Ubuntu 14.6-1.pgdg20.04+1) on x86_64-pc-linux-gnu, compiled by gcc Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, 64-bit

Relevant log output:

2023-03-16 12:06:16.921 +05 [32] LOG:  00000: server process (PID 1223) was terminated by signal 11: Segmentation fault
2023-03-16 12:06:16.921 +05 [32] DETAIL:  Failed process was running: select * from pg_settings;

Core file:

Reading symbols from /usr/lib/postgresql/14/bin/postgres...
(No debugging symbols found in /usr/lib/postgresql/14/bin/postgres)
[New LWP 266]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `postgres: 14/main: test postgres 172.17.0.1(46460) SELECT                     '.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:65
65      ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory.
(gdb) where
#0  __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:65
#1  0x000055f360cc9c4a in appendStringInfoString ()
#2  0x000055f360c9903a in ?? ()
#3  0x000055f360c9ddd7 in GetConfigOptionByNum ()
#4  0x000055f360c9e148 in show_all_settings ()
#5  0x000055f3609f940c in ExecMakeTableFunctionResult ()
#6  0x000055f360a0a56a in ?? ()
#7  0x000055f3609f9ccb in ExecScan ()
#8  0x000055f3609f0f84 in standard_ExecutorRun ()
#9  0x00007f897a93c9e5 in ?? () from /usr/lib/postgresql/14/lib/pg_stat_statements.so
#10 0x00007f897a933829 in pgsp_ExecutorRun (queryDesc=0x55f36107f728, direction=ForwardScanDirection, count=0, execute_once=<optimized out>) at pg_show_plans.c:456
#11 0x000055f360b666db in ?? ()
#12 0x000055f360b67a03 in PortalRun ()
#13 0x000055f360b63c7a in ?? ()
#14 0x000055f360b65ddf in PostgresMain ()
#15 0x000055f360ae3f7b in ?? ()
#16 0x000055f360ae4dfc in PostmasterMain ()
#17 0x000055f3608611ad in main ()`

If it matters, the database is running inside a docker container.

GUC parameter crashes Postgres

Hi.
After setting the parameter pg_show_plans.is_enabled = false in the config file postgresql.conf or postgresql.auto.conf and trying to reload the configuration, postgres crashes with an error.

2024-05-15 17:45:38.602 2658283 0 LOG: received SIGHUP, reloading configuration files
2024-05-15 17:45:38.713 postgres [local] postgres 2658300 idle 0 FATAL: terminating connection due to unexpected postmaster exit

PostgreSQL 15.5, pg_show_plans 2.1

wrong CLANG path centos8

Hi,
I've detected a wrong path for CLANG in the Makefile.global on Centos 8.
Maybe it depends on Centos 8 or my environment, though I just leave a notice ;)

what I've changed:
231 #CLANG = /usr/lib64/ccache/clang
232 CLANG = /usr/bin/clang

after this changed make install works as expected

Postgresql 15 pg_show_plans.so: undefined symbol: elog_finish

Hi, version 1.1 support pg15?
And i install without errors in pg12

[oracle8 pg_show_plans]$ sudo make install
/usr/bin/mkdir -p '/usr/pgsql-15/lib'
/usr/bin/mkdir -p '/usr/pgsql-15/share/extension'
/usr/bin/mkdir -p '/usr/pgsql-15/share/extension'
/usr/bin/install -c -m 755 pg_show_plans.so '/usr/pgsql-15/lib/pg_show_plans.so'
/usr/bin/install -c -m 644 .//pg_show_plans.control '/usr/pgsql-15/share/extension/'
/usr/bin/install -c -m 644 .//pg_show_plans--1.0--1.1.sql .//pg_show_plans--1.1.sql '/usr/pgsql-15/share/extension/'
/usr/bin/mkdir -p '/usr/pgsql-15/lib/bitcode/pg_show_plans'
/usr/bin/mkdir -p '/usr/pgsql-15/lib/bitcode'/pg_show_plans/
/usr/bin/install -c -m 644 pg_show_plans.bc '/usr/pgsql-15/lib/bitcode'/pg_show_plans/./
cd '/usr/pgsql-15/lib/bitcode' && /usr/bin/llvm-lto -thinlto -thinlto-action=thinlink -o pg_show_plans.index.bc pg_show_plans/pg_show_plans.bc

/usr/pgsql-15/bin/pg_ctl -D /var/lib/pgsql/15 start
waiting for server to start....2023-05-19 11:42:23.041 UTC [83599] FATAL: could not load library "/usr/pgsql-15/lib/pg_show_plans.so": /usr/pgsql-15/lib/pg_show_plans.so: undefined symbol: elog_finish
2023-05-19 11:42:23.041 UTC [83599] LOG: database system is shut down

OS
Red Hat Enterprise Linux release 8.7 (Ootpa)

performances: getpid() vs MyProcPid

Hello,
playing with
do $$ declare i int;j int; begin for i in 1..1000000 loop select 1 into j; end loop; end; $$;
and pg_show_plans_enable()

perf tool on my Ubuntu server is showing an high cpu activity arround _getpid.
Replacing getpid() with MyProcPid in pg_show_plans seems to help.

Maybe you will be able to reproduce.
regards
PAscal

Make not work

When I make the Install like the Readme.md it not work because the Makefile.global is not available.

/postgresql-13.0/contrib/pg_show_plans> make
Makefile:16: ../../src/Makefile.global: No such file or directory
Makefile:17: /contrib/contrib-global.mk: No such file or directory
make: *** No rule to make target '/contrib/contrib-global.mk'.  Stop.

Nested plans after level 0 join their text with subsequent level plans

Greetings. I noticed the following behaviour while using pgsp: if a certain query shows more than 2 levels of nested queries, level 1 plan gets every subsequent level plan joined to it, and the same happens to any level higher than 1 (see the test output).
I made a small test to replicate the issue.

CREATE OR REPLACE FUNCTION inner_test3()
	RETURNS int4
	LANGUAGE plpgsql
AS $function$
	BEGIN
	return 1 where pg_sleep(5) is not null;
	END;
$function$;

CREATE OR REPLACE FUNCTION inner_test2()
	RETURNS int4
	LANGUAGE plpgsql
AS $function$
	declare 
	a text;
	begin
	select gen_random_uuid() into a where inner_test3() = 1;
	return 1;
	END;
$function$;

CREATE OR REPLACE FUNCTION inner_test()
	RETURNS int4
	LANGUAGE plpgsql
AS $function$
	BEGIN
	return inner_test2();
	END;
$function$;

After creating the functions we need two open db connections. In one run select inner_test(); , and in the other one runselect * from pg_show_plans order by pid, level asc until a plan for this query with three level shows up.
It consistently gives out the following output:

pid level userid dbid plan
11126 0 2777805 13726 Result  (cost=0.00..0.26 rows=1 width=4)
11126 1 2777805 13726 Result  (cost=0.25..0.27 rows=1 width=16)
One-Time Filter: (inner_test3() = 1)Result  (cost=0.00..0.01 rows=1 width=4)
One-Time Filter: (pg_sleep('5'::double precision) IS NOT NULL)
11126 2 2777805 13726 Result  (cost=0.00..0.01 rows=1 width=4)
One-Time Filter: (pg_sleep('5'::double precision) IS NOT NULL)

As you can see, level 1 plan got level 2 joined to it.
If this is an intended behaviour, can you make it use some sort of the separator between plan levels to be able to understand where each nested plan starts?

The database info: PostgreSQL 14.6 (Ubuntu 14.6-1.pgdg20.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, 64-bit

explain (SETTINGS on)

Hello,
First of all, thank you for this so long awaited extension, that works without needing any patch on core ! This is really helpfull !!!

I wanted to know if you thought about adding the explain SETTINGS parameter( available with pg12 and more), that permits to see all the modified parameters from the query execution context ?

Most monitored parameters as described here
https://fluca1978.github.io/2019/12/05/Explain_settings.html

Regards
PAscal

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.