aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2024-10-25 06:51:06 -0700
committerNoah Misch <noah@leadboat.com>2024-10-25 06:51:07 -0700
commit3baf804b7295fff7551f93ed94550d8268804cc1 (patch)
treed7f5f6b480f87c217e29805f598ca3ac64153225 /src/backend/access/transam/xlog.c
parentd34ffbaa102910490f427752fa4b28e786225e80 (diff)
downloadpostgresql-3baf804b7295fff7551f93ed94550d8268804cc1.tar.gz
postgresql-3baf804b7295fff7551f93ed94550d8268804cc1.zip
At end of recovery, reset all sinval-managed caches.
An inplace update's invalidation messages are part of its transaction's commit record. However, the update survives even if its transaction aborts or we stop recovery before replaying its transaction commit. After recovery, a backend that started in recovery could update the row without incorporating the inplace update. That could result in a table with an index, yet relhasindex=f. That is a source of index corruption. This bulk invalidation avoids the functional consequences. A future change can fix the !RecoveryInProgress() scenario without changing the WAL format. Back-patch to v17 - v12 (all supported versions). v18 will instead add invalidations to WAL. Discussion: https://postgr.es/m/20240618152349.7f.nmisch@google.com
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r--src/backend/access/transam/xlog.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index daad1ff1c3b..5d8322fbd04 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -94,6 +94,7 @@
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/reinit.h"
+#include "storage/sinvaladt.h"
#include "storage/smgr.h"
#include "storage/spin.h"
#include "storage/sync.h"
@@ -5515,6 +5516,30 @@ StartupXLOG(void)
XLogCtl->LogwrtRqst.Flush = EndOfLog;
/*
+ * Invalidate all sinval-managed caches before READ WRITE transactions
+ * begin. The xl_heap_inplace WAL record doesn't store sufficient data
+ * for invalidations. The commit record, if any, has the invalidations.
+ * However, the inplace update is permanent, whether or not we reach a
+ * commit record. Fortunately, read-only transactions tolerate caches not
+ * reflecting the latest inplace updates. Read-only transactions
+ * experience the notable inplace updates as follows:
+ *
+ * - relhasindex=true affects readers only after the CREATE INDEX
+ * transaction commit makes an index fully available to them.
+ *
+ * - datconnlimit=DATCONNLIMIT_INVALID_DB affects readers only at
+ * InitPostgres() time, and that read does not use a cache.
+ *
+ * - relfrozenxid, datfrozenxid, relminmxid, and datminmxid have no effect
+ * on readers.
+ *
+ * Hence, hot standby queries (all READ ONLY) function correctly without
+ * the missing invalidations. This avoided changing the WAL format in
+ * back branches.
+ */
+ SIResetAll();
+
+ /*
* Preallocate additional log files, if wanted.
*/
PreallocXlogFiles(EndOfLog, newTLI);