31 #ifdef HAVE_SYS_SELECT_H 32 #include <sys/select.h> 78 #define PGSTAT_STAT_INTERVAL 500 81 #define PGSTAT_RETRY_DELAY 10 84 #define PGSTAT_MAX_WAIT_TIME 10000 87 #define PGSTAT_INQ_INTERVAL 640 90 #define PGSTAT_RESTART_INTERVAL 60 94 #define PGSTAT_POLL_LOOP_COUNT (PGSTAT_MAX_WAIT_TIME / PGSTAT_RETRY_DELAY) 95 #define PGSTAT_INQ_LOOP_COUNT (PGSTAT_INQ_INTERVAL / PGSTAT_RETRY_DELAY) 98 #define PGSTAT_MIN_RCVBUF (100 * 1024) 105 #define PGSTAT_DB_HASH_SIZE 16 106 #define PGSTAT_TAB_HASH_SIZE 512 107 #define PGSTAT_FUNCTION_HASH_SIZE 512 119 #define NumBackendStatSlots (MaxBackends + NUM_AUXPROCTYPES) 171 #define SLRU_NUM_ELEMENTS lengthof(slru_names) 204 #define TABSTAT_QUANTUM 100 323 static pid_t pgstat_forkexec(
void);
331 Oid tableoid,
bool create);
406 ACCEPT_TYPE_ARG3 alen;
417 #define TESTBYTEVAL ((char) 199) 427 "maximum stats message size exceeds PGSTAT_MAX_MSG_SIZE");
433 hints.ai_family = AF_UNSPEC;
434 hints.ai_socktype = SOCK_DGRAM;
435 hints.ai_protocol = 0;
436 hints.ai_addrlen = 0;
437 hints.ai_addr = NULL;
438 hints.ai_canonname = NULL;
439 hints.ai_next = NULL;
444 (
errmsg(
"could not resolve \"localhost\": %s",
457 for (addr = addrs; addr; addr = addr->
ai_next)
459 #ifdef HAVE_UNIX_SOCKETS 461 if (addr->ai_family == AF_UNIX)
467 (
errmsg(
"trying another address for the statistics collector")));
476 errmsg(
"could not create socket for statistics collector: %m")));
488 errmsg(
"could not bind socket for statistics collector: %m")));
499 errmsg(
"could not get address of socket for statistics collector: %m")));
515 errmsg(
"could not connect socket for statistics collector: %m")));
536 errmsg(
"could not send test message on socket for statistics collector: %m")));
555 if (sel_res >= 0 || errno !=
EINTR)
562 errmsg(
"select() failed in statistics collector: %m")));
567 if (sel_res == 0 || !FD_ISSET(
pgStatSock, &rset))
576 (
errcode(ERRCODE_CONNECTION_FAILURE),
577 errmsg(
"test message did not get through on socket for statistics collector")));
592 errmsg(
"could not receive test message on socket for statistics collector: %m")));
601 (
errcode(ERRCODE_INTERNAL_ERROR),
602 errmsg(
"incorrect test message transmission on socket for statistics collector")));
625 errmsg(
"could not set statistics collector socket to nonblocking mode: %m")));
639 ACCEPT_TYPE_ARG3 rcvbufsize =
sizeof(old_rcvbuf);
641 if (getsockopt(
pgStatSock, SOL_SOCKET, SO_RCVBUF,
642 (
char *) &old_rcvbuf, &rcvbufsize) < 0)
645 (
errmsg(
"getsockopt(%s) failed: %m",
"SO_RCVBUF")));
651 if (old_rcvbuf < new_rcvbuf)
653 if (setsockopt(
pgStatSock, SOL_SOCKET, SO_RCVBUF,
654 (
char *) &new_rcvbuf,
sizeof(new_rcvbuf)) < 0)
656 (
errmsg(
"setsockopt(%s) failed: %m",
"SO_RCVBUF")));
669 (
errmsg(
"disabling statistics collector for lack of working socket")));
698 while ((entry =
ReadDir(dir, directory)) != NULL)
707 if (strncmp(entry->
d_name,
"global.", 7) == 0)
712 (void) sscanf(entry->
d_name,
"db_%u.%n",
717 if (strchr(
"0123456789", entry->
d_name[3]) == NULL)
721 if (strcmp(entry->
d_name + nchars,
"tmp") != 0 &&
722 strcmp(entry->
d_name + nchars,
"stat") != 0)
725 snprintf(fname,
sizeof(fname),
"%s/%s", directory,
753 pgstat_forkexec(
void)
758 av[ac++] =
"postgres";
759 av[ac++] =
"--forkcol";
765 return postmaster_forkexec(ac, av);
799 curtime = time(NULL);
809 switch ((pgStatPid = pgstat_forkexec()))
816 (
errmsg(
"could not fork statistics collector: %m")));
836 return (
int) pgStatPid;
883 if ((pgStatTabList == NULL || pgStatTabList->
tsa_used == 0) &&
912 pgStatTabHash = NULL;
925 for (tsa = pgStatTabList; tsa != NULL; tsa = tsa->
tsa_next)
940 if (memcmp(&entry->
t_counts, &all_zeroes,
947 this_msg = entry->
t_shared ? &shared_msg : ®ular_msg;
1041 if (pgStatFunctions == NULL)
1054 if (memcmp(&entry->
f_counts, &all_zeroes,
1142 if (dbentry == NULL || dbentry->
tables == NULL)
1165 if (
hash_search(htab, (
void *) &tabid, HASH_FIND, NULL) != NULL)
1225 if (
hash_search(htab, (
void *) &funcid, HASH_FIND, NULL) != NULL)
1348 pgstat_drop_relation(
Oid relid)
1404 msg.
m_count = (last_report == 0) ? 1 : 0;
1449 if (strcmp(target,
"archiver") == 0)
1451 else if (strcmp(target,
"bgwriter") == 0)
1453 else if (strcmp(target,
"wal") == 0)
1457 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1458 errmsg(
"unrecognized reset target: \"%s\"", target),
1459 errhint(
"Target must be \"archiver\", \"bgwriter\" or \"wal\".")));
1547 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1548 errmsg(
"replication slot \"%s\" does not exist",
1659 livetuples =
Max(livetuples, 0);
1660 deadtuples =
Max(deadtuples, 0);
1777 int spillbytes,
int streamtxns,
int streamcount,
int streambytes)
1861 if (pgstat_track_functions <= fcinfo->flinfo->fn_stats)
1868 if (!pgStatFunctions)
1875 pgStatFunctions =
hash_create(
"Function stat entries",
1908 if (pgStatFunctions == NULL)
1986 char relkind = rel->
rd_rel->relkind;
1989 if (!RELKIND_HAS_STORAGE(relkind))
2028 if (pgStatTabHash == NULL)
2035 pgStatTabHash =
hash_create(
"pgstat TabStatusArray lookup hash table",
2062 if (pgStatTabList == NULL)
2085 entry->
t_id = rel_id;
2131 if (xact_state == NULL || xact_state->
nest_level != nest_level)
2138 xact_state->
first = NULL;
2139 pgStatXactStack = xact_state;
2165 trans->
parent = pgstat_info;
2179 if (pgstat_info != NULL)
2184 if (pgstat_info->
trans == NULL ||
2200 if (pgstat_info != NULL)
2205 if (pgstat_info->
trans == NULL ||
2225 if (pgstat_info != NULL)
2230 if (pgstat_info->
trans == NULL ||
2280 if (pgstat_info != NULL)
2285 if (pgstat_info->
trans == NULL ||
2309 if (pgstat_info != NULL)
2344 if (xact_state != NULL)
2350 for (trans = xact_state->
first; trans != NULL; trans = trans->
next)
2392 tabstat->
trans = NULL;
2395 pgStatXactStack = NULL;
2417 if (xact_state != NULL &&
2424 pgStatXactStack = xact_state->
prev;
2426 for (trans = xact_state->
first; trans != NULL; trans = next_trans)
2430 next_trans = trans->
next;
2512 if (xact_state != NULL)
2518 for (trans = xact_state->
first; trans != NULL; trans = trans->
next)
2565 if (xact_state != NULL)
2569 for (trans = xact_state->
first; trans != NULL; trans = trans->
next)
2574 tabstat->
trans = NULL;
2577 pgStatXactStack = NULL;
2590 void *recdata,
uint32 len)
2626 void *recdata,
uint32 len)
2705 if (dbentry != NULL && dbentry->
tables != NULL)
2721 if (dbentry != NULL && dbentry->
tables != NULL)
2752 if (dbentry != NULL && dbentry->
functions != NULL)
2803 return &localBackendStatusTable[beid - 1];
2978 MemSet(BackendStatusArray, 0, size);
3048 MemSet(BackendSslStatusBuffer, 0, size);
3051 ptr = BackendSslStatusBuffer;
3070 MemSet(BackendGssStatusBuffer, 0, size);
3073 ptr = BackendGssStatusBuffer;
3157 Assert(vbeentry != NULL);
3176 memset(&lsslstatus, 0,
sizeof(lsslstatus));
3179 memset(&lgssstatus, 0,
sizeof(lgssstatus));
3362 TRACE_POSTGRESQL_STATEMENT_STATUS(cmd_str);
3396 if (cmd_str != NULL)
3439 if (cmd_str != NULL)
3511 for (i = 0; i < nparam; ++
i)
3570 memcpy((
char *) beentry->
st_appname, appname, len);
3614 *localclienthostname,
3625 if (localBackendStatusTable)
3641 localappname = (
char *)
3644 localclienthostname = (
char *)
3647 localactivity = (
char *)
3664 localentry = localtable;
3676 int before_changecount;
3677 int after_changecount;
3695 strcpy(localappname, (
char *) beentry->
st_appname);
3750 localBackendStatusTable = localtable;
3763 const char *event_type;
3766 if (wait_event_info == 0)
3769 classId = wait_event_info & 0xFF000000;
3774 event_type =
"LWLock";
3777 event_type =
"Lock";
3780 event_type =
"BufferPin";
3783 event_type =
"Activity";
3786 event_type =
"Client";
3789 event_type =
"Extension";
3795 event_type =
"Timeout";
3819 const char *event_name;
3822 if (wait_event_info == 0)
3825 classId = wait_event_info & 0xFF000000;
3826 eventId = wait_event_info & 0x0000FFFF;
3837 event_name =
"BufferPin";
3854 event_name =
"Extension";
3878 event_name =
"unknown wait event";
3894 const char *event_name =
"unknown wait event";
3899 event_name =
"ArchiverMain";
3902 event_name =
"AutoVacuumMain";
3905 event_name =
"BgWriterHibernate";
3908 event_name =
"BgWriterMain";
3911 event_name =
"CheckpointerMain";
3914 event_name =
"LogicalApplyMain";
3917 event_name =
"LogicalLauncherMain";
3920 event_name =
"PgStatMain";
3923 event_name =
"RecoveryWalStream";
3926 event_name =
"SysLoggerMain";
3929 event_name =
"WalReceiverMain";
3932 event_name =
"WalSenderMain";
3935 event_name =
"WalWriterMain";
3952 const char *event_name =
"unknown wait event";
3957 event_name =
"ClientRead";
3960 event_name =
"ClientWrite";
3963 event_name =
"GSSOpenServer";
3966 event_name =
"LibPQWalReceiverConnect";
3969 event_name =
"LibPQWalReceiverReceive";
3972 event_name =
"SSLOpenServer";
3975 event_name =
"WalReceiverWaitStart";
3978 event_name =
"WalSenderWaitForWAL";
3981 event_name =
"WalSenderWriteData";
3998 const char *event_name =
"unknown wait event";
4003 event_name =
"BackupWaitWalArchive";
4006 event_name =
"BgWorkerShutdown";
4009 event_name =
"BgWorkerStartup";
4012 event_name =
"BtreePage";
4015 event_name =
"CheckpointDone";
4018 event_name =
"CheckpointStart";
4021 event_name =
"ExecuteGather";
4024 event_name =
"HashBatchAllocate";
4027 event_name =
"HashBatchElect";
4030 event_name =
"HashBatchLoad";
4033 event_name =
"HashBuildAllocate";
4036 event_name =
"HashBuildElect";
4039 event_name =
"HashBuildHashInner";
4042 event_name =
"HashBuildHashOuter";
4045 event_name =
"HashGrowBatchesAllocate";
4048 event_name =
"HashGrowBatchesDecide";
4051 event_name =
"HashGrowBatchesElect";
4054 event_name =
"HashGrowBatchesFinish";
4057 event_name =
"HashGrowBatchesRepartition";
4060 event_name =
"HashGrowBucketsAllocate";
4063 event_name =
"HashGrowBucketsElect";
4066 event_name =
"HashGrowBucketsReinsert";
4069 event_name =
"LogicalSyncData";
4072 event_name =
"LogicalSyncStateChange";
4075 event_name =
"MessageQueueInternal";
4078 event_name =
"MessageQueuePutMessage";
4081 event_name =
"MessageQueueReceive";
4084 event_name =
"MessageQueueSend";
4087 event_name =
"ParallelBitmapScan";
4090 event_name =
"ParallelCreateIndexScan";
4093 event_name =
"ParallelFinish";
4096 event_name =
"ProcArrayGroupUpdate";
4099 event_name =
"ProcSignalBarrier";
4102 event_name =
"Promote";
4105 event_name =
"RecoveryConflictSnapshot";
4108 event_name =
"RecoveryConflictTablespace";
4111 event_name =
"RecoveryPause";
4114 event_name =
"ReplicationOriginDrop";
4117 event_name =
"ReplicationSlotDrop";
4120 event_name =
"SafeSnapshot";
4123 event_name =
"SyncRep";
4126 event_name =
"XactGroupUpdate";
4143 const char *event_name =
"unknown wait event";
4148 event_name =
"BaseBackupThrottle";
4151 event_name =
"PgSleep";
4154 event_name =
"RecoveryApplyDelay";
4157 event_name =
"RecoveryRetrieveRetryInterval";
4160 event_name =
"VacuumDelay";
4177 const char *event_name =
"unknown wait event";
4182 event_name =
"BaseBackupRead";
4185 event_name =
"BufFileRead";
4188 event_name =
"BufFileWrite";
4191 event_name =
"BufFileTruncate";
4194 event_name =
"ControlFileRead";
4197 event_name =
"ControlFileSync";
4200 event_name =
"ControlFileSyncUpdate";
4203 event_name =
"ControlFileWrite";
4206 event_name =
"ControlFileWriteUpdate";
4209 event_name =
"CopyFileRead";
4212 event_name =
"CopyFileWrite";
4215 event_name =
"DataFileExtend";
4218 event_name =
"DataFileFlush";
4221 event_name =
"DataFileImmediateSync";
4224 event_name =
"DataFilePrefetch";
4227 event_name =
"DataFileRead";
4230 event_name =
"DataFileSync";
4233 event_name =
"DataFileTruncate";
4236 event_name =
"DataFileWrite";
4239 event_name =
"DSMFillZeroWrite";
4242 event_name =
"LockFileAddToDataDirRead";
4245 event_name =
"LockFileAddToDataDirSync";
4248 event_name =
"LockFileAddToDataDirWrite";
4251 event_name =
"LockFileCreateRead";
4254 event_name =
"LockFileCreateSync";
4257 event_name =
"LockFileCreateWrite";
4260 event_name =
"LockFileReCheckDataDirRead";
4263 event_name =
"LogicalRewriteCheckpointSync";
4266 event_name =
"LogicalRewriteMappingSync";
4269 event_name =
"LogicalRewriteMappingWrite";
4272 event_name =
"LogicalRewriteSync";
4275 event_name =
"LogicalRewriteTruncate";
4278 event_name =
"LogicalRewriteWrite";
4281 event_name =
"RelationMapRead";
4284 event_name =
"RelationMapSync";
4287 event_name =
"RelationMapWrite";
4290 event_name =
"ReorderBufferRead";
4293 event_name =
"ReorderBufferWrite";
4296 event_name =
"ReorderLogicalMappingRead";
4299 event_name =
"ReplicationSlotRead";
4302 event_name =
"ReplicationSlotRestoreSync";
4305 event_name =
"ReplicationSlotSync";
4308 event_name =
"ReplicationSlotWrite";
4311 event_name =
"SLRUFlushSync";
4314 event_name =
"SLRURead";
4317 event_name =
"SLRUSync";
4320 event_name =
"SLRUWrite";
4323 event_name =
"SnapbuildRead";
4326 event_name =
"SnapbuildSync";
4329 event_name =
"SnapbuildWrite";
4332 event_name =
"TimelineHistoryFileSync";
4335 event_name =
"TimelineHistoryFileWrite";
4338 event_name =
"TimelineHistoryRead";
4341 event_name =
"TimelineHistorySync";
4344 event_name =
"TimelineHistoryWrite";
4347 event_name =
"TwophaseFileRead";
4350 event_name =
"TwophaseFileSync";
4353 event_name =
"TwophaseFileWrite";
4356 event_name =
"WALSenderTimelineHistoryRead";
4359 event_name =
"WALBootstrapSync";
4362 event_name =
"WALBootstrapWrite";
4365 event_name =
"WALCopyRead";
4368 event_name =
"WALCopySync";
4371 event_name =
"WALCopyWrite";
4374 event_name =
"WALInitSync";
4377 event_name =
"WALInitWrite";
4380 event_name =
"WALRead";
4383 event_name =
"WALSync";
4386 event_name =
"WALSyncMethodAssign";
4389 event_name =
"WALWrite";
4392 event_name =
"LogicalChangesRead";
4395 event_name =
"LogicalChangesWrite";
4398 event_name =
"LogicalSubxactRead";
4401 event_name =
"LogicalSubxactWrite";
4454 int before_changecount;
4455 int after_changecount;
4475 return "<insufficient privilege>";
4477 return "<command string not enabled>";
4489 return "<backend information not available>";
4529 const char *activity_last;
4541 activity > activity_last)
4545 if (activity[0] ==
'\0')
4555 Min(buflen, pgstat_track_activity_query_size));
4606 }
while (rc < 0 && errno ==
EINTR);
4608 #ifdef USE_ASSERT_CHECKING 4611 elog(
LOG,
"could not send to statistics collector: %m");
4661 pgstat_send(&BgWriterStats,
sizeof(BgWriterStats));
4666 MemSet(&BgWriterStats, 0,
sizeof(BgWriterStats));
4700 if (memcmp(&WalStats, &all_zeroes,
sizeof(
PgStat_MsgWal)) == 0)
4717 MemSet(&WalStats, 0,
sizeof(WalStats));
4881 errmsg(
"could not read statistics message: %m")));
4893 if (msg.msg_hdr.m_size != len)
4899 switch (msg.msg_hdr.m_type)
5123 if (!create && !found)
5154 if (!create && !found)
5213 elog(
DEBUG2,
"writing stats file \"%s\"", statfile);
5223 errmsg(
"could not open temporary statistics file \"%s\": %m",
5237 rc = fwrite(&format_id,
sizeof(format_id), 1, fpout);
5243 rc = fwrite(&globalStats,
sizeof(globalStats), 1, fpout);
5249 rc = fwrite(&archiverStats,
sizeof(archiverStats), 1, fpout);
5255 rc = fwrite(&walStats,
sizeof(walStats), 1, fpout);
5261 rc = fwrite(slruStats,
sizeof(slruStats), 1, fpout);
5312 errmsg(
"could not write temporary statistics file \"%s\": %m",
5321 errmsg(
"could not close temporary statistics file \"%s\": %m",
5325 else if (rename(tmpfile, statfile) < 0)
5329 errmsg(
"could not rename temporary statistics file \"%s\" to \"%s\": %m",
5330 tmpfile, statfile)));
5342 pending_write_requests =
NIL;
5356 printed =
snprintf(filename, len,
"%s/db_%u.%s",
5360 tempname ?
"tmp" :
"stat");
5392 elog(
DEBUG2,
"writing stats file \"%s\"", statfile);
5402 errmsg(
"could not open temporary statistics file \"%s\": %m",
5411 rc = fwrite(&format_id,
sizeof(format_id), 1, fpout);
5447 errmsg(
"could not write temporary statistics file \"%s\": %m",
5456 errmsg(
"could not close temporary statistics file \"%s\": %m",
5460 else if (rename(tmpfile, statfile) < 0)
5464 errmsg(
"could not rename temporary statistics file \"%s\" to \"%s\": %m",
5465 tmpfile, statfile)));
5473 elog(
DEBUG2,
"removing temporary stats file \"%s\"", statfile);
5533 memset(&globalStats, 0,
sizeof(globalStats));
5534 memset(&archiverStats, 0,
sizeof(archiverStats));
5535 memset(&walStats, 0,
sizeof(walStats));
5536 memset(&slruStats, 0,
sizeof(slruStats));
5569 if (errno != ENOENT)
5572 errmsg(
"could not open statistics file \"%s\": %m",
5580 if (fread(&format_id, 1,
sizeof(format_id), fpin) !=
sizeof(format_id) ||
5584 (
errmsg(
"corrupted statistics file \"%s\"", statfile)));
5591 if (fread(&globalStats, 1,
sizeof(globalStats), fpin) !=
sizeof(globalStats))
5594 (
errmsg(
"corrupted statistics file \"%s\"", statfile)));
5595 memset(&globalStats, 0,
sizeof(globalStats));
5612 if (fread(&archiverStats, 1,
sizeof(archiverStats), fpin) !=
sizeof(archiverStats))
5615 (
errmsg(
"corrupted statistics file \"%s\"", statfile)));
5616 memset(&archiverStats, 0,
sizeof(archiverStats));
5623 if (fread(&walStats, 1,
sizeof(walStats), fpin) !=
sizeof(walStats))
5626 (
errmsg(
"corrupted statistics file \"%s\"", statfile)));
5627 memset(&walStats, 0,
sizeof(walStats));
5634 if (fread(slruStats, 1,
sizeof(slruStats), fpin) !=
sizeof(slruStats))
5637 (
errmsg(
"corrupted statistics file \"%s\"", statfile)));
5638 memset(&slruStats, 0,
sizeof(slruStats));
5648 switch (fgetc(fpin))
5659 (
errmsg(
"corrupted statistics file \"%s\"",
5674 (
errmsg(
"corrupted statistics file \"%s\"",
5740 (
errmsg(
"corrupted statistics file \"%s\"",
5753 (
errmsg(
"corrupted statistics file \"%s\"",
5765 elog(
DEBUG2,
"removing permanent stats file \"%s\"", statfile);
5813 if (errno != ENOENT)
5816 errmsg(
"could not open statistics file \"%s\": %m",
5824 if (fread(&format_id, 1,
sizeof(format_id), fpin) !=
sizeof(format_id) ||
5828 (
errmsg(
"corrupted statistics file \"%s\"", statfile)));
5838 switch (fgetc(fpin))
5848 (
errmsg(
"corrupted statistics file \"%s\"",
5856 if (tabhash == NULL)
5866 (
errmsg(
"corrupted statistics file \"%s\"",
5871 memcpy(tabentry, &tabbuf,
sizeof(tabbuf));
5882 (
errmsg(
"corrupted statistics file \"%s\"",
5890 if (funchash == NULL)