v6-0004-Acquire-ControlFileLock-in-SQL-functions.patch
application/x-patch
Filename: v6-0004-Acquire-ControlFileLock-in-SQL-functions.patch
Type: application/x-patch
Part: 3
Patch
Format: format-patch
Series: patch v6-0004
Subject: Acquire ControlFileLock in SQL functions.
| File | + | − |
|---|---|---|
| src/backend/utils/misc/pg_controldata.c | 9 | 0 |
From b7b5e85f0e4929441ab27402de5afd32392d9193 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 v6 4/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 (Apple Git-143)