mirror of https://github.com/postgres/postgres
This feature was using a process local map to track the first few blocks in the relation. The map was reset each time we get the block with enough freespace. It was discussed that it would be better to track this map on a per-relation basis in relcache and then invalidate the same whenever vacuum frees up some space in the page or when FSM is created. The new design would be better both in terms of API design and performance. List of commits reverted, in reverse chronological order:pull/41/head06c8a5090e
Improve code comments inb0eaa4c51b
.13e8643bfc
During pg_upgrade, conditionally skip transfer of FSMs.6f918159a9
Add more tests for FSM.9c32e4c350
Clear the local map when not used.29d108cdec
Update the documentation for FSM behavior..08ecdfe7e5
Make FSM test portable.b0eaa4c51b
Avoid creation of the free space map for small heap relations. Discussion: https://postgr.es/m/20190416180452.3pm6uegx54iitbt5@alap3.anarazel.de
parent
af82f95abb
commit
7db0cde6b5
@ -1,73 +0,0 @@ |
||||
-- |
||||
-- 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); |
||||
-- Fill 3 blocks with one record each |
||||
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; |
||||
heap_nblocks | fsm_nblocks |
||||
--------------+------------- |
||||
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) |
||||
|
||||
-- Extend table with enough blocks to exceed the FSM threshold |
||||
DO $$ |
||||
DECLARE curtid tid; |
||||
num int; |
||||
BEGIN |
||||
num = 11; |
||||
LOOP |
||||
INSERT INTO fsm_check_size VALUES (num, 'b') RETURNING ctid INTO curtid; |
||||
EXIT WHEN curtid >= tid '(4, 0)'; |
||||
num = num + 1; |
||||
END LOOP; |
||||
END; |
||||
$$; |
||||
VACUUM fsm_check_size; |
||||
SELECT pg_relation_size('fsm_check_size', 'fsm') / :blocksize AS fsm_nblocks; |
||||
fsm_nblocks |
||||
------------- |
||||
3 |
||||
(1 row) |
||||
|
||||
-- Add long random string to extend TOAST table to 1 block |
||||
INSERT INTO fsm_check_size |
||||
VALUES(0, (SELECT string_agg(md5(chr(i)), '') |
||||
FROM generate_series(1, :blocksize / 100) i)); |
||||
VACUUM fsm_check_size; |
||||
SELECT pg_relation_size(reltoastrelid, 'main') / :blocksize AS toast_nblocks, |
||||
pg_relation_size(reltoastrelid, 'fsm') / :blocksize AS toast_fsm_nblocks |
||||
FROM pg_class WHERE relname = 'fsm_check_size'; |
||||
toast_nblocks | toast_fsm_nblocks |
||||
---------------+------------------- |
||||
1 | 0 |
||||
(1 row) |
||||
|
||||
DROP TABLE fsm_check_size; |
@ -1,66 +0,0 @@ |
||||
-- |
||||
-- 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); |
||||
|
||||
-- Fill 3 blocks with one record each |
||||
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; |
||||
SELECT pg_relation_size('fsm_check_size', 'main') / :blocksize AS heap_nblocks, |
||||
pg_relation_size('fsm_check_size', 'fsm') / :blocksize AS fsm_nblocks; |
||||
|
||||
-- Extend table with enough blocks to exceed the FSM threshold |
||||
DO $$ |
||||
DECLARE curtid tid; |
||||
num int; |
||||
BEGIN |
||||
num = 11; |
||||
LOOP |
||||
INSERT INTO fsm_check_size VALUES (num, 'b') RETURNING ctid INTO curtid; |
||||
EXIT WHEN curtid >= tid '(4, 0)'; |
||||
num = num + 1; |
||||
END LOOP; |
||||
END; |
||||
$$; |
||||
|
||||
VACUUM fsm_check_size; |
||||
SELECT pg_relation_size('fsm_check_size', 'fsm') / :blocksize AS fsm_nblocks; |
||||
|
||||
-- Add long random string to extend TOAST table to 1 block |
||||
INSERT INTO fsm_check_size |
||||
VALUES(0, (SELECT string_agg(md5(chr(i)), '') |
||||
FROM generate_series(1, :blocksize / 100) i)); |
||||
|
||||
VACUUM fsm_check_size; |
||||
SELECT pg_relation_size(reltoastrelid, 'main') / :blocksize AS toast_nblocks, |
||||
pg_relation_size(reltoastrelid, 'fsm') / :blocksize AS toast_fsm_nblocks |
||||
FROM pg_class WHERE relname = 'fsm_check_size'; |
||||
|
||||
DROP TABLE fsm_check_size; |
Loading…
Reference in new issue