v5-0002-Acquire-ControlFileLock-in-SQL-functions.patch
text/x-patch
Filename: v5-0002-Acquire-ControlFileLock-in-SQL-functions.patch
Type: text/x-patch
Part: 1
Patch
Format: format-patch
Series: patch v5-0002
Subject: Acquire ControlFileLock in SQL functions.
| File | + | − |
|---|---|---|
| src/backend/utils/misc/pg_controldata.c | 9 | 0 |
From e55b05d52b792c2de35cb519e3a6f0de6030b8f9 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 22 Jul 2023 11:50:27 +1200
Subject: [PATCH v5 2/4] Acquire ControlFileLock in SQL functions.
Commit dc7d70ea added functions that read the control file, but didn't
acquire ControlFileLock. With unlucky timing and on certain file
systems, they could read corrupted data that is in the process of being
overwritten, and the checksum would fail.
Back-patch to all supported releases.
Discussion: https://postgr.es/m/20221123014224.xisi44byq3cf5psi%40awork3.anarazel.de
---
src/backend/utils/misc/pg_controldata.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c
index f2c1084797..a1003a464d 100644
--- a/src/backend/utils/misc/pg_controldata.c
+++ b/src/backend/utils/misc/pg_controldata.c
@@ -24,6 +24,7 @@
#include "common/controldata_utils.h"
#include "funcapi.h"
#include "miscadmin.h"
+#include "storage/lwlock.h"
#include "utils/builtins.h"
#include "utils/pg_lsn.h"
#include "utils/timestamp.h"
@@ -42,7 +43,9 @@ pg_control_system(PG_FUNCTION_ARGS)
elog(ERROR, "return type must be a row type");
/* read the control file */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -80,7 +83,9 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
elog(ERROR, "return type must be a row type");
/* Read the control file. */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -169,7 +174,9 @@ pg_control_recovery(PG_FUNCTION_ARGS)
elog(ERROR, "return type must be a row type");
/* read the control file */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -208,7 +215,9 @@ pg_control_init(PG_FUNCTION_ARGS)
elog(ERROR, "return type must be a row type");
/* read the control file */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
--
2.39.2