Postgresql
postgres 是否有效地重用已刪除行中的空間?
從文件:
在 PostgreSQL 中,行的 UPDATE 或 DELETE不會立即刪除該行的舊版本
$$ … $$但最終,任何事務都不再對過時或刪除的行版本感興趣。然後必須回收它佔用的空間以供新行重用,以避免磁碟空間需求的無限增長。這是通過執行 VACUUM來完成的。
當真空執行時,它是否通過重寫整個塊來有效地釋放被刪除行佔用的空間,或者只有當新行小於為它們讓路的已刪除行時才會出現塊碎片,新行適合可用的“洞” ?
VACUUM 重寫整個塊,有效地打包剩餘的行並留下一個連續的空閒空間塊(儘管這個空間沒有歸零,並且物理磁碟文件可能包含已刪除行的剩餘部分,當然這些剩餘部分對數據庫使用者)。
測試時間表:
--#psql postgres postgres select oid from pg_database where datname='postgres'; /* oid ------- 12035 */ create schema stack; set search_path=stack; create table foo(bar text); insert into stack.foo(bar) values('row 1'); insert into stack.foo(bar) values('row 2'); checkpoint; select * from foo; /* bar ------- row 1 row 2 */ select relfilenode from pg_class c join pg_namespace n on n.oid=c.relnamespace where nspname='stack' and relname='foo'; /* relfilenode ------------- 446488 */
表支持文件的物理內容:
xxd -a /var/lib/postgresql/9.3/main/base/12035/446488 0000000: 3800 0000 f093 9d83 0000 0000 2000 c01f 8........... ... 0000010: 0020 0420 0000 0000 e09f 3c00 c09f 3c00 . . ......<...<. 0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ * 0001fc0: 2176 4c14 0000 0000 0000 0000 0000 0000 !vL............. 0001fd0: 0200 0100 0208 1800 0d72 6f77 2032 0000 .........row 2.. <---- this is row 2 0001fe0: 2176 4c14 0000 0000 0000 0000 0000 0000 !vL............. 0001ff0: 0100 0100 0208 1800 0d72 6f77 2031 0000 .........row 1..
刪除和真空:
delete from foo where bar='row 1'; vacuum stack.foo; checkpoint;
表支持文件的物理內容:
xxd -a /var/lib/postgresql/9.3/main/base/12035/446488 0000000: 3800 0000 e8b5 9e83 0000 0500 2000 e01f 8........... ... 0000010: 0020 0420 0000 0000 0000 0000 e09f 3c00 . . ..........<. 0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ * 0001fc0: 2176 4c14 0000 0000 0000 0000 0000 0000 !vL............. 0001fd0: 0200 0100 0209 1800 0d72 6f77 2032 0000 .........row 2.. <---- this is free space 0001fe0: 2176 4c14 0000 0000 0000 0000 0000 0000 !vL............. 0001ff0: 0200 0100 0209 1800 0d72 6f77 2032 0000 .........row 2..
插入新行:
insert into stack.foo(bar) values('row 3'); checkpoint;
表支持文件的最終物理內容:
xxd -a /var/lib/postgresql/9.3/main/base/12035/446488 0000000: 3800 0000 c8ec 9e83 0000 0100 2000 c01f 8........... ... 0000010: 0020 0420 0000 0000 c09f 3c00 e09f 3c00 . . ......<...<. 0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ * 0001fc0: 2476 4c14 0000 0000 0000 0000 0000 0000 $vL............. 0001fd0: 0100 0100 0208 1800 0d72 6f77 2033 0000 .........row 3.. <---- this is row 3 0001fe0: 2176 4c14 0000 0000 0000 0000 0000 0000 !vL............. 0001ff0: 0200 0100 0209 1800 0d72 6f77 2032 0000 .........row 2..
清理:
drop schema stack cascade;