Add more tests for FSM.

In commit b0eaa4c51b, we left out a test that used a vacuum to remove dead
rows as the behavior of test was not predictable.  This test has been
rewritten to use fillfactor instead to control free space.  Since we no
longer need to remove dead rows as part of the test, put the fsm regression
test in a parallel group.

Author: John Naylor
Reviewed-by: Amit Kapila
Discussion: https://postgr.es/m/CAA4eK1L=qWp_bJ5aTc9+fy4Ewx2LPaLWY-RbR4a60g_rupCKnQ@mail.gmail.com
This commit is contained in:
Amit Kapila 2019-03-12 08:14:28 +05:30
parent ce6afc6823
commit 6f918159a9
4 changed files with 77 additions and 33 deletions

View File

@ -1,15 +1,40 @@
-- --
-- Free Space Map test -- Free Space Map test
-- --
SELECT current_setting('block_size')::integer AS blocksize,
current_setting('block_size')::integer / 8 AS strsize
\gset
CREATE TABLE fsm_check_size (num int, str text); CREATE TABLE fsm_check_size (num int, str text);
-- With one block, there should be no FSM -- Fill 3 blocks with one record each
INSERT INTO fsm_check_size VALUES(1, 'a'); ALTER TABLE fsm_check_size SET (fillfactor=15);
INSERT INTO fsm_check_size SELECT i, rpad('', :strsize, 'a')
FROM generate_series(1,3) i;
-- There should be no FSM
VACUUM fsm_check_size; VACUUM fsm_check_size;
SELECT pg_relation_size('fsm_check_size', 'main') AS heap_size, SELECT pg_relation_size('fsm_check_size', 'main') / :blocksize AS heap_nblocks,
pg_relation_size('fsm_check_size', 'fsm') AS fsm_size; pg_relation_size('fsm_check_size', 'fsm') / :blocksize AS fsm_nblocks;
heap_size | fsm_size heap_nblocks | fsm_nblocks
-----------+---------- --------------+-------------
8192 | 0 3 | 0
(1 row)
-- The following operations are for testing the functionality of the local
-- in-memory map. In particular, we want to be able to insert into some
-- other block than the one at the end of the heap, without using a FSM.
-- Fill most of the last block
ALTER TABLE fsm_check_size SET (fillfactor=100);
INSERT INTO fsm_check_size SELECT i, rpad('', :strsize, 'a')
FROM generate_series(101,105) i;
-- Make sure records can go into any block but the last one
ALTER TABLE fsm_check_size SET (fillfactor=30);
-- Insert large record and make sure it does not cause the relation to extend
INSERT INTO fsm_check_size VALUES (111, rpad('', :strsize, 'a'));
VACUUM fsm_check_size;
SELECT pg_relation_size('fsm_check_size', 'main') / :blocksize AS heap_nblocks,
pg_relation_size('fsm_check_size', 'fsm') / :blocksize AS fsm_nblocks;
heap_nblocks | fsm_nblocks
--------------+-------------
3 | 0
(1 row) (1 row)
-- Extend table with enough blocks to exceed the FSM threshold -- Extend table with enough blocks to exceed the FSM threshold
@ -26,23 +51,23 @@ num = 11;
END; END;
$$; $$;
VACUUM fsm_check_size; VACUUM fsm_check_size;
SELECT pg_relation_size('fsm_check_size', 'fsm') AS fsm_size; SELECT pg_relation_size('fsm_check_size', 'fsm') / :blocksize AS fsm_nblocks;
fsm_size fsm_nblocks
---------- -------------
24576 3
(1 row) (1 row)
-- Add long random string to extend TOAST table to 1 block -- Add long random string to extend TOAST table to 1 block
INSERT INTO fsm_check_size INSERT INTO fsm_check_size
VALUES(0, (SELECT string_agg(md5(chr(i)), '') VALUES(0, (SELECT string_agg(md5(chr(i)), '')
FROM generate_series(1,100) i)); FROM generate_series(1, :blocksize / 100) i));
VACUUM fsm_check_size; VACUUM fsm_check_size;
SELECT pg_relation_size(reltoastrelid, 'main') AS toast_size, SELECT pg_relation_size(reltoastrelid, 'main') / :blocksize AS toast_nblocks,
pg_relation_size(reltoastrelid, 'fsm') AS toast_fsm_size pg_relation_size(reltoastrelid, 'fsm') / :blocksize AS toast_fsm_nblocks
FROM pg_class WHERE relname = 'fsm_check_size'; FROM pg_class WHERE relname = 'fsm_check_size';
toast_size | toast_fsm_size toast_nblocks | toast_fsm_nblocks
------------+---------------- ---------------+-------------------
8192 | 0 1 | 0
(1 row) (1 row)
DROP TABLE fsm_check_size; DROP TABLE fsm_check_size;

View File

