資料庫就跟舊手機舊電腦一樣時間一久,
無用的垃圾會越來越多,
用越用慢,這時就需要來清理一下。
還記得前面章節在介紹 postgres mvcc 時,
修改刪除 rollback 都會在表上標記為 dead tuple,
其實那些資料都還是會在 table 中,這時我們就要透過 VACUUM 來做清理。
在 postgres 中,預設 table 的 autovacuum 是開啟的,
當 dead tuple 累積到一個閥值後,
將會自動下 VACUUM 語法,這就是我們所謂的 Autovacuum。
因 VACUUM 的操作,會使用到大量的 IO,
有時我們會希望在離峰時段自行用 cronjob 來執行 VACUUM 動作。
所以如果想建立一個沒有 autovacuum 的 table,可以這樣做。CREATE TABLE table1(col text) WITH (autovacuum_enabled = off);
先來看看做 VACUUM 前的大小
SELECT pg_size_pretty(pg_table_size('table1')) table_size;
-- 7112 kB
做 VACUUM 後的大小
VACUUM table1;
SELECT pg_size_pretty(pg_table_size('table1')) table_size;
-- 7120 kB
只有 7112 kB 減少一點點到 7120 kB,
單純 VACUUM 只有回收該 dead tuple 但並非真實的刪除該物理空間,
將會被新的資料重複利用,就像是留著殼一樣,等待被其他新資料使用。
若要徹底的刪除物理空間,我們可以透過 FULL VACUUM 的方式,讓空間完全讓出來。
VACUUM FULL table1;
SELECT pg_size_pretty(pg_table_size('table1')) table_size;
-- 3552 kB
可以看到從 7120kB 到了 3552kB,非常大的降幅,
不過 VACUUM FULL 將會使用互斥鎖,處理過程中將造成資料無法讀取。
經過一連串的新增修改刪除,index tree 也會隨之膨脹,造成許多 dead tuple 被標記為無效。
也因這些多餘的節點,造成 tree 變得更大更高,我們可以透過 ReIndex 的方式重新移除那些在 index 上的 dead tuple。
所以定期 REINDEX 其實是值得做的,REINDEX INDEX index_name;
直接 REINDEX 將會使用互斥鎖鎖定,將造成資料無法讀取。
如果想要使用共享鎖,可以加上 CONCURRENTLYREINDEX INDEX CONCURRENTLY index_name;
今天介紹了