vacuum:該選項主要是清理數據庫表中的垃圾空間,該動作會消耗系統一定的資源,引起系統的IO上升,對有一定系統瓶頸來說容易造成堵塞,嚴重會把GP宕掉,造成數據庫瞬斷。一般不建議vacuum庫中全表,通常做法是 vacuum 指定的表。
GPDB 與PostgreSQL一樣,在執行delete語句時,並沒有將數據刪除,而是標誌爲刪。
執行update,只是將舊數據標記爲刪除,重新再插入一條新數據。
這樣如果一張表刪改的動作特別多,就會導致體積持續變大,比較浪費磁盤空間。
(delete或update操作的數據不會從真實的物理空間中移除,只是針對目標數據進行了標記,數據還是保留在了磁盤上,這樣做只是提升了操作效率。vacuum操作可以將磁盤中的此類空間釋放出來,所以對那些經常更新刪除的表做vacuum操作很有必要)
例:
- 創建測試表:
CREATE TABLE "public"."vacuum_test" (
"id" int4 NOT NULL,
"name" varchar(255) NOT NULL
);
- 插入測試數據
INSERT INTO vacuum_test select generate_series(1,100000) as id,random() as name;
- 查看錶大小:
select pg_relation_size('vacuum_test');
- 然後進行刪除操作:
DELETE from vacuum_test;
- 數據已經刪除,然後觀察磁盤空間。
大小沒有變化。
- 重新插入數據。
磁盤空間翻倍
- 更新操作
更新操作後空間繼續增長。此時就有一部分空空間爲標記的刪除數據沒有釋放。
- vacuum
執行後大小沒有變化,空間沒有釋放麼?
是的沒有釋放,因爲剛纔操作的空間不是末端數據,只有末端數據vacuum纔會歸還給操作系統,非末端位置,可以再次寫入覆蓋。vacuum full可以直接清除歸還操作系統。
- 重新插入數據(查看是否能覆蓋剛纔的空間)
INSERT INTO vacuum_test select generate_series(1,100000) as id,'77777' as name;
是的已經覆蓋掉了。
- 再次插入
INSERT INTO vacuum_test select generate_series(1,100000) as id,'88888' as name;
空間增加了。
- 這是刪除末端進行測試
DELETE from vacuum_test where name='88888';
然後vacuum 查看空間
空間釋放,印證末端問題。