diff options
author | Thomas Munro <tmunro@postgresql.org> | 2020-06-08 13:57:24 +1200 |
---|---|---|
committer | Thomas Munro <tmunro@postgresql.org> | 2020-06-08 13:57:24 +1200 |
commit | 57cb8063089a7d6c54e27adfd5d028cc01f21536 (patch) | |
tree | 6f94c16e82d493347025b3f7fc7f474510703369 /src/backend/access/transam/xlog.c | |
parent | d094bf93014b467cc3c129cc0d7d3f0f69968c96 (diff) | |
download | postgresql-57cb8063089a7d6c54e27adfd5d028cc01f21536.tar.gz postgresql-57cb8063089a7d6c54e27adfd5d028cc01f21536.zip |
Fix locking bugs that could corrupt pg_control.
The redo routines for XLOG_CHECKPOINT_{ONLINE,SHUTDOWN} must acquire
ControlFileLock before modifying ControlFile->checkPointCopy, or the
checkpointer could write out a control file with a bad checksum.
Likewise, XLogReportParameters() must acquire ControlFileLock before
modifying ControlFile and calling UpdateControlFile().
Back-patch to all supported releases.
Author: Nathan Bossart <bossartn@amazon.com>
Author: Fujii Masao <masao.fujii@oss.nttdata.com>
Reviewed-by: Fujii Masao <masao.fujii@oss.nttdata.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/70BF24D6-DC51-443F-B55A-95735803842A%40amazon.com
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index ca09d81b08c..55cac186dc7 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -9743,6 +9743,8 @@ XLogReportParameters(void) XLogFlush(recptr); } + LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); + ControlFile->MaxConnections = MaxConnections; ControlFile->max_worker_processes = max_worker_processes; ControlFile->max_wal_senders = max_wal_senders; @@ -9752,6 +9754,8 @@ XLogReportParameters(void) ControlFile->wal_log_hints = wal_log_hints; ControlFile->track_commit_timestamp = track_commit_timestamp; UpdateControlFile(); + + LWLockRelease(ControlFileLock); } } @@ -9976,7 +9980,9 @@ xlog_redo(XLogReaderState *record) } /* ControlFile->checkPointCopy always tracks the latest ckpt XID */ + LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); ControlFile->checkPointCopy.nextFullXid = checkPoint.nextFullXid; + LWLockRelease(ControlFileLock); /* Update shared-memory copy of checkpoint XID/epoch */ SpinLockAcquire(&XLogCtl->info_lck); @@ -10033,7 +10039,9 @@ xlog_redo(XLogReaderState *record) SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB); /* ControlFile->checkPointCopy always tracks the latest ckpt XID */ + LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); ControlFile->checkPointCopy.nextFullXid = checkPoint.nextFullXid; + LWLockRelease(ControlFileLock); /* Update shared-memory copy of checkpoint XID/epoch */ SpinLockAcquire(&XLogCtl->info_lck); |