@ -23,7 +23,7 @@ test: numerology
# ---------- # ----------
# The second group of parallel tests # The second group of parallel tests
# ---------- # ----------
test: point lseg line box path polygon circle date time timetz timestamp timestamptz interval inet macaddr macaddr8 tstypes test: point lseg line box path polygon circle date time timetz timestamp timestamptz interval inet macaddr macaddr8 tstypes fsm
# ---------- # ----------
# Another group of parallel tests # Another group of parallel tests
@ -68,12 +68,6 @@ test: create_aggregate create_function_3 create_cast constraints triggers inheri
# ---------- # ----------
test: sanity_check test: sanity_check
# ----------
# fsm does a delete followed by vacuum, and running it in parallel can prevent
# removal of rows.
# ----------
test: fsm
# ---------- # ----------
# Believe it or not, select creates a table, subsequent # Believe it or not, select creates a table, subsequent
# tests need. # tests need.

View File

@ -40,6 +40,7 @@ test: inet
test: macaddr test: macaddr
test: macaddr8 test: macaddr8
test: tstypes test: tstypes
test: fsm
test: geometry test: geometry
test: horology test: horology
test: regex test: regex
@ -81,7 +82,6 @@ test: roleattributes
test: create_am test: create_am
test: hash_func test: hash_func
test: sanity_check test: sanity_check
test: fsm
test: errors test: errors
test: select test: select
test: select_into test: select_into

View File

@ -1,15 +1,40 @@
-- --
-- Free Space Map test -- Free Space Map test
-- --
SELECT current_setting('block_size')::integer AS blocksize,
current_setting('block_size')::integer / 8 AS strsize
\gset
CREATE TABLE fsm_check_size (num int, str text); CREATE TABLE fsm_check_size (num int, str text);
-- With one block, there should be no FSM -- Fill 3 blocks with one record each
INSERT INTO fsm_check_size VALUES(1, 'a'); ALTER TABLE fsm_check_size SET (fillfactor=15);
INSERT INTO fsm_check_size SELECT i, rpad('', :strsize, 'a')
FROM generate_series(1,3) i;
-- There should be no FSM
VACUUM fsm_check_size;
SELECT pg_relation_size('fsm_check_size', 'main') / :blocksize AS heap_nblocks,
pg_relation_size('fsm_check_size', 'fsm') / :blocksize AS fsm_nblocks;
-- The following operations are for testing the functionality of the local
-- in-memory map. In particular, we want to be able to insert into some
-- other block than the one at the end of the heap, without using a FSM.
-- Fill most of the last block
ALTER TABLE fsm_check_size SET (fillfactor=100);
INSERT INTO fsm_check_size SELECT i, rpad('', :strsize, 'a')
FROM generate_series(101,105) i;
-- Make sure records can go into any block but the last one
ALTER TABLE fsm_check_size SET (fillfactor=30);
-- Insert large record and make sure it does not cause the relation to extend
INSERT INTO fsm_check_size VALUES (111, rpad('', :strsize, 'a'));
VACUUM fsm_check_size; VACUUM fsm_check_size;
SELECT pg_relation_size('fsm_check_size', 'main') AS heap_size, SELECT pg_relation_size('fsm_check_size', 'main') / :blocksize AS heap_nblocks,
pg_relation_size('fsm_check_size', 'fsm') AS fsm_size; pg_relation_size('fsm_check_size', 'fsm') / :blocksize AS fsm_nblocks;
-- Extend table with enough blocks to exceed the FSM threshold -- Extend table with enough blocks to exceed the FSM threshold
DO $$ DO $$
@ -26,16 +51,16 @@ END;
$$; $$;
VACUUM fsm_check_size; VACUUM fsm_check_size;
SELECT pg_relation_size('fsm_check_size', 'fsm') AS fsm_size; SELECT pg_relation_size('fsm_check_size', 'fsm') / :blocksize AS fsm_nblocks;
-- Add long random string to extend TOAST table to 1 block -- Add long random string to extend TOAST table to 1 block
INSERT INTO fsm_check_size INSERT INTO fsm_check_size
VALUES(0, (SELECT string_agg(md5(chr(i)), '') VALUES(0, (SELECT string_agg(md5(chr(i)), '')
FROM generate_series(1,100) i)); FROM generate_series(1, :blocksize / 100) i));
VACUUM fsm_check_size; VACUUM fsm_check_size;
SELECT pg_relation_size(reltoastrelid, 'main') AS toast_size, SELECT pg_relation_size(reltoastrelid, 'main') / :blocksize AS toast_nblocks,
pg_relation_size(reltoastrelid, 'fsm') AS toast_fsm_size pg_relation_size(reltoastrelid, 'fsm') / :blocksize AS toast_fsm_nblocks
FROM pg_class WHERE relname = 'fsm_check_size'; FROM pg_class WHERE relname = 'fsm_check_size';
DROP TABLE fsm_check_size; DROP TABLE fsm_check_size;