Hi Antonin,
Thanks for your update.
I think v04 fixes the finalize_block_range() problem.
The compute_new_xmax_infomask() Assert is easy to hit. The
AccessExclusiveLock in rebuild_relation_finish_concurrent() assigns an
XID, so any UPDATE or DELETE committed while REPACK waits for it fails
on replay. The attached spec does it every time.
If you give the new counter a slot that index builds don't write,
like 13, 0008 does not have to depend on 6958.
Thanks,
Shihao
# v04-0008: an UPDATE that commits while REPACK (CONCURRENTLY) waits for
# AccessExclusiveLock on the table is replayed after the lock is granted.
# LockAcquireExtended() assigned REPACK an XID for the standby lock record
# (wal_level >= replica), so the replayed heap_update() runs with a valid
# top XID and add_to_xmax of the original transaction.
setup
{
CREATE EXTENSION injection_points;
CREATE TABLE t(i int PRIMARY KEY, j int);
INSERT INTO t SELECT x, 0 FROM generate_series(1, 100) x;
}
teardown
{
DROP TABLE t;
DROP EXTENSION injection_points;
}
session s1
setup
{
SELECT injection_points_set_local();
SELECT injection_points_attach('repack-concurrently-before-lock',
'wait');
}
step repack { REPACK (CONCURRENTLY) t; }
step check { SELECT count(*), sum(j) FROM t; }
session s2
step begin { BEGIN; }
step upd { UPDATE t SET j = j + 1 WHERE i = 10; }
step del { DELETE FROM t WHERE i = 20; }
step commit { COMMIT; }
session s3
step wakeup
{
SELECT injection_points_detach('repack-concurrently-before-lock');
SELECT injection_points_wakeup('repack-concurrently-before-lock');
}
# Make sure REPACK is queued for AccessExclusiveLock before s2 commits.
step waitlock
{
DO $$
BEGIN
WHILE NOT EXISTS (SELECT 1 FROM pg_locks
WHERE relation =
't'::regclass AND NOT granted
AND mode =
'AccessExclusiveLock')
LOOP
PERFORM pg_sleep(0.01);
END LOOP;
END
$$;
}
permutation repack begin upd wakeup waitlock commit check
permutation repack begin del wakeup waitlock commit check
# Controls: the change commits before REPACK leaves the injection point,
# so it is replayed before the lock is requested.
permutation repack begin upd commit wakeup check
permutation repack begin del commit wakeup check