What is a snapshot

Поиск
Список
Период
Сортировка
От Alvaro Herrera
Тема What is a snapshot
Дата
Msg-id 20030511232926.GB10614@dcc.uchile.cl
обсуждение исходный текст
Список 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 по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: Re: 7.3 and HEAD broken for dropped columns of dropped types
Следующее
От: "Andrew Dunstan"
Дата:
Сообщение: Re: Plans for index names unique to a table?