From 701a51fd4e01dbbd02067d8f01905a04bc571131 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Tue, 11 Feb 2020 17:22:37 +1300 Subject: [PATCH] Use pg_pwrite() in more places. This removes some lseek() system calls. Author: Thomas Munro Reviewed-by: Andres Freund Discussion: https://postgr.es/m/CA%2BhUKGJ%2BoHhnvqjn3%3DHro7xu-YDR8FPr0FL6LF35kHRX%3D_bUzg%40mail.gmail.com --- .../pg_stat_statements/pg_stat_statements.c | 7 ++--- src/backend/access/heap/rewriteheap.c | 9 +----- src/backend/replication/walreceiver.c | 28 ++----------------- src/backend/utils/init/miscinit.c | 3 +- 4 files changed, 7 insertions(+), 40 deletions(-) diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 6f82a671ee..e0dbeebde3 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -1868,12 +1868,9 @@ qtext_store(const char *query, int query_len, if (fd < 0) goto error; - if (lseek(fd, off, SEEK_SET) != off) + if (pg_pwrite(fd, query, query_len, off) != query_len) goto error; - - if (write(fd, query, query_len) != query_len) - goto error; - if (write(fd, "\0", 1) != 1) + if (pg_pwrite(fd, "\0", 1, off + query_len) != 1) goto error; CloseTransientFile(fd); diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c index 5869922ff8..9c29bc0e0f 100644 --- a/src/backend/access/heap/rewriteheap.c +++ b/src/backend/access/heap/rewriteheap.c @@ -1156,13 +1156,6 @@ heap_xlog_logical_rewrite(XLogReaderState *r) 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) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not seek to end of file \"%s\": %m", - path))); - data = XLogRecGetData(r) + sizeof(*xlrec); len = xlrec->num_mappings * sizeof(LogicalRewriteMappingData); @@ -1170,7 +1163,7 @@ heap_xlog_logical_rewrite(XLogReaderState *r) /* write out tail end of mapping file (again) */ errno = 0; pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE); - if (write(fd, data, len) != len) + if (pg_pwrite(fd, data, len, xlrec->offset) != len) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index a5e85d32f3..2ab15c3cbb 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -85,14 +85,13 @@ WalReceiverFunctionsType *WalReceiverFunctions = NULL; #define NAPTIME_PER_CYCLE 100 /* max sleep time between cycles (100ms) */ /* - * These variables are used similarly to openLogFile/SegNo/Off, + * These variables are used similarly to openLogFile/SegNo, * but for walreceiver to write the XLOG. recvFileTLI is the TimeLineID * corresponding the filename of recvFile. */ static int recvFile = -1; static TimeLineID recvFileTLI = 0; static XLogSegNo recvSegNo = 0; -static uint32 recvOff = 0; /* * Flags set by interrupt handlers of walreceiver for later service in the @@ -945,7 +944,6 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr) use_existent = true; recvFile = XLogFileInit(recvSegNo, &use_existent, true); recvFileTLI = ThisTimeLineID; - recvOff = 0; } /* Calculate the start offset of the received logs */ @@ -956,29 +954,10 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr) else segbytes = nbytes; - /* Need to seek in the file? */ - if (recvOff != startoff) - { - if (lseek(recvFile, (off_t) startoff, SEEK_SET) < 0) - { - char xlogfname[MAXFNAMELEN]; - int save_errno = errno; - - XLogFileName(xlogfname, recvFileTLI, recvSegNo, wal_segment_size); - errno = save_errno; - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not seek in log segment %s to offset %u: %m", - xlogfname, startoff))); - } - - recvOff = startoff; - } - /* OK to write the logs */ errno = 0; - byteswritten = write(recvFile, buf, segbytes); + byteswritten = pg_pwrite(recvFile, buf, segbytes, (off_t) startoff); if (byteswritten <= 0) { char xlogfname[MAXFNAMELEN]; @@ -995,13 +974,12 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr) (errcode_for_file_access(), errmsg("could not write to log segment %s " "at offset %u, length %lu: %m", - xlogfname, recvOff, (unsigned long) segbytes))); + xlogfname, startoff, (unsigned long) segbytes))); } /* Update state for write */ recptr += byteswritten; - recvOff += byteswritten; nbytes -= byteswritten; buf += byteswritten; diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index c4b2946986..c7c9bef617 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -1333,8 +1333,7 @@ AddToDataDirLockFile(int target_line, const char *str) 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) + if (pg_pwrite(fd, destbuffer, len, 0) != len) { pgstat_report_wait_end(); /* if write didn't set errno, assume problem is no disk space */