point.
</para>
</listitem>
+ <listitem>
+ <para>
+ <literal>IO</>: The server process is waiting for a IO to complete.
+ <literal>wait_event</> will identify the specific wait point.
+ </para>
+ </listitem>
</itemizedlist>
</entry>
</row>
<entry><literal>RecoveryApplyDelay</></entry>
<entry>Waiting to apply WAL at recovery because it is delayed.</entry>
</row>
+ <row>
+ <entry morerows="66"><literal>IO</></entry>
+ <entry><literal>BufFileRead</></entry>
+ <entry>Waiting for a read from a buffered file.</entry>
+ </row>
+ <row>
+ <entry><literal>BufFileWrite</></entry>
+ <entry>Waiting for a write to a buffered file.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileRead</></entry>
+ <entry>Waiting for a read from the control file.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileSync</></entry>
+ <entry>Waiting for the control file to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileSyncUpdate</></entry>
+ <entry>Waiting for an update to the control file to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileWrite</></entry>
+ <entry>Waiting for a write to the control file.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileWriteUpdate</></entry>
+ <entry>Waiting for a write to update the control file.</entry>
+ </row>
+ <row>
+ <entry><literal>CopyFileRead</></entry>
+ <entry>Waiting for a read during a file copy operation.</entry>
+ </row>
+ <row>
+ <entry><literal>CopyFileWrite</></entry>
+ <entry>Waiting for a write during a file copy operation.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileExtend</></entry>
+ <entry>Waiting for a relation data file to be extended.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileFlush</></entry>
+ <entry>Waiting for a relation data file to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileImmediateSync</></entry>
+ <entry>Waiting for an immediate synchronization of a relation data file to stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFilePrefetch</></entry>
+ <entry>Waiting for an asynchronous prefetch from a relation data file.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileRead</></entry>
+ <entry>Waiting for a read from a relation data file.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileSync</></entry>
+ <entry>Waiting for changes to a relation data file to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileTruncate</></entry>
+ <entry>Waiting for a relation data file to be truncated.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileWrite</></entry>
+ <entry>Waiting for a write to a relation data file.</entry>
+ </row>
+ <row>
+ <entry><literal>DSMFillZeroWrite</></entry>
+ <entry>Waiting to write zero bytes to a dynamic shared memory backing file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileAddToDataDirRead</></entry>
+ <entry>Waiting for a read while adding a line to the data directory lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileAddToDataDirSync</></entry>
+ <entry>Waiting for data to reach stable storage while adding a line to the data directory lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileAddToDataDirWrite</></entry>
+ <entry>Waiting for a write while adding a line to the data directory lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileCreateRead</></entry>
+ <entry>Waiting to read while creating the data directory lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileCreateSync</></entry>
+ <entry>Waiting for data to reach stable storage while creating the data directory lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileCreateWrite</></entry>
+ <entry>Waiting for a write while creating the data directory lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileReCheckDataDirRead</></entry>
+ <entry>Waiting for a read during recheck of the data directory lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteCheckpointSync</></entry>
+ <entry>Waiting for logical rewrite mappings to reach stable storage during a checkpoint.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteMappingSync</></entry>
+ <entry>Waiting for mapping data to reach stable storage during a logical rewrite.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteMappingWrite</></entry>
+ <entry>Waiting for a write of mapping data during a logical rewrite.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteSync</></entry>
+ <entry>Waiting for logical rewrite mappings to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteWrite</></entry>
+ <entry>Waiting for a write of logical rewrite mappings.</entry>
+ </row>
+ <row>
+ <entry><literal>RelationMapRead</></entry>
+ <entry>Waiting for a read of the relation map file.</entry>
+ </row>
+ <row>
+ <entry><literal>RelationMapSync</></entry>
+ <entry>Waiting for the relation map file to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>RelationMapWrite</></entry>
+ <entry>Waiting for a write to the relation map file.</entry>
+ </row>
+ <row>
+ <entry><literal>ReorderBufferRead</></entry>
+ <entry>Waiting for a read during reorder buffer management.</entry>
+ </row>
+ <row>
+ <entry><literal>ReorderBufferWrite</></entry>
+ <entry>Waiting for a write during reorder buffer management.</entry>
+ </row>
+ <row>
+ <entry><literal>ReorderLogicalMappingRead</></entry>
+ <entry>Waiting for a read of a logical mapping during reorder buffer management.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotRead</></entry>
+ <entry>Waiting for a read from a replication slot control file.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotRestoreSync</></entry>
+ <entry>Waiting for a replication slot control file to reach stable storage while restoring it to memory.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotSync</></entry>
+ <entry>Waiting for a replication slot control file to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotWrite</></entry>
+ <entry>Waiting for a write to a replication slot control file.</entry>
+ </row>
+ <row>
+ <entry><literal>SLRUFlushSync</></entry>
+ <entry>Waiting for SLRU data to reach stable storage during a checkpoint or database shutdown.</entry>
+ </row>
+ <row>
+ <entry><literal>SLRURead</></entry>
+ <entry>Waiting for a read of an SLRU page.</entry>
+ </row>
+ <row>
+ <entry><literal>SLRUSync</></entry>
+ <entry>Waiting for SLRU data to reach stable storage following a page write.</entry>
+ </row>
+ <row>
+ <entry><literal>SLRUWrite</></entry>
+ <entry>Waiting for a write of an SLRU page.</entry>
+ </row>
+ <row>
+ <entry><literal>SnapbuildRead</></entry>
+ <entry>Waiting for a read of a serialized historical catalog snapshot.</entry>
+ </row>
+ <row>
+ <entry><literal>SnapbuildSync</></entry>
+ <entry>Waiting for a serialized historical catalog snapshot to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>SnapbuildWrite</></entry>
+ <entry>Waiting for a write of a serialized historical catalog snapshot.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistoryFileSync</></entry>
+ <entry>Waiting for a timeline history file received via streaming replication to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistoryFileWrite</></entry>
+ <entry>Waiting for a write of a timeline history file received via streaming replication.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistoryRead</></entry>
+ <entry>Waiting for a read of a timeline history file.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistorySync</></entry>
+ <entry>Waiting for a newly created timeline history file to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistoryWrite</></entry>
+ <entry>Waiting for a write of a newly created timeline history file.</entry>
+ </row>
+ <row>
+ <entry><literal>TwophaseFileRead</></entry>
+ <entry>Waiting for a read of a two phase state file.</entry>
+ </row>
+ <row>
+ <entry><literal>TwophaseFileSync</></entry>
+ <entry>Waiting for a two phase state file to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>TwophaseFileWrite</></entry>
+ <entry>Waiting for a write of a two phase state file.</entry>
+ </row>
+ <row>
+ <entry><literal>WALBootstrapSync</></entry>
+ <entry>Waiting for WAL to reach stable storage during bootstrapping.</entry>
+ </row>
+ <row>
+ <entry><literal>WALBootstrapWrite</></entry>
+ <entry>Waiting for a write of a WAL page during bootstrapping.</entry>
+ </row>
+ <row>
+ <entry><literal>WALCopyRead</></entry>
+ <entry>Waiting for a read when creating a new WAL segment by copying an existing one.</entry>
+ </row>
+ <row>
+ <entry><literal>WALCopySync</></entry>
+ <entry>Waiting a new WAL segment created by copying an existing one to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>WALCopyWrite</></entry>
+ <entry>Waiting for a write when creating a new WAL segment by copying an existing one.</entry>
+ </row>
+ <row>
+ <entry><literal>WALInitSync</></entry>
+ <entry>Waiting for a newly initialized WAL file to reach stable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>WALInitWrite</></entry>
+ <entry>Waiting for a write while initializing a new WAL file.</entry>
+ </row>
+ <row>
+ <entry><literal>WALRead</></entry>
+ <entry>Waiting for a read from a WAL file.</entry>
+ </row>
+ <row>
+ <entry><literal>WALSenderTimelineHistoryRead</></entry>
+ <entry>Waiting for a read from a timeline history file during walsender timeline command.</entry>
+ </row>
+ <row>
+ <entry><literal>WALSyncMethodAssign</></entry>
+ <entry>Waiting for data to reach stable storage while assigning WAL sync method.</entry>
+ </row>
+ <row>
+ <entry><literal>WALWrite</></entry>
+ <entry>Waiting for a write to a WAL file.</entry>
+ </row>
</tbody>
</tgroup>
</table>
#include "lib/ilist.h"
+#include "pgstat.h"
+
#include "replication/logical.h"
#include "replication/slot.h"
* Note that we deviate from the usual WAL coding practices here,
* check the above "Logical rewrite support" comment for reasoning.
*/
- written = FileWrite(src->vfd, waldata_start, len);
+ written = FileWrite(src->vfd, waldata_start, len,
+ WAIT_EVENT_LOGICAL_REWRITE_WRITE);
if (written != len)
ereport(ERROR,
(errcode_for_file_access(),
hash_seq_init(&seq_status, state->rs_logical_mappings);
while ((src = (RewriteMappingFile *) hash_seq_search(&seq_status)) != NULL)
{
- if (FileSync(src->vfd) != 0)
+ if (FileSync(src->vfd, WAIT_EVENT_LOGICAL_REWRITE_SYNC) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", src->path)));
* Truncate all data that's not guaranteed to have been safely fsynced (by
* previous record or by the last checkpoint).
*/
+ pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE);
if (ftruncate(fd, xlrec->offset) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not truncate file \"%s\" to %u: %m",
path, (uint32) xlrec->offset)));
+ pgstat_report_wait_end();
/* now seek to the position we want to write our data to */
if (lseek(fd, xlrec->offset, SEEK_SET) != xlrec->offset)
len = xlrec->num_mappings * sizeof(LogicalRewriteMappingData);
/* write out tail end of mapping file (again) */
+ pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE);
if (write(fd, data, len) != len)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to file \"%s\": %m", path)));
+ pgstat_report_wait_end();
/*
* Now fsync all previously written data. We could improve things and only
* do this for the last write to a file, but the required bookkeeping
* doesn't seem worth the trouble.
*/
+ pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC);
if (pg_fsync(fd) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", path)));
+ pgstat_report_wait_end();
CloseTransientFile(fd);
}
* changed or have only been created since the checkpoint's start,
* but it's currently not deemed worth the effort.
*/
- else if (pg_fsync(fd) != 0)
+ pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC);
+ if (pg_fsync(fd) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", path)));
+ pgstat_report_wait_end();
CloseTransientFile(fd);
}
}
#include "access/slru.h"
#include "access/transam.h"
#include "access/xlog.h"
+#include "pgstat.h"
#include "storage/fd.h"
#include "storage/shmem.h"
#include "miscadmin.h"
}
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_SLRU_READ);
if (read(fd, shared->page_buffer[slotno], BLCKSZ) != BLCKSZ)
{
+ pgstat_report_wait_end();
slru_errcause = SLRU_READ_FAILED;
slru_errno = errno;
CloseTransientFile(fd);
return false;
}
+ pgstat_report_wait_end();
if (CloseTransientFile(fd))
{
}
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_SLRU_WRITE);
if (write(fd, shared->page_buffer[slotno], BLCKSZ) != BLCKSZ)
{
+ pgstat_report_wait_end();
/* if write didn't set errno, assume problem is no disk space */
if (errno == 0)
errno = ENOSPC;
CloseTransientFile(fd);
return false;
}
+ pgstat_report_wait_end();
/*
* If not part of Flush, need to fsync now. We assume this happens
*/
if (!fdata)
{
+ pgstat_report_wait_start(WAIT_EVENT_SLRU_SYNC);
if (ctl->do_fsync && pg_fsync(fd))
{
+ pgstat_report_wait_end();
slru_errcause = SLRU_FSYNC_FAILED;
slru_errno = errno;
CloseTransientFile(fd);
return false;
}
+ pgstat_report_wait_end();
if (CloseTransientFile(fd))
{
ok = true;
for (i = 0; i < fdata.num_files; i++)
{
+ pgstat_report_wait_start(WAIT_EVENT_SLRU_FLUSH_SYNC);
if (ctl->do_fsync && pg_fsync(fdata.fd[i]))
{
slru_errcause = SLRU_FSYNC_FAILED;
pageno = fdata.segno[i] * SLRU_PAGES_PER_SEGMENT;
ok = false;
}
+ pgstat_report_wait_end();
if (CloseTransientFile(fdata.fd[i]))
{
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xlogdefs.h"
+#include "pgstat.h"
#include "storage/fd.h"
/*
for (;;)
{
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_READ);
nbytes = (int) read(srcfd, buffer, sizeof(buffer));
+ pgstat_report_wait_end();
if (nbytes < 0 || errno != 0)
ereport(ERROR,
(errcode_for_file_access(),
if (nbytes == 0)
break;
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_WRITE);
if ((int) write(fd, buffer, nbytes) != nbytes)
{
int save_errno = errno;
(errcode_for_file_access(),
errmsg("could not write to file \"%s\": %m", tmppath)));
}
+ pgstat_report_wait_end();
}
CloseTransientFile(srcfd);
}
errmsg("could not write to file \"%s\": %m", tmppath)));
}
+ pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_SYNC);
if (pg_fsync(fd) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", tmppath)));
+ pgstat_report_wait_end();
if (CloseTransientFile(fd))
ereport(ERROR,
errmsg("could not create file \"%s\": %m", tmppath)));
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE);
if ((int) write(fd, content, size) != size)
{
int save_errno = errno;
(errcode_for_file_access(),
errmsg("could not write to file \"%s\": %m", tmppath)));
}
+ pgstat_report_wait_end();
+ pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC);
if (pg_fsync(fd) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", tmppath)));
+ pgstat_report_wait_end();
if (CloseTransientFile(fd))
ereport(ERROR,
*/
buf = (char *) palloc(stat.st_size);
+ pgstat_report_wait_start(WAIT_EVENT_TWOPHASE_FILE_READ);
if (read(fd, buf, stat.st_size) != stat.st_size)
{
+ pgstat_report_wait_end();
CloseTransientFile(fd);
if (give_warnings)
ereport(WARNING,
return NULL;
}
+ pgstat_report_wait_end();
CloseTransientFile(fd);
hdr = (TwoPhaseFileHeader *) buf;
path)));
/* Write content and CRC */
+ pgstat_report_wait_start(WAIT_EVENT_TWOPHASE_FILE_WRITE);
if (write(fd, content, len) != len)
{
+ pgstat_report_wait_end();
CloseTransientFile(fd);
ereport(ERROR,
(errcode_for_file_access(),
}
if (write(fd, &statefile_crc, sizeof(pg_crc32c)) != sizeof(pg_crc32c))
{
+ pgstat_report_wait_end();
CloseTransientFile(fd);
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write two-phase state file: %m")));
}
+ pgstat_report_wait_end();
/*
* We must fsync the file because the end-of-replay checkpoint will not do
* so, there being no GXACT in shared memory yet to tell it to.
*/
+ pgstat_report_wait_start(WAIT_EVENT_TWOPHASE_FILE_SYNC);
if (pg_fsync(fd) != 0)
{
CloseTransientFile(fd);
(errcode_for_file_access(),
errmsg("could not fsync two-phase state file: %m")));
}
+ pgstat_report_wait_end();
if (CloseTransientFile(fd) != 0)
ereport(ERROR,
do
{
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE);
written = write(openLogFile, from, nleft);
+ pgstat_report_wait_end();
if (written <= 0)
{
if (errno == EINTR)
for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
{
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_WAL_INIT_WRITE);
if ((int) write(fd, zbuffer, XLOG_BLCKSZ) != (int) XLOG_BLCKSZ)
{
int save_errno = errno;
(errcode_for_file_access(),
errmsg("could not write to file \"%s\": %m", tmppath)));
}
+ pgstat_report_wait_end();
}
+ pgstat_report_wait_start(WAIT_EVENT_WAL_INIT_SYNC);
if (pg_fsync(fd) != 0)
{
close(fd);
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", tmppath)));
}
+ pgstat_report_wait_end();
if (close(fd))
ereport(ERROR,
if (nread > sizeof(buffer))
nread = sizeof(buffer);
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_WAL_COPY_READ);
if (read(srcfd, buffer, nread) != nread)
{
if (errno != 0)
(errmsg("not enough data in file \"%s\"",
path)));
}
+ pgstat_report_wait_end();
}
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_WAL_COPY_WRITE);
if ((int) write(fd, buffer, sizeof(buffer)) != (int) sizeof(buffer))
{
int save_errno = errno;
(errcode_for_file_access(),
errmsg("could not write to file \"%s\": %m", tmppath)));
}
+ pgstat_report_wait_end();
}
+ pgstat_report_wait_start(WAIT_EVENT_WAL_COPY_SYNC);
if (pg_fsync(fd) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", tmppath)));
+ pgstat_report_wait_end();
if (CloseTransientFile(fd))
ereport(ERROR,
XLOG_CONTROL_FILE)));
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE);
if (write(fd, buffer, PG_CONTROL_SIZE) != PG_CONTROL_SIZE)
{
/* if write didn't set errno, assume problem is no disk space */
(errcode_for_file_access(),
errmsg("could not write to control file: %m")));
}
+ pgstat_report_wait_end();
+ pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC);
if (pg_fsync(fd) != 0)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not fsync control file: %m")));
+ pgstat_report_wait_end();
if (close(fd))
ereport(PANIC,
errmsg("could not open control file \"%s\": %m",
XLOG_CONTROL_FILE)));
+ pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_READ);
if (read(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not read from control file: %m")));
+ pgstat_report_wait_end();
close(fd);
XLOG_CONTROL_FILE)));
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE);
if (write(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
{
/* if write didn't set errno, assume problem is no disk space */
(errcode_for_file_access(),
errmsg("could not write to control file: %m")));
}
+ pgstat_report_wait_end();
+ pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE);
if (pg_fsync(fd) != 0)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not fsync control file: %m")));
+ pgstat_report_wait_end();
if (close(fd))
ereport(PANIC,
/* Write the first page with the initial record */
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_WRITE);
if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
{
/* if write didn't set errno, assume problem is no disk space */
(errcode_for_file_access(),
errmsg("could not write bootstrap transaction log file: %m")));
}
+ pgstat_report_wait_end();
+ pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_SYNC);
if (pg_fsync(openLogFile) != 0)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not fsync bootstrap transaction log file: %m")));
+ pgstat_report_wait_end();
if (close(openLogFile))
ereport(PANIC,
*/
if (openLogFile >= 0)
{
+ pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN);
if (pg_fsync(openLogFile) != 0)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not fsync log segment %s: %m",
XLogFileNameP(ThisTimeLineID, openLogSegNo))));
+ pgstat_report_wait_end();
if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
XLogFileClose();
}
goto next_record_is_invalid;
}
+ pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
{
char fname[MAXFNAMELEN];
+ pgstat_report_wait_end();
XLogFileName(fname, curFileTLI, readSegNo);
ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen),
(errcode_for_file_access(),
fname, readOff)));
goto next_record_is_invalid;
}
+ pgstat_report_wait_end();
Assert(targetSegNo == readSegNo);
Assert(targetPageOff == readOff);
#include "access/xlogutils.h"
#include "catalog/catalog.h"
#include "miscadmin.h"
+#include "pgstat.h"
#include "storage/smgr.h"
#include "utils/guc.h"
#include "utils/hsearch.h"
else
segbytes = nbytes;
+ pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
readbytes = read(sendFile, p, segbytes);
+ pgstat_report_wait_end();
if (readbytes <= 0)
{
char path[MAXPGPATH];
static const char *pgstat_get_wait_client(WaitEventClient w);
static const char *pgstat_get_wait_ipc(WaitEventIPC w);
static const char *pgstat_get_wait_timeout(WaitEventTimeout w);
+static const char *pgstat_get_wait_io(WaitEventIO w);
static void pgstat_setheader(PgStat_MsgHdr *hdr, StatMsgType mtype);
static void pgstat_send(void *msg, int len);
case PG_WAIT_TIMEOUT:
event_type = "Timeout";
break;
+ case PG_WAIT_IO:
+ event_type = "IO";
+ break;
default:
event_type = "???";
break;
event_name = pgstat_get_wait_timeout(w);
break;
}
+ case PG_WAIT_IO:
+ {
+ WaitEventIO w = (WaitEventIO) wait_event_info;
+
+ event_name = pgstat_get_wait_io(w);
+ break;
+ }
default:
event_name = "unknown wait event";
break;
return event_name;
}
+/* ----------
+ * pgstat_get_wait_io() -
+ *
+ * Convert WaitEventIO to string.
+ * ----------
+ */
+static const char *
+pgstat_get_wait_io(WaitEventIO w)
+{
+ const char *event_name = "unknown wait event";
+
+ switch (w)
+ {
+ case WAIT_EVENT_BUFFILE_READ:
+ event_name = "BufFileRead";
+ break;
+ case WAIT_EVENT_BUFFILE_WRITE:
+ event_name = "BufFileWrite";
+ break;
+ case WAIT_EVENT_CONTROL_FILE_READ:
+ event_name = "ControlFileRead";
+ break;
+ case WAIT_EVENT_CONTROL_FILE_SYNC:
+ event_name = "ControlFileSync";
+ break;
+ case WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE:
+ event_name = "ControlFileSyncUpdate";
+ break;
+ case WAIT_EVENT_CONTROL_FILE_WRITE:
+ event_name = "ControlFileWrite";
+ break;
+ case WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE:
+ event_name = "ControlFileWriteUpdate";
+ break;
+ case WAIT_EVENT_COPY_FILE_READ:
+ event_name = "CopyFileRead";
+ break;
+ case WAIT_EVENT_COPY_FILE_WRITE:
+ event_name = "CopyFileWrite";
+ break;
+ case WAIT_EVENT_DATA_FILE_EXTEND:
+ event_name = "DataFileExtend";
+ break;
+ case WAIT_EVENT_DATA_FILE_FLUSH:
+ event_name = "DataFileFlush";
+ break;
+ case WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC:
+ event_name = "DataFileImmediateSync";
+ break;
+ case WAIT_EVENT_DATA_FILE_PREFETCH:
+ event_name = "DataFilePrefetch";
+ break;
+ case WAIT_EVENT_DATA_FILE_READ:
+ event_name = "DataFileRead";
+ break;
+ case WAIT_EVENT_DATA_FILE_SYNC:
+ event_name = "DataFileSync";
+ break;
+ case WAIT_EVENT_DATA_FILE_TRUNCATE:
+ event_name = "DataFileTruncate";
+ break;
+ case WAIT_EVENT_DATA_FILE_WRITE:
+ event_name = "DataFileWrite";
+ break;
+ case WAIT_EVENT_DSM_FILL_ZERO_WRITE:
+ event_name = "DSMFillZeroWrite";
+ break;
+ case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ:
+ event_name = "LockFileAddToDataDirRead";
+ break;
+ case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC:
+ event_name = "LockFileAddToDataDirSync";
+ break;
+ case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE:
+ event_name = "LockFileAddToDataDirWrite";
+ break;
+ case WAIT_EVENT_LOCK_FILE_CREATE_READ:
+ event_name = "LockFileCreateRead";
+ break;
+ case WAIT_EVENT_LOCK_FILE_CREATE_SYNC:
+ event_name = "LockFileCreateSync";
+ break;
+ case WAIT_EVENT_LOCK_FILE_CREATE_WRITE:
+ event_name = "LockFileCreateWRITE";
+ break;
+ case WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ:
+ event_name = "LockFileReCheckDataDirRead";
+ break;
+ case WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC:
+ event_name = "LogicalRewriteCheckpointSync";
+ break;
+ case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC:
+ event_name = "LogicalRewriteMappingSync";
+ break;
+ case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE:
+ event_name = "LogicalRewriteMappingWrite";
+ break;
+ case WAIT_EVENT_LOGICAL_REWRITE_SYNC:
+ event_name = "LogicalRewriteSync";
+ break;
+ case WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE:
+ event_name = "LogicalRewriteTruncate";
+ break;
+ case WAIT_EVENT_LOGICAL_REWRITE_WRITE:
+ event_name = "LogicalRewriteWrite";
+ break;
+ case WAIT_EVENT_RELATION_MAP_READ:
+ event_name = "RelationMapRead";
+ break;
+ case WAIT_EVENT_RELATION_MAP_SYNC:
+ event_name = "RelationMapSync";
+ break;
+ case WAIT_EVENT_RELATION_MAP_WRITE:
+ event_name = "RelationMapWrite";
+ break;
+ case WAIT_EVENT_REORDER_BUFFER_READ:
+ event_name = "ReorderBufferRead";
+ break;
+ case WAIT_EVENT_REORDER_BUFFER_WRITE:
+ event_name = "ReorderBufferWrite";
+ break;
+ case WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ:
+ event_name = "ReorderLogicalMappingRead";
+ break;
+ case WAIT_EVENT_REPLICATION_SLOT_READ:
+ event_name = "ReplicationSlotRead";
+ break;
+ case WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC:
+ event_name = "ReplicationSlotRestoreSync";
+ break;
+ case WAIT_EVENT_REPLICATION_SLOT_SYNC:
+ event_name = "ReplicationSlotSync";
+ break;
+ case WAIT_EVENT_REPLICATION_SLOT_WRITE:
+ event_name = "ReplicationSlotWrite";
+ break;
+ case WAIT_EVENT_SLRU_FLUSH_SYNC:
+ event_name = "SLRUFlushSync";
+ break;
+ case WAIT_EVENT_SLRU_READ:
+ event_name = "SLRURead";
+ break;
+ case WAIT_EVENT_SLRU_SYNC:
+ event_name = "SLRUSync";
+ break;
+ case WAIT_EVENT_SLRU_WRITE:
+ event_name = "SLRUWrite";
+ break;
+ case WAIT_EVENT_SNAPBUILD_READ:
+ event_name = "SnapbuildRead";
+ break;
+ case WAIT_EVENT_SNAPBUILD_SYNC:
+ event_name = "SnapbuildSync";
+ break;
+ case WAIT_EVENT_SNAPBUILD_WRITE:
+ event_name = "SnapbuildWrite";
+ break;
+ case WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC:
+ event_name = "TimelineHistoryFileSync";
+ break;
+ case WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE:
+ event_name = "TimelineHistoryFileWrite";
+ break;
+ case WAIT_EVENT_TIMELINE_HISTORY_READ:
+ event_name = "TimelineHistoryRead";
+ break;
+ case WAIT_EVENT_TIMELINE_HISTORY_SYNC:
+ event_name = "TimelineHistorySync";
+ break;
+ case WAIT_EVENT_TIMELINE_HISTORY_WRITE:
+ event_name = "TimelineHistoryWrite";
+ break;
+ case WAIT_EVENT_TWOPHASE_FILE_READ:
+ event_name = "TwophaseFileRead";
+ break;
+ case WAIT_EVENT_TWOPHASE_FILE_SYNC:
+ event_name = "TwophaseFileSync";
+ break;
+ case WAIT_EVENT_TWOPHASE_FILE_WRITE:
+ event_name = "TwophaseFileWrite";
+ break;
+ case WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ:
+ event_name = "WALSenderTimelineHistoryRead";
+ break;
+ case WAIT_EVENT_WAL_BOOTSTRAP_SYNC:
+ event_name = "WALBootstrapSync";
+ break;
+ case WAIT_EVENT_WAL_BOOTSTRAP_WRITE:
+ event_name = "WALBootstrapWrite";
+ break;
+ case WAIT_EVENT_WAL_COPY_READ:
+ event_name = "WALCopyRead";
+ break;
+ case WAIT_EVENT_WAL_COPY_SYNC:
+ event_name = "WALCopySync";
+ break;
+ case WAIT_EVENT_WAL_COPY_WRITE:
+ event_name = "WALCopyWrite";
+ break;
+ case WAIT_EVENT_WAL_INIT_SYNC:
+ event_name = "WALInitSync";
+ break;
+ case WAIT_EVENT_WAL_INIT_WRITE:
+ event_name = "WALInitWrite";
+ break;
+ case WAIT_EVENT_WAL_READ:
+ event_name = "WALRead";
+ break;
+ case WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN:
+ event_name = "WALSyncMethodAssign";
+ break;
+ case WAIT_EVENT_WAL_WRITE:
+ event_name = "WALWrite";
+ break;
+
+ /* no default case, so that compiler will warn */
+ }
+
+ return event_name;
+}
+
+
/* ----------
* pgstat_get_backend_current_activity() -
*
#include "catalog/catalog.h"
#include "lib/binaryheap.h"
#include "miscadmin.h"
+#include "pgstat.h"
#include "replication/logical.h"
#include "replication/reorderbuffer.h"
#include "replication/slot.h"
ondisk->size = sz;
+ pgstat_report_wait_start(WAIT_EVENT_REORDER_BUFFER_WRITE);
if (write(fd, rb->outbuf, ondisk->size) != ondisk->size)
{
int save_errno = errno;
errmsg("could not write to data file for XID %u: %m",
txn->xid)));
}
+ pgstat_report_wait_end();
Assert(ondisk->change.action == change->action);
}
* end of this file.
*/
ReorderBufferSerializeReserve(rb, sizeof(ReorderBufferDiskChange));
+ pgstat_report_wait_start(WAIT_EVENT_REORDER_BUFFER_READ);
readBytes = read(*fd, rb->outbuf, sizeof(ReorderBufferDiskChange));
+ pgstat_report_wait_end();
/* eof */
if (readBytes == 0)
sizeof(ReorderBufferDiskChange) + ondisk->size);
ondisk = (ReorderBufferDiskChange *) rb->outbuf;
+ pgstat_report_wait_start(WAIT_EVENT_REORDER_BUFFER_READ);
readBytes = read(*fd, rb->outbuf + sizeof(ReorderBufferDiskChange),
ondisk->size - sizeof(ReorderBufferDiskChange));
+ pgstat_report_wait_end();
if (readBytes < 0)
ereport(ERROR,
memset(&key, 0, sizeof(ReorderBufferTupleCidKey));
/* read all mappings till the end of the file */
+ pgstat_report_wait_start(WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ);
readBytes = read(fd, &map, sizeof(LogicalRewriteMappingData));
+ pgstat_report_wait_end();
if (readBytes < 0)
ereport(ERROR,
#include "access/transam.h"
#include "access/xact.h"
+#include "pgstat.h"
+
#include "replication/logical.h"
#include "replication/reorderbuffer.h"
#include "replication/snapbuild.h"
ereport(ERROR,
(errmsg("could not open file \"%s\": %m", path)));
+ pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_WRITE);
if ((write(fd, ondisk, needed_length)) != needed_length)
{
CloseTransientFile(fd);
(errcode_for_file_access(),
errmsg("could not write to file \"%s\": %m", tmppath)));
}
+ pgstat_report_wait_end();
/*
* fsync the file before renaming so that even if we crash after this we
* some noticeable overhead since it's performed synchronously during
* decoding?
*/
+ pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_SYNC);
if (pg_fsync(fd) != 0)
{
CloseTransientFile(fd);
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m", tmppath)));
}
+ pgstat_report_wait_end();
CloseTransientFile(fd);
fsync_fname("pg_logical/snapshots", true);
/* read statically sized portion of snapshot */
+ pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_READ);
readBytes = read(fd, &ondisk, SnapBuildOnDiskConstantSize);
+ pgstat_report_wait_end();
if (readBytes != SnapBuildOnDiskConstantSize)
{
CloseTransientFile(fd);
SnapBuildOnDiskConstantSize - SnapBuildOnDiskNotChecksummedSize);
/* read SnapBuild */
+ pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_READ);
readBytes = read(fd, &ondisk.builder, sizeof(SnapBuild));
+ pgstat_report_wait_end();
if (readBytes != sizeof(SnapBuild))
{
CloseTransientFile(fd);
/* restore running xacts information */
sz = sizeof(TransactionId) * ondisk.builder.running.xcnt_space;
ondisk.builder.running.xip = MemoryContextAllocZero(builder->context, sz);
+ pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_READ);
readBytes = read(fd, ondisk.builder.running.xip, sz);
+ pgstat_report_wait_end();
if (readBytes != sz)
{
CloseTransientFile(fd);
/* restore committed xacts information */
sz = sizeof(TransactionId) * ondisk.builder.committed.xcnt;
ondisk.builder.committed.xip = MemoryContextAllocZero(builder->context, sz);
+ pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_READ);
readBytes = read(fd, ondisk.builder.committed.xip, sz);
+ pgstat_report_wait_end();
if (readBytes != sz)
{
CloseTransientFile(fd);
#include "access/xlog_internal.h"
#include "common/string.h"
#include "miscadmin.h"
+#include "pgstat.h"
#include "replication/slot.h"
#include "storage/fd.h"
#include "storage/proc.h"
SnapBuildOnDiskChecksummedSize);
FIN_CRC32C(cp.checksum);
+ pgstat_report_wait_start(WAIT_EVENT_REPLICATION_SLOT_WRITE);
if ((write(fd, &cp, sizeof(cp))) != sizeof(cp))
{
int save_errno = errno;
+ pgstat_report_wait_end();
CloseTransientFile(fd);
errno = save_errno;
ereport(elevel,
tmppath)));
return;
}
+ pgstat_report_wait_end();
/* fsync the temporary file */
+ pgstat_report_wait_start(WAIT_EVENT_REPLICATION_SLOT_SYNC);
if (pg_fsync(fd) != 0)
{
int save_errno = errno;
+ pgstat_report_wait_end();
CloseTransientFile(fd);
errno = save_errno;
ereport(elevel,
tmppath)));
return;
}
+ pgstat_report_wait_end();
CloseTransientFile(fd);
* Sync state file before we're reading from it. We might have crashed
* while it wasn't synced yet and we shouldn't continue on that basis.
*/
+ pgstat_report_wait_start(WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC);
if (pg_fsync(fd) != 0)
{
CloseTransientFile(fd);
errmsg("could not fsync file \"%s\": %m",
path)));
}
+ pgstat_report_wait_end();
/* Also sync the parent directory */
START_CRIT_SECTION();
END_CRIT_SECTION();
/* read part of statefile that's guaranteed to be version independent */
+ pgstat_report_wait_start(WAIT_EVENT_REPLICATION_SLOT_READ);
readBytes = read(fd, &cp, ReplicationSlotOnDiskConstantSize);
+ pgstat_report_wait_end();
if (readBytes != ReplicationSlotOnDiskConstantSize)
{
int saved_errno = errno;
path, cp.length)));
/* Now that we know the size, read the entire file */
+ pgstat_report_wait_start(WAIT_EVENT_REPLICATION_SLOT_READ);
readBytes = read(fd,
(char *) &cp + ReplicationSlotOnDiskConstantSize,
cp.length);
+ pgstat_report_wait_end();
if (readBytes != cp.length)
{
int saved_errno = errno;
char rbuf[BLCKSZ];
int nread;
+ pgstat_report_wait_start(WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ);
nread = read(fd, rbuf, sizeof(rbuf));
+ pgstat_report_wait_end();
if (nread <= 0)
ereport(ERROR,
(errcode_for_file_access(),
else
segbytes = nbytes;
+ pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
readbytes = read(sendFile, p, segbytes);
+ pgstat_report_wait_end();
if (readbytes <= 0)
{
ereport(ERROR,
#include "postgres.h"
#include "executor/instrument.h"
+#include "pgstat.h"
#include "storage/fd.h"
#include "storage/buffile.h"
#include "storage/buf_internals.h"
/*
* Read whatever we can get, up to a full bufferload.
*/
- file->nbytes = FileRead(thisfile, file->buffer, sizeof(file->buffer));
+ file->nbytes = FileRead(thisfile,
+ file->buffer,
+ sizeof(file->buffer),
+ WAIT_EVENT_BUFFILE_READ);
if (file->nbytes < 0)
file->nbytes = 0;
file->offsets[file->curFile] += file->nbytes;
return; /* seek failed, give up */
file->offsets[file->curFile] = file->curOffset;
}
- bytestowrite = FileWrite(thisfile, file->buffer + wpos, bytestowrite);
+ bytestowrite = FileWrite(thisfile,
+ file->buffer + wpos,
+ bytestowrite,
+ WAIT_EVENT_BUFFILE_WRITE);
if (bytestowrite <= 0)
return; /* failed to write */
file->offsets[file->curFile] += bytestowrite;
#include "storage/copydir.h"
#include "storage/fd.h"
#include "miscadmin.h"
-
+#include "pgstat.h"
/*
* copydir: copy a directory
/* If we got a cancel signal during the copy of the file, quit */
CHECK_FOR_INTERRUPTS();
+ pgstat_report_wait_start(WAIT_EVENT_COPY_FILE_READ);
nbytes = read(srcfd, buffer, COPY_BUF_SIZE);
+ pgstat_report_wait_end();
if (nbytes < 0)
ereport(ERROR,
(errcode_for_file_access(),
if (nbytes == 0)
break;
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_COPY_FILE_WRITE);
if ((int) write(dstfd, buffer, nbytes) != nbytes)
{
+ pgstat_report_wait_end();
/* if write didn't set errno, assume problem is no disk space */
if (errno == 0)
errno = ENOSPC;
(errcode_for_file_access(),
errmsg("could not write to file \"%s\": %m", tofile)));
}
+ pgstat_report_wait_end();
/*
* We fsync the files later but first flush them to avoid spamming the
* to read into.
*/
int
-FilePrefetch(File file, off_t offset, int amount)
+FilePrefetch(File file, off_t offset, int amount, uint32 wait_event_info)
{
#if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
int returnCode;
if (returnCode < 0)
return returnCode;
+ pgstat_report_wait_start(wait_event_info);
returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
POSIX_FADV_WILLNEED);
+ pgstat_report_wait_end();
return returnCode;
#else
}
void
-FileWriteback(File file, off_t offset, off_t nbytes)
+FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info)
{
int returnCode;
if (returnCode < 0)
return;
+ pgstat_report_wait_start(wait_event_info);
pg_flush_data(VfdCache[file].fd, offset, nbytes);
+ pgstat_report_wait_end();
}
int
-FileRead(File file, char *buffer, int amount)
+FileRead(File file, char *buffer, int amount, uint32 wait_event_info)
{
int returnCode;
Vfd *vfdP;
vfdP = &VfdCache[file];
retry:
+ pgstat_report_wait_start(wait_event_info);
returnCode = read(vfdP->fd, buffer, amount);
+ pgstat_report_wait_end();
if (returnCode >= 0)
{
}
int
-FileWrite(File file, char *buffer, int amount)
+FileWrite(File file, char *buffer, int amount, uint32 wait_event_info)
{
int returnCode;
Vfd *vfdP;
retry:
errno = 0;
+ pgstat_report_wait_start(wait_event_info);
returnCode = write(vfdP->fd, buffer, amount);
+ pgstat_report_wait_end();
/* if write didn't set errno, assume problem is no disk space */
if (returnCode != amount && errno == 0)
}
int
-FileSync(File file)
+FileSync(File file, uint32 wait_event_info)
{
int returnCode;
if (returnCode < 0)
return returnCode;
- return pg_fsync(VfdCache[file].fd);
+ pgstat_report_wait_start(wait_event_info);
+ returnCode = pg_fsync(VfdCache[file].fd);
+ pgstat_report_wait_end();
+
+ return returnCode;
}
off_t
#endif
int
-FileTruncate(File file, off_t offset)
+FileTruncate(File file, off_t offset, uint32 wait_event_info)
{
int returnCode;
if (returnCode < 0)
return returnCode;
+ pgstat_report_wait_start(wait_event_info);
returnCode = ftruncate(VfdCache[file].fd, offset);
+ pgstat_report_wait_end();
if (returnCode == 0 && VfdCache[file].fileSize > offset)
{
#ifdef HAVE_SYS_SHM_H
#include <sys/shm.h>
#endif
+#include "pgstat.h"
#include "portability/mem.h"
#include "storage/dsm_impl.h"
if (goal > ZBUFFER_SIZE)
goal = ZBUFFER_SIZE;
+ pgstat_report_wait_start(WAIT_EVENT_DSM_FILL_ZERO_WRITE);
if (write(fd, zbuffer, goal) == goal)
remaining -= goal;
else
success = false;
+ pgstat_report_wait_end();
}
if (!success)
#include "miscadmin.h"
#include "access/xlog.h"
#include "catalog/catalog.h"
+#include "pgstat.h"
#include "portability/instr_time.h"
#include "postmaster/bgwriter.h"
#include "storage/fd.h"
errmsg("could not seek to block %u in file \"%s\": %m",
blocknum, FilePathName(v->mdfd_vfd))));
- if ((nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ)) != BLCKSZ)
+ if ((nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, WAIT_EVENT_DATA_FILE_EXTEND)) != BLCKSZ)
{
if (nbytes < 0)
ereport(ERROR,
Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
- (void) FilePrefetch(v->mdfd_vfd, seekpos, BLCKSZ);
+ (void) FilePrefetch(v->mdfd_vfd, seekpos, BLCKSZ, WAIT_EVENT_DATA_FILE_PREFETCH);
#endif /* USE_PREFETCH */
}
seekpos = (off_t) BLCKSZ *(blocknum % ((BlockNumber) RELSEG_SIZE));
- FileWriteback(v->mdfd_vfd, seekpos, (off_t) BLCKSZ * nflush);
+ FileWriteback(v->mdfd_vfd, seekpos, (off_t) BLCKSZ * nflush, WAIT_EVENT_DATA_FILE_FLUSH);
nblocks -= nflush;
blocknum += nflush;
errmsg("could not seek to block %u in file \"%s\": %m",
blocknum, FilePathName(v->mdfd_vfd))));
- nbytes = FileRead(v->mdfd_vfd, buffer, BLCKSZ);
+ nbytes = FileRead(v->mdfd_vfd, buffer, BLCKSZ, WAIT_EVENT_DATA_FILE_READ);
TRACE_POSTGRESQL_SMGR_MD_READ_DONE(forknum, blocknum,
reln->smgr_rnode.node.spcNode,
errmsg("could not seek to block %u in file \"%s\": %m",
blocknum, FilePathName(v->mdfd_vfd))));
- nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ);
+ nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, WAIT_EVENT_DATA_FILE_WRITE);
TRACE_POSTGRESQL_SMGR_MD_WRITE_DONE(forknum, blocknum,
reln->smgr_rnode.node.spcNode,
* This segment is no longer active. We truncate the file, but do
* not delete it, for reasons explained in the header comments.
*/
- if (FileTruncate(v->mdfd_vfd, 0) < 0)
+ if (FileTruncate(v->mdfd_vfd, 0, WAIT_EVENT_DATA_FILE_TRUNCATE) < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not truncate file \"%s\": %m",
*/
BlockNumber lastsegblocks = nblocks - priorblocks;
- if (FileTruncate(v->mdfd_vfd, (off_t) lastsegblocks * BLCKSZ) < 0)
+ if (FileTruncate(v->mdfd_vfd, (off_t) lastsegblocks * BLCKSZ, WAIT_EVENT_DATA_FILE_TRUNCATE) < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not truncate file \"%s\" to %u blocks: %m",
{
MdfdVec *v = &reln->md_seg_fds[forknum][segno - 1];
- if (FileSync(v->mdfd_vfd) < 0)
+ if (FileSync(v->mdfd_vfd, WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC) < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m",
INSTR_TIME_SET_CURRENT(sync_start);
if (seg != NULL &&
- FileSync(seg->mdfd_vfd) >= 0)
+ FileSync(seg->mdfd_vfd, WAIT_EVENT_DATA_FILE_SYNC) >= 0)
{
/* Success; update statistics about sync timing */
INSTR_TIME_SET_CURRENT(sync_end);
ereport(DEBUG1,
(errmsg("could not forward fsync request because request queue is full")));
- if (FileSync(seg->mdfd_vfd) < 0)
+ if (FileSync(seg->mdfd_vfd, WAIT_EVENT_DATA_FILE_SYNC) < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync file \"%s\": %m",
#include "catalog/pg_tablespace.h"
#include "catalog/storage.h"
#include "miscadmin.h"
+#include "pgstat.h"
#include "storage/fd.h"
#include "storage/lwlock.h"
#include "utils/inval.h"
* look, the sinval signaling mechanism will make us re-read it before we
* are able to access any relation that's affected by the change.
*/
+ pgstat_report_wait_start(WAIT_EVENT_RELATION_MAP_READ);
if (read(fd, map, sizeof(RelMapFile)) != sizeof(RelMapFile))
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not read relation mapping file \"%s\": %m",
mapfilename)));
+ pgstat_report_wait_end();
CloseTransientFile(fd);
}
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_RELATION_MAP_WRITE);
if (write(fd, newmap, sizeof(RelMapFile)) != sizeof(RelMapFile))
{
/* if write didn't set errno, assume problem is no disk space */
errmsg("could not write to relation mapping file \"%s\": %m",
mapfilename)));
}
+ pgstat_report_wait_end();
/*
* We choose to fsync the data to disk before considering the task done.
* issue, but it would complicate checkpointing --- see notes for
* CheckPointRelationMap.
*/
+ pgstat_report_wait_start(WAIT_EVENT_RELATION_MAP_SYNC);
if (pg_fsync(fd) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not fsync relation mapping file \"%s\": %m",
mapfilename)));
+ pgstat_report_wait_end();
if (CloseTransientFile(fd))
ereport(ERROR,
#include "libpq/libpq.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
+#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "postmaster/postmaster.h"
#include "storage/fd.h"
errmsg("could not open lock file \"%s\": %m",
filename)));
}
+ pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_CREATE_READ);
if ((len = read(fd, buffer, sizeof(buffer) - 1)) < 0)
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not read lock file \"%s\": %m",
filename)));
+ pgstat_report_wait_end();
close(fd);
if (len == 0)
strlcat(buffer, "\n", sizeof(buffer));
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_CREATE_WRITE);
if (write(fd, buffer, strlen(buffer)) != strlen(buffer))
{
int save_errno = errno;
(errcode_for_file_access(),
errmsg("could not write lock file \"%s\": %m", filename)));
}
+ pgstat_report_wait_end();
+
+ pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_CREATE_SYNC);
if (pg_fsync(fd) != 0)
{
int save_errno = errno;
(errcode_for_file_access(),
errmsg("could not write lock file \"%s\": %m", filename)));
}
+ pgstat_report_wait_end();
if (close(fd) != 0)
{
int save_errno = errno;
DIRECTORY_LOCK_FILE)));
return;
}
+ pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ);
len = read(fd, srcbuffer, sizeof(srcbuffer) - 1);
+ pgstat_report_wait_end();
if (len < 0)
{
ereport(LOG,
*/
len = strlen(destbuffer);
errno = 0;
+ pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE);
if (lseek(fd, (off_t) 0, SEEK_SET) != 0 ||
(int) write(fd, destbuffer, len) != len)
{
+ pgstat_report_wait_end();
/* if write didn't set errno, assume problem is no disk space */
if (errno == 0)
errno = ENOSPC;
close(fd);
return;
}
+ pgstat_report_wait_end();
+ pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC);
if (pg_fsync(fd) != 0)
{
ereport(LOG,
errmsg("could not write to file \"%s\": %m",
DIRECTORY_LOCK_FILE)));
}
+ pgstat_report_wait_end();
if (close(fd) != 0)
{
ereport(LOG,
return true;
}
}
+ pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ);
len = read(fd, buffer, sizeof(buffer) - 1);
+ pgstat_report_wait_end();
if (len < 0)
{
ereport(LOG,
#define PG_WAIT_EXTENSION 0x07000000U
#define PG_WAIT_IPC 0x08000000U
#define PG_WAIT_TIMEOUT 0x09000000U
+#define PG_WAIT_IO 0x0A000000U
/* ----------
* Wait Events - Activity
WAIT_EVENT_RECOVERY_APPLY_DELAY
} WaitEventTimeout;
+/* ----------
+ * Wait Events - IO
+ *
+ * Use this category when a process is waiting for a IO.
+ * ----------
+ */
+typedef enum
+{
+ WAIT_EVENT_BUFFILE_READ,
+ WAIT_EVENT_BUFFILE_WRITE,
+ WAIT_EVENT_CONTROL_FILE_READ,
+ WAIT_EVENT_CONTROL_FILE_SYNC,
+ WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE,
+ WAIT_EVENT_CONTROL_FILE_WRITE,
+ WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE,
+ WAIT_EVENT_COPY_FILE_READ,
+ WAIT_EVENT_COPY_FILE_WRITE,
+ WAIT_EVENT_DATA_FILE_EXTEND,
+ WAIT_EVENT_DATA_FILE_FLUSH,
+ WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC,
+ WAIT_EVENT_DATA_FILE_PREFETCH,
+ WAIT_EVENT_DATA_FILE_READ = PG_WAIT_IO,
+ WAIT_EVENT_DATA_FILE_SYNC,
+ WAIT_EVENT_DATA_FILE_TRUNCATE,
+ WAIT_EVENT_DATA_FILE_WRITE,
+ WAIT_EVENT_DSM_FILL_ZERO_WRITE,
+ WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ,
+ WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC,
+ WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE,
+ WAIT_EVENT_LOCK_FILE_CREATE_READ,
+ WAIT_EVENT_LOCK_FILE_CREATE_SYNC,
+ WAIT_EVENT_LOCK_FILE_CREATE_WRITE,
+ WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ,
+ WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC,
+ WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC,
+ WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE,
+ WAIT_EVENT_LOGICAL_REWRITE_SYNC,
+ WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE,
+ WAIT_EVENT_LOGICAL_REWRITE_WRITE,
+ WAIT_EVENT_RELATION_MAP_READ,
+ WAIT_EVENT_RELATION_MAP_SYNC,
+ WAIT_EVENT_RELATION_MAP_WRITE,
+ WAIT_EVENT_REORDER_BUFFER_READ,
+ WAIT_EVENT_REORDER_BUFFER_WRITE,
+ WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ,
+ WAIT_EVENT_REPLICATION_SLOT_READ,
+ WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC,
+ WAIT_EVENT_REPLICATION_SLOT_SYNC,
+ WAIT_EVENT_REPLICATION_SLOT_WRITE,
+ WAIT_EVENT_SLRU_FLUSH_SYNC,
+ WAIT_EVENT_SLRU_READ,
+ WAIT_EVENT_SLRU_SYNC,
+ WAIT_EVENT_SLRU_WRITE,
+ WAIT_EVENT_SNAPBUILD_READ,
+ WAIT_EVENT_SNAPBUILD_SYNC,
+ WAIT_EVENT_SNAPBUILD_WRITE,
+ WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC,
+ WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE,
+ WAIT_EVENT_TIMELINE_HISTORY_READ,
+ WAIT_EVENT_TIMELINE_HISTORY_SYNC,
+ WAIT_EVENT_TIMELINE_HISTORY_WRITE,
+ WAIT_EVENT_TWOPHASE_FILE_READ,
+ WAIT_EVENT_TWOPHASE_FILE_SYNC,
+ WAIT_EVENT_TWOPHASE_FILE_WRITE,
+ WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ,
+ WAIT_EVENT_WAL_BOOTSTRAP_SYNC,
+ WAIT_EVENT_WAL_BOOTSTRAP_WRITE,
+ WAIT_EVENT_WAL_COPY_READ,
+ WAIT_EVENT_WAL_COPY_SYNC,
+ WAIT_EVENT_WAL_COPY_WRITE,
+ WAIT_EVENT_WAL_INIT_SYNC,
+ WAIT_EVENT_WAL_INIT_WRITE,
+ WAIT_EVENT_WAL_READ,
+ WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN,
+ WAIT_EVENT_WAL_WRITE
+} WaitEventIO;
+
/* ----------
* Command type for progress reporting purposes
* ----------
extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode);
extern File OpenTemporaryFile(bool interXact);
extern void FileClose(File file);
-extern int FilePrefetch(File file, off_t offset, int amount);
-extern int FileRead(File file, char *buffer, int amount);
-extern int FileWrite(File file, char *buffer, int amount);
-extern int FileSync(File file);
+extern int FilePrefetch(File file, off_t offset, int amount, uint32 wait_event_info);
+extern int FileRead(File file, char *buffer, int amount, uint32 wait_event_info);
+extern int FileWrite(File file, char *buffer, int amount, uint32 wait_event_info);
+extern int FileSync(File file, uint32 wait_event_info);
extern off_t FileSeek(File file, off_t offset, int whence);
-extern int FileTruncate(File file, off_t offset);
-extern void FileWriteback(File file, off_t offset, off_t nbytes);
+extern int FileTruncate(File file, off_t offset, uint32 wait_event_info);
+extern void FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info);
extern char *FilePathName(File file);
extern int FileGetRawDesc(File file);
extern int FileGetRawFlags(File file);