summaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/indexcmds.c57
-rw-r--r--src/backend/commands/sequence.c21
-rw-r--r--src/backend/commands/vacuum.c29
-rw-r--r--src/backend/commands/vacuumlazy.c7
4 files changed, 51 insertions, 63 deletions
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index d79e73f59d..ac56b583f1 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.162 2007/08/25 19:08:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.163 2007/09/05 18:10:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,6 +38,7 @@
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parsetree.h"
+#include "storage/procarray.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
@@ -126,9 +127,8 @@ DefineIndex(RangeVar *heapRelation,
int16 *coloptions;
IndexInfo *indexInfo;
int numberOfAttributes;
- List *old_xact_list;
- ListCell *lc;
- uint32 ixcnt;
+ VirtualTransactionId *old_lockholders;
+ VirtualTransactionId *old_snapshots;
LockRelId heaprelid;
LOCKTAG heaplocktag;
Snapshot snapshot;
@@ -484,24 +484,36 @@ DefineIndex(RangeVar *heapRelation,
* xacts that open the table for writing after this point; they will see
* the new index when they open it.
*
+ * Note: the reason we use actual lock acquisition here, rather than
+ * just checking the ProcArray and sleeping, is that deadlock is possible
+ * if one of the transactions in question is blocked trying to acquire
+ * an exclusive lock on our table. The lock code will detect deadlock
+ * and error out properly.
+ *
* Note: GetLockConflicts() never reports our own xid, hence we need not
- * check for that.
+ * check for that. Also, prepared xacts are not reported, which is
+ * fine since they certainly aren't going to do anything more.
*/
SET_LOCKTAG_RELATION(heaplocktag, heaprelid.dbId, heaprelid.relId);
- old_xact_list = GetLockConflicts(&heaplocktag, ShareLock);
+ old_lockholders = GetLockConflicts(&heaplocktag, ShareLock);
- foreach(lc, old_xact_list)
+ while (VirtualTransactionIdIsValid(*old_lockholders))
{
- TransactionId xid = lfirst_xid(lc);
-
- XactLockTableWait(xid);
+ VirtualXactLockTableWait(*old_lockholders);
+ old_lockholders++;
}
/*
* Now take the "reference snapshot" that will be used by validate_index()
- * to filter candidate tuples. All other transactions running at this
- * time will have to be out-waited before we can commit, because we can't
- * guarantee that tuples deleted just before this will be in the index.
+ * to filter candidate tuples. Beware! There might be still snapshots
+ * in use that treat some transaction as in-progress that our reference
+ * snapshot treats as committed. If such a recently-committed transaction
+ * deleted tuples in the table, we will not include them in the index; yet
+ * those transactions which see the deleting one as still-in-progress will
+ * expect them to be there once we mark the index as valid.
+ *
+ * We solve this by waiting for all endangered transactions to exit before
+ * we mark the index as valid.
*
* We also set ActiveSnapshot to this snap, since functions in indexes may
* need a snapshot.
@@ -518,14 +530,21 @@ DefineIndex(RangeVar *heapRelation,
* The index is now valid in the sense that it contains all currently
* interesting tuples. But since it might not contain tuples deleted just
* before the reference snap was taken, we have to wait out any
- * transactions older than the reference snap. We can do this by waiting
- * for each xact explicitly listed in the snap.
+ * transactions that might have older snapshots. Obtain a list of
+ * VXIDs of such transactions, and wait for them individually.
*
- * Note: GetSnapshotData() never stores our own xid into a snap, hence we
- * need not check for that.
+ * We can exclude any running transactions that have xmin >= the xmax of
+ * our reference snapshot, since they are clearly not interested in any
+ * missing older tuples. Also, GetCurrentVirtualXIDs never reports our
+ * own vxid, so we need not check for that.
*/
- for (ixcnt = 0; ixcnt < snapshot->xcnt; ixcnt++)
- XactLockTableWait(snapshot->xip[ixcnt]);
+ old_snapshots = GetCurrentVirtualXIDs(ActiveSnapshot->xmax);
+
+ while (VirtualTransactionIdIsValid(*old_snapshots))
+ {
+ VirtualXactLockTableWait(*old_snapshots);
+ old_snapshots++;
+ }
/*
* Index can now be marked valid -- update its pg_index entry
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index bd06bfb5da..cb2a1380ca 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.143 2007/02/01 19:10:26 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.144 2007/09/05 18:10:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,6 +25,7 @@
#include "commands/tablecmds.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
+#include "storage/proc.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
@@ -63,7 +64,7 @@ typedef struct SeqTableData
{
struct SeqTableData *next; /* link to next SeqTable object */
Oid relid; /* pg_class OID of this sequence */
- TransactionId xid; /* xact in which we last did a seq op */
+ LocalTransactionId lxid; /* xact in which we last did a seq op */
int64 last; /* value last returned by nextval */
int64 cached; /* last value already cached for nextval */
/* if last != cached, we have not used up all the cached values */
@@ -282,7 +283,7 @@ DefineSequence(CreateSeqStmt *seq)
rdata[1].buffer = InvalidBuffer;
rdata[1].next = NULL;
- recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG | XLOG_NO_TRAN, rdata);
+ recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG, rdata);
PageSetLSN(page, recptr);
PageSetTLI(page, ThisTimeLineID);
@@ -366,7 +367,7 @@ AlterSequence(AlterSeqStmt *stmt)
rdata[1].buffer = InvalidBuffer;
rdata[1].next = NULL;
- recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG | XLOG_NO_TRAN, rdata);
+ recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG, rdata);
PageSetLSN(page, recptr);
PageSetTLI(page, ThisTimeLineID);
@@ -594,7 +595,7 @@ nextval_internal(Oid relid)
rdata[1].buffer = InvalidBuffer;
rdata[1].next = NULL;
- recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG | XLOG_NO_TRAN, rdata);
+ recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG, rdata);
PageSetLSN(page, recptr);
PageSetTLI(page, ThisTimeLineID);
@@ -764,7 +765,7 @@ do_setval(Oid relid, int64 next, bool iscalled)
rdata[1].buffer = InvalidBuffer;
rdata[1].next = NULL;
- recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG | XLOG_NO_TRAN, rdata);
+ recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG, rdata);
PageSetLSN(page, recptr);
PageSetTLI(page, ThisTimeLineID);
@@ -825,10 +826,10 @@ setval3_oid(PG_FUNCTION_ARGS)
static Relation
open_share_lock(SeqTable seq)
{
- TransactionId thisxid = GetTopTransactionId();
+ LocalTransactionId thislxid = MyProc->lxid;
/* Get the lock if not already held in this xact */
- if (seq->xid != thisxid)
+ if (seq->lxid != thislxid)
{
ResourceOwner currentOwner;
@@ -848,7 +849,7 @@ open_share_lock(SeqTable seq)
CurrentResourceOwner = currentOwner;
/* Flag that we have a lock in the current xact */
- seq->xid = thisxid;
+ seq->lxid = thislxid;
}
/* We now know we have AccessShareLock, and can safely open the rel */
@@ -891,7 +892,7 @@ init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
elm->relid = relid;
- elm->xid = InvalidTransactionId;
+ elm->lxid = InvalidLocalTransactionId;
/* increment is set to 0 until we do read_info (see currval) */
elm->last = elm->cached = elm->increment = 0;
elm->next = seqtab;
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 358e9a5ad9..87cf57daec 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.355 2007/08/13 19:08:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.356 2007/09/05 18:10:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2601,14 +2601,6 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
PageSetLSN(page, recptr);
PageSetTLI(page, ThisTimeLineID);
}
- else
- {
- /*
- * No XLOG record, but still need to flag that XID exists on
- * disk
- */
- MyXactMadeTempRelUpdate = true;
- }
END_CRIT_SECTION();
@@ -2761,13 +2753,6 @@ move_chain_tuple(Relation rel,
PageSetLSN(dst_page, recptr);
PageSetTLI(dst_page, ThisTimeLineID);
}
- else
- {
- /*
- * No XLOG record, but still need to flag that XID exists on disk
- */
- MyXactMadeTempRelUpdate = true;
- }
END_CRIT_SECTION();
@@ -2868,13 +2853,6 @@ move_plain_tuple(Relation rel,
PageSetLSN(dst_page, recptr);
PageSetTLI(dst_page, ThisTimeLineID);
}
- else
- {
- /*
- * No XLOG record, but still need to flag that XID exists on disk
- */
- MyXactMadeTempRelUpdate = true;
- }
END_CRIT_SECTION();
@@ -3070,11 +3048,6 @@ vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage)
PageSetLSN(page, recptr);
PageSetTLI(page, ThisTimeLineID);
}
- else
- {
- /* No XLOG record, but still need to flag that XID exists on disk */
- MyXactMadeTempRelUpdate = true;
- }
END_CRIT_SECTION();
}
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index 3ac097388b..ecc0ee7807 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -36,7 +36,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.90 2007/05/30 20:11:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.91 2007/09/05 18:10:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -658,11 +658,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
PageSetLSN(page, recptr);
PageSetTLI(page, ThisTimeLineID);
}
- else
- {
- /* No XLOG record, but still need to flag that XID exists on disk */
- MyXactMadeTempRelUpdate = true;
- }
END_CRIT_SECTION();