blob: a419123b5d6e676e3cd06cee33fd1d410eba9bfa [file] [log] [blame]
-- These tests verify that vacuum freeze correctly updates age of auxiliary
-- tables along with the age of a parent appendonly table
-- First, create some helper functions.
CREATE TEMPORARY TABLE dummytable (id int4) distributed randomly;
CREATE FUNCTION advance_xid_counter(n integer) RETURNS void as $$
declare
i integer;
begin
-- do multiple updates to advance the XID counter
-- The purpose of the exception block is to begin a new subtransaction for
-- each command, to consume an XID.
for i in 1..n loop
begin
insert into dummytable values (i);
exception when others then
raise notice 'something went wrong: %', sqlerrm;
end;
end loop;
end;
$$ language 'plpgsql';
CREATE FUNCTION classify_age(age integer) RETURNS text AS $$
SELECT CASE WHEN $1 < 0 THEN 'negative'
WHEN $1 = 0 THEN 'zero'
WHEN $1 < 50 THEN 'very young' -- less than vacuum_freeze_min_age=50 that we use below
WHEN $1 < 100 THEN 'young' -- recently processed by vacuum freeze
ELSE 'old' END; -- not frozen
$$ LANGUAGE SQL IMMUTABLE STRICT;
CREATE TYPE rel_ages AS (segid integer, relname text, age integer);
-- Get age(relfrozenxid) of a table, and all its auxiliary tables. On master,
-- and on all segments. For AO and CO table relfrozenxid = 0 and should stay
-- 0. So, essentially base AO / CO tables should not show-up in the results.
CREATE OR REPLACE FUNCTION aux_rel_ages(testrelid regclass) RETURNS SETOF rel_ages as
$$
declare
rec rel_ages;
begin
for rec in select gp_segment_id, replace(relname, testrelid::oid::text, '<oid>'), age(relfrozenxid)
from pg_class
where relkind in ('r','t','o','b','M') and relam in (2, 3434, 3435)
and (relname like '%\_' || testrelid::oid or oid = testrelid::oid )
and not relfrozenxid = 0
loop
return next rec;
end loop;
for rec in select gp_segment_id, replace(relname, testrelid::oid::text, '<oid>'), age(relfrozenxid)
from gp_dist_random('pg_class')
where relkind in ('r','t','o','b','M') and relam in (2, 3434, 3435)
and (relname like '%\_' || testrelid::oid or oid = testrelid::oid )
and not relfrozenxid = 0
loop
return next rec;
end loop;
end;
$$ language plpgsql;
-- Start tests
--
-- The basic test structure is:
-- 1. CREATE TABLE, leave it empty
-- 2. Run some commands, to advance XID counter
-- 3. VACUUM
-- 4. Verify that the relfrozenxid was advanced by the vacuum
--
set vacuum_freeze_min_age = 50;
create table test_table_heap (id int, col1 int) with (appendonly=false);
create table test_table_heap_with_toast (id int, col1 int, col2 text) with (appendonly=false);
create table test_table_ao (id int, col1 int) with (appendonly=true, orientation=row);
create table test_table_ao_with_toast (id int, col1 int, col2 text) with (appendonly=true, orientation=row);
create table test_table_co (id int, col1 int) with (appendonly=true, orientation=column);
create index test_heap_idx on test_table_heap using btree(id);
create index test_heap_wt_idx on test_table_heap_with_toast using btree(id);
create index test_heap_ao_idx on test_table_ao using btree(id);
create index test_heap_ao_wt_idx on test_table_ao_with_toast using btree(id);
create index test_heap_co_idx on test_table_co using btree(id);
-- Advance XID counter, vacuum, and check that relfrozenxid was advanced for
-- all the tables, including auxiliary tables, even though there were no
-- dead tuples.
select advance_xid_counter(500);
-- check table ages before vacuum.
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_heap')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_heap_with_toast')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_ao')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_ao_with_toast')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_co')
group by segid = -1, relname, classify_age(age);
-- Vacuum. This should advance relfrozenxid on all the tables.
vacuum test_table_heap;
vacuum test_table_heap_with_toast;
vacuum test_table_ao;
vacuum test_table_ao_with_toast;
vacuum test_table_co;
-- Check table ages.
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_heap')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_heap_with_toast')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_ao')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_ao_with_toast')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_co')
group by segid = -1, relname, classify_age(age);
-- Repeat the tests on a table that has been inserted to, but all the rows
-- have been deleted.
INSERT INTO test_table_heap select i, i*2 from generate_series(1, 20)i;
INSERT INTO test_table_heap_with_toast select i, i*2, i*5 from generate_series(1, 20)i;
INSERT INTO test_table_ao select i, i*2 from generate_series(1, 20)i;
INSERT INTO test_table_ao_with_toast select i, i*2, i*5 from generate_series(1, 20)i;
INSERT INTO test_table_co select i, i*2 from generate_series(1, 20)i;
delete from test_table_heap;
delete from test_table_heap_with_toast;
delete from test_table_ao;
delete from test_table_ao_with_toast;
delete from test_table_co;
select count(*) from test_table_heap;
select count(*) from test_table_heap_with_toast;
select count(*) from test_table_ao;
select count(*) from test_table_ao_with_toast;
select count(*) from test_table_co;
select advance_xid_counter(500);
vacuum freeze test_table_heap;
vacuum freeze test_table_heap_with_toast;
vacuum freeze test_table_ao;
vacuum freeze test_table_ao_with_toast;
vacuum freeze test_table_co;
-- Check table ages again. Because we used VACUUM FREEZE, they should be
-- very young now.
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_heap')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_heap_with_toast')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_ao')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_ao_with_toast')
group by segid = -1, relname, classify_age(age);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_co')
group by segid = -1, relname, classify_age(age);