Postgresql
在 VACUUM FULL (postgres) 之前檢查空間可用性
在大表上執行 VACUUM FULL之前,是否可以檢查表空間中有多少可重用空間?
我有一個大的 postgres 表(大約 20G),偶爾會出現 VACUUM FULL。該驅動器上的可用空間在 15-25 GB 之間變化。在嘗試每次清理之前,我會記錄表大小(使用 postgres 查詢)和可用磁碟空間(使用 OS 工具)。
我知道 VACUUM FULL 需要製作表格的完整副本。因此,如果表是 20G,則需要 20G 的可用空間。
有時表是 20G,只有 15G 的作業系統空間可用,而 Vacuum 可以工作。我猜需要的額外 5G 是從表空間內部恢復的。
其他時候由於空間不足,真空會失敗,我猜在這些情況下,在表空間中找不到所需的額外 5G。
我希望能夠事先檢查我是否有足夠的空間容納 VACUUM FULL,我該怎麼做?我知道表有多大,我知道作業系統有多少可用空間,但我不知道表空間中有多少可回收空間。
首先,我建議使用pgstattuple來獲取元組級別的統計資訊。
pgstattuple返回關係的物理長度、“死”元組的百分比和其他資訊。這可以幫助使用者確定是否 需要真空。
例如:
create extension pgstattuple ; create table my_table ( id int , name text); insert into my_table select a, md5(a::text) from generate_series(1, 1e7)a; -- size of my_table Schema | Name | Type | Owner | Size | Description --------+----------+-------+----------+--------+------------- public | my_table | table | postgres | 651 MB | -- dead_tuple_percent = 0, pgstattuple will not lock your table SELECT tuple_percent, dead_tuple_count, dead_tuple_percent, free_space, free_percent FROM pgstattuple('my_table'); tuple_percent | dead_tuple_count | dead_tuple_percent | free_space | free_percent ---------------+------------------+--------------------+------------+-------------- 89.35 | 0 | 0 | 338776 | 0.05 -- let update 50% rows update my_table set name = name || id where id < 5000000; -- now, dead_tuple_percent = 28.63% tuple_percent | dead_tuple_count | dead_tuple_percent | free_space | free_percent ---------------+------------------+--------------------+------------+-------------- 60.43 | 4999999 | 28.63 | 1834236 | 0.17 -- size of my_table has increased Schema | Name | Type | Owner | Size | Description --------+----------+-------+----------+---------+------------- public | my_table | table | postgres | 1016 MB | -- try to vacuum full vacuum full my_table; -- after that, dead_tuple_percent = 0 and size of my_table has reduced tuple_percent | dead_tuple_count | dead_tuple_percent | free_space | free_percent ---------------+------------------+--------------------+------------+-------------- 88.92 | 0 | 0 | 1664780 | 0.23 Schema | Name | Type | Owner | Size | Description --------+----------+-------+----------+------------+------------- public | my_table | table | postgres | 691 MB |
其次,如果您在生產環境中,我建議您使用pg_repack來回收磁碟而不鎖定您的表。
pg_repack 是一個 PostgreSQL 擴展,可讓您從表和索引中刪除膨脹,並可選擇恢復聚集索引的物理順序。與 CLUSTER 和 VACUUM FULL 不同,它線上工作,在處理過程中不會對已處理的表持有獨占鎖。pg_repack 啟動效率很高,性能與直接使用 CLUSTER 相當。
例如:
/usr/pgsql-11/bin/pg_repack -d postgres -U postgres -n -t my_table &