DT wrote > Hi, > > I'm reading code of ALTER TABLE, and I found when target table needs > rewrite, tuple inserted into new heap uses current transaction's xid as > xmin. Does this behavior satisfy serializable isolation? I wrote some test > cases: > CREATE TABLE t1(a INT);CREATE TABLE t2(a INT);INSERT INTO t1 > VALUES(1);INSERT INTO t2 VALUES(1); > transaction one: > postgres=# commit;COMMITpostgres=# BEGIN;BEGINpostgres=# SET TRANSACTION > ISOLATION LEVEL SERIALIZABLE;SETpostgres=# SELECT * FROM t1; a--- 1(1 > rows) > transaction two execute SQL: ALTER TABLE t2 ADD COLUMN b INT > DEFAULT 1; > postgres=# SELECT * FROM t2; a | b---+---(0 rows) > Transaction one sees nothing in t2, and i can not give any serial > execution order of these two transactions, does it still satisfy > serializable isolation?
I'm not a hacker but I wanted to try and understand this better so I took a look...my testing is on 9.0 Wrapping the ALTER TABLE into serializable transaction causes the SELECT to wait on the lock established by the ALTER TABLE transaction but once the ALTER TABLE commits the result of the SELECT includes the new column but does not contain any data. I was curious if it would fail on commit instead of mid-transaction but that did not pan out. It is correct that the new xmin should be the xid of the ALTER TABLE transaction; the problem is that the original table seems to be basically erased - i.e. like it was truncated (an explicitly MVCC-unsafe operation and one which exhibits this same interaction {i.e., replace "ALTER TABLE" with "TRUNCATE"}). As noted on the TRUNCATE page if you manage to perform the SELECT * FROM t2 prior to the ALTER/TRUNCATE command the attempt to LOCK the table (for ALTER/TRUNCATE) blocks. While I can understand avoiding the use of TRUNCATE (you can always just DELETE) avoid ALTER TABLE is much more difficult since there is no MVCC-safe alternative to accomplish the same functional goal. At first glance I'd say at minimum this could use some improved documentation if the underlying behavior cannot be corrected. Again, not a hacker, but for repeatable read and serializeable it would seem that when a re-write of a table occurs that some kind of "table exists as of xid" value needs to be set and then if that ID is greater than the xid of the calling transaction the table effectively does not exist and a 'relation "table" does not exist' error should be thrown. I'm doubtful it is worthwhile to make it so the SELECT returns the pre-ALTER table structure and records so exploration should be done on the "how do we make this fail cheaply" path. Not fixing these cases (TRUNCATE and ALTER TABLE) but just documenting it doesn't seem good given that the result is contrary to the promises these isolation levels make. I really hope that I am on the right track with all this but if not at least you get some insight into how a non-hacker (mis-)understands what is happening behind the scenes. David J. -- View this message in context: http://postgresql.1045698.n5.nabble.com/ALTER-TABLE-transaction-isolation-problem-tp5769289p5769347.html Sent from the PostgreSQL - general mailing list archive at Nabble.com. -- Sent via pgsql-general mailing list (pgsql-general@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-general