Skip to content

Commit 48eb6a3

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 a35896c commit 48eb6a3

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
@@ -9680,6 +9680,8 @@ XLogReportParameters(void)
96809680
XLogFlush(recptr);
96819681
}
96829682

9683+
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9684+
96839685
ControlFile->MaxConnections = MaxConnections;
96849686
ControlFile->max_worker_processes = max_worker_processes;
96859687
ControlFile->max_prepared_xacts = max_prepared_xacts;
@@ -9688,6 +9690,8 @@ XLogReportParameters(void)
96889690
ControlFile->wal_log_hints = wal_log_hints;
96899691
ControlFile->track_commit_timestamp = track_commit_timestamp;
96909692
UpdateControlFile();
9693+
9694+
LWLockRelease(ControlFileLock);
96919695
}
96929696
}
96939697

@@ -9912,8 +9916,10 @@ xlog_redo(XLogReaderState *record)
99129916
}
99139917

99149918
/* ControlFile->checkPointCopy always tracks the latest ckpt XID */
9919+
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
99159920
ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch;
99169921
ControlFile->checkPointCopy.nextXid = checkPoint.nextXid;
9922+
LWLockRelease(ControlFileLock);
99179923

99189924
/* Update shared-memory copy of checkpoint XID/epoch */
99199925
SpinLockAcquire(&XLogCtl->info_lck);
@@ -9971,8 +9977,10 @@ xlog_redo(XLogReaderState *record)
99719977
SetTransactionIdLimit(checkPoint.oldestXid,
99729978
checkPoint.oldestXidDB);
99739979
/* ControlFile->checkPointCopy always tracks the latest ckpt XID */
9980+
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
99749981
ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch;
99759982
ControlFile->checkPointCopy.nextXid = checkPoint.nextXid;
9983+
LWLockRelease(ControlFileLock);
99769984

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

0 commit comments

Comments
 (0)