提交 7408fffc 编写于 作者: H Heikki Linnakangas

Rewrite TINC test for freezing auxiliary tables on an empty relation.

These tests test for an old bug, where vacuuming an empty AO relation would
not advance its relfrozenxid. Doesn't seem very likely for that particular
bug to reappear, but seems like a good idea to have some coverage for
freezing and relfrozenxid advancement. In this rewritten form, these tests
are fairly quick, too (1-2 seconds on my laptop).
上级 34d1ada7
-- 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 < 100 THEN 'very young'
WHEN $1 < 150 THEN 'young'
ELSE 'old' END;
$$ 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.
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 relstorage not in ('x','f','v')
and (relname like '%' || testrelid::oid || '%' or oid = testrelid::oid )
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 relstorage not in ('x','f','v')
and (relname like '%' || testrelid::oid || '%' or oid = testrelid::oid )
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 = 100;
create table test_table_heap (id int, col1 int) with (appendonly=false);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
create table test_table_heap_with_toast (id int, col1 int, col2 text) with (appendonly=false);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
create table test_table_ao (id int, col1 int) with (appendonly=true, orientation=row);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
create table test_table_ao_with_toast (id int, col1 int, col2 text) with (appendonly=true, orientation=row);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
create table test_table_co (id int, col1 int) with (appendonly=true, orientation=column);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
create table test_table_co_with_toast (id int, col1 int, col2 text) with (appendonly=true, orientation=column);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
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);
create index test_heap_co_wt_idx on test_table_co_with_toast 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);
advance_xid_counter
---------------------
(1 row)
-- 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);
is_master | relname | classify_age
-----------+-----------------+--------------
f | test_table_heap | old
t | test_table_heap | very young
(2 rows)
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);
is_master | relname | classify_age
-----------+----------------------------+--------------
f | pg_toast_<oid> | old
f | test_table_heap_with_toast | old
t | pg_toast_<oid> | very young
t | test_table_heap_with_toast | very young
(4 rows)
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);
is_master | relname | classify_age
-----------+--------------------+--------------
f | pg_aoblkdir_<oid> | old
f | pg_aoseg_<oid> | old
f | pg_aovisimap_<oid> | old
f | test_table_ao | old
t | pg_aoblkdir_<oid> | very young
t | pg_aoseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | test_table_ao | very young
(8 rows)
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);
is_master | relname | classify_age
-----------+--------------------------+--------------
f | pg_aoblkdir_<oid> | old
f | pg_aoseg_<oid> | old
f | pg_aovisimap_<oid> | old
f | pg_toast_<oid> | old
f | test_table_ao_with_toast | old
t | pg_aoblkdir_<oid> | very young
t | pg_aoseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | pg_toast_<oid> | very young
t | test_table_ao_with_toast | very young
(10 rows)
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);
is_master | relname | classify_age
-----------+--------------------+--------------
f | pg_aoblkdir_<oid> | old
f | pg_aocsseg_<oid> | old
f | pg_aovisimap_<oid> | old
f | test_table_co | old
t | pg_aoblkdir_<oid> | very young
t | pg_aocsseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | test_table_co | very young
(8 rows)
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_co_with_toast')
group by segid = -1, relname, classify_age(age);
is_master | relname | classify_age
-----------+--------------------------+--------------
f | pg_aoblkdir_<oid> | old
f | pg_aocsseg_<oid> | old
f | pg_aovisimap_<oid> | old
f | pg_toast_<oid> | old
f | test_table_co_with_toast | old
t | pg_aoblkdir_<oid> | very young
t | pg_aocsseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | pg_toast_<oid> | very young
t | test_table_co_with_toast | very young
(10 rows)
-- 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;
vacuum test_table_co_with_toast;
-- 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);
is_master | relname | classify_age
-----------+-----------------+--------------
f | test_table_heap | young
t | test_table_heap | very young
(2 rows)
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);
is_master | relname | classify_age
-----------+----------------------------+--------------
f | pg_toast_<oid> | young
f | test_table_heap_with_toast | young
t | pg_toast_<oid> | very young
t | test_table_heap_with_toast | very young
(4 rows)
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);
is_master | relname | classify_age
-----------+--------------------+--------------
f | pg_aoblkdir_<oid> | young
f | pg_aoseg_<oid> | young
f | pg_aovisimap_<oid> | young
f | test_table_ao | young
t | pg_aoblkdir_<oid> | very young
t | pg_aoseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | test_table_ao | very young
(8 rows)
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);
is_master | relname | classify_age
-----------+--------------------------+--------------
f | pg_aoblkdir_<oid> | young
f | pg_aoseg_<oid> | young
f | pg_aovisimap_<oid> | young
f | pg_toast_<oid> | young
f | test_table_ao_with_toast | young
t | pg_aoblkdir_<oid> | very young
t | pg_aoseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | pg_toast_<oid> | very young
t | test_table_ao_with_toast | very young
(10 rows)
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);
is_master | relname | classify_age
-----------+--------------------+--------------
f | pg_aoblkdir_<oid> | young
f | pg_aocsseg_<oid> | young
f | pg_aovisimap_<oid> | young
f | test_table_co | young
t | pg_aoblkdir_<oid> | very young
t | pg_aocsseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | test_table_co | very young
(8 rows)
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_co_with_toast')
group by segid = -1, relname, classify_age(age);
is_master | relname | classify_age
-----------+--------------------------+--------------
f | pg_aoblkdir_<oid> | young
f | pg_aocsseg_<oid> | young
f | pg_aovisimap_<oid> | young
f | pg_toast_<oid> | young
f | test_table_co_with_toast | young
t | pg_aoblkdir_<oid> | very young
t | pg_aocsseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | pg_toast_<oid> | very young
t | test_table_co_with_toast | very young
(10 rows)
-- 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, i*5 from generate_series(1, 20)i;
ERROR: INSERT has more expressions than target columns
INSERT INTO test_table_co_with_toast 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;
delete from test_table_co_with_toast;
select count(*) from test_table_heap;
count
-------
0
(1 row)
select count(*) from test_table_heap_with_toast;
count
-------
0
(1 row)
select count(*) from test_table_ao;
count
-------
0
(1 row)
select count(*) from test_table_ao_with_toast;
count
-------
0
(1 row)
select count(*) from test_table_co;
count
-------
0
(1 row)
select count(*) from test_table_co_with_toast;
count
-------
0
(1 row)
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;
vacuum freeze test_table_co_with_toast;
-- 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);
is_master | relname | classify_age
-----------+-----------------+--------------
f | test_table_heap | very young
t | test_table_heap | very young
(2 rows)
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);
is_master | relname | classify_age
-----------+----------------------------+--------------
f | pg_toast_<oid> | very young
f | test_table_heap_with_toast | very young
t | pg_toast_<oid> | very young
t | test_table_heap_with_toast | very young
(4 rows)
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);
is_master | relname | classify_age
-----------+--------------------+--------------
f | pg_aoblkdir_<oid> | very young
f | pg_aoseg_<oid> | very young
f | pg_aovisimap_<oid> | very young
f | test_table_ao | very young
t | pg_aoblkdir_<oid> | very young
t | pg_aoseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | test_table_ao | very young
(8 rows)
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);
is_master | relname | classify_age
-----------+--------------------------+--------------
f | pg_aoblkdir_<oid> | very young
f | pg_aoseg_<oid> | very young
f | pg_aovisimap_<oid> | very young
f | pg_toast_<oid> | very young
f | test_table_ao_with_toast | very young
t | pg_aoblkdir_<oid> | very young
t | pg_aoseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | pg_toast_<oid> | very young
t | test_table_ao_with_toast | very young
(10 rows)
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);
is_master | relname | classify_age
-----------+--------------------+--------------
f | pg_aoblkdir_<oid> | very young
f | pg_aocsseg_<oid> | very young
f | pg_aovisimap_<oid> | very young
f | test_table_co | very young
t | pg_aoblkdir_<oid> | very young
t | pg_aocsseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | test_table_co | very young
(8 rows)
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_co_with_toast')
group by segid = -1, relname, classify_age(age);
is_master | relname | classify_age
-----------+--------------------------+--------------
f | pg_aoblkdir_<oid> | very young
f | pg_aocsseg_<oid> | very young
f | pg_aovisimap_<oid> | very young
f | pg_toast_<oid> | very young
f | test_table_co_with_toast | very young
t | pg_aoblkdir_<oid> | very young
t | pg_aocsseg_<oid> | very young
t | pg_aovisimap_<oid> | very young
t | pg_toast_<oid> | very young
t | test_table_co_with_toast | very young
(10 rows)
......@@ -159,6 +159,7 @@ test: uao_ddl/alter_ao_part_exch_column uao_ddl/alter_ao_part_tables_row uao_ddl
test: uao_ddl/alter_drop_allcol_row uao_ddl/alter_drop_allcol_column uao_ddl/alter_rollback_row uao_ddl/alter_rollback_column uao_ddl/uao_allalter_row uao_ddl/uao_allalter_column uao_col/alter_ao_table_oid_column uao_row/alter_ao_table_oid_row
test: ao_locks
test: freeze_aux_tables
# These cannot run in parallel, because they check that VACUUM FULL shrinks table size.
# A concurrent session could hold back the xid horizon and prevent old tuples from being
......
-- 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 < 100 THEN 'very young'
WHEN $1 < 150 THEN 'young'
ELSE 'old' END;
$$ 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.
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 relstorage not in ('x','f','v')
and (relname like '%' || testrelid::oid || '%' or oid = testrelid::oid )
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 relstorage not in ('x','f','v')
and (relname like '%' || testrelid::oid || '%' or oid = testrelid::oid )
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 = 100;
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 table test_table_co_with_toast (id int, col1 int, col2 text) 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);
create index test_heap_co_wt_idx on test_table_co_with_toast 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);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_co_with_toast')
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;
vacuum test_table_co_with_toast;
-- 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);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_co_with_toast')
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, i*5 from generate_series(1, 20)i;
INSERT INTO test_table_co_with_toast 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;
delete from test_table_co_with_toast;
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 count(*) from test_table_co_with_toast;
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;
vacuum freeze test_table_co_with_toast;
-- 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);
select segid = -1 as is_master, relname, classify_age(age) from aux_rel_ages('test_table_co_with_toast')
group by segid = -1, relname, classify_age(age);
"""
Copyright (C) 2004-2015 Pivotal Software, Inc. All rights reserved.
This program and the accompanying materials are made available under
the terms of the under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import tinctest
from mpp.models import MPPTestCase
import time
from tinctest.lib import local_path, run_shell_command
from mpp.lib.PSQL import PSQL
class RelfrozenxidUpdateTestCase(MPPTestCase):
'''
@gucs gp_create_table_random_default_distribution=off
@product_version gpdb: [4.3.3-]
'''
#These tests verify if vacuum freeze correctly updates age of auxiliary tables along with the age of parent appendonly table
def run_validation(self):
relid_out = PSQL.run_sql_command("select oid from pg_class where relname='test_table';", flags ='-q -t')
relid_out = relid_out.replace("\n", "").strip()
#doing multiple selects to increase the age of the table
for x in range(0, 150):
PSQL.run_sql_command("select age(relfrozenxid) from gp_dist_random('pg_class') where relname = 'test_table'", flags ='-q -t')
PSQL.run_sql_command("drop table if exists table_master; \
create table table_master as select age(relfrozenxid), relname \
from pg_class \
where relkind in ('r','t','o','b','m') and relstorage not in ('x','f','v') and (relname like '%"+str(relid_out)+"%' or relname ='test_table' )", \
flags ='-q -t')
PSQL.run_sql_command("drop table if exists table_seg; \
create table table_seg as select age(relfrozenxid), relname \
from gp_dist_random('pg_class') \
where relkind in ('r','t','o','b','m') and relstorage not in ('x','f','v') and (relname like '%"+str(relid_out)+"%' or relname ='test_table' )", \
flags ='-q -t', out_file="debug.out")
count=PSQL.run_sql_command("select count(*) from table_master where age > 30", flags ='-q -t')
count=count.replace("\n", "").strip()
if int(count)== 0:
timestr = time.strftime("ages_from_master_%Y%m%d-%H%M%S.out")
out_file=local_path(timestr)
PSQL.run_sql_command("select * from table_master", flags ='-q -t', out_file=out_file)
self.fail("the age was not increased correctly. Refer %s" %out_file)
count=PSQL.run_sql_command("select count(*) from table_seg where age > 30", flags ='-q -t')
count=count.replace("\n", "").strip()
if int(count) == 0:
timestr = time.strftime("ages_from_seg_%Y%m%d-%H%M%S.out")
out_file=local_path(timestr)
PSQL.run_sql_command("select * from table_seg", flags ='-q -t', out_file=out_file)
self.fail("the age was not increased correctly. Refer %s" %out_file)
PSQL.run_sql_command("set vacuum_freeze_min_age = 30;", flags ='-q -t')
PSQL.run_sql_command("vacuum freeze test_table;", flags ='-q -t')
PSQL.run_sql_command("drop table if exists table_master; \
create table table_master as select age(relfrozenxid), relname \
from pg_class \
where relkind in ('r','t','o','b','m') and relstorage not in ('x','f','v') and (relname like '%"+str(relid_out)+"%' or relname ='test_table' )", \
flags ='-q -t')
PSQL.run_sql_command("drop table if exists table_seg; \
create table table_seg as select age(relfrozenxid), relname \
from gp_dist_random('pg_class') \
where relkind in ('r','t','o','b','m') and relstorage not in ('x','f','v') and (relname like '%"+str(relid_out)+"%' or relname ='test_table' )", \
flags ='-q -t', out_file="debug.out")
count=PSQL.run_sql_command("select count(*) from table_master where age > 30", flags ='-q -t')
count=count.replace("\n", "").strip()
if not(int(count)== 0):
timestr = time.strftime("ages_from_master_%Y%m%d-%H%M%S.out")
out_file=local_path(timestr)
PSQL.run_sql_command("select * from table_master", flags ='-q -t', out_file=out_file)
self.fail("vacuum did not happend correctly. Refer %s" %out_file)
count=PSQL.run_sql_command("select count(*) from table_seg where age > 30", flags ='-q -t')
count=count.replace("\n", "").strip()
if not(int(count) == 0):
timestr = time.strftime("ages_from_seg_%Y%m%d-%H%M%S.out")
out_file=local_path(timestr)
PSQL.run_sql_command("select * from table_seg", flags ='-q -t', out_file=out_file)
self.fail("vacuum did not happend correctly. Refer %s" %out_file)
def test_ao_notoast_empty(self):
PSQL.run_sql_file(local_path("workload_ao_notoast_empty.sql"), out_file=local_path("workload_ao_notoast_empty.out"))
self.run_validation()
#We perform insert, delete and vacuum before final validation to ensure that the table is empty again before validation
PSQL.run_sql_command("INSERT INTO test_table select i, i*2, i*5 from generate_series(1, 20)i;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("update_ao_notoast_empty.out"))
PSQL.run_sql_command("delete from test_table;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("delete_ao_notoast_empty.out"))
PSQL.run_sql_command("VACUUM;", flags ='-q -t', out_file=local_path("vac_ao_notoast_empty.out"))
self.run_validation()
def test_ao_toast_empty(self):
PSQL.run_sql_file(local_path("workload_ao_toast_empty.sql"), out_file=local_path("workload_ao_toast_empty.out"))
self.run_validation()
PSQL.run_sql_command("INSERT INTO test_table select i, i*2, i*5, CURRENT_TIMESTAMP from generate_series(1, 20)i;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("update_ao_toast_empty.out"))
PSQL.run_sql_command("delete from test_table;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("delete_ao_toast_empty.out"))
PSQL.run_sql_command("VACUUM;", flags ='-q -t', out_file=local_path("vac_ao_toast_empty.out"))
self.run_validation()
def test_ao_toast_update(self):
PSQL.run_sql_file(local_path("workload_ao_toast_update.sql"), out_file=local_path("workload_ao_toast_update.out"))
self.run_validation()
PSQL.run_sql_command("INSERT INTO test_table select i, i*2, i*5, CURRENT_TIMESTAMP from generate_series(1, 20)i;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("update_ao_toast_update.out"))
PSQL.run_sql_command("delete from test_table;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("delete_ao_toast_update.out"))
PSQL.run_sql_command("VACUUM;", flags ='-q -t', out_file=local_path("vac_ao_toast_update.out"))
self.run_validation()
def test_co_notoast_empty(self):
PSQL.run_sql_file(local_path("workload_co_notoast_empty.sql"), out_file=local_path("workload_co_notoast_empty.out"))
self.run_validation()
PSQL.run_sql_command("INSERT INTO test_table select i, i*2, i*5 from generate_series(1, 20)i;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("update_co_notoast_empty.out"))
PSQL.run_sql_command("delete from test_table;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("delete_co_notoast_empty.out"))
PSQL.run_sql_command("VACUUM;", flags ='-q -t', out_file=local_path("vac_co_notoast_empty.out"))
self.run_validation()
def test_co_toast_empty(self):
PSQL.run_sql_file(local_path("workload_co_toast_empty.sql"), out_file=local_path("workload_co_toast_empty.out"))
self.run_validation()
PSQL.run_sql_command("INSERT INTO test_table select i, i*2, i*5, CURRENT_TIMESTAMP from generate_series(1, 20)i;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("update_co_toast_empty.out"))
PSQL.run_sql_command("delete from test_table;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("delete_co_toast_empty.out"))
PSQL.run_sql_command("VACUUM;", flags ='-q -t', out_file=local_path("vac_co_toast_empty.out"))
self.run_validation()
def test_co_toast_update(self):
PSQL.run_sql_file(local_path("workload_co_toast_update.sql"), out_file=local_path("workload_co_toast_update.out"))
self.run_validation()
PSQL.run_sql_command("INSERT INTO test_table select i, i*2, i*5, CURRENT_TIMESTAMP from generate_series(1, 20)i;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("update_co_toast_update.out"))
PSQL.run_sql_command("delete from test_table;"
"select count(*) from test_table;", flags ='-q -t', out_file=local_path("delete_co_toast_update.out"))
PSQL.run_sql_command("VACUUM;", flags ='-q -t', out_file=local_path("vac_co_toast_update.out"))
self.run_validation()
-- start_ignore
SET gp_create_table_random_default_distribution=off;
-- end_ignore
drop table if exists test_table;
create table test_table (id int, col1 int, col2 int) with (appendonly=true);
drop index if exists index_24168;
create index index_24168 on test_table using btree(id);
-- start_ignore
SET gp_create_table_random_default_distribution=off;
-- end_ignore
drop table if exists test_table;
create table test_table (id int, col1 int, col2 int, name text) with (appendonly=true);
drop index if exists index_mpp24168;
create index index_mpp24168 on test_table using btree(id);
-- start_ignore
SET gp_create_table_random_default_distribution=off;
-- end_ignore
drop table if exists test_table;
create table test_table (id int, col1 int, col2 int, name text) with (appendonly=true);
drop index if exists index_mpp24168;
create index index_mpp24168 on test_table using btree(id);
INSERT INTO test_table select i, i*2, i*5, CURRENT_TIMESTAMP from generate_series(1, 20)i;
select count(*) from test_table;
update test_table set name ='NEW NAME' where id%3=0;
select count(*) from test_table where name='NEW NAME';
-- start_ignore
SET gp_create_table_random_default_distribution=off;
-- end_ignore
drop table if exists test_table;
create table test_table (id int, col1 int, col2 int) with (appendonly=true, orientation=column);
drop index if exists index_mpp24168;
create index index_mpp24168 on test_table using btree(id);
-- start_ignore
SET gp_create_table_random_default_distribution=off;
-- end_ignore
drop table if exists test_table;
create table test_table (id int, col1 int, col2 int, name text) with (appendonly=true, orientation=column);
drop index if exists index_mpp24168;
create index index_mpp24168 on test_table using btree(id);
-- start_ignore
SET gp_create_table_random_default_distribution=off;
-- end_ignore
drop table if exists test_table;
create table test_table (id int, col1 int, col2 int, name text) with (appendonly=true, orientation=column);
drop index if exists index_mpp24168;
create index index_mpp24168 on test_table using btree(id);
INSERT INTO test_table select i, i*2, i*5, CURRENT_TIMESTAMP from generate_series(1, 20)i;
select count(*) from test_table;
update test_table set name ='NEW NAME' where id%3=0;
select count(*) from test_table where name='NEW NAME';
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册