| -- @Description Test scenario where a backend accesses AO table with a snapshot |
| -- that was acquired before vacuum. |
| -- |
| DROP TABLE IF EXISTS ao; |
| CREATE TABLE ao (a INT, b INT) USING @amname@; |
| INSERT INTO ao SELECT i as a, i as b FROM generate_series(1, 100) AS i; |
| |
| DELETE FROM ao WHERE a <= 30; |
| |
| create or replace function myfunc() returns bigint as $$ |
| begin /* inside a function */ |
| perform pg_sleep(10); /* inside a function */ |
| return (select count(*) from ao); /* inside a function */ |
| end; /* inside a function */ |
| $$ stable language plpgsql; |
| |
| -- Launch function into the background. |
| 1&: select myfunc(); |
| |
| -- Meanwhile, DELETE some rows and VACUUM. VACUUM should not recycle the |
| -- old tuple versions that are still needed by the function later. It will |
| -- compact the segfile, but keep the old segfile in AWAITING_DROP state. |
| 2: DELETE FROM ao WHERE a <= 50; |
| 2: SELECT segno, tupcount, state FROM gp_ao_or_aocs_seg('ao'); |
| 2: VACUUM ao; |
| 2: SELECT segno, tupcount, state FROM gp_ao_or_aocs_seg('ao'); |
| |
| -- A second VACUUM shouldn't recycle them either. |
| 2: VACUUM ao; |
| 2: SELECT segno, tupcount, state FROM gp_ao_or_aocs_seg('ao'); |
| 1<: |
| |
| -- Now that the first transaction has finished, VACUUM can recycle. |
| 2: VACUUM ao; |
| 2: SELECT segno, tupcount, state FROM gp_ao_or_aocs_seg('ao'); |