1. 程式人生 > >PostgreSQL vacuum_freeze_table_age和vacuum_freeze_min_age理解

PostgreSQL vacuum_freeze_table_age和vacuum_freeze_min_age理解

  • vacuum_freeze_table_age : 如果pg_class.relfrozenxid的事務年齡大於該引數的值,那麼PostgreSQL會在該表上自動vacuum執行全表掃描,預設是150億個事務。 因為VACUUM通常會忽略沒有任何死行版本頁面,但這些頁面可能仍然有舊XID值的行版本。為了確保所有舊的XID已被FrozenXID替換, 需要全表掃描。

  • vacuum_freeze_min_age : 指定VACUUM在掃描一個表時用於判斷是否用FrozenXID 替換記錄的xmin欄位(在同一個事務中)。 預設值為5000萬。

理解vacuum_freeze_min_age引數:

1. 插入測試資料

postgres=# insert into tb9 select generate_series(1,5),'aa';
INSERT 0 5

postgres=# select xmin,age(xmin),xmax,* from tb9;
 xmin | age | xmax | id | name 
------+-----+------+----+------
 2523 |   1 |    0 |  1 | aa
 2523 |   1 |    0 |  2 | aa
 2523 |   1 |    0 |  3 | aa
 2523 |   1 |    0 |  4 | aa
 2523 |   1 |    0 |  5 | aa
(5 rows)

2. 手動設定vacuum_freeze_min_age 值

postgres=# set vacuum_freeze_min_age =10;
SET

  這個設定為10的意思是當age(xmin)大於等於10的時候,當執行vacuum操作的時候會將此時表中記錄的xmin置為特殊值FrozenXID。

  多次執行 select txid_current() 使得事務id增加。

postgres=# select txid_current();
 txid_current 
--------------
         2539
(1 row)

3. 檢視資料

postgres=# select xmin,age(xmin),xmax,* from tb9;
 xmin | age | xmax | id | name 
------+-----+------+----+------
2523 | 17 | 0 | 1 | aa 2523 | 17 | 0 | 2 | aa 2523 | 17 | 0 | 3 | aa 2523 | 17 | 0 | 4 | aa 2523 | 17 | 0 | 5 | aa (5 rows)

看到xmin的事務年齡已經是17。

4. 執行vacuum操作

postgres=# vacuum tb9;
VACUUM

5. 再次檢視資料

postgres=# select xmin,age(xmin),xmax,* from tb9;
 xmin |    age     | xmax | id | name 
------+------------+------+----+------
    2 | 2147483647 |    0 |  1 | aa
    2 | 2147483647 |    0 |  2 | aa
    2 | 2147483647 |    0 |  3 | aa
    2 | 2147483647 |    0 |  4 | aa
    2 | 2147483647 |    0 |  5 | aa
(5 rows)

  freeze後的tuple, xmin 變成了一個FrozenXID,這個XID不參與比較,始終認為這個ID比其他的XID老,所以用 age 去計算始終顯示 2147483647 。

說明:
  當沒有手動設定vacuum_freeze_min_age的值的時候,執行
vacuum freeze tb9;
強制使用freeze的效果是一樣的。