Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * pgstatfuncs.c
4 : : * Functions for accessing various forms of statistics data
5 : : *
6 : : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : *
10 : : * IDENTIFICATION
11 : : * src/backend/utils/adt/pgstatfuncs.c
12 : : *
13 : : *-------------------------------------------------------------------------
14 : : */
15 : : #include "postgres.h"
16 : :
17 : : #include "access/htup_details.h"
18 : : #include "access/xlog.h"
19 : : #include "access/xlogprefetcher.h"
20 : : #include "catalog/catalog.h"
21 : : #include "catalog/pg_authid.h"
22 : : #include "catalog/pg_type.h"
23 : : #include "common/ip.h"
24 : : #include "funcapi.h"
25 : : #include "miscadmin.h"
26 : : #include "pgstat.h"
27 : : #include "postmaster/bgworker.h"
28 : : #include "replication/logicallauncher.h"
29 : : #include "storage/proc.h"
30 : : #include "storage/procarray.h"
31 : : #include "utils/acl.h"
32 : : #include "utils/builtins.h"
33 : : #include "utils/timestamp.h"
34 : :
35 : : #define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
36 : :
37 : : #define HAS_PGSTAT_PERMISSIONS(role) (has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role))
38 : :
39 : : #define PG_STAT_GET_RELENTRY_INT64(stat) \
40 : : Datum \
41 : : CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
42 : : { \
43 : : Oid relid = PG_GETARG_OID(0); \
44 : : int64 result; \
45 : : PgStat_StatTabEntry *tabentry; \
46 : : \
47 : : if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
48 : : result = 0; \
49 : : else \
50 : : result = (int64) (tabentry->stat); \
51 : : \
52 : : PG_RETURN_INT64(result); \
53 : : }
54 : :
55 : : /* pg_stat_get_analyze_count */
1053 michael@paquier.xyz 56 [ # # ]:UBC 0 : PG_STAT_GET_RELENTRY_INT64(analyze_count)
57 : :
58 : : /* pg_stat_get_autoanalyze_count */
59 [ # # ]: 0 : PG_STAT_GET_RELENTRY_INT64(autoanalyze_count)
60 : :
61 : : /* pg_stat_get_autovacuum_count */
62 [ # # ]: 0 : PG_STAT_GET_RELENTRY_INT64(autovacuum_count)
63 : :
64 : : /* pg_stat_get_blocks_fetched */
1053 michael@paquier.xyz 65 [ - + ]:CBC 60 : PG_STAT_GET_RELENTRY_INT64(blocks_fetched)
66 : :
67 : : /* pg_stat_get_blocks_hit */
68 [ - + ]: 120 : PG_STAT_GET_RELENTRY_INT64(blocks_hit)
69 : :
70 : : /* pg_stat_get_dead_tuples */
71 [ + + ]: 34 : PG_STAT_GET_RELENTRY_INT64(dead_tuples)
72 : :
73 : : /* pg_stat_get_ins_since_vacuum */
1053 michael@paquier.xyz 74 [ # # ]:UBC 0 : PG_STAT_GET_RELENTRY_INT64(ins_since_vacuum)
75 : :
76 : : /* pg_stat_get_live_tuples */
1053 michael@paquier.xyz 77 [ + + ]:CBC 70 : PG_STAT_GET_RELENTRY_INT64(live_tuples)
78 : :
79 : : /* pg_stat_get_mod_since_analyze */
1053 michael@paquier.xyz 80 [ # # ]:UBC 0 : PG_STAT_GET_RELENTRY_INT64(mod_since_analyze)
81 : :
82 : : /* pg_stat_get_numscans */
1053 michael@paquier.xyz 83 [ + + ]:CBC 84 : PG_STAT_GET_RELENTRY_INT64(numscans)
84 : :
85 : : /* pg_stat_get_tuples_deleted */
86 [ + + ]: 34 : PG_STAT_GET_RELENTRY_INT64(tuples_deleted)
87 : :
88 : : /* pg_stat_get_tuples_fetched */
89 [ - + ]: 24 : PG_STAT_GET_RELENTRY_INT64(tuples_fetched)
90 : :
91 : : /* pg_stat_get_tuples_hot_updated */
92 [ - + ]: 6 : PG_STAT_GET_RELENTRY_INT64(tuples_hot_updated)
93 : :
94 : : /* pg_stat_get_tuples_newpage_updated */
950 pg@bowt.ie 95 [ # # ]:UBC 0 : PG_STAT_GET_RELENTRY_INT64(tuples_newpage_updated)
96 : :
97 : : /* pg_stat_get_tuples_inserted */
1053 michael@paquier.xyz 98 [ + + ]:CBC 52 : PG_STAT_GET_RELENTRY_INT64(tuples_inserted)
99 : :
100 : : /* pg_stat_get_tuples_returned */
101 [ + + ]: 25 : PG_STAT_GET_RELENTRY_INT64(tuples_returned)
102 : :
103 : : /* pg_stat_get_tuples_updated */
104 [ + + ]: 40 : PG_STAT_GET_RELENTRY_INT64(tuples_updated)
105 : :
106 : : /* pg_stat_get_vacuum_count */
107 [ + + ]: 4024 : PG_STAT_GET_RELENTRY_INT64(vacuum_count)
108 : :
109 : : #define PG_STAT_GET_RELENTRY_FLOAT8(stat) \
110 : : Datum \
111 : : CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
112 : : { \
113 : : Oid relid = PG_GETARG_OID(0); \
114 : : double result; \
115 : : PgStat_StatTabEntry *tabentry; \
116 : : \
117 : : if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
118 : : result = 0; \
119 : : else \
120 : : result = (double) (tabentry->stat); \
121 : : \
122 : : PG_RETURN_FLOAT8(result); \
123 : : }
124 : :
125 : : /* pg_stat_get_total_vacuum_time */
273 michael@paquier.xyz 126 [ # # ]:UBC 0 : PG_STAT_GET_RELENTRY_FLOAT8(total_vacuum_time)
127 : :
128 : : /* pg_stat_get_total_autovacuum_time */
129 [ # # ]: 0 : PG_STAT_GET_RELENTRY_FLOAT8(total_autovacuum_time)
130 : :
131 : : /* pg_stat_get_total_analyze_time */
132 [ # # ]: 0 : PG_STAT_GET_RELENTRY_FLOAT8(total_analyze_time)
133 : :
134 : : /* pg_stat_get_total_autoanalyze_time */
135 [ # # ]: 0 : PG_STAT_GET_RELENTRY_FLOAT8(total_autoanalyze_time)
136 : :
137 : : #define PG_STAT_GET_RELENTRY_TIMESTAMPTZ(stat) \
138 : : Datum \
139 : : CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
140 : : { \
141 : : Oid relid = PG_GETARG_OID(0); \
142 : : TimestampTz result; \
143 : : PgStat_StatTabEntry *tabentry; \
144 : : \
145 : : if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
146 : : result = 0; \
147 : : else \
148 : : result = tabentry->stat; \
149 : : \
150 : : if (result == 0) \
151 : : PG_RETURN_NULL(); \
152 : : else \
153 : : PG_RETURN_TIMESTAMPTZ(result); \
154 : : }
155 : :
156 : : /* pg_stat_get_last_analyze_time */
1053 michael@paquier.xyz 157 [ - + + + ]:CBC 36 : PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_analyze_time)
158 : :
159 : : /* pg_stat_get_last_autoanalyze_time */
1053 michael@paquier.xyz 160 [ # # # # ]:UBC 0 : PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_autoanalyze_time)
161 : :
162 : : /* pg_stat_get_last_autovacuum_time */
163 [ # # # # ]: 0 : PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_autovacuum_time)
164 : :
165 : : /* pg_stat_get_last_vacuum_time */
1053 michael@paquier.xyz 166 [ - + + + ]:CBC 36 : PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_vacuum_time)
167 : :
168 : : /* pg_stat_get_lastscan */
169 [ - + + + ]: 45 : PG_STAT_GET_RELENTRY_TIMESTAMPTZ(lastscan)
170 : :
171 : : /* pg_stat_get_stat_reset_time */
22 michael@paquier.xyz 172 [ - + + + ]:GNC 12 : PG_STAT_GET_RELENTRY_TIMESTAMPTZ(stat_reset_time)
173 : :
174 : : Datum
6375 tgl@sss.pgh.pa.us 175 :CBC 139 : pg_stat_get_function_calls(PG_FUNCTION_ARGS)
176 : : {
5983 bruce@momjian.us 177 : 139 : Oid funcid = PG_GETARG_OID(0);
178 : : PgStat_StatFuncEntry *funcentry;
179 : :
6375 tgl@sss.pgh.pa.us 180 [ + + ]: 139 : if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
181 : 62 : PG_RETURN_NULL();
949 michael@paquier.xyz 182 : 77 : PG_RETURN_INT64(funcentry->numcalls);
183 : : }
184 : :
185 : : /* convert counter from microsec to millisec for display */
186 : : #define PG_STAT_GET_FUNCENTRY_FLOAT8_MS(stat) \
187 : : Datum \
188 : : CppConcat(pg_stat_get_function_,stat)(PG_FUNCTION_ARGS) \
189 : : { \
190 : : Oid funcid = PG_GETARG_OID(0); \
191 : : double result; \
192 : : PgStat_StatFuncEntry *funcentry; \
193 : : \
194 : : if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL) \
195 : : PG_RETURN_NULL(); \
196 : : result = ((double) funcentry->stat) / 1000.0; \
197 : : PG_RETURN_FLOAT8(result); \
198 : : }
199 : :
200 : : /* pg_stat_get_function_total_time */
945 201 [ + + ]: 77 : PG_STAT_GET_FUNCENTRY_FLOAT8_MS(total_time)
202 : :
203 : : /* pg_stat_get_function_self_time */
204 [ + + ]: 77 : PG_STAT_GET_FUNCENTRY_FLOAT8_MS(self_time)
205 : :
206 : : Datum
20 michael@paquier.xyz 207 :GNC 2 : pg_stat_get_function_stat_reset_time(PG_FUNCTION_ARGS)
208 : : {
209 : 2 : Oid funcid = PG_GETARG_OID(0);
210 : : TimestampTz result;
211 : : PgStat_StatFuncEntry *funcentry;
212 : :
213 [ - + ]: 2 : if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
20 michael@paquier.xyz 214 :UNC 0 : result = 0;
215 : : else
20 michael@paquier.xyz 216 :GNC 2 : result = funcentry->stat_reset_timestamp;
217 : :
218 [ + + ]: 2 : if (result == 0)
219 : 1 : PG_RETURN_NULL();
220 : : else
221 : 1 : PG_RETURN_TIMESTAMPTZ(result);
222 : : }
223 : :
224 : : Datum
8894 JanWieck@Yahoo.com 225 :CBC 52 : pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
226 : : {
227 : : FuncCallContext *funcctx;
228 : : int *fctx;
229 : :
230 : : /* stuff done only on the first call of the function */
7697 tgl@sss.pgh.pa.us 231 [ + + ]: 52 : if (SRF_IS_FIRSTCALL())
232 : : {
233 : : /* create a function context for cross-call persistence */
234 : 3 : funcctx = SRF_FIRSTCALL_INIT();
235 : :
236 : 3 : fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
237 : : sizeof(int));
238 : 3 : funcctx->user_fctx = fctx;
239 : :
240 : 3 : fctx[0] = 0;
241 : : }
242 : :
243 : : /* stuff done on every call of the function */
244 : 52 : funcctx = SRF_PERCALL_SETUP();
245 : 52 : fctx = funcctx->user_fctx;
246 : :
247 : 52 : fctx[0] += 1;
248 : :
249 : : /*
250 : : * We recheck pgstat_fetch_stat_numbackends() each time through, just in
251 : : * case the local status data has been refreshed since we started. It's
252 : : * plenty cheap enough if not. If a refresh does happen, we'll likely
253 : : * miss or duplicate some backend IDs, but we're content not to crash.
254 : : * (Refreshing midway through such a query would be problematic usage
255 : : * anyway, since the backend IDs we've already returned might no longer
256 : : * refer to extant sessions.)
257 : : */
1125 258 [ + + ]: 52 : if (fctx[0] <= pgstat_fetch_stat_numbackends())
259 : : {
260 : : /* do when there is more left to send */
790 nathan@postgresql.or 261 : 49 : LocalPgBackendStatus *local_beentry = pgstat_get_local_beentry_by_index(fctx[0]);
262 : :
604 heikki.linnakangas@i 263 : 49 : SRF_RETURN_NEXT(funcctx, Int32GetDatum(local_beentry->proc_number));
264 : : }
265 : : else
266 : : {
267 : : /* do when there is no more left */
7697 tgl@sss.pgh.pa.us 268 : 3 : SRF_RETURN_DONE(funcctx);
269 : : }
270 : : }
271 : :
272 : : /*
273 : : * Returns command progress information for the named command.
274 : : */
275 : : Datum
3520 rhaas@postgresql.org 276 : 11 : pg_stat_get_progress_info(PG_FUNCTION_ARGS)
277 : : {
278 : : #define PG_STAT_GET_PROGRESS_COLS PGSTAT_NUM_PROGRESS_PARAM + 3
279 : 11 : int num_backends = pgstat_fetch_stat_numbackends();
280 : : int curr_backend;
281 : 11 : char *cmd = text_to_cstring(PG_GETARG_TEXT_PP(0));
282 : : ProgressCommandType cmdtype;
283 : 11 : ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
284 : :
285 : : /* Translate command name into command type code. */
286 [ + + ]: 11 : if (pg_strcasecmp(cmd, "VACUUM") == 0)
287 : 1 : cmdtype = PROGRESS_COMMAND_VACUUM;
2113 alvherre@alvh.no-ip. 288 [ - + ]: 10 : else if (pg_strcasecmp(cmd, "ANALYZE") == 0)
2113 alvherre@alvh.no-ip. 289 :UBC 0 : cmdtype = PROGRESS_COMMAND_ANALYZE;
2409 rhaas@postgresql.org 290 [ - + ]:CBC 10 : else if (pg_strcasecmp(cmd, "CLUSTER") == 0)
2409 rhaas@postgresql.org 291 :UBC 0 : cmdtype = PROGRESS_COMMAND_CLUSTER;
2401 alvherre@alvh.no-ip. 292 [ - + ]:CBC 10 : else if (pg_strcasecmp(cmd, "CREATE INDEX") == 0)
2401 alvherre@alvh.no-ip. 293 :UBC 0 : cmdtype = PROGRESS_COMMAND_CREATE_INDEX;
2065 fujii@postgresql.org 294 [ + + ]:CBC 10 : else if (pg_strcasecmp(cmd, "BASEBACKUP") == 0)
2065 fujii@postgresql.org 295 :GBC 1 : cmdtype = PROGRESS_COMMAND_BASEBACKUP;
1756 tomas.vondra@postgre 296 [ + - ]:CBC 9 : else if (pg_strcasecmp(cmd, "COPY") == 0)
297 : 9 : cmdtype = PROGRESS_COMMAND_COPY;
298 : : else
3520 rhaas@postgresql.org 299 [ # # ]:UBC 0 : ereport(ERROR,
300 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
301 : : errmsg("invalid command name: \"%s\"", cmd)));
302 : :
1106 michael@paquier.xyz 303 :CBC 11 : InitMaterializedSRF(fcinfo, 0);
304 : :
305 : : /* 1-based index */
3520 rhaas@postgresql.org 306 [ + + ]: 135 : for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
307 : : {
308 : : LocalPgBackendStatus *local_beentry;
309 : : PgBackendStatus *beentry;
1200 peter@eisentraut.org 310 : 124 : Datum values[PG_STAT_GET_PROGRESS_COLS] = {0};
311 : 124 : bool nulls[PG_STAT_GET_PROGRESS_COLS] = {0};
312 : : int i;
313 : :
790 nathan@postgresql.or 314 : 124 : local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
3520 rhaas@postgresql.org 315 : 124 : beentry = &local_beentry->backendStatus;
316 : :
317 : : /*
318 : : * Report values for only those backends which are running the given
319 : : * command.
320 : : */
1125 tgl@sss.pgh.pa.us 321 [ + + ]: 124 : if (beentry->st_progress_command != cmdtype)
3520 rhaas@postgresql.org 322 : 113 : continue;
323 : :
324 : : /* Value available to all callers */
325 : 11 : values[0] = Int32GetDatum(beentry->st_procpid);
326 : 11 : values[1] = ObjectIdGetDatum(beentry->st_databaseid);
327 : :
328 : : /* show rest of the values including relid only to role members */
2017 magnus@hagander.net 329 [ - + - - ]: 22 : if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
330 : : {
3520 rhaas@postgresql.org 331 : 11 : values[2] = ObjectIdGetDatum(beentry->st_progress_command_target);
3428 332 [ + + ]: 231 : for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
333 : 220 : values[i + 3] = Int64GetDatum(beentry->st_progress_param[i]);
334 : : }
335 : : else
336 : : {
3520 rhaas@postgresql.org 337 :UBC 0 : nulls[2] = true;
3519 338 [ # # ]: 0 : for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
3428 339 : 0 : nulls[i + 3] = true;
340 : : }
341 : :
1331 michael@paquier.xyz 342 :CBC 11 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
343 : : }
344 : :
3520 rhaas@postgresql.org 345 : 11 : return (Datum) 0;
346 : : }
347 : :
348 : : /*
349 : : * Returns activity of PG backends.
350 : : */
351 : : Datum
6383 magnus@hagander.net 352 : 1021 : pg_stat_get_activity(PG_FUNCTION_ARGS)
353 : : {
354 : : #define PG_STAT_GET_ACTIVITY_COLS 31
3811 bruce@momjian.us 355 : 1021 : int num_backends = pgstat_fetch_stat_numbackends();
356 : : int curr_backend;
357 [ + + ]: 1021 : int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
358 : 1021 : ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
359 : :
1106 michael@paquier.xyz 360 : 1021 : InitMaterializedSRF(fcinfo, 0);
361 : :
362 : : /* 1-based index */
3826 sfrost@snowman.net 363 [ + + ]: 11695 : for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
364 : : {
365 : : /* for each row */
1200 peter@eisentraut.org 366 : 10675 : Datum values[PG_STAT_GET_ACTIVITY_COLS] = {0};
367 : 10675 : bool nulls[PG_STAT_GET_ACTIVITY_COLS] = {0};
368 : : LocalPgBackendStatus *local_beentry;
369 : : PgBackendStatus *beentry;
370 : : PGPROC *proc;
3138 rhaas@postgresql.org 371 : 10675 : const char *wait_event_type = NULL;
372 : 10675 : const char *wait_event = NULL;
373 : :
374 : : /* Get the next one in the list */
790 nathan@postgresql.or 375 : 10675 : local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
3335 tgl@sss.pgh.pa.us 376 : 10675 : beentry = &local_beentry->backendStatus;
377 : :
378 : : /* If looking for specific PID, ignore all the others */
379 [ + + - + ]: 10675 : if (pid != -1 && beentry->st_procpid != pid)
3335 tgl@sss.pgh.pa.us 380 :UBC 0 : continue;
381 : :
382 : : /* Values available to all callers */
3138 rhaas@postgresql.org 383 [ + + ]:CBC 10675 : if (beentry->st_databaseid != InvalidOid)
384 : 1942 : values[0] = ObjectIdGetDatum(beentry->st_databaseid);
385 : : else
386 : 8733 : nulls[0] = true;
387 : :
6383 magnus@hagander.net 388 : 10675 : values[1] = Int32GetDatum(beentry->st_procpid);
389 : :
3138 rhaas@postgresql.org 390 [ + + ]: 10675 : if (beentry->st_userid != InvalidOid)
391 : 3172 : values[2] = ObjectIdGetDatum(beentry->st_userid);
392 : : else
393 : 7503 : nulls[2] = true;
394 : :
5812 tgl@sss.pgh.pa.us 395 [ + - ]: 10675 : if (beentry->st_appname)
396 : 10675 : values[3] = CStringGetTextDatum(beentry->st_appname);
397 : : else
5812 tgl@sss.pgh.pa.us 398 :UBC 0 : nulls[3] = true;
399 : :
4263 rhaas@postgresql.org 400 [ + + ]:CBC 10675 : if (TransactionIdIsValid(local_beentry->backend_xid))
3519 401 : 80 : values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
402 : : else
403 : 10595 : nulls[15] = true;
404 : :
4263 405 [ + + ]: 10675 : if (TransactionIdIsValid(local_beentry->backend_xmin))
3519 406 : 1166 : values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
407 : : else
408 : 9509 : nulls[16] = true;
409 : :
410 : : /* Values only available to role member or pg_read_all_stats */
2017 magnus@hagander.net 411 [ + + + + ]: 10675 : if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
6383 412 : 8802 : {
413 : : char *clipped_activity;
414 : :
5031 415 [ - + + + : 8802 : switch (beentry->st_state)
- - + +
- ]
416 : : {
238 michael@paquier.xyz 417 :LBC (3) : case STATE_STARTING:
418 : (3) : values[4] = CStringGetTextDatum("starting");
419 : (3) : break;
5031 magnus@hagander.net 420 :CBC 156 : case STATE_IDLE:
421 : 156 : values[4] = CStringGetTextDatum("idle");
422 : 156 : break;
423 : 1985 : case STATE_RUNNING:
424 : 1985 : values[4] = CStringGetTextDatum("active");
425 : 1985 : break;
426 : 16 : case STATE_IDLEINTRANSACTION:
427 : 16 : values[4] = CStringGetTextDatum("idle in transaction");
428 : 16 : break;
5031 magnus@hagander.net 429 :UBC 0 : case STATE_FASTPATH:
430 : 0 : values[4] = CStringGetTextDatum("fastpath function call");
431 : 0 : break;
432 : 0 : case STATE_IDLEINTRANSACTION_ABORTED:
433 : 0 : values[4] = CStringGetTextDatum("idle in transaction (aborted)");
434 : 0 : break;
5031 magnus@hagander.net 435 :CBC 3 : case STATE_DISABLED:
436 : 3 : values[4] = CStringGetTextDatum("disabled");
437 : 3 : break;
438 : 6642 : case STATE_UNDEFINED:
439 : 6642 : nulls[4] = true;
440 : 6642 : break;
441 : : }
442 : :
2961 andres@anarazel.de 443 : 8802 : clipped_activity = pgstat_clip_activity(beentry->st_activity_raw);
444 : 8802 : values[5] = CStringGetTextDatum(clipped_activity);
445 : 8802 : pfree(clipped_activity);
446 : :
447 : : /* leader_pid */
585 dgustafsson@postgres 448 : 8802 : nulls[29] = true;
449 : :
2091 michael@paquier.xyz 450 : 8802 : proc = BackendPidGetProc(beentry->st_procpid);
451 : :
452 [ + + + - ]: 8802 : if (proc == NULL && (beentry->st_backendType != B_BACKEND))
453 : : {
454 : : /*
455 : : * For an auxiliary process, retrieve process info from
456 : : * AuxiliaryProcs stored in shared-memory.
457 : : */
3138 rhaas@postgresql.org 458 : 5133 : proc = AuxiliaryPidGetProc(beentry->st_procpid);
459 : : }
460 : :
461 : : /*
462 : : * If a PGPROC entry was retrieved, display wait events and lock
463 : : * group leader or apply leader information if any. To avoid
464 : : * extra overhead, no extra lock is being held, so there is no
465 : : * guarantee of consistency across multiple rows.
466 : : */
2091 michael@paquier.xyz 467 [ + - ]: 8802 : if (proc != NULL)
468 : : {
469 : : uint32 raw_wait_event;
470 : : PGPROC *leader;
471 : :
472 : 8802 : raw_wait_event = UINT32_ACCESS_ONCE(proc->wait_event_info);
473 : 8802 : wait_event_type = pgstat_get_wait_event_type(raw_wait_event);
474 : 8802 : wait_event = pgstat_get_wait_event(raw_wait_event);
475 : :
476 : 8802 : leader = proc->lockGroupLeader;
477 : :
478 : : /*
479 : : * Show the leader only for active parallel workers. This
480 : : * leaves the field as NULL for the leader of a parallel group
481 : : * or the leader of parallel apply workers.
482 : : */
1920 483 [ + + - + ]: 8802 : if (leader && leader->pid != beentry->st_procpid)
484 : : {
585 dgustafsson@postgres 485 :LBC (2) : values[29] = Int32GetDatum(leader->pid);
486 : (2) : nulls[29] = false;
487 : : }
1014 akapila@postgresql.o 488 [ + + ]:CBC 8802 : else if (beentry->st_backendType == B_BG_WORKER)
489 : : {
490 : 854 : int leader_pid = GetLeaderApplyWorkerPid(beentry->st_procpid);
491 : :
492 [ - + ]: 854 : if (leader_pid != InvalidPid)
493 : : {
585 dgustafsson@postgres 494 :UBC 0 : values[29] = Int32GetDatum(leader_pid);
495 : 0 : nulls[29] = false;
496 : : }
497 : : }
498 : : }
499 : :
3519 rhaas@postgresql.org 500 [ + + ]:CBC 8802 : if (wait_event_type)
501 : 7682 : values[6] = CStringGetTextDatum(wait_event_type);
502 : : else
503 : 1120 : nulls[6] = true;
504 : :
505 [ + + ]: 8802 : if (wait_event)
506 : 7682 : values[7] = CStringGetTextDatum(wait_event);
507 : : else
5031 magnus@hagander.net 508 : 1120 : nulls[7] = true;
509 : :
510 : : /*
511 : : * Don't expose transaction time for walsenders; it confuses
512 : : * monitoring, particularly because we don't keep the time up-to-
513 : : * date.
514 : : */
2120 alvherre@alvh.no-ip. 515 [ + + ]: 8802 : if (beentry->st_xact_start_timestamp != 0 &&
516 [ + + ]: 1176 : beentry->st_backendType != B_WAL_SENDER)
3519 rhaas@postgresql.org 517 : 1172 : values[8] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
518 : : else
5031 magnus@hagander.net 519 : 7630 : nulls[8] = true;
520 : :
3519 rhaas@postgresql.org 521 [ + + ]: 8802 : if (beentry->st_activity_start_timestamp != 0)
522 : 2100 : values[9] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
523 : : else
5031 magnus@hagander.net 524 : 6702 : nulls[9] = true;
525 : :
3519 rhaas@postgresql.org 526 [ + - ]: 8802 : if (beentry->st_proc_start_timestamp != 0)
527 : 8802 : values[10] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
528 : : else
5031 magnus@hagander.net 529 :UBC 0 : nulls[10] = true;
530 : :
3519 rhaas@postgresql.org 531 [ + + ]:CBC 8802 : if (beentry->st_state_start_timestamp != 0)
532 : 2157 : values[11] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
533 : : else
534 : 6645 : nulls[11] = true;
535 : :
536 : : /* A zeroed client addr means we don't know */
321 nathan@postgresql.or 537 [ + + ]: 8802 : if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
538 : : sizeof(beentry->st_clientaddr)))
539 : : {
5031 magnus@hagander.net 540 : 6719 : nulls[12] = true;
541 : 6719 : nulls[13] = true;
3519 rhaas@postgresql.org 542 : 6719 : nulls[14] = true;
543 : : }
544 : : else
545 : : {
1159 tmunro@postgresql.or 546 [ + + ]: 2083 : if (beentry->st_clientaddr.addr.ss_family == AF_INET ||
547 [ - + ]: 1852 : beentry->st_clientaddr.addr.ss_family == AF_INET6)
6383 magnus@hagander.net 548 : 231 : {
549 : : char remote_host[NI_MAXHOST];
550 : : char remote_port[NI_MAXSERV];
551 : : int ret;
552 : :
553 : 231 : remote_host[0] = '\0';
554 : 231 : remote_port[0] = '\0';
555 : 231 : ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
556 : 231 : beentry->st_clientaddr.salen,
557 : : remote_host, sizeof(remote_host),
558 : : remote_port, sizeof(remote_port),
559 : : NI_NUMERICHOST | NI_NUMERICSERV);
5194 peter_e@gmx.net 560 [ + - ]: 231 : if (ret == 0)
561 : : {
6383 magnus@hagander.net 562 : 231 : clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
3519 rhaas@postgresql.org 563 : 231 : values[12] = DirectFunctionCall1(inet_in,
564 : : CStringGetDatum(remote_host));
4228 tgl@sss.pgh.pa.us 565 [ + - ]: 231 : if (beentry->st_clienthostname &&
566 [ + + ]: 231 : beentry->st_clienthostname[0])
3519 rhaas@postgresql.org 567 : 7 : values[13] = CStringGetTextDatum(beentry->st_clienthostname);
568 : : else
569 : 224 : nulls[13] = true;
570 : 231 : values[14] = Int32GetDatum(atoi(remote_port));
571 : : }
572 : : else
573 : : {
5031 magnus@hagander.net 574 :UBC 0 : nulls[12] = true;
575 : 0 : nulls[13] = true;
3519 rhaas@postgresql.org 576 : 0 : nulls[14] = true;
577 : : }
578 : : }
6383 magnus@hagander.net 579 [ + - ]:CBC 1852 : else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
580 : : {
581 : : /*
582 : : * Unix sockets always reports NULL for host and -1 for
583 : : * port, so it's possible to tell the difference to
584 : : * connections we have no permissions to view, or with
585 : : * errors.
586 : : */
5031 587 : 1852 : nulls[12] = true;
3519 rhaas@postgresql.org 588 : 1852 : nulls[13] = true;
2736 tgl@sss.pgh.pa.us 589 : 1852 : values[14] = Int32GetDatum(-1);
590 : : }
591 : : else
592 : : {
593 : : /* Unknown address type, should never happen */
5031 magnus@hagander.net 594 :UBC 0 : nulls[12] = true;
595 : 0 : nulls[13] = true;
3519 rhaas@postgresql.org 596 : 0 : nulls[14] = true;
597 : : }
598 : : }
599 : : /* Add backend type */
2980 peter_e@gmx.net 600 [ + + ]:CBC 8802 : if (beentry->st_backendType == B_BG_WORKER)
601 : : {
602 : : const char *bgw_type;
603 : :
604 : 854 : bgw_type = GetBackgroundWorkerTypeByPid(beentry->st_procpid);
605 [ + - ]: 854 : if (bgw_type)
606 : 854 : values[17] = CStringGetTextDatum(bgw_type);
607 : : else
2980 peter_e@gmx.net 608 :UBC 0 : nulls[17] = true;
609 : : }
610 : : else
2980 peter_e@gmx.net 611 :CBC 7948 : values[17] =
2057 peter@eisentraut.org 612 : 7948 : CStringGetTextDatum(GetBackendTypeDesc(beentry->st_backendType));
613 : :
614 : : /* SSL information */
2442 615 [ + + ]: 8802 : if (beentry->st_ssl)
616 : : {
617 : 55 : values[18] = BoolGetDatum(true); /* ssl */
618 : 55 : values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
619 : 55 : values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
620 : 55 : values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
621 : :
622 [ + + ]: 55 : if (beentry->st_sslstatus->ssl_client_dn[0])
1694 michael@paquier.xyz 623 : 6 : values[22] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn);
624 : : else
625 : 49 : nulls[22] = true;
626 : :
2442 peter@eisentraut.org 627 [ + + ]: 55 : if (beentry->st_sslstatus->ssl_client_serial[0])
1694 michael@paquier.xyz 628 : 6 : values[23] = DirectFunctionCall3(numeric_in,
629 : : CStringGetDatum(beentry->st_sslstatus->ssl_client_serial),
630 : : ObjectIdGetDatum(InvalidOid),
631 : : Int32GetDatum(-1));
632 : : else
633 : 49 : nulls[23] = true;
634 : :
2442 peter@eisentraut.org 635 [ + + ]: 55 : if (beentry->st_sslstatus->ssl_issuer_dn[0])
1694 michael@paquier.xyz 636 : 6 : values[24] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn);
637 : : else
638 : 49 : nulls[24] = true;
639 : : }
640 : : else
641 : : {
2442 peter@eisentraut.org 642 : 8747 : values[18] = BoolGetDatum(false); /* ssl */
585 dgustafsson@postgres 643 : 8747 : nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = true;
644 : : }
645 : :
646 : : /* GSSAPI information */
2400 sfrost@snowman.net 647 [ + + ]: 8802 : if (beentry->st_gss)
648 : : {
585 dgustafsson@postgres 649 : 118 : values[25] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */
650 : 118 : values[26] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ);
651 : 118 : values[27] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */
652 : 118 : values[28] = BoolGetDatum(beentry->st_gssstatus->gss_delegation); /* GSS credentials
653 : : * delegated */
654 : : }
655 : : else
656 : : {
657 : 8684 : values[25] = BoolGetDatum(false); /* gss_auth */
658 : 8684 : nulls[26] = true; /* No GSS principal */
659 : 8684 : values[27] = BoolGetDatum(false); /* GSS Encryption not in
660 : : * use */
661 : 8684 : values[28] = BoolGetDatum(false); /* GSS credentials not
662 : : * delegated */
663 : : }
151 drowley@postgresql.o 664 [ + + ]: 8802 : if (beentry->st_query_id == INT64CONST(0))
585 dgustafsson@postgres 665 : 8748 : nulls[30] = true;
666 : : else
151 drowley@postgresql.o 667 : 54 : values[30] = Int64GetDatum(beentry->st_query_id);
668 : : }
669 : : else
670 : : {
671 : : /* No permissions to view data about this session */
5031 magnus@hagander.net 672 : 1873 : values[5] = CStringGetTextDatum("<insufficient privilege>");
673 : 1873 : nulls[4] = true;
6383 674 : 1873 : nulls[6] = true;
675 : 1873 : nulls[7] = true;
676 : 1873 : nulls[8] = true;
677 : 1873 : nulls[9] = true;
5813 tgl@sss.pgh.pa.us 678 : 1873 : nulls[10] = true;
5367 rhaas@postgresql.org 679 : 1873 : nulls[11] = true;
5031 magnus@hagander.net 680 : 1873 : nulls[12] = true;
681 : 1873 : nulls[13] = true;
3519 rhaas@postgresql.org 682 : 1873 : nulls[14] = true;
3138 683 : 1873 : nulls[17] = true;
2442 peter@eisentraut.org 684 : 1873 : nulls[18] = true;
685 : 1873 : nulls[19] = true;
686 : 1873 : nulls[20] = true;
687 : 1873 : nulls[21] = true;
688 : 1873 : nulls[22] = true;
689 : 1873 : nulls[23] = true;
690 : 1873 : nulls[24] = true;
691 : 1873 : nulls[25] = true;
2400 sfrost@snowman.net 692 : 1873 : nulls[26] = true;
693 : 1873 : nulls[27] = true;
694 : 1873 : nulls[28] = true;
1665 bruce@momjian.us 695 : 1873 : nulls[29] = true;
929 sfrost@snowman.net 696 : 1873 : nulls[30] = true;
697 : : }
698 : :
1331 michael@paquier.xyz 699 : 10675 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
700 : :
701 : : /* If only a single backend was requested, and we found it, break. */
3826 sfrost@snowman.net 702 [ + + ]: 10675 : if (pid != -1)
703 : 1 : break;
704 : : }
705 : :
706 : 1021 : return (Datum) 0;
707 : : }
708 : :
709 : :
710 : : Datum
8486 bruce@momjian.us 711 : 1392 : pg_backend_pid(PG_FUNCTION_ARGS)
712 : : {
8490 713 : 1392 : PG_RETURN_INT32(MyProcPid);
714 : : }
715 : :
716 : :
717 : : Datum
8894 JanWieck@Yahoo.com 718 : 49 : pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
719 : : {
604 heikki.linnakangas@i 720 : 49 : int32 procNumber = PG_GETARG_INT32(0);
721 : : PgBackendStatus *beentry;
722 : :
723 [ - + ]: 49 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
8894 JanWieck@Yahoo.com 724 :UBC 0 : PG_RETURN_NULL();
725 : :
7071 tgl@sss.pgh.pa.us 726 :CBC 49 : PG_RETURN_INT32(beentry->st_procpid);
727 : : }
728 : :
729 : :
730 : : Datum
8894 JanWieck@Yahoo.com 731 :UBC 0 : pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
732 : : {
604 heikki.linnakangas@i 733 : 0 : int32 procNumber = PG_GETARG_INT32(0);
734 : : PgBackendStatus *beentry;
735 : :
736 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
8894 JanWieck@Yahoo.com 737 : 0 : PG_RETURN_NULL();
738 : :
7071 tgl@sss.pgh.pa.us 739 : 0 : PG_RETURN_OID(beentry->st_databaseid);
740 : : }
741 : :
742 : :
743 : : Datum
8894 JanWieck@Yahoo.com 744 : 0 : pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
745 : : {
604 heikki.linnakangas@i 746 : 0 : int32 procNumber = PG_GETARG_INT32(0);
747 : : PgBackendStatus *beentry;
748 : :
749 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
8894 JanWieck@Yahoo.com 750 : 0 : PG_RETURN_NULL();
751 : :
7071 tgl@sss.pgh.pa.us 752 : 0 : PG_RETURN_OID(beentry->st_userid);
753 : : }
754 : :
755 : : Datum
1044 rhaas@postgresql.org 756 : 0 : pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
757 : : {
758 : : #define PG_STAT_GET_SUBXACT_COLS 2
759 : : TupleDesc tupdesc;
770 peter@eisentraut.org 760 : 0 : Datum values[PG_STAT_GET_SUBXACT_COLS] = {0};
761 : 0 : bool nulls[PG_STAT_GET_SUBXACT_COLS] = {0};
604 heikki.linnakangas@i 762 : 0 : int32 procNumber = PG_GETARG_INT32(0);
763 : : LocalPgBackendStatus *local_beentry;
764 : :
765 : : /* Initialise attributes information in the tuple descriptor */
1044 rhaas@postgresql.org 766 : 0 : tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_SUBXACT_COLS);
767 : 0 : TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subxact_count",
768 : : INT4OID, -1, 0);
769 : 0 : TupleDescInitEntry(tupdesc, (AttrNumber) 2, "subxact_overflow",
770 : : BOOLOID, -1, 0);
771 : :
772 : 0 : BlessTupleDesc(tupdesc);
773 : :
604 heikki.linnakangas@i 774 [ # # ]: 0 : if ((local_beentry = pgstat_get_local_beentry_by_proc_number(procNumber)) != NULL)
775 : : {
776 : : /* Fill values and NULLs */
1044 rhaas@postgresql.org 777 : 0 : values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
778 : 0 : values[1] = BoolGetDatum(local_beentry->backend_subxact_overflowed);
779 : : }
780 : : else
781 : : {
782 : 0 : nulls[0] = true;
783 : 0 : nulls[1] = true;
784 : : }
785 : :
786 : : /* Returns the record as Datum */
787 : 0 : PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
788 : : }
789 : :
790 : : Datum
8894 JanWieck@Yahoo.com 791 : 0 : pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
792 : : {
604 heikki.linnakangas@i 793 : 0 : int32 procNumber = PG_GETARG_INT32(0);
794 : : PgBackendStatus *beentry;
795 : : const char *activity;
796 : : char *clipped_activity;
797 : : text *ret;
798 : :
799 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
7929 JanWieck@Yahoo.com 800 : 0 : activity = "<backend information not available>";
2017 magnus@hagander.net 801 [ # # # # ]: 0 : else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
7929 JanWieck@Yahoo.com 802 : 0 : activity = "<insufficient privilege>";
2961 andres@anarazel.de 803 [ # # ]: 0 : else if (*(beentry->st_activity_raw) == '\0')
7929 JanWieck@Yahoo.com 804 : 0 : activity = "<command string not enabled>";
805 : : else
2961 andres@anarazel.de 806 : 0 : activity = beentry->st_activity_raw;
807 : :
808 : 0 : clipped_activity = pgstat_clip_activity(activity);
809 : 0 : ret = cstring_to_text(activity);
810 : 0 : pfree(clipped_activity);
811 : :
812 : 0 : PG_RETURN_TEXT_P(ret);
813 : : }
814 : :
815 : : Datum
3519 rhaas@postgresql.org 816 : 0 : pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
817 : : {
604 heikki.linnakangas@i 818 : 0 : int32 procNumber = PG_GETARG_INT32(0);
819 : : PgBackendStatus *beentry;
820 : : PGPROC *proc;
3477 rhaas@postgresql.org 821 : 0 : const char *wait_event_type = NULL;
822 : :
604 heikki.linnakangas@i 823 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
3519 rhaas@postgresql.org 824 : 0 : wait_event_type = "<backend information not available>";
2017 magnus@hagander.net 825 [ # # # # ]: 0 : else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
3519 rhaas@postgresql.org 826 : 0 : wait_event_type = "<insufficient privilege>";
3477 827 [ # # ]: 0 : else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
3519 828 : 0 : wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
829 : :
830 [ # # ]: 0 : if (!wait_event_type)
7010 tgl@sss.pgh.pa.us 831 : 0 : PG_RETURN_NULL();
832 : :
3519 rhaas@postgresql.org 833 : 0 : PG_RETURN_TEXT_P(cstring_to_text(wait_event_type));
834 : : }
835 : :
836 : : Datum
837 : 0 : pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
838 : : {
604 heikki.linnakangas@i 839 : 0 : int32 procNumber = PG_GETARG_INT32(0);
840 : : PgBackendStatus *beentry;
841 : : PGPROC *proc;
3477 rhaas@postgresql.org 842 : 0 : const char *wait_event = NULL;
843 : :
604 heikki.linnakangas@i 844 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
3519 rhaas@postgresql.org 845 : 0 : wait_event = "<backend information not available>";
2017 magnus@hagander.net 846 [ # # # # ]: 0 : else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
3519 rhaas@postgresql.org 847 : 0 : wait_event = "<insufficient privilege>";
3477 848 [ # # ]: 0 : else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
3519 849 : 0 : wait_event = pgstat_get_wait_event(proc->wait_event_info);
850 : :
851 [ # # ]: 0 : if (!wait_event)
852 : 0 : PG_RETURN_NULL();
853 : :
854 : 0 : PG_RETURN_TEXT_P(cstring_to_text(wait_event));
855 : : }
856 : :
857 : :
858 : : Datum
8258 bruce@momjian.us 859 : 0 : pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
860 : : {
604 heikki.linnakangas@i 861 : 0 : int32 procNumber = PG_GETARG_INT32(0);
862 : : TimestampTz result;
863 : : PgBackendStatus *beentry;
864 : :
865 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
8258 bruce@momjian.us 866 : 0 : PG_RETURN_NULL();
867 : :
2017 magnus@hagander.net 868 [ # # # # ]: 0 : else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
8258 bruce@momjian.us 869 : 0 : PG_RETURN_NULL();
870 : :
7071 tgl@sss.pgh.pa.us 871 : 0 : result = beentry->st_activity_start_timestamp;
872 : :
873 : : /*
874 : : * No time recorded for start of current query -- this is the case if the
875 : : * user hasn't enabled query-level stats collection.
876 : : */
7426 877 [ # # ]: 0 : if (result == 0)
8258 bruce@momjian.us 878 : 0 : PG_RETURN_NULL();
879 : :
8243 tgl@sss.pgh.pa.us 880 : 0 : PG_RETURN_TIMESTAMPTZ(result);
881 : : }
882 : :
883 : :
884 : : Datum
6622 885 : 0 : pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
886 : : {
604 heikki.linnakangas@i 887 : 0 : int32 procNumber = PG_GETARG_INT32(0);
888 : : TimestampTz result;
889 : : PgBackendStatus *beentry;
890 : :
891 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
6901 neilc@samurai.com 892 : 0 : PG_RETURN_NULL();
893 : :
2017 magnus@hagander.net 894 [ # # # # ]: 0 : else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
6901 neilc@samurai.com 895 : 0 : PG_RETURN_NULL();
896 : :
6622 tgl@sss.pgh.pa.us 897 : 0 : result = beentry->st_xact_start_timestamp;
898 : :
6901 neilc@samurai.com 899 [ # # ]: 0 : if (result == 0) /* not in a transaction */
900 : 0 : PG_RETURN_NULL();
901 : :
902 : 0 : PG_RETURN_TIMESTAMPTZ(result);
903 : : }
904 : :
905 : :
906 : : Datum
7477 907 : 0 : pg_stat_get_backend_start(PG_FUNCTION_ARGS)
908 : : {
604 heikki.linnakangas@i 909 : 0 : int32 procNumber = PG_GETARG_INT32(0);
910 : : TimestampTz result;
911 : : PgBackendStatus *beentry;
912 : :
913 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
7477 neilc@samurai.com 914 : 0 : PG_RETURN_NULL();
915 : :
2017 magnus@hagander.net 916 [ # # # # ]: 0 : else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
7477 neilc@samurai.com 917 : 0 : PG_RETURN_NULL();
918 : :
7071 tgl@sss.pgh.pa.us 919 : 0 : result = beentry->st_proc_start_timestamp;
920 : :
7426 921 [ # # ]: 0 : if (result == 0) /* probably can't happen? */
7477 neilc@samurai.com 922 : 0 : PG_RETURN_NULL();
923 : :
924 : 0 : PG_RETURN_TIMESTAMPTZ(result);
925 : : }
926 : :
927 : :
928 : : Datum
929 : 0 : pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
930 : : {
604 heikki.linnakangas@i 931 : 0 : int32 procNumber = PG_GETARG_INT32(0);
932 : : PgBackendStatus *beentry;
933 : : char remote_host[NI_MAXHOST];
934 : : int ret;
935 : :
936 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
7477 neilc@samurai.com 937 : 0 : PG_RETURN_NULL();
938 : :
2017 magnus@hagander.net 939 [ # # # # ]: 0 : else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
7477 neilc@samurai.com 940 : 0 : PG_RETURN_NULL();
941 : :
942 : : /* A zeroed client addr means we don't know */
321 nathan@postgresql.or 943 [ # # ]: 0 : if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
944 : : sizeof(beentry->st_clientaddr)))
7102 alvherre@alvh.no-ip. 945 : 0 : PG_RETURN_NULL();
946 : :
7071 tgl@sss.pgh.pa.us 947 [ # # ]: 0 : switch (beentry->st_clientaddr.addr.ss_family)
948 : : {
7477 neilc@samurai.com 949 : 0 : case AF_INET:
950 : : case AF_INET6:
951 : 0 : break;
952 : 0 : default:
953 : 0 : PG_RETURN_NULL();
954 : : }
955 : :
956 : 0 : remote_host[0] = '\0';
7071 tgl@sss.pgh.pa.us 957 : 0 : ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
958 : 0 : beentry->st_clientaddr.salen,
959 : : remote_host, sizeof(remote_host),
960 : : NULL, 0,
961 : : NI_NUMERICHOST | NI_NUMERICSERV);
5194 peter_e@gmx.net 962 [ # # ]: 0 : if (ret != 0)
7477 neilc@samurai.com 963 : 0 : PG_RETURN_NULL();
964 : :
6739 tgl@sss.pgh.pa.us 965 : 0 : clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
966 : :
1157 peter@eisentraut.org 967 : 0 : PG_RETURN_DATUM(DirectFunctionCall1(inet_in,
968 : : CStringGetDatum(remote_host)));
969 : : }
970 : :
971 : : Datum
7477 neilc@samurai.com 972 : 0 : pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
973 : : {
604 heikki.linnakangas@i 974 : 0 : int32 procNumber = PG_GETARG_INT32(0);
975 : : PgBackendStatus *beentry;
976 : : char remote_port[NI_MAXSERV];
977 : : int ret;
978 : :
979 [ # # ]: 0 : if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
7477 neilc@samurai.com 980 : 0 : PG_RETURN_NULL();
981 : :
2017 magnus@hagander.net 982 [ # # # # ]: 0 : else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
7477 neilc@samurai.com 983 : 0 : PG_RETURN_NULL();
984 : :
985 : : /* A zeroed client addr means we don't know */
321 nathan@postgresql.or 986 [ # # ]: 0 : if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
987 : : sizeof(beentry->st_clientaddr)))
7102 alvherre@alvh.no-ip. 988 : 0 : PG_RETURN_NULL();
989 : :
7071 tgl@sss.pgh.pa.us 990 [ # # # ]: 0 : switch (beentry->st_clientaddr.addr.ss_family)
991 : : {
7477 neilc@samurai.com 992 : 0 : case AF_INET:
993 : : case AF_INET6:
994 : 0 : break;
995 : 0 : case AF_UNIX:
996 : 0 : PG_RETURN_INT32(-1);
997 : 0 : default:
998 : 0 : PG_RETURN_NULL();
999 : : }
1000 : :
1001 : 0 : remote_port[0] = '\0';
7071 tgl@sss.pgh.pa.us 1002 : 0 : ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
1003 : 0 : beentry->st_clientaddr.salen,
1004 : : NULL, 0,
1005 : : remote_port, sizeof(remote_port),
1006 : : NI_NUMERICHOST | NI_NUMERICSERV);
5194 peter_e@gmx.net 1007 [ # # ]: 0 : if (ret != 0)
7477 neilc@samurai.com 1008 : 0 : PG_RETURN_NULL();
1009 : :
7071 tgl@sss.pgh.pa.us 1010 : 0 : PG_RETURN_DATUM(DirectFunctionCall1(int4in,
1011 : : CStringGetDatum(remote_port)));
1012 : : }
1013 : :
1014 : :
1015 : : Datum
8894 JanWieck@Yahoo.com 1016 : 0 : pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
1017 : : {
7071 tgl@sss.pgh.pa.us 1018 : 0 : Oid dbid = PG_GETARG_OID(0);
1019 : : int32 result;
1020 : 0 : int tot_backends = pgstat_fetch_stat_numbackends();
1021 : : int idx;
1022 : :
1023 : 0 : result = 0;
790 nathan@postgresql.or 1024 [ # # ]: 0 : for (idx = 1; idx <= tot_backends; idx++)
1025 : : {
1026 : 0 : LocalPgBackendStatus *local_beentry = pgstat_get_local_beentry_by_index(idx);
1027 : :
1125 tgl@sss.pgh.pa.us 1028 [ # # ]: 0 : if (local_beentry->backendStatus.st_databaseid == dbid)
7071 1029 : 0 : result++;
1030 : : }
1031 : :
8894 JanWieck@Yahoo.com 1032 : 0 : PG_RETURN_INT32(result);
1033 : : }
1034 : :
1035 : :
1036 : : #define PG_STAT_GET_DBENTRY_INT64(stat) \
1037 : : Datum \
1038 : : CppConcat(pg_stat_get_db_,stat)(PG_FUNCTION_ARGS) \
1039 : : { \
1040 : : Oid dbid = PG_GETARG_OID(0); \
1041 : : int64 result; \
1042 : : PgStat_StatDBEntry *dbentry; \
1043 : : \
1044 : : if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) \
1045 : : result = 0; \
1046 : : else \
1047 : : result = (int64) (dbentry->stat); \
1048 : : \
1049 : : PG_RETURN_INT64(result); \
1050 : : }
1051 : :
1052 : : /* pg_stat_get_db_blocks_fetched */
1053 michael@paquier.xyz 1053 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(blocks_fetched)
1054 : :
1055 : : /* pg_stat_get_db_blocks_hit */
1056 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(blocks_hit)
1057 : :
1058 : : /* pg_stat_get_db_conflict_bufferpin */
1053 michael@paquier.xyz 1059 [ - + ]:CBC 1 : PG_STAT_GET_DBENTRY_INT64(conflict_bufferpin)
1060 : :
1061 : : /* pg_stat_get_db_conflict_lock */
1062 [ - + ]: 1 : PG_STAT_GET_DBENTRY_INT64(conflict_lock)
1063 : :
1064 : : /* pg_stat_get_db_conflict_snapshot */
1065 [ - + ]: 1 : PG_STAT_GET_DBENTRY_INT64(conflict_snapshot)
1066 : :
1067 : : /* pg_stat_get_db_conflict_startup_deadlock */
1068 [ - + ]: 1 : PG_STAT_GET_DBENTRY_INT64(conflict_startup_deadlock)
1069 : :
1070 : : /* pg_stat_get_db_conflict_tablespace */
1071 [ - + ]: 1 : PG_STAT_GET_DBENTRY_INT64(conflict_tablespace)
1072 : :
1073 : : /* pg_stat_get_db_deadlocks */
1074 [ - + ]: 1 : PG_STAT_GET_DBENTRY_INT64(deadlocks)
1075 : :
1076 : : /* pg_stat_get_db_sessions */
1077 [ - + ]: 6 : PG_STAT_GET_DBENTRY_INT64(sessions)
1078 : :
1079 : : /* pg_stat_get_db_sessions_abandoned */
1053 michael@paquier.xyz 1080 [ # # ]:UBC 0 : PG_STAT_GET_DBENTRY_INT64(sessions_abandoned)
1081 : :
1082 : : /* pg_stat_get_db_sessions_fatal */
1083 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(sessions_fatal)
1084 : :
1085 : : /* pg_stat_get_db_sessions_killed */
1086 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(sessions_killed)
1087 : :
1088 : : /* pg_stat_get_db_parallel_workers_to_launch */
351 michael@paquier.xyz 1089 [ - + ]:CBC 6 : PG_STAT_GET_DBENTRY_INT64(parallel_workers_to_launch)
1090 : :
1091 : : /* pg_stat_get_db_parallel_workers_launched */
1092 [ - + ]: 6 : PG_STAT_GET_DBENTRY_INT64(parallel_workers_launched)
1093 : :
1094 : : /* pg_stat_get_db_temp_bytes */
1053 michael@paquier.xyz 1095 [ # # ]:UBC 0 : PG_STAT_GET_DBENTRY_INT64(temp_bytes)
1096 : :
1097 : : /* pg_stat_get_db_temp_files */
1098 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(temp_files)
1099 : :
1100 : : /* pg_stat_get_db_tuples_deleted */
1101 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(tuples_deleted)
1102 : :
1103 : : /* pg_stat_get_db_tuples_fetched */
1104 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(tuples_fetched)
1105 : :
1106 : : /* pg_stat_get_db_tuples_inserted */
1107 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(tuples_inserted)
1108 : :
1109 : : /* pg_stat_get_db_tuples_returned */
1110 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(tuples_returned)
1111 : :
1112 : : /* pg_stat_get_db_tuples_updated */
1113 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(tuples_updated)
1114 : :
1115 : : /* pg_stat_get_db_xact_commit */
1116 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(xact_commit)
1117 : :
1118 : : /* pg_stat_get_db_xact_rollback */
1119 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(xact_rollback)
1120 : :
1121 : : /* pg_stat_get_db_conflict_logicalslot */
935 andres@anarazel.de 1122 [ # # ]: 0 : PG_STAT_GET_DBENTRY_INT64(conflict_logicalslot)
1123 : :
1124 : : Datum
5374 magnus@hagander.net 1125 :CBC 6 : pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS)
1126 : : {
1127 : 6 : Oid dbid = PG_GETARG_OID(0);
1128 : : TimestampTz result;
1129 : : PgStat_StatDBEntry *dbentry;
1130 : :
1131 [ - + ]: 6 : if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
5374 magnus@hagander.net 1132 :UBC 0 : result = 0;
1133 : : else
5374 magnus@hagander.net 1134 :CBC 6 : result = dbentry->stat_reset_timestamp;
1135 : :
1136 [ - + ]: 6 : if (result == 0)
5374 magnus@hagander.net 1137 :UBC 0 : PG_RETURN_NULL();
1138 : : else
5374 magnus@hagander.net 1139 :CBC 6 : PG_RETURN_TIMESTAMPTZ(result);
1140 : : }
1141 : :
1142 : :
1143 : : Datum
5412 1144 : 1 : pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS)
1145 : : {
1146 : 1 : Oid dbid = PG_GETARG_OID(0);
1147 : : int64 result;
1148 : : PgStat_StatDBEntry *dbentry;
1149 : :
1150 [ - + ]: 1 : if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
5412 magnus@hagander.net 1151 :UBC 0 : result = 0;
1152 : : else
1056 michael@paquier.xyz 1153 :CBC 1 : result = (int64) (dbentry->conflict_tablespace +
1154 : 1 : dbentry->conflict_lock +
1155 : 1 : dbentry->conflict_snapshot +
935 andres@anarazel.de 1156 : 1 : dbentry->conflict_logicalslot +
1056 michael@paquier.xyz 1157 : 1 : dbentry->conflict_bufferpin +
1158 : 1 : dbentry->conflict_startup_deadlock);
1159 : :
5024 magnus@hagander.net 1160 : 1 : PG_RETURN_INT64(result);
1161 : : }
1162 : :
1163 : : Datum
2425 1164 : 24 : pg_stat_get_db_checksum_failures(PG_FUNCTION_ARGS)
1165 : : {
1166 : 24 : Oid dbid = PG_GETARG_OID(0);
1167 : : int64 result;
1168 : : PgStat_StatDBEntry *dbentry;
1169 : :
2386 1170 [ - + ]: 24 : if (!DataChecksumsEnabled())
2386 magnus@hagander.net 1171 :UBC 0 : PG_RETURN_NULL();
1172 : :
2425 magnus@hagander.net 1173 [ - + ]:CBC 24 : if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
2425 magnus@hagander.net 1174 :UBC 0 : result = 0;
1175 : : else
1056 michael@paquier.xyz 1176 :CBC 24 : result = (int64) (dbentry->checksum_failures);
1177 : :
2425 magnus@hagander.net 1178 : 24 : PG_RETURN_INT64(result);
1179 : : }
1180 : :
1181 : : Datum
2391 1182 : 24 : pg_stat_get_db_checksum_last_failure(PG_FUNCTION_ARGS)
1183 : : {
1184 : 24 : Oid dbid = PG_GETARG_OID(0);
1185 : : TimestampTz result;
1186 : : PgStat_StatDBEntry *dbentry;
1187 : :
2386 1188 [ - + ]: 24 : if (!DataChecksumsEnabled())
2386 magnus@hagander.net 1189 :UBC 0 : PG_RETURN_NULL();
1190 : :
2391 magnus@hagander.net 1191 [ - + ]:CBC 24 : if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
2391 magnus@hagander.net 1192 :UBC 0 : result = 0;
1193 : : else
2391 magnus@hagander.net 1194 :CBC 24 : result = dbentry->last_checksum_failure;
1195 : :
1196 [ + + ]: 24 : if (result == 0)
1197 : 9 : PG_RETURN_NULL();
1198 : : else
1199 : 15 : PG_RETURN_TIMESTAMPTZ(result);
1200 : : }
1201 : :
1202 : : /* convert counter from microsec to millisec for display */
1203 : : #define PG_STAT_GET_DBENTRY_FLOAT8_MS(stat) \
1204 : : Datum \
1205 : : CppConcat(pg_stat_get_db_,stat)(PG_FUNCTION_ARGS) \
1206 : : { \
1207 : : Oid dbid = PG_GETARG_OID(0); \
1208 : : double result; \
1209 : : PgStat_StatDBEntry *dbentry; \
1210 : : \
1211 : : if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) \
1212 : : result = 0; \
1213 : : else \
1214 : : result = ((double) dbentry->stat) / 1000.0; \
1215 : : \
1216 : : PG_RETURN_FLOAT8(result); \
1217 : : }
1218 : :
1219 : : /* pg_stat_get_db_active_time */
945 michael@paquier.xyz 1220 [ # # ]:UBC 0 : PG_STAT_GET_DBENTRY_FLOAT8_MS(active_time)
1221 : :
1222 : : /* pg_stat_get_db_blk_read_time */
1223 [ # # ]: 0 : PG_STAT_GET_DBENTRY_FLOAT8_MS(blk_read_time)
1224 : :
1225 : : /* pg_stat_get_db_blk_write_time */
1226 [ # # ]: 0 : PG_STAT_GET_DBENTRY_FLOAT8_MS(blk_write_time)
1227 : :
1228 : : /* pg_stat_get_db_idle_in_transaction_time */
1229 [ # # ]: 0 : PG_STAT_GET_DBENTRY_FLOAT8_MS(idle_in_transaction_time)
1230 : :
1231 : : /* pg_stat_get_db_session_time */
1232 [ # # ]: 0 : PG_STAT_GET_DBENTRY_FLOAT8_MS(session_time)
1233 : :
1234 : : Datum
729 michael@paquier.xyz 1235 :CBC 4 : pg_stat_get_checkpointer_num_timed(PG_FUNCTION_ARGS)
1236 : : {
1237 : 4 : PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->num_timed);
1238 : : }
1239 : :
1240 : : Datum
1241 : 10 : pg_stat_get_checkpointer_num_requested(PG_FUNCTION_ARGS)
1242 : : {
1243 : 10 : PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->num_requested);
1244 : : }
1245 : :
1246 : : Datum
393 fujii@postgresql.org 1247 :UBC 0 : pg_stat_get_checkpointer_num_performed(PG_FUNCTION_ARGS)
1248 : : {
1249 : 0 : PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->num_performed);
1250 : : }
1251 : :
1252 : : Datum
673 akorotkov@postgresql 1253 : 0 : pg_stat_get_checkpointer_restartpoints_timed(PG_FUNCTION_ARGS)
1254 : : {
1255 : 0 : PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->restartpoints_timed);
1256 : : }
1257 : :
1258 : : Datum
1259 : 0 : pg_stat_get_checkpointer_restartpoints_requested(PG_FUNCTION_ARGS)
1260 : : {
1261 : 0 : PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->restartpoints_requested);
1262 : : }
1263 : :
1264 : : Datum
1265 : 0 : pg_stat_get_checkpointer_restartpoints_performed(PG_FUNCTION_ARGS)
1266 : : {
1267 : 0 : PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->restartpoints_performed);
1268 : : }
1269 : :
1270 : : Datum
729 michael@paquier.xyz 1271 : 0 : pg_stat_get_checkpointer_buffers_written(PG_FUNCTION_ARGS)
1272 : : {
1273 : 0 : PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buffers_written);
1274 : : }
1275 : :
1276 : : Datum
391 fujii@postgresql.org 1277 : 0 : pg_stat_get_checkpointer_slru_written(PG_FUNCTION_ARGS)
1278 : : {
1279 : 0 : PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->slru_written);
1280 : : }
1281 : :
1282 : : Datum
6697 tgl@sss.pgh.pa.us 1283 : 0 : pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
1284 : : {
1546 andres@anarazel.de 1285 : 0 : PG_RETURN_INT64(pgstat_fetch_stat_bgwriter()->buf_written_clean);
1286 : : }
1287 : :
1288 : : Datum
6697 tgl@sss.pgh.pa.us 1289 : 0 : pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
1290 : : {
1546 andres@anarazel.de 1291 : 0 : PG_RETURN_INT64(pgstat_fetch_stat_bgwriter()->maxwritten_clean);
1292 : : }
1293 : :
1294 : : Datum
729 michael@paquier.xyz 1295 : 0 : pg_stat_get_checkpointer_write_time(PG_FUNCTION_ARGS)
1296 : : {
1297 : : /* time is already in msec, just convert to double for presentation */
1546 andres@anarazel.de 1298 : 0 : PG_RETURN_FLOAT8((double)
1299 : : pgstat_fetch_stat_checkpointer()->write_time);
1300 : : }
1301 : :
1302 : : Datum
729 michael@paquier.xyz 1303 : 0 : pg_stat_get_checkpointer_sync_time(PG_FUNCTION_ARGS)
1304 : : {
1305 : : /* time is already in msec, just convert to double for presentation */
1546 andres@anarazel.de 1306 : 0 : PG_RETURN_FLOAT8((double)
1307 : : pgstat_fetch_stat_checkpointer()->sync_time);
1308 : : }
1309 : :
1310 : : Datum
729 michael@paquier.xyz 1311 :CBC 10 : pg_stat_get_checkpointer_stat_reset_time(PG_FUNCTION_ARGS)
1312 : : {
1313 : 10 : PG_RETURN_TIMESTAMPTZ(pgstat_fetch_stat_checkpointer()->stat_reset_timestamp);
1314 : : }
1315 : :
1316 : : Datum
5374 magnus@hagander.net 1317 : 6 : pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
1318 : : {
1546 andres@anarazel.de 1319 : 6 : PG_RETURN_TIMESTAMPTZ(pgstat_fetch_stat_bgwriter()->stat_reset_timestamp);
1320 : : }
1321 : :
1322 : : Datum
6608 tgl@sss.pgh.pa.us 1323 :UBC 0 : pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
1324 : : {
1546 andres@anarazel.de 1325 : 0 : PG_RETURN_INT64(pgstat_fetch_stat_bgwriter()->buf_alloc);
1326 : : }
1327 : :
1328 : : /*
1329 : : * When adding a new column to the pg_stat_io view and the
1330 : : * pg_stat_get_backend_io() function, add a new enum value here above
1331 : : * IO_NUM_COLUMNS.
1332 : : */
1333 : : typedef enum io_stat_col
1334 : : {
1335 : : IO_COL_INVALID = -1,
1336 : : IO_COL_BACKEND_TYPE,
1337 : : IO_COL_OBJECT,
1338 : : IO_COL_CONTEXT,
1339 : : IO_COL_READS,
1340 : : IO_COL_READ_BYTES,
1341 : : IO_COL_READ_TIME,
1342 : : IO_COL_WRITES,
1343 : : IO_COL_WRITE_BYTES,
1344 : : IO_COL_WRITE_TIME,
1345 : : IO_COL_WRITEBACKS,
1346 : : IO_COL_WRITEBACK_TIME,
1347 : : IO_COL_EXTENDS,
1348 : : IO_COL_EXTEND_BYTES,
1349 : : IO_COL_EXTEND_TIME,
1350 : : IO_COL_HITS,
1351 : : IO_COL_EVICTIONS,
1352 : : IO_COL_REUSES,
1353 : : IO_COL_FSYNCS,
1354 : : IO_COL_FSYNC_TIME,
1355 : : IO_COL_RESET_TIME,
1356 : : IO_NUM_COLUMNS,
1357 : : } io_stat_col;
1358 : :
1359 : : /*
1360 : : * When adding a new IOOp, add a new io_stat_col and add a case to this
1361 : : * function returning the corresponding io_stat_col.
1362 : : */
1363 : : static io_stat_col
990 andres@anarazel.de 1364 :CBC 47480 : pgstat_get_io_op_index(IOOp io_op)
1365 : : {
1366 [ + + + + : 47480 : switch (io_op)
+ + + +
- ]
1367 : : {
1368 : 5935 : case IOOP_EVICT:
1369 : 5935 : return IO_COL_EVICTIONS;
943 1370 : 5935 : case IOOP_EXTEND:
1371 : 5935 : return IO_COL_EXTENDS;
1372 : 5935 : case IOOP_FSYNC:
1373 : 5935 : return IO_COL_FSYNCS;
1374 : 5935 : case IOOP_HIT:
1375 : 5935 : return IO_COL_HITS;
990 1376 : 5935 : case IOOP_READ:
1377 : 5935 : return IO_COL_READS;
1378 : 5935 : case IOOP_REUSE:
1379 : 5935 : return IO_COL_REUSES;
1380 : 5935 : case IOOP_WRITE:
1381 : 5935 : return IO_COL_WRITES;
895 1382 : 5935 : case IOOP_WRITEBACK:
1383 : 5935 : return IO_COL_WRITEBACKS;
1384 : : }
1385 : :
990 andres@anarazel.de 1386 [ # # ]:UBC 0 : elog(ERROR, "unrecognized IOOp value: %d", io_op);
1387 : : pg_unreachable();
1388 : : }
1389 : :
1390 : : /*
1391 : : * Get the number of the column containing IO bytes for the specified IOOp.
1392 : : * If an IOOp is not tracked in bytes, IO_COL_INVALID is returned.
1393 : : */
1394 : : static io_stat_col
287 michael@paquier.xyz 1395 :CBC 47480 : pgstat_get_io_byte_index(IOOp io_op)
1396 : : {
1397 [ + + + + : 47480 : switch (io_op)
- ]
1398 : : {
1399 : 5935 : case IOOP_EXTEND:
1400 : 5935 : return IO_COL_EXTEND_BYTES;
1401 : 5935 : case IOOP_READ:
1402 : 5935 : return IO_COL_READ_BYTES;
1403 : 5935 : case IOOP_WRITE:
1404 : 5935 : return IO_COL_WRITE_BYTES;
1405 : 29675 : case IOOP_EVICT:
1406 : : case IOOP_FSYNC:
1407 : : case IOOP_HIT:
1408 : : case IOOP_REUSE:
1409 : : case IOOP_WRITEBACK:
1410 : 29675 : return IO_COL_INVALID;
1411 : : }
1412 : :
287 michael@paquier.xyz 1413 [ # # ]:UBC 0 : elog(ERROR, "unrecognized IOOp value: %d", io_op);
1414 : : pg_unreachable();
1415 : : }
1416 : :
1417 : : /*
1418 : : * Get the number of the column containing IO times for the specified IOOp.
1419 : : * If an op has no associated time, IO_COL_INVALID is returned.
1420 : : */
1421 : : static io_stat_col
935 andres@anarazel.de 1422 :CBC 47480 : pgstat_get_io_time_index(IOOp io_op)
1423 : : {
1424 [ + + + + : 47480 : switch (io_op)
+ + - ]
1425 : : {
1426 : 5935 : case IOOP_READ:
287 michael@paquier.xyz 1427 : 5935 : return IO_COL_READ_TIME;
935 andres@anarazel.de 1428 : 5935 : case IOOP_WRITE:
287 michael@paquier.xyz 1429 : 5935 : return IO_COL_WRITE_TIME;
895 andres@anarazel.de 1430 : 5935 : case IOOP_WRITEBACK:
287 michael@paquier.xyz 1431 : 5935 : return IO_COL_WRITEBACK_TIME;
935 andres@anarazel.de 1432 : 5935 : case IOOP_EXTEND:
287 michael@paquier.xyz 1433 : 5935 : return IO_COL_EXTEND_TIME;
935 andres@anarazel.de 1434 : 5935 : case IOOP_FSYNC:
287 michael@paquier.xyz 1435 : 5935 : return IO_COL_FSYNC_TIME;
935 andres@anarazel.de 1436 : 17805 : case IOOP_EVICT:
1437 : : case IOOP_HIT:
1438 : : case IOOP_REUSE:
1439 : 17805 : return IO_COL_INVALID;
1440 : : }
1441 : :
935 andres@anarazel.de 1442 [ # # ]:UBC 0 : elog(ERROR, "unrecognized IOOp value: %d", io_op);
1443 : : pg_unreachable();
1444 : : }
1445 : :
1446 : : static inline double
935 andres@anarazel.de 1447 :CBC 20100 : pg_stat_us_to_ms(PgStat_Counter val_ms)
1448 : : {
1449 : 20100 : return val_ms * (double) 0.001;
1450 : : }
1451 : :
1452 : : /*
1453 : : * pg_stat_io_build_tuples
1454 : : *
1455 : : * Helper routine for pg_stat_get_io() and pg_stat_get_backend_io()
1456 : : * filling a result tuplestore with one tuple for each object and each
1457 : : * context supported by the caller, based on the contents of bktype_stats.
1458 : : */
1459 : : static void
313 michael@paquier.xyz 1460 : 1043 : pg_stat_io_build_tuples(ReturnSetInfo *rsinfo,
1461 : : PgStat_BktypeIO *bktype_stats,
1462 : : BackendType bktype,
1463 : : TimestampTz stat_reset_timestamp)
1464 : : {
1465 : 1043 : Datum bktype_desc = CStringGetTextDatum(GetBackendTypeDesc(bktype));
1466 : :
1467 [ + + ]: 4172 : for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++)
1468 : : {
1469 : 3129 : const char *obj_name = pgstat_get_io_object_name(io_obj);
1470 : :
1471 [ + + ]: 18774 : for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
1472 : : {
1473 : 15645 : const char *context_name = pgstat_get_io_context_name(io_context);
1474 : :
1475 : 15645 : Datum values[IO_NUM_COLUMNS] = {0};
1476 : 15645 : bool nulls[IO_NUM_COLUMNS] = {0};
1477 : :
1478 : : /*
1479 : : * Some combinations of BackendType, IOObject, and IOContext are
1480 : : * not valid for any type of IOOp. In such cases, omit the entire
1481 : : * row from the view.
1482 : : */
1483 [ + + ]: 15645 : if (!pgstat_tracks_io_object(bktype, io_obj, io_context))
1484 : 9710 : continue;
1485 : :
1486 : 5935 : values[IO_COL_BACKEND_TYPE] = bktype_desc;
1487 : 5935 : values[IO_COL_CONTEXT] = CStringGetTextDatum(context_name);
1488 : 5935 : values[IO_COL_OBJECT] = CStringGetTextDatum(obj_name);
1489 [ + + ]: 5935 : if (stat_reset_timestamp != 0)
1490 : 5791 : values[IO_COL_RESET_TIME] = TimestampTzGetDatum(stat_reset_timestamp);
1491 : : else
1492 : 144 : nulls[IO_COL_RESET_TIME] = true;
1493 : :
1494 [ + + ]: 53415 : for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
1495 : : {
1496 : 47480 : int op_idx = pgstat_get_io_op_index(io_op);
1497 : 47480 : int time_idx = pgstat_get_io_time_index(io_op);
287 1498 : 47480 : int byte_idx = pgstat_get_io_byte_index(io_op);
1499 : :
1500 : : /*
1501 : : * Some combinations of BackendType and IOOp, of IOContext and
1502 : : * IOOp, and of IOObject and IOOp are not tracked. Set these
1503 : : * cells in the view NULL.
1504 : : */
313 1505 [ + + ]: 47480 : if (pgstat_tracks_io_op(bktype, io_obj, io_context, io_op))
1506 : : {
1507 : 29029 : PgStat_Counter count =
1508 : : bktype_stats->counts[io_obj][io_context][io_op];
1509 : :
1510 : 29029 : values[op_idx] = Int64GetDatum(count);
1511 : : }
1512 : : else
1513 : 18451 : nulls[op_idx] = true;
1514 : :
1515 [ + + ]: 47480 : if (!nulls[op_idx])
1516 : : {
1517 : : /* not every operation is timed */
287 1518 [ + + ]: 29029 : if (time_idx != IO_COL_INVALID)
1519 : : {
1520 : 20100 : PgStat_Counter time =
1521 : : bktype_stats->times[io_obj][io_context][io_op];
1522 : :
1523 : 20100 : values[time_idx] = Float8GetDatum(pg_stat_us_to_ms(time));
1524 : : }
1525 : :
1526 : : /* not every IO is tracked in bytes */
1527 [ + + ]: 29029 : if (byte_idx != IO_COL_INVALID)
1528 : : {
1529 : : char buf[256];
1530 : 12903 : PgStat_Counter byte =
1531 : 12903 : bktype_stats->bytes[io_obj][io_context][io_op];
1532 : :
1533 : : /* Convert to numeric */
147 peter@eisentraut.org 1534 : 12903 : snprintf(buf, sizeof buf, INT64_FORMAT, byte);
287 michael@paquier.xyz 1535 : 12903 : values[byte_idx] = DirectFunctionCall3(numeric_in,
1536 : : CStringGetDatum(buf),
1537 : : ObjectIdGetDatum(0),
1538 : : Int32GetDatum(-1));
1539 : : }
1540 : : }
1541 : : else
1542 : : {
1543 [ + + ]: 18451 : if (time_idx != IO_COL_INVALID)
1544 : 9575 : nulls[time_idx] = true;
1545 [ + + ]: 18451 : if (byte_idx != IO_COL_INVALID)
1546 : 4902 : nulls[byte_idx] = true;
1547 : : }
1548 : : }
1549 : :
313 1550 : 5935 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1551 : : values, nulls);
1552 : : }
1553 : : }
1554 : 1043 : }
1555 : :
1556 : : Datum
990 andres@anarazel.de 1557 : 73 : pg_stat_get_io(PG_FUNCTION_ARGS)
1558 : : {
1559 : : ReturnSetInfo *rsinfo;
1560 : : PgStat_IO *backends_io_stats;
1561 : :
1562 : 73 : InitMaterializedSRF(fcinfo, 0);
1563 : 73 : rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1564 : :
1565 : 73 : backends_io_stats = pgstat_fetch_stat_io();
1566 : :
974 tgl@sss.pgh.pa.us 1567 [ + + ]: 1387 : for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++)
1568 : : {
990 andres@anarazel.de 1569 : 1314 : PgStat_BktypeIO *bktype_stats = &backends_io_stats->stats[bktype];
1570 : :
1571 : : /*
1572 : : * In Assert builds, we can afford an extra loop through all of the
1573 : : * counters (in pg_stat_io_build_tuples()), checking that only
1574 : : * expected stats are non-zero, since it keeps the non-Assert code
1575 : : * cleaner.
1576 : : */
1577 [ - + ]: 1314 : Assert(pgstat_bktype_io_stats_valid(bktype_stats, bktype));
1578 : :
1579 : : /*
1580 : : * For those BackendTypes without IO Operation stats, skip
1581 : : * representing them in the view altogether.
1582 : : */
1583 [ + + ]: 1314 : if (!pgstat_tracks_io_bktype(bktype))
1584 : 292 : continue;
1585 : :
1586 : : /* save tuples with data from this PgStat_BktypeIO */
313 michael@paquier.xyz 1587 : 1022 : pg_stat_io_build_tuples(rsinfo, bktype_stats, bktype,
1588 : : backends_io_stats->stat_reset_timestamp);
1589 : : }
1590 : :
990 andres@anarazel.de 1591 : 73 : return (Datum) 0;
1592 : : }
1593 : :
1594 : : /*
1595 : : * Returns I/O statistics for a backend with given PID.
1596 : : */
1597 : : Datum
313 michael@paquier.xyz 1598 : 27 : pg_stat_get_backend_io(PG_FUNCTION_ARGS)
1599 : : {
1600 : : ReturnSetInfo *rsinfo;
1601 : : BackendType bktype;
1602 : : int pid;
1603 : : PgStat_Backend *backend_stats;
1604 : : PgStat_BktypeIO *bktype_stats;
1605 : :
1606 : 27 : InitMaterializedSRF(fcinfo, 0);
1607 : 27 : rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1608 : :
1609 : 27 : pid = PG_GETARG_INT32(0);
242 1610 : 27 : backend_stats = pgstat_fetch_stat_backend_by_pid(pid, &bktype);
1611 : :
313 1612 [ + + ]: 27 : if (!backend_stats)
1613 : 6 : return (Datum) 0;
1614 : :
291 1615 : 21 : bktype_stats = &backend_stats->io_stats;
1616 : :
1617 : : /*
1618 : : * In Assert builds, we can afford an extra loop through all of the
1619 : : * counters (in pg_stat_io_build_tuples()), checking that only expected
1620 : : * stats are non-zero, since it keeps the non-Assert code cleaner.
1621 : : */
313 1622 [ - + ]: 21 : Assert(pgstat_bktype_io_stats_valid(bktype_stats, bktype));
1623 : :
1624 : : /* save tuples with data from this PgStat_BktypeIO */
1625 : 21 : pg_stat_io_build_tuples(rsinfo, bktype_stats, bktype,
1626 : : backend_stats->stat_reset_timestamp);
1627 : 21 : return (Datum) 0;
1628 : : }
1629 : :
1630 : : /*
1631 : : * pg_stat_wal_build_tuple
1632 : : *
1633 : : * Helper routine for pg_stat_get_wal() and pg_stat_get_backend_wal()
1634 : : * returning one tuple based on the contents of wal_counters.
1635 : : */
1636 : : static Datum
243 1637 : 41 : pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
1638 : : TimestampTz stat_reset_timestamp)
1639 : : {
1640 : : #define PG_STAT_WAL_COLS 5
1641 : : TupleDesc tupdesc;
1642 : 41 : Datum values[PG_STAT_WAL_COLS] = {0};
1643 : 41 : bool nulls[PG_STAT_WAL_COLS] = {0};
1644 : : char buf[256];
1645 : :
1646 : : /* Initialise attributes information in the tuple descriptor */
1647 : 41 : tupdesc = CreateTemplateTupleDesc(PG_STAT_WAL_COLS);
1791 fujii@postgresql.org 1648 : 41 : TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records",
1649 : : INT8OID, -1, 0);
1650 : 41 : TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi",
1651 : : INT8OID, -1, 0);
1652 : 41 : TupleDescInitEntry(tupdesc, (AttrNumber) 3, "wal_bytes",
1653 : : NUMERICOID, -1, 0);
1654 : 41 : TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_buffers_full",
1655 : : INT8OID, -1, 0);
246 michael@paquier.xyz 1656 : 41 : TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stats_reset",
1657 : : TIMESTAMPTZOID, -1, 0);
1658 : :
1852 fujii@postgresql.org 1659 : 41 : BlessTupleDesc(tupdesc);
1660 : :
1661 : : /* Fill values and NULLs */
244 michael@paquier.xyz 1662 : 41 : values[0] = Int64GetDatum(wal_counters.wal_records);
1663 : 41 : values[1] = Int64GetDatum(wal_counters.wal_fpi);
1664 : :
1665 : : /* Convert to numeric. */
1666 : 41 : snprintf(buf, sizeof buf, UINT64_FORMAT, wal_counters.wal_bytes);
1791 fujii@postgresql.org 1667 : 41 : values[2] = DirectFunctionCall3(numeric_in,
1668 : : CStringGetDatum(buf),
1669 : : ObjectIdGetDatum(0),
1670 : : Int32GetDatum(-1));
1671 : :
244 michael@paquier.xyz 1672 : 41 : values[3] = Int64GetDatum(wal_counters.wal_buffers_full);
1673 : :
243 1674 [ + + ]: 41 : if (stat_reset_timestamp != 0)
1675 : 35 : values[4] = TimestampTzGetDatum(stat_reset_timestamp);
1676 : : else
1677 : 6 : nulls[4] = true;
1678 : :
1679 : : /* Returns the record as Datum */
1852 fujii@postgresql.org 1680 : 41 : PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
1681 : : }
1682 : :
1683 : : /*
1684 : : * Returns WAL statistics for a backend with given PID.
1685 : : */
1686 : : Datum
231 michael@paquier.xyz 1687 : 6 : pg_stat_get_backend_wal(PG_FUNCTION_ARGS)
1688 : : {
1689 : : int pid;
1690 : : PgStat_Backend *backend_stats;
1691 : : PgStat_WalCounters bktype_stats;
1692 : :
1693 : 6 : pid = PG_GETARG_INT32(0);
1694 : 6 : backend_stats = pgstat_fetch_stat_backend_by_pid(pid, NULL);
1695 : :
1696 [ - + ]: 6 : if (!backend_stats)
231 michael@paquier.xyz 1697 :UBC 0 : PG_RETURN_NULL();
1698 : :
231 michael@paquier.xyz 1699 :CBC 6 : bktype_stats = backend_stats->wal_counters;
1700 : :
1701 : : /* save tuples with data from this PgStat_WalCounters */
1702 : 6 : return (pg_stat_wal_build_tuple(bktype_stats, backend_stats->stat_reset_timestamp));
1703 : : }
1704 : :
1705 : : /*
1706 : : * Returns statistics of WAL activity
1707 : : */
1708 : : Datum
243 1709 : 35 : pg_stat_get_wal(PG_FUNCTION_ARGS)
1710 : : {
1711 : : PgStat_WalStats *wal_stats;
1712 : :
1713 : : /* Get statistics about WAL activity */
1714 : 35 : wal_stats = pgstat_fetch_stat_wal();
1715 : :
1716 : 35 : return (pg_stat_wal_build_tuple(wal_stats->wal_counters,
1717 : : wal_stats->stat_reset_timestamp));
1718 : : }
1719 : :
1720 : : /*
1721 : : * Returns statistics of SLRU caches.
1722 : : */
1723 : : Datum
2035 tomas.vondra@postgre 1724 : 62 : pg_stat_get_slru(PG_FUNCTION_ARGS)
1725 : : {
1726 : : #define PG_STAT_GET_SLRU_COLS 9
1993 tgl@sss.pgh.pa.us 1727 : 62 : ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1728 : : int i;
1729 : : PgStat_SLRUStats *stats;
1730 : :
1106 michael@paquier.xyz 1731 : 62 : InitMaterializedSRF(fcinfo, 0);
1732 : :
1733 : : /* request SLRU stats from the cumulative stats system */
2035 tomas.vondra@postgre 1734 : 62 : stats = pgstat_fetch_slru();
1735 : :
1993 tgl@sss.pgh.pa.us 1736 : 62 : for (i = 0;; i++)
2035 tomas.vondra@postgre 1737 : 496 : {
1738 : : /* for each row */
1200 peter@eisentraut.org 1739 : 558 : Datum values[PG_STAT_GET_SLRU_COLS] = {0};
1740 : 558 : bool nulls[PG_STAT_GET_SLRU_COLS] = {0};
1741 : : PgStat_SLRUStats stat;
1742 : : const char *name;
1743 : :
1301 andres@anarazel.de 1744 : 558 : name = pgstat_get_slru_name(i);
1745 : :
2035 tomas.vondra@postgre 1746 [ + + ]: 558 : if (!name)
1747 : 62 : break;
1748 : :
1446 michael@paquier.xyz 1749 : 496 : stat = stats[i];
1750 : :
2035 tomas.vondra@postgre 1751 : 496 : values[0] = PointerGetDatum(cstring_to_text(name));
1752 : 496 : values[1] = Int64GetDatum(stat.blocks_zeroed);
1753 : 496 : values[2] = Int64GetDatum(stat.blocks_hit);
1754 : 496 : values[3] = Int64GetDatum(stat.blocks_read);
1755 : 496 : values[4] = Int64GetDatum(stat.blocks_written);
1756 : 496 : values[5] = Int64GetDatum(stat.blocks_exists);
1757 : 496 : values[6] = Int64GetDatum(stat.flush);
1758 : 496 : values[7] = Int64GetDatum(stat.truncate);
1994 fujii@postgresql.org 1759 : 496 : values[8] = TimestampTzGetDatum(stat.stat_reset_timestamp);
1760 : :
1331 michael@paquier.xyz 1761 : 496 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
1762 : : }
1763 : :
2035 tomas.vondra@postgre 1764 : 62 : return (Datum) 0;
1765 : : }
1766 : :
1767 : : #define PG_STAT_GET_XACT_RELENTRY_INT64(stat) \
1768 : : Datum \
1769 : : CppConcat(pg_stat_get_xact_,stat)(PG_FUNCTION_ARGS) \
1770 : : { \
1771 : : Oid relid = PG_GETARG_OID(0); \
1772 : : int64 result; \
1773 : : PgStat_TableStatus *tabentry; \
1774 : : \
1775 : : if ((tabentry = find_tabstat_entry(relid)) == NULL) \
1776 : : result = 0; \
1777 : : else \
1778 : : result = (int64) (tabentry->counts.stat); \
1779 : : \
1780 : : PG_RETURN_INT64(result); \
1781 : : }
1782 : :
1783 : : /* pg_stat_get_xact_numscans */
946 michael@paquier.xyz 1784 [ # # ]:UBC 0 : PG_STAT_GET_XACT_RELENTRY_INT64(numscans)
1785 : :
1786 : : /* pg_stat_get_xact_tuples_returned */
1787 [ # # ]: 0 : PG_STAT_GET_XACT_RELENTRY_INT64(tuples_returned)
1788 : :
1789 : : /* pg_stat_get_xact_tuples_fetched */
1790 [ # # ]: 0 : PG_STAT_GET_XACT_RELENTRY_INT64(tuples_fetched)
1791 : :
1792 : : /* pg_stat_get_xact_tuples_hot_updated */
1793 [ # # ]: 0 : PG_STAT_GET_XACT_RELENTRY_INT64(tuples_hot_updated)
1794 : :
1795 : : /* pg_stat_get_xact_tuples_newpage_updated */
1796 [ # # ]: 0 : PG_STAT_GET_XACT_RELENTRY_INT64(tuples_newpage_updated)
1797 : :
1798 : : /* pg_stat_get_xact_blocks_fetched */
1799 [ # # ]: 0 : PG_STAT_GET_XACT_RELENTRY_INT64(blocks_fetched)
1800 : :
1801 : : /* pg_stat_get_xact_blocks_hit */
1802 [ # # ]: 0 : PG_STAT_GET_XACT_RELENTRY_INT64(blocks_hit)
1803 : :
1804 : : /* pg_stat_get_xact_tuples_inserted */
729 michael@paquier.xyz 1805 [ + + ]:CBC 24 : PG_STAT_GET_XACT_RELENTRY_INT64(tuples_inserted)
1806 : :
1807 : : /* pg_stat_get_xact_tuples_updated */
729 michael@paquier.xyz 1808 [ # # ]:UBC 0 : PG_STAT_GET_XACT_RELENTRY_INT64(tuples_updated)
1809 : :
1810 : : /* pg_stat_get_xact_tuples_deleted */
1811 [ # # ]: 0 : PG_STAT_GET_XACT_RELENTRY_INT64(tuples_deleted)
1812 : :
1813 : : Datum
5560 tgl@sss.pgh.pa.us 1814 :CBC 12 : pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
1815 : : {
1816 : 12 : Oid funcid = PG_GETARG_OID(0);
1817 : : PgStat_FunctionCounts *funcentry;
1818 : :
1819 [ + + ]: 12 : if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1820 : 3 : PG_RETURN_NULL();
949 michael@paquier.xyz 1821 : 9 : PG_RETURN_INT64(funcentry->numcalls);
1822 : : }
1823 : :
1824 : : #define PG_STAT_GET_XACT_FUNCENTRY_FLOAT8_MS(stat) \
1825 : : Datum \
1826 : : CppConcat(pg_stat_get_xact_function_,stat)(PG_FUNCTION_ARGS) \
1827 : : { \
1828 : : Oid funcid = PG_GETARG_OID(0); \
1829 : : PgStat_FunctionCounts *funcentry; \
1830 : : \
1831 : : if ((funcentry = find_funcstat_entry(funcid)) == NULL) \
1832 : : PG_RETURN_NULL(); \
1833 : : PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(funcentry->stat)); \
1834 : : }
1835 : :
1836 : : /* pg_stat_get_xact_function_total_time */
945 michael@paquier.xyz 1837 [ # # ]:UBC 0 : PG_STAT_GET_XACT_FUNCENTRY_FLOAT8_MS(total_time)
1838 : :
1839 : : /* pg_stat_get_xact_function_self_time */
1840 [ # # ]: 0 : PG_STAT_GET_XACT_FUNCENTRY_FLOAT8_MS(self_time)
1841 : :
1842 : : /* Get the timestamp of the current statistics snapshot */
1843 : : Datum
3904 tgl@sss.pgh.pa.us 1844 :CBC 30 : pg_stat_get_snapshot_timestamp(PG_FUNCTION_ARGS)
1845 : : {
1846 : : bool have_snapshot;
1847 : : TimestampTz ts;
1848 : :
1301 andres@anarazel.de 1849 : 30 : ts = pgstat_get_stat_snapshot_timestamp(&have_snapshot);
1850 : :
1851 [ + + ]: 30 : if (!have_snapshot)
1852 : 18 : PG_RETURN_NULL();
1853 : :
1854 : 12 : PG_RETURN_TIMESTAMPTZ(ts);
1855 : : }
1856 : :
1857 : : /* Discard the active statistics snapshot */
1858 : : Datum
6838 tgl@sss.pgh.pa.us 1859 : 7 : pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
1860 : : {
1861 : 7 : pgstat_clear_snapshot();
1862 : :
1863 : 7 : PG_RETURN_VOID();
1864 : : }
1865 : :
1866 : :
1867 : : /* Force statistics to be reported at the next occasion */
1868 : : Datum
1301 andres@anarazel.de 1869 : 242 : pg_stat_force_next_flush(PG_FUNCTION_ARGS)
1870 : : {
1871 : 242 : pgstat_force_next_flush();
1872 : :
1873 : 242 : PG_RETURN_VOID();
1874 : : }
1875 : :
1876 : :
1877 : : /* Reset all counters for the current database */
1878 : : Datum
6838 tgl@sss.pgh.pa.us 1879 : 7 : pg_stat_reset(PG_FUNCTION_ARGS)
1880 : : {
1881 : 7 : pgstat_reset_counters();
1882 : :
1883 : 7 : PG_RETURN_VOID();
1884 : : }
1885 : :
1886 : : /*
1887 : : * Reset some shared cluster-wide counters
1888 : : *
1889 : : * When adding a new reset target, ideally the name should match that in
1890 : : * pgstat_kind_builtin_infos, if relevant.
1891 : : */
1892 : : Datum
5761 magnus@hagander.net 1893 : 28 : pg_stat_reset_shared(PG_FUNCTION_ARGS)
1894 : : {
716 michael@paquier.xyz 1895 : 28 : char *target = NULL;
1896 : :
1897 [ - + ]: 28 : if (PG_ARGISNULL(0))
1898 : : {
1899 : : /* Reset all the statistics when nothing is specified */
716 michael@paquier.xyz 1900 :UBC 0 : pgstat_reset_of_kind(PGSTAT_KIND_ARCHIVER);
1901 : 0 : pgstat_reset_of_kind(PGSTAT_KIND_BGWRITER);
1902 : 0 : pgstat_reset_of_kind(PGSTAT_KIND_CHECKPOINTER);
1903 : 0 : pgstat_reset_of_kind(PGSTAT_KIND_IO);
1904 : 0 : XLogPrefetchResetStats();
712 1905 : 0 : pgstat_reset_of_kind(PGSTAT_KIND_SLRU);
716 1906 : 0 : pgstat_reset_of_kind(PGSTAT_KIND_WAL);
1907 : :
1908 : 0 : PG_RETURN_VOID();
1909 : : }
1910 : :
716 michael@paquier.xyz 1911 :CBC 28 : target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1912 : :
1301 andres@anarazel.de 1913 [ + + ]: 28 : if (strcmp(target, "archiver") == 0)
1914 : 3 : pgstat_reset_of_kind(PGSTAT_KIND_ARCHIVER);
1915 [ + + ]: 25 : else if (strcmp(target, "bgwriter") == 0)
1916 : 3 : pgstat_reset_of_kind(PGSTAT_KIND_BGWRITER);
729 michael@paquier.xyz 1917 [ + + ]: 22 : else if (strcmp(target, "checkpointer") == 0)
1301 andres@anarazel.de 1918 : 4 : pgstat_reset_of_kind(PGSTAT_KIND_CHECKPOINTER);
993 1919 [ + + ]: 18 : else if (strcmp(target, "io") == 0)
1920 : 5 : pgstat_reset_of_kind(PGSTAT_KIND_IO);
1300 tmunro@postgresql.or 1921 [ + + ]: 13 : else if (strcmp(target, "recovery_prefetch") == 0)
1922 : 3 : XLogPrefetchResetStats();
712 michael@paquier.xyz 1923 [ + + ]: 10 : else if (strcmp(target, "slru") == 0)
1924 : 3 : pgstat_reset_of_kind(PGSTAT_KIND_SLRU);
1301 andres@anarazel.de 1925 [ + + ]: 7 : else if (strcmp(target, "wal") == 0)
1926 : 4 : pgstat_reset_of_kind(PGSTAT_KIND_WAL);
1927 : : else
1928 [ + - ]: 3 : ereport(ERROR,
1929 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1930 : : errmsg("unrecognized reset target: \"%s\"", target),
1931 : : errhint("Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"recovery_prefetch\", \"slru\", or \"wal\".")));
1932 : :
5761 magnus@hagander.net 1933 : 25 : PG_RETURN_VOID();
1934 : : }
1935 : :
1936 : : /*
1937 : : * Reset a statistics for a single object, which may be of current
1938 : : * database or shared across all databases in the cluster.
1939 : : */
1940 : : Datum
5752 1941 : 9 : pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
1942 : : {
5723 bruce@momjian.us 1943 : 9 : Oid taboid = PG_GETARG_OID(0);
799 michael@paquier.xyz 1944 [ + + ]: 9 : Oid dboid = (IsSharedRelation(taboid) ? InvalidOid : MyDatabaseId);
1945 : :
1946 : 9 : pgstat_reset(PGSTAT_KIND_RELATION, dboid, taboid);
1947 : :
5752 magnus@hagander.net 1948 : 9 : PG_RETURN_VOID();
1949 : : }
1950 : :
1951 : : Datum
1952 : 2 : pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
1953 : : {
5723 bruce@momjian.us 1954 : 2 : Oid funcoid = PG_GETARG_OID(0);
1955 : :
1301 andres@anarazel.de 1956 : 2 : pgstat_reset(PGSTAT_KIND_FUNCTION, MyDatabaseId, funcoid);
1957 : :
5752 magnus@hagander.net 1958 : 2 : PG_RETURN_VOID();
1959 : : }
1960 : :
1961 : : /*
1962 : : * Reset statistics of backend with given PID.
1963 : : */
1964 : : Datum
313 michael@paquier.xyz 1965 : 3 : pg_stat_reset_backend_stats(PG_FUNCTION_ARGS)
1966 : : {
1967 : : PGPROC *proc;
1968 : : PgBackendStatus *beentry;
1969 : : ProcNumber procNumber;
1970 : 3 : int backend_pid = PG_GETARG_INT32(0);
1971 : :
1972 : 3 : proc = BackendPidGetProc(backend_pid);
1973 : :
1974 : : /* This could be an auxiliary process */
239 1975 [ - + ]: 3 : if (!proc)
239 michael@paquier.xyz 1976 :UBC 0 : proc = AuxiliaryPidGetProc(backend_pid);
1977 : :
313 michael@paquier.xyz 1978 [ - + ]:CBC 3 : if (!proc)
313 michael@paquier.xyz 1979 :UBC 0 : PG_RETURN_VOID();
1980 : :
239 michael@paquier.xyz 1981 :CBC 3 : procNumber = GetNumberFromPGProc(proc);
1982 : :
1983 : 3 : beentry = pgstat_get_beentry_by_proc_number(procNumber);
1984 [ - + ]: 3 : if (!beentry)
239 michael@paquier.xyz 1985 :UBC 0 : PG_RETURN_VOID();
1986 : :
1987 : : /* Check if the backend type tracks statistics */
239 michael@paquier.xyz 1988 [ - + ]:CBC 3 : if (!pgstat_tracks_backend_bktype(beentry->st_backendType))
239 michael@paquier.xyz 1989 :UBC 0 : PG_RETURN_VOID();
1990 : :
239 michael@paquier.xyz 1991 :CBC 3 : pgstat_reset(PGSTAT_KIND_BACKEND, InvalidOid, procNumber);
1992 : :
313 1993 : 3 : PG_RETURN_VOID();
1994 : : }
1995 : :
1996 : : /* Reset SLRU counters (a specific one or all of them). */
1997 : : Datum
2035 tomas.vondra@postgre 1998 : 6 : pg_stat_reset_slru(PG_FUNCTION_ARGS)
1999 : : {
2000 : 6 : char *target = NULL;
2001 : :
1301 andres@anarazel.de 2002 [ + + ]: 6 : if (PG_ARGISNULL(0))
2003 : 3 : pgstat_reset_of_kind(PGSTAT_KIND_SLRU);
2004 : : else
2005 : : {
2035 tomas.vondra@postgre 2006 : 3 : target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1301 andres@anarazel.de 2007 : 3 : pgstat_reset_slru(target);
2008 : : }
2009 : :
2035 tomas.vondra@postgre 2010 : 6 : PG_RETURN_VOID();
2011 : : }
2012 : :
2013 : : /* Reset replication slots stats (a specific one or all of them). */
2014 : : Datum
1846 akapila@postgresql.o 2015 : 6 : pg_stat_reset_replication_slot(PG_FUNCTION_ARGS)
2016 : : {
2017 : 6 : char *target = NULL;
2018 : :
1301 andres@anarazel.de 2019 [ + + ]: 6 : if (PG_ARGISNULL(0))
2020 : 2 : pgstat_reset_of_kind(PGSTAT_KIND_REPLSLOT);
2021 : : else
2022 : : {
1846 akapila@postgresql.o 2023 : 4 : target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1301 andres@anarazel.de 2024 : 4 : pgstat_reset_replslot(target);
2025 : : }
2026 : :
1846 akapila@postgresql.o 2027 : 5 : PG_RETURN_VOID();
2028 : : }
2029 : :
2030 : : /* Reset subscription stats (a specific one or all of them) */
2031 : : Datum
1337 2032 : 10 : pg_stat_reset_subscription_stats(PG_FUNCTION_ARGS)
2033 : : {
2034 : : Oid subid;
2035 : :
2036 [ + + ]: 10 : if (PG_ARGISNULL(0))
2037 : : {
2038 : : /* Clear all subscription stats */
1301 andres@anarazel.de 2039 : 2 : pgstat_reset_of_kind(PGSTAT_KIND_SUBSCRIPTION);
2040 : : }
2041 : : else
2042 : : {
1337 akapila@postgresql.o 2043 : 8 : subid = PG_GETARG_OID(0);
2044 : :
2045 [ - + ]: 8 : if (!OidIsValid(subid))
1337 akapila@postgresql.o 2046 [ # # ]:UBC 0 : ereport(ERROR,
2047 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2048 : : errmsg("invalid subscription OID %u", subid)));
1301 andres@anarazel.de 2049 :CBC 8 : pgstat_reset(PGSTAT_KIND_SUBSCRIPTION, InvalidOid, subid);
2050 : : }
2051 : :
1337 akapila@postgresql.o 2052 : 10 : PG_RETURN_VOID();
2053 : : }
2054 : :
2055 : : Datum
4290 fujii@postgresql.org 2056 : 19 : pg_stat_get_archiver(PG_FUNCTION_ARGS)
2057 : : {
2058 : : TupleDesc tupdesc;
1200 peter@eisentraut.org 2059 : 19 : Datum values[7] = {0};
2060 : 19 : bool nulls[7] = {0};
2061 : : PgStat_ArchiverStats *archiver_stats;
2062 : :
2063 : : /* Initialise attributes information in the tuple descriptor */
2534 andres@anarazel.de 2064 : 19 : tupdesc = CreateTemplateTupleDesc(7);
4290 fujii@postgresql.org 2065 : 19 : TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
2066 : : INT8OID, -1, 0);
2067 : 19 : TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
2068 : : TEXTOID, -1, 0);
2069 : 19 : TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
2070 : : TIMESTAMPTZOID, -1, 0);
2071 : 19 : TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
2072 : : INT8OID, -1, 0);
2073 : 19 : TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
2074 : : TEXTOID, -1, 0);
2075 : 19 : TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
2076 : : TIMESTAMPTZOID, -1, 0);
2077 : 19 : TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
2078 : : TIMESTAMPTZOID, -1, 0);
2079 : :
2080 : 19 : BlessTupleDesc(tupdesc);
2081 : :
2082 : : /* Get statistics about the archiver process */
2083 : 19 : archiver_stats = pgstat_fetch_stat_archiver();
2084 : :
2085 : : /* Fill values and NULLs */
2086 : 19 : values[0] = Int64GetDatum(archiver_stats->archived_count);
4284 2087 [ + + ]: 19 : if (*(archiver_stats->last_archived_wal) == '\0')
4290 2088 : 9 : nulls[1] = true;
2089 : : else
2090 : 10 : values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);
2091 : :
2092 [ + + ]: 19 : if (archiver_stats->last_archived_timestamp == 0)
2093 : 9 : nulls[2] = true;
2094 : : else
2095 : 10 : values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);
2096 : :
2097 : 19 : values[3] = Int64GetDatum(archiver_stats->failed_count);
4284 2098 [ + + ]: 19 : if (*(archiver_stats->last_failed_wal) == '\0')
4290 2099 : 11 : nulls[4] = true;
2100 : : else
2101 : 8 : values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);
2102 : :
2103 [ + + ]: 19 : if (archiver_stats->last_failed_timestamp == 0)
2104 : 11 : nulls[5] = true;
2105 : : else
2106 : 8 : values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);
2107 : :
2108 [ - + ]: 19 : if (archiver_stats->stat_reset_timestamp == 0)
4290 fujii@postgresql.org 2109 :UBC 0 : nulls[6] = true;
2110 : : else
4290 fujii@postgresql.org 2111 :CBC 19 : values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);
2112 : :
2113 : : /* Returns the record as Datum */
2098 alvherre@alvh.no-ip. 2114 : 19 : PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
2115 : : }
2116 : :
2117 : : /*
2118 : : * Get the statistics for the replication slot. If the slot statistics is not
2119 : : * available, return all-zeroes stats.
2120 : : */
2121 : : Datum
1645 akapila@postgresql.o 2122 : 47 : pg_stat_get_replication_slot(PG_FUNCTION_ARGS)
2123 : : {
2124 : : #define PG_STAT_GET_REPLICATION_SLOT_COLS 11
2125 : 47 : text *slotname_text = PG_GETARG_TEXT_P(0);
2126 : : NameData slotname;
2127 : : TupleDesc tupdesc;
1200 peter@eisentraut.org 2128 : 47 : Datum values[PG_STAT_GET_REPLICATION_SLOT_COLS] = {0};
2129 : 47 : bool nulls[PG_STAT_GET_REPLICATION_SLOT_COLS] = {0};
2130 : : PgStat_StatReplSlotEntry *slotent;
2131 : : PgStat_StatReplSlotEntry allzero;
2132 : :
2133 : : /* Initialise attributes information in the tuple descriptor */
1645 akapila@postgresql.o 2134 : 47 : tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_REPLICATION_SLOT_COLS);
2135 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 1, "slot_name",
2136 : : TEXTOID, -1, 0);
2137 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 2, "spill_txns",
2138 : : INT8OID, -1, 0);
2139 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 3, "spill_count",
2140 : : INT8OID, -1, 0);
2141 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 4, "spill_bytes",
2142 : : INT8OID, -1, 0);
2143 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stream_txns",
2144 : : INT8OID, -1, 0);
2145 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stream_count",
2146 : : INT8OID, -1, 0);
2147 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stream_bytes",
2148 : : INT8OID, -1, 0);
20 msawada@postgresql.o 2149 :GNC 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 8, "mem_exceeded_count",
2150 : : INT8OID, -1, 0);
2151 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_txns",
2152 : : INT8OID, -1, 0);
2153 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 10, "total_bytes",
2154 : : INT8OID, -1, 0);
2155 : 47 : TupleDescInitEntry(tupdesc, (AttrNumber) 11, "stats_reset",
2156 : : TIMESTAMPTZOID, -1, 0);
1645 akapila@postgresql.o 2157 :CBC 47 : BlessTupleDesc(tupdesc);
2158 : :
2159 : 47 : namestrcpy(&slotname, text_to_cstring(slotname_text));
2160 : 47 : slotent = pgstat_fetch_replslot(slotname);
2161 [ + + ]: 47 : if (!slotent)
2162 : : {
2163 : : /*
2164 : : * If the slot is not found, initialise its stats. This is possible if
2165 : : * the create slot message is lost.
2166 : : */
2167 : 2 : memset(&allzero, 0, sizeof(PgStat_StatReplSlotEntry));
2168 : 2 : slotent = &allzero;
2169 : : }
2170 : :
2171 : 47 : values[0] = CStringGetTextDatum(NameStr(slotname));
2172 : 47 : values[1] = Int64GetDatum(slotent->spill_txns);
2173 : 47 : values[2] = Int64GetDatum(slotent->spill_count);
2174 : 47 : values[3] = Int64GetDatum(slotent->spill_bytes);
2175 : 47 : values[4] = Int64GetDatum(slotent->stream_txns);
2176 : 47 : values[5] = Int64GetDatum(slotent->stream_count);
2177 : 47 : values[6] = Int64GetDatum(slotent->stream_bytes);
20 msawada@postgresql.o 2178 :GNC 47 : values[7] = Int64GetDatum(slotent->mem_exceeded_count);
2179 : 47 : values[8] = Int64GetDatum(slotent->total_txns);
2180 : 47 : values[9] = Int64GetDatum(slotent->total_bytes);
2181 : :
1645 akapila@postgresql.o 2182 [ + + ]:CBC 47 : if (slotent->stat_reset_timestamp == 0)
20 msawada@postgresql.o 2183 :GNC 23 : nulls[10] = true;
2184 : : else
2185 : 24 : values[10] = TimestampTzGetDatum(slotent->stat_reset_timestamp);
2186 : :
2187 : : /* Returns the record as Datum */
1645 akapila@postgresql.o 2188 :CBC 47 : PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
2189 : : }
2190 : :
2191 : : /*
2192 : : * Get the subscription statistics for the given subscription. If the
2193 : : * subscription statistics is not available, return all-zeros stats.
2194 : : */
2195 : : Datum
1337 2196 : 37 : pg_stat_get_subscription_stats(PG_FUNCTION_ARGS)
2197 : : {
2198 : : #define PG_STAT_GET_SUBSCRIPTION_STATS_COLS 12
1428 2199 : 37 : Oid subid = PG_GETARG_OID(0);
2200 : : TupleDesc tupdesc;
1200 peter@eisentraut.org 2201 : 37 : Datum values[PG_STAT_GET_SUBSCRIPTION_STATS_COLS] = {0};
2202 : 37 : bool nulls[PG_STAT_GET_SUBSCRIPTION_STATS_COLS] = {0};
2203 : : PgStat_StatSubEntry *subentry;
2204 : : PgStat_StatSubEntry allzero;
419 akapila@postgresql.o 2205 : 37 : int i = 0;
2206 : :
2207 : : /* Get subscription stats */
1337 2208 : 37 : subentry = pgstat_fetch_stat_subscription(subid);
2209 : :
2210 : : /* Initialise attributes information in the tuple descriptor */
2211 : 37 : tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_SUBSCRIPTION_STATS_COLS);
1428 2212 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subid",
2213 : : OIDOID, -1, 0);
1337 2214 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 2, "apply_error_count",
2215 : : INT8OID, -1, 0);
2216 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 3, "sync_error_count",
2217 : : INT8OID, -1, 0);
419 2218 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 4, "confl_insert_exists",
2219 : : INT8OID, -1, 0);
2220 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 5, "confl_update_origin_differs",
2221 : : INT8OID, -1, 0);
2222 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 6, "confl_update_exists",
2223 : : INT8OID, -1, 0);
85 akapila@postgresql.o 2224 :GNC 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 7, "confl_update_deleted",
2225 : : INT8OID, -1, 0);
2226 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 8, "confl_update_missing",
2227 : : INT8OID, -1, 0);
2228 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 9, "confl_delete_origin_differs",
2229 : : INT8OID, -1, 0);
2230 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 10, "confl_delete_missing",
2231 : : INT8OID, -1, 0);
2232 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 11, "confl_multiple_unique_conflicts",
2233 : : INT8OID, -1, 0);
2234 : 37 : TupleDescInitEntry(tupdesc, (AttrNumber) 12, "stats_reset",
2235 : : TIMESTAMPTZOID, -1, 0);
1428 akapila@postgresql.o 2236 :CBC 37 : BlessTupleDesc(tupdesc);
2237 : :
1337 2238 [ - + ]: 37 : if (!subentry)
2239 : : {
2240 : : /* If the subscription is not found, initialise its stats */
1337 akapila@postgresql.o 2241 :UBC 0 : memset(&allzero, 0, sizeof(PgStat_StatSubEntry));
2242 : 0 : subentry = &allzero;
2243 : : }
2244 : :
2245 : : /* subid */
419 akapila@postgresql.o 2246 :CBC 37 : values[i++] = ObjectIdGetDatum(subid);
2247 : :
2248 : : /* apply_error_count */
2249 : 37 : values[i++] = Int64GetDatum(subentry->apply_error_count);
2250 : :
2251 : : /* sync_error_count */
2252 : 37 : values[i++] = Int64GetDatum(subentry->sync_error_count);
2253 : :
2254 : : /* conflict count */
2255 [ + + ]: 333 : for (int nconflict = 0; nconflict < CONFLICT_NUM_TYPES; nconflict++)
2256 : 296 : values[i++] = Int64GetDatum(subentry->conflict_count[nconflict]);
2257 : :
2258 : : /* stats_reset */
1337 2259 [ + + ]: 37 : if (subentry->stat_reset_timestamp == 0)
419 2260 : 18 : nulls[i] = true;
2261 : : else
2262 : 19 : values[i] = TimestampTzGetDatum(subentry->stat_reset_timestamp);
2263 : :
2264 [ - + ]: 37 : Assert(i + 1 == PG_STAT_GET_SUBSCRIPTION_STATS_COLS);
2265 : :
2266 : : /* Returns the record as Datum */
1428 2267 : 37 : PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
2268 : : }
2269 : :
2270 : : /*
2271 : : * Checks for presence of stats for object with provided kind, database oid,
2272 : : * object oid.
2273 : : *
2274 : : * This is useful for tests, but not really anything else. Therefore not
2275 : : * documented.
2276 : : */
2277 : : Datum
1300 andres@anarazel.de 2278 : 83 : pg_stat_have_stats(PG_FUNCTION_ARGS)
2279 : : {
2280 : 83 : char *stats_type = text_to_cstring(PG_GETARG_TEXT_P(0));
2281 : 83 : Oid dboid = PG_GETARG_OID(1);
405 michael@paquier.xyz 2282 : 83 : uint64 objid = PG_GETARG_INT64(2);
1265 tgl@sss.pgh.pa.us 2283 : 83 : PgStat_Kind kind = pgstat_get_kind_from_str(stats_type);
2284 : :
405 michael@paquier.xyz 2285 : 80 : PG_RETURN_BOOL(pgstat_have_entry(kind, dboid, objid));
2286 : : }
|