Skip to content

Commit 72766ad

Browse files
committed
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
1 parent b944b1d commit 72766ad

File tree

1 file changed

+8
-0
lines changed
  • src/backend/access/transam

1 file changed

+8
-0
lines changed

src/backend/access/transam/xlog.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9539,6 +9539,8 @@ XLogReportParameters(void)
95399539
XLogFlush(recptr);
95409540
}
95419541

9542+
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9543+
95429544
ControlFile->MaxConnections = MaxConnections;
95439545
ControlFile->max_worker_processes = max_worker_processes;
95449546
ControlFile->max_wal_senders = max_wal_senders;
@@ -9548,6 +9550,8 @@ XLogReportParameters(void)
95489550
ControlFile->wal_log_hints = wal_log_hints;
95499551
ControlFile->track_commit_timestamp = track_commit_timestamp;
95509552
UpdateControlFile();
9553+
9554+
LWLockRelease(ControlFileLock);
95519555
}
95529556
}
95539557

@@ -9772,7 +9776,9 @@ xlog_redo(XLogReaderState *record)
97729776
}
97739777

97749778
/* ControlFile->checkPointCopy always tracks the latest ckpt XID */
9779+
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
97759780
ControlFile->checkPointCopy.nextFullXid = checkPoint.nextFullXid;
9781+
LWLockRelease(ControlFileLock);
97769782

97779783
/* Update shared-memory copy of checkpoint XID/epoch */
97789784
SpinLockAcquire(&XLogCtl->info_lck);
@@ -9829,7 +9835,9 @@ xlog_redo(XLogReaderState *record)
98299835
SetTransactionIdLimit(checkPoint.oldestXid,
98309836
checkPoint.oldestXidDB);
98319837
/* ControlFile->checkPointCopy always tracks the latest ckpt XID */
9838+
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
98329839
ControlFile->checkPointCopy.nextFullXid = checkPoint.nextFullXid;
9840+
LWLockRelease(ControlFileLock);
98339841

98349842
/* Update shared-memory copy of checkpoint XID/epoch */
98359843
SpinLockAcquire(&XLogCtl->info_lck);

0 commit comments

Comments
 (0)