What is a snapshot - Mailing list pgsql-hackers
From | Alvaro Herrera |
---|---|
Subject | What is a snapshot |
Date | |
Msg-id | 20030511232926.GB10614@dcc.uchile.cl Whole thread Raw |
List | pgsql-hackers |
Hackers, Clearly it's not going to help to all the nested transactions project if we don't make clear the concept of a snapshot. In the current implementation, it's sufficient to know a) what transactions come before me (Xmin), b) what transactions come after me (Xmax), c) what transactions are in progress (xip), and d) what commands come before me in the current transaction (curcid) In the nested transactions case, we also need to know e) what subtransactions of my own parent transactions come before me, and f) what commands of my parent transactions come before me. Consider the following scenario: BEGIN; xid=1 CREATE TABLE a (p int UNIQUE, q int); xid=1 cid=1 INSERT INTO a (p) VALUES (1); xid=1 cid=2 BEGIN; xid=2-- should fail due to unique constraintINSERT INTO a (p) VALUES (1); xid=2 cid=1 ROLLBACK; BEGIN; xid=3INSERT INTO a (p) VALUES (2); cid=1DELETE FROM a WHERE one=1; cid=2--"a" should have 1 tuple COMMIT; -- should work, because the old tuple doesn't exist anymore INSERT INTO a (p) VALUES (1); xid=1 cid=3 COMMIT; Here, the QuerySnapshot of xid 1, at the time of cid=3 should see the results of execution from xid 3, but it is not before Xmin, and it's after Xmax, and is not in the xip array. Also, the QuerySnapshot of xid 3, should see the results of commands from xid 1 just like they'd be seen if they where in the same xact but with a lesser CommandId. Both cases are not implementable with the current notion of a Snapshot. I propose that the SnapshotData struct is expanded as: typedef struct SnapshotData { TransactionId xmin; /* XID < xmin are visible to me */ TransactionId xmax; /* XID >= xmax are invisibleto me */ uint32 xcnt; /* # of xact ids in xip[] */ TransactionId *xip; /* array of xactIDs in progress */ /* note: all ids in xip[] satisfy xmin <= xip[i] < xmax */ CommandId curcid; /* in myxact, CID < curcid are visible */ ItemPointerData tid; /* required for Dirty snapshot -:( *//* new members below*/ uint32 childcnt; /* # of xact ids in childcnt[] */ TransactionId *childxact; /* array of completed childxact IDs */ uint32 parentcnt; /* # of xact ids in parentcnt[] */ TransactionId *parentxact; /* array ofparent xact IDs */ } SnapshotData; And then we will have to rewrite the HeapTupleSatisfies* routines to act according to this new Snapshot structure, and also with the pg_subtrans mechanism to know which subtransactions were aborted. When starting a subtransaction, the child will have the parent's XID in parentxact, and all the XID's the parent has in parentxact as well. When ending a subtransaction, the parent will record its XID in childxact, and all the XID's the child had in childxact. It's not necessary to keep the parent's CommandId, because there are no future CommandIds recorded in any tuple (no need to check). I'm not sure what the SerializableSnapshot should be. It does need to take into account the changes made by previous committed subtransactions, right? It's also clear that we need to differentiate a parent's QuerySnapshot from their child's. It's not clear to me what should be done in the case of a SerializableSnapshot. -- Alvaro Herrera (<alvherre[a]dcc.uchile.cl>) "The Postgresql hackers have what I call a "NASA space shot" mentality. Quite refreshing in a world of "weekend drag racer" developers." (Scott Marlowe)
pgsql-hackers by date: