1. 程式人生 > >autovacuum程序----資料架構師的PostgreSQL修煉

autovacuum程序----資料架構師的PostgreSQL修煉

1. 檢查autovacuum程序

  1. sherrywangs-MacBook-Pro:data postgres$ ps -fu postgres |grep autov  
  2.   502  3199  3192   0 Sun08PM ??         0:00.27 postgres: autovacuum launcher process  

這是一個可選程序預設在postgresql.conf中,autovacuum = on。

2. 理解vacuum

當從表中刪除某些記錄時,PostgreSQL並不會立即從資料檔案中刪除這些記錄,他們會被標記為刪除。

當更新某些記錄時,粗略看起來,像是執行了一次刪除和一次插入操作;老版本的記錄仍然留在系統中。

為什麼這麼做呢?

因為有一些正活躍的事務,希望看到它之前的資料。

這就是經典的MVCC(Multiversion Concurrent Control)技術,目的是提高併發度,讀操作不會阻塞寫操作,寫操作也不會阻止讀操作。

這樣會引入一個新問題,一段時間之後,有些死記錄變得無關緊要,因為已經沒有事務再想要檢視這些已經標記為刪除的記錄。

vacuum操作將對死記錄的空間進行標識,進而可以在表內重用,該操作不需要鎖定資料表。

vacuum full操作還會對死記錄進行移除,該操作需要表上的一個排它鎖。

3. vacuum實驗

3.1 建立新的資料庫vac和表myt,並檢視所佔磁碟空間

建立新資料庫vac:

  1. postgres=# create database vac;  
  2. CREATE DATABASE  

用oid2name那麼檢視vac的oid:
  1. postgres=# \! oid2name  
  2. Password:  
  3. All databases:  
  4.     Oid  Database Name  Tablespace  
  5. ----------------------------------  
  6.   12669       postgres  pg_default  
  7.   12668      template0  pg_default  
  8.       1      template1  pg_default  
  9.   16393            vac  pg_default  


連線到資料庫vac:
  1. postgres=# \c vac  
  2. You are now connected to database "vac" as user "postgres".  

建立表myt:
  1. vac=# create table myt(id integer);  
  2. CREATE TABLE  

表myt在磁碟上的檔名:
  1. vac=# select pg_relation_filepath('myt');  
  2.  pg_relation_filepath  
  3. ----------------------  
  4.  base/16393/16397  
  5. (1 row)  

表myt所佔磁碟空間為0:
  1. M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16397*  
  2. -rw-------  1 postgres  daemon  0 Sep 13 18:28 /PostgreSQL/9.6/data/base/16393/16397  

可以用更便捷的方法查詢表myt所佔磁碟空間:
  1. vac=# select pg_total_relation_size('myt');  
  2.  pg_total_relation_size  
  3. ------------------------  
  4.                       0  
  5. (1 row)  

向表myt插入100000行資料,檢視myt所佔用的磁碟空間:
  1. vac=# insert into myt select generate_series(1,100000);  
  2. INSERT 0 100000  
  3. vac=# select pg_total_relation_size('myt');  
  4.  pg_total_relation_size  
  5. ------------------------  
  6.                 3653632  
  7. (1 row)  
  1. M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16397*  
  2. -rw-------  1 postgres  daemon  3629056 Sep 13 18:47 /PostgreSQL/9.6/data/base/16393/16397  
  3. -rw-------  1 postgres  daemon    24576 Sep 13 18:46 /PostgreSQL/9.6/data/base/16393/16397_fsm  

刪除表myt中的一部分資料,檢視myt所佔用的磁碟空間:
  1. vac=# delete from myt where id>5 and id<10000;  
  2. DELETE 9994  
  3. vac=# delete from myt where id>5 and id<100000;  
  4. DELETE 90000  
  5. vac=# select pg_total_relation_size('myt');  
  6.  pg_total_relation_size  
  7. ------------------------  
  8.                 3653632  
  9. (1 row)  
  10. M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16397*  
  11. -rw-------  1 postgres  daemon  3629056 Sep 13 18:51 /PostgreSQL/9.6/data/base/16393/16397  
  12. -rw-------  1 postgres  daemon    24576 Sep 13 18:46 /PostgreSQL/9.6/data/base/16393/16397_fsm  

可以看到,刪除了9994行資料後,表myt所佔用的空間沒有減小

vacuum myt,檢視myt所佔用的磁碟空間:
  1. vac=# vacuum myt ;  
  2. VACUUM  
  3. vac=# select pg_total_relation_size('myt');  
  4.  pg_total_relation_size  
  5. ------------------------  
  6.                 3661824  
  7. (1 row)  
  8. M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16397*  
  9. -rw-------  1 postgres  daemon  3629056 Sep 13 18:51 /PostgreSQL/9.6/data/base/16393/16397  
  10. -rw-------  1 postgres  daemon    24576 Sep 13 18:46 /PostgreSQL/9.6/data/base/16393/16397_fsm  
  11. -rw-------  1 postgres  daemon     8192 Sep 13 18:52 /PostgreSQL/9.6/data/base/16393/16397_vm  

可以看到myt所佔用磁碟空間沒有顯著減小。
另外發現新增加了一個16397_vm的檔案,看來這個字尾_vm的檔案和vacuum有關。

vacuum full myt,檢視myt所佔用的磁碟空間:
  1. vac=# vacuum full myt ;  
  2. VACUUM  
  3. vac=# select pg_total_relation_size('myt');  
  4.  pg_total_relation_size  
  5. ------------------------  
  6.                    8192  
  7. (1 row)  
  8. vac=# select pg_relation_filepath('myt');  
  9.  pg_relation_filepath  
  10. ----------------------  
  11.  base/16393/16400  
  12. (1 row)  
  13. M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16400*  
  14. -rw-------  1 postgres  daemon  8192 Sep 13 18:56 /PostgreSQL/9.6/data/base/16393/16400  

可以發現,原來myt對應檔案16397內容被移動到新檔案16400,16397被清空,後續16397會被刪除。

4.Autovacuum

vacuum程序可以自動清理資料檔案,一般不推薦關閉autovacuum功能,因為vacuum會更新資料庫統計資訊,這些資訊對查詢計劃有幫助。