Compare commits

..

2 Commits

Author SHA1 Message Date
Thomas Munro
3090213690 Fix comment from commit 22655aa231.
Per automated complaint from BF animal koel this needed to be
re-indented, but there was also a typo.  Back-patch to 16.
2023-10-16 13:32:55 +13:00
Thomas Munro
2371432cd6 Acquire ControlFileLock in relevant SQL functions.
Commit dc7d70ea added functions that read the control file, but didn't
acquire ControlFileLock.  With unlucky timing, file systems that have
weak interlocking like ext4 and ntfs could expose partially overwritten
contents, and the checksum would fail.

Back-patch to all supported releases.

Reviewed-by: David Steele <david@pgmasters.net>
Reviewed-by: Anton A. Melnikov <aamelnikov@inbox.ru>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/20221123014224.xisi44byq3cf5psi%40awork3.anarazel.de
2023-10-16 10:45:05 +13:00
2 changed files with 13 additions and 4 deletions

View File

@ -1803,10 +1803,10 @@ ReleaseBulkInsertStatePin(BulkInsertState bistate)
bistate->current_buf = InvalidBuffer; bistate->current_buf = InvalidBuffer;
/* /*
* Despite the name, we also reset bulk relation extension * Despite the name, we also reset bulk relation extension state.
* state. Otherwise we can end up erroring out due to looking for free * Otherwise we can end up erroring out due to looking for free space in
* space in ->next_free of one partition, even though ->next_free was set * ->next_free of one partition, even though ->next_free was set when
* when extending another partition. It's obviously also could be bad for * extending another partition. It could obviously also be bad for
* efficiency to look at existing blocks at offsets from another * efficiency to look at existing blocks at offsets from another
* partition, even if we don't error out. * partition, even if we don't error out.
*/ */

View File

@ -24,6 +24,7 @@
#include "common/controldata_utils.h" #include "common/controldata_utils.h"
#include "funcapi.h" #include "funcapi.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "storage/lwlock.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/pg_lsn.h" #include "utils/pg_lsn.h"
#include "utils/timestamp.h" #include "utils/timestamp.h"
@ -42,7 +43,9 @@ pg_control_system(PG_FUNCTION_ARGS)
elog(ERROR, "return type must be a row type"); elog(ERROR, "return type must be a row type");
/* read the control file */ /* read the control file */
LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok); ControlFile = get_controlfile(DataDir, &crc_ok);
LWLockRelease(ControlFileLock);
if (!crc_ok) if (!crc_ok)
ereport(ERROR, ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file"))); (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"); elog(ERROR, "return type must be a row type");
/* Read the control file. */ /* Read the control file. */
LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok); ControlFile = get_controlfile(DataDir, &crc_ok);
LWLockRelease(ControlFileLock);
if (!crc_ok) if (!crc_ok)
ereport(ERROR, ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file"))); (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"); elog(ERROR, "return type must be a row type");
/* read the control file */ /* read the control file */
LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok); ControlFile = get_controlfile(DataDir, &crc_ok);
LWLockRelease(ControlFileLock);
if (!crc_ok) if (!crc_ok)
ereport(ERROR, ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file"))); (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"); elog(ERROR, "return type must be a row type");
/* read the control file */ /* read the control file */
LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, &crc_ok); ControlFile = get_controlfile(DataDir, &crc_ok);
LWLockRelease(ControlFileLock);
if (!crc_ok) if (!crc_ok)
ereport(ERROR, ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file"))); (errmsg("calculated CRC checksum does not match value stored in file")));