On Wed, Feb 20, 2019 at 3:41 AM Michael Paquier <mich...@paquier.xyz> wrote:
> On Tue, Feb 19, 2019 at 09:56:28AM +0100, Magnus Hagander wrote: > > 2. Or probably even better, just put it in PgBackendStatus? Overhead here > > is a lot cheaper than PGPROC. > > > > ISTM 2 is probably the most reasonable option here? > > Yes, I forgot this one. That would be more consistent, even if the > information can be out of date quickly we don't care here. > I think it would be something like the attached. Thoughts? I did the "insert column in the middle of pg_stat_get_activity", I'm not sure that is right -- how do we treate that one? Do we just append at the end because people are expected to use the pg_stat_activity view? It's a nontrivial part of the patch. That one aside, does the general way to track it appear reasonable? (docs excluded until we have agreement on that) And should we also expose the oid in pg_stat_activity in this case, since we have it? -- Magnus Hagander Me: https://www.hagander.net/ <http://www.hagander.net/> Work: https://www.redpill-linpro.com/ <http://www.redpill-linpro.com/>
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index cdd5006a72..77be87c50a 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -45,6 +45,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "parser/parse_func.h" +#include "pgstat.h" #include "storage/ipc.h" #include "storage/lmgr.h" #include "storage/sinvaladt.h" @@ -3929,6 +3930,9 @@ InitTempTableNamespace(void) true); /* Advance command counter to make namespace visible */ CommandCounterIncrement(); + + /* Indicate that this is the xid that created the namespace */ + pgstat_report_temp_namespace_xid(GetTopTransactionId()); } else { diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 3e229c693c..081d655c91 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -709,7 +709,8 @@ CREATE VIEW pg_stat_activity AS S.backend_xid, s.backend_xmin, S.query, - S.backend_type + S.backend_type, + S.temp_namespace_xid FROM pg_stat_get_activity(NULL) AS S LEFT JOIN pg_database AS D ON (S.datid = D.oid) LEFT JOIN pg_authid AS U ON (S.usesysid = U.oid); diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 81c6499251..7af6563031 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -2923,6 +2923,7 @@ pgstat_bestart(void) /* Also make sure the last byte in each string area is always 0 */ beentry->st_clienthostname[NAMEDATALEN - 1] = '\0'; beentry->st_appname[NAMEDATALEN - 1] = '\0'; + beentry->st_temp_namespace_xid = InvalidTransactionId; beentry->st_activity_raw[pgstat_track_activity_query_size - 1] = '\0'; beentry->st_progress_command = PROGRESS_COMMAND_INVALID; beentry->st_progress_command_target = InvalidOid; @@ -3207,6 +3208,28 @@ pgstat_report_xact_timestamp(TimestampTz tstamp) pgstat_increment_changecount_after(beentry); } +/* + * Report the transaction id that created a temporary namespace in this + * session. + */ +void +pgstat_report_temp_namespace_xid(TransactionId xid) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + + if (!pgstat_track_activities || !beentry) + return; + + /* + * Update my status entry, following the protocol of bumping + * st_changecount before and after. We use a volatile pointer here to + * ensure the compiler doesn't try to get cute. + */ + pgstat_increment_changecount_before(beentry); + beentry->st_temp_namespace_xid = xid; + pgstat_increment_changecount_after(beentry); +} + /* ---------- * pgstat_read_current_status() - * diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 69f7265779..2b98af372b 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -541,7 +541,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) Datum pg_stat_get_activity(PG_FUNCTION_ARGS) { -#define PG_STAT_GET_ACTIVITY_COLS 26 +#define PG_STAT_GET_ACTIVITY_COLS 27 int num_backends = pgstat_fetch_stat_numbackends(); int curr_backend; int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0); @@ -645,6 +645,11 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) else nulls[16] = true; + if (TransactionIdIsValid(local_beentry->backendStatus.st_temp_namespace_xid)) + values[17] = TransactionIdGetDatum(local_beentry->backendStatus.st_temp_namespace_xid); + else + nulls[17] = true; + /* Values only available to role member or pg_read_all_stats */ if (has_privs_of_role(GetUserId(), beentry->st_userid) || is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS)) @@ -815,45 +820,45 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) bgw_type = GetBackgroundWorkerTypeByPid(beentry->st_procpid); if (bgw_type) - values[17] = CStringGetTextDatum(bgw_type); + values[18] = CStringGetTextDatum(bgw_type); else - nulls[17] = true; + nulls[18] = true; } else - values[17] = + values[18] = CStringGetTextDatum(pgstat_get_backend_desc(beentry->st_backendType)); /* SSL information */ if (beentry->st_ssl) { - values[18] = BoolGetDatum(true); /* ssl */ - values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version); - values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher); - values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits); - values[22] = BoolGetDatum(beentry->st_sslstatus->ssl_compression); + values[19] = BoolGetDatum(true); /* ssl */ + values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version); + values[21] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher); + values[22] = Int32GetDatum(beentry->st_sslstatus->ssl_bits); + values[23] = BoolGetDatum(beentry->st_sslstatus->ssl_compression); if (beentry->st_sslstatus->ssl_client_dn[0]) - values[23] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn); + values[24] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn); else - nulls[23] = true; + nulls[24] = true; if (beentry->st_sslstatus->ssl_client_serial[0]) - values[24] = DirectFunctionCall3(numeric_in, + values[25] = DirectFunctionCall3(numeric_in, CStringGetDatum(beentry->st_sslstatus->ssl_client_serial), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1)); else - nulls[24] = true; + nulls[25] = true; if (beentry->st_sslstatus->ssl_issuer_dn[0]) - values[25] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn); + values[26] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn); else - nulls[25] = true; + nulls[26] = true; } else { - values[18] = BoolGetDatum(false); /* ssl */ - nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = nulls[25] = true; + values[19] = BoolGetDatum(false); /* ssl */ + nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = nulls[25] = nulls[26] = true; } } else @@ -870,7 +875,6 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) nulls[12] = true; nulls[13] = true; nulls[14] = true; - nulls[17] = true; nulls[18] = true; nulls[19] = true; nulls[20] = true; @@ -879,6 +883,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) nulls[23] = true; nulls[24] = true; nulls[25] = true; + nulls[26] = true; } tuplestore_putvalues(tupstore, tupdesc, values, nulls); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index a4e173b484..7ad1e1e284 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5070,9 +5070,9 @@ proname => 'pg_stat_get_activity', prorows => '100', proisstrict => 'f', proretset => 't', provolatile => 's', proparallel => 'r', prorettype => 'record', proargtypes => 'int4', - proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,bool,text,numeric,text}', - proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', - proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,sslcompression,ssl_client_dn,ssl_client_serial,ssl_issuer_dn}', + proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,xid,text,bool,text,text,int4,bool,text,numeric,text}', + proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,temp_namespace_xid,backend_type,ssl,sslversion,sslcipher,sslbits,sslcompression,ssl_client_dn,ssl_client_serial,ssl_issuer_dn}', prosrc => 'pg_stat_get_activity' }, { oid => '3318', descr => 'statistics: information about progress of backends running maintenance command', diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 88a75fb798..c224c86f39 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -1031,6 +1031,9 @@ typedef struct PgBackendStatus /* application name; MUST be null-terminated */ char *st_appname; + /* If a temporary namespace was created in this session, xid of the creating transaction */ + TransactionId st_temp_namespace_xid; + /* * Current command string; MUST be null-terminated. Note that this string * possibly is truncated in the middle of a multi-byte character. As @@ -1208,6 +1211,7 @@ extern void pgstat_report_activity(BackendState state, const char *cmd_str); extern void pgstat_report_tempfile(size_t filesize); extern void pgstat_report_appname(const char *appname); extern void pgstat_report_xact_timestamp(TimestampTz tstamp); +extern void pgstat_report_temp_namespace_xid(TransactionId xid); extern const char *pgstat_get_wait_event(uint32 wait_event_info); extern const char *pgstat_get_wait_event_type(uint32 wait_event_info); extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser); diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 98f417cb57..039c081292 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1738,8 +1738,9 @@ pg_stat_activity| SELECT s.datid, s.backend_xid, s.backend_xmin, s.query, - s.backend_type - FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn) + s.backend_type, + s.temp_namespace_xid + FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, temp_namespace_xid, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn) LEFT JOIN pg_database d ON ((s.datid = d.oid))) LEFT JOIN pg_authid u ON ((s.usesysid = u.oid))); pg_stat_all_indexes| SELECT c.oid AS relid, @@ -1871,7 +1872,7 @@ pg_stat_replication| SELECT s.pid, w.sync_priority, w.sync_state, w.reply_time - FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn) + FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, temp_namespace_xid, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn) JOIN pg_stat_get_wal_senders() w(pid, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag, sync_priority, sync_state, reply_time) ON ((s.pid = w.pid))) LEFT JOIN pg_authid u ON ((s.usesysid = u.oid))); pg_stat_ssl| SELECT s.pid, @@ -1883,7 +1884,7 @@ pg_stat_ssl| SELECT s.pid, s.ssl_client_dn AS client_dn, s.ssl_client_serial AS client_serial, s.ssl_issuer_dn AS issuer_dn - FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn); + FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, temp_namespace_xid, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn); pg_stat_subscription| SELECT su.oid AS subid, su.subname, st.pid,