aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/spgist/spgxlog.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-08-02 15:34:14 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-08-02 15:34:14 -0400
commit962e0cc71e839c58fb9125fa85511b8bbb8bdbee (patch)
treee91d54f941d8207c0a48b642fd59fe9fcd46072e /src/backend/access/spgist/spgxlog.c
parent7719ed04bc4b8f08dab85ffe9c79a52fdb4756dd (diff)
downloadpostgresql-962e0cc71e839c58fb9125fa85511b8bbb8bdbee.tar.gz
postgresql-962e0cc71e839c58fb9125fa85511b8bbb8bdbee.zip
Fix race conditions associated with SPGiST redirection tuples.
The correct test for whether a redirection tuple is removable is whether tuple's xid < RecentGlobalXmin, not OldestXmin; the previous coding failed to protect index searches being done in concurrent transactions that have no XID. This mirrors the recent fix in btree's page recycling logic made in commit d3abbbebe52eb1e59e621c880ad57df9d40d13f2. Also, WAL-log the newest XID of any removed redirection tuple on an index page, and apply ResolveRecoveryConflictWithSnapshot during InHotStandby WAL replay. This protects against concurrent Hot Standby transactions possibly needing to see the redirection tuple(s). Per my query of 2012-03-12 and subsequent discussion.
Diffstat (limited to 'src/backend/access/spgist/spgxlog.c')
-rw-r--r--src/backend/access/spgist/spgxlog.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/backend/access/spgist/spgxlog.c b/src/backend/access/spgist/spgxlog.c
index 82f8c8b978a..45eda70ac76 100644
--- a/src/backend/access/spgist/spgxlog.c
+++ b/src/backend/access/spgist/spgxlog.c
@@ -15,8 +15,9 @@
#include "postgres.h"
#include "access/spgist_private.h"
+#include "access/transam.h"
#include "access/xlogutils.h"
-#include "storage/bufmgr.h"
+#include "storage/standby.h"
#include "utils/memutils.h"
@@ -888,6 +889,15 @@ spgRedoVacuumRedirect(XLogRecPtr lsn, XLogRecord *record)
ptr += sizeof(spgxlogVacuumRedirect);
itemToPlaceholder = (OffsetNumber *) ptr;
+ /*
+ * If any redirection tuples are being removed, make sure there are no
+ * live Hot Standby transactions that might need to see them. This code
+ * behaves similarly to btree's XLOG_BTREE_REUSE_PAGE case.
+ */
+ if (InHotStandby && TransactionIdIsValid(xldata->newestRedirectXid))
+ ResolveRecoveryConflictWithSnapshot(xldata->newestRedirectXid,
+ xldata->node);
+
if (!(record->xl_info & XLR_BKP_BLOCK_1))
{
buffer = XLogReadBuffer(xldata->node, xldata->blkno, false);
@@ -1060,8 +1070,9 @@ spg_desc(StringInfo buf, uint8 xl_info, char *rec)
break;
case XLOG_SPGIST_VACUUM_REDIRECT:
out_target(buf, ((spgxlogVacuumRedirect *) rec)->node);
- appendStringInfo(buf, "vacuum redirect tuples on page %u",
- ((spgxlogVacuumRedirect *) rec)->blkno);
+ appendStringInfo(buf, "vacuum redirect tuples on page %u, newest XID %u",
+ ((spgxlogVacuumRedirect *) rec)->blkno,
+ ((spgxlogVacuumRedirect *) rec)->newestRedirectXid);
break;
default:
appendStringInfo(buf, "unknown spgist op code %u", info);