diff options
Diffstat (limited to 'src/backend/commands')
| -rw-r--r-- | src/backend/commands/indexcmds.c | 57 | ||||
| -rw-r--r-- | src/backend/commands/sequence.c | 21 | ||||
| -rw-r--r-- | src/backend/commands/vacuum.c | 29 | ||||
| -rw-r--r-- | src/backend/commands/vacuumlazy.c | 7 |
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(); |
