數(shù)據(jù)膨脹診斷
AnalyticDB PostgreSQL版提供的智能診斷數(shù)據(jù)膨脹功能,可以定期自動(dòng)診斷數(shù)據(jù)庫內(nèi)的所有表,并生成診斷信息表。您可以通過診斷信息表,查看表的膨脹情況并獲得相應(yīng)的處理建議(如執(zhí)行VACUUM或VACUUM FULL操作)。
注意事項(xiàng)
智能診斷數(shù)據(jù)膨脹功能僅支持存儲(chǔ)彈性模式實(shí)例,且內(nèi)核版本須滿足以下條件:
AnalyticDB PostgreSQL 6.0版實(shí)例為v6.3.10.0及以上。
AnalyticDB PostgreSQL 7.0版實(shí)例為v7.0.4.0及以上。
如何查看和升級(jí)內(nèi)核版本,請參見查看內(nèi)核小版本和版本升級(jí)。
智能診斷數(shù)據(jù)膨脹功能在后臺(tái)啟動(dòng)是以庫為維度進(jìn)行診斷,但不包括系統(tǒng)庫(postgres、template0、template1、adbpgadmin和aurora 5個(gè)系統(tǒng)庫),建議您將業(yè)務(wù)數(shù)據(jù)放在新建庫中,不要將數(shù)據(jù)放在上述5個(gè)系統(tǒng)庫中,否則無法診斷數(shù)據(jù)。
智能診斷數(shù)據(jù)膨脹功能在用戶庫中會(huì)掃描每張表(不包括臨時(shí)表和unlogged表),但為了兼顧掃描的速度和診斷的意義,默認(rèn)情況下,數(shù)據(jù)量小于1 GB的表會(huì)被過濾。如需調(diào)整該閾值,請參見設(shè)置數(shù)據(jù)量閾值。
智能診斷功能會(huì)定期自動(dòng)診斷實(shí)例的每個(gè)用戶庫,定期啟動(dòng)的時(shí)間是每隔一個(gè)小時(shí),且在整點(diǎn)啟動(dòng)。例如,5點(diǎn)啟動(dòng)自動(dòng)診斷功能后,下個(gè)啟動(dòng)點(diǎn)時(shí)間是6點(diǎn)整。
為何會(huì)數(shù)據(jù)膨脹
數(shù)據(jù)膨脹是對表中未使用空間量和死亡元組占用空間量的度量。AnalyticDB PostgreSQL版數(shù)據(jù)庫使用PostgreSQL多版本并發(fā)控制(MVCC)來管理并發(fā)事務(wù),底層表的儲(chǔ)存數(shù)據(jù)被劃分成固定大小的Page,默認(rèn)Page大小為32 KB。每個(gè)Page包含Header(數(shù)據(jù)頭)、Item pointer array(指向內(nèi)部數(shù)據(jù)的指針數(shù)組)、Unused space(未使用空間量)和Tuples(數(shù)據(jù)元組)。
INSERT數(shù)據(jù)時(shí),會(huì)從Page的未使用空間中分配新的Tuple。如果當(dāng)前Page的未使用空間不足時(shí),會(huì)分配新的Page來存放寫入的數(shù)據(jù)。
DELETE數(shù)據(jù)時(shí),數(shù)據(jù)不會(huì)從Page內(nèi)部真正刪除,只是標(biāo)記成死亡元組(Dead Tuple)。這些死亡元組依然占據(jù)著空間,會(huì)導(dǎo)致數(shù)據(jù)膨脹。
UPDATE數(shù)據(jù)時(shí),由于多版本并發(fā)控制機(jī)制,數(shù)據(jù)不會(huì)在原地更新,而是將原來的Tuple標(biāo)記成Dead Tuple,再插入New Tuple來達(dá)到數(shù)據(jù)更新的目的。因此,UPDATE操作也會(huì)造成數(shù)據(jù)表膨脹。
查看數(shù)據(jù)膨脹
智能診斷功能的診斷信息存儲(chǔ)在adbpg_toolkit.diag_bloat_tables
表中。
診斷信息表
diag_bloat_tables
中的數(shù)據(jù)是按照ORDER BY bloat_coeff desc, real_size DESC
排序的,即膨脹率越大的表越靠前。如果兩個(gè)表的膨脹率相同時(shí),數(shù)據(jù)量大的表更靠前。診斷信息表內(nèi)部原理是基于PostgreSQL的Statistic Collector進(jìn)程的統(tǒng)計(jì)信息來進(jìn)行診斷的,Statistic Collector在PostgreSQL Server發(fā)生Crash時(shí)統(tǒng)計(jì)信息會(huì)重置(極小概率發(fā)生)。如果您發(fā)現(xiàn)診斷信息出現(xiàn)偏差時(shí),可以通過ANALYZE命令來重新采集統(tǒng)計(jì)信息。具體操作,請參見使用ANALYZE收集統(tǒng)計(jì)信息。
您可以通過以下兩種方式查看診斷信息。
控制臺(tái)查看診斷信息。具體操作,請參見數(shù)據(jù)膨脹、傾斜與索引統(tǒng)計(jì)。
執(zhí)行SQL語句查看診斷信息。SQL語句如下:
SELECT * FROM adbpg_toolkit.diag_bloat_tables;
表
diag_bloat_tables
各個(gè)字段的詳細(xì)說明如下:字段
類型
說明
schema_name
name (63-byte type for storing system identifiers)
表所在的Schema的名稱。
table_name
name
表名。
storage_type
text
表的存儲(chǔ)類型,例如堆表或AO表。
expect_size
bigint
表預(yù)期沒有膨脹的大小,單位為字節(jié)(Byte)。
real_size
bigint
表真正的大小,單位為字節(jié)(Byte)。
bloat_size
bigint
表膨脹的大小,單位為字節(jié)(Byte)。
bloat_coeff
bigint
表的膨脹率,取值范圍為0~100,單位為%。
suggest_action
text
診斷該表建議采取的動(dòng)作,取值如下:
空(不需要操作)
VACUUM
VACUUM FULL
last_vacuum
timestamp with time zone
最后一次手動(dòng)清理表的時(shí)間(不計(jì)算VACUUM FULL)。
diagnose_time
timestamp with time zone
診斷信息生成的時(shí)間。
您也可以添加過濾條件,查看指定Schema或指定表的數(shù)據(jù)膨脹情況,查詢語句如下:
查看指定Schema下所有表的數(shù)據(jù)膨脹情況:
SELECT * FROM adbpg_toolkit.diag_bloat_tables WHERE schema_name = '<Schema名稱>';
查看指定表的數(shù)據(jù)膨脹情況:
SELECT * FROM adbpg_toolkit.diag_bloat_tables WHERE table_name = '<Table名稱>';
手動(dòng)觸發(fā)數(shù)據(jù)膨脹診斷
智能診斷功能默認(rèn)在每個(gè)整點(diǎn)啟動(dòng)。如果您對某張表執(zhí)行了VACUUM或VACUUM FULL操作,需要立即查看操作后的效果,需要手動(dòng)觸發(fā)一次數(shù)據(jù)膨脹診斷。手動(dòng)觸發(fā)數(shù)據(jù)膨脹診斷的語句如下:
SELECT adbpg_toolkit.diagnose_bloat_tables();
設(shè)置數(shù)據(jù)量閾值
默認(rèn)情況下,智能診斷功能會(huì)過濾小于1 GB的表,如需調(diào)整過濾的表的閾值大小,可以通過如下語句進(jìn)行設(shè)置:
ALTER DATABASE <數(shù)據(jù)庫名稱> SET adb_diagnose_table_threshold_size to <表的數(shù)據(jù)量,單位為字節(jié)>;
例如,您需要診斷500 MB以上的表,示例語句如下:
ALTER DATABASE diagnose SET adb_diagnose_table_threshold_size to 536870912;
消除數(shù)據(jù)膨脹
隨著對表不斷進(jìn)行INSERT、DELETE或UPDATE操作,會(huì)積累大量Dead Tuple,占據(jù)大部分本可以用來存放數(shù)據(jù)的空間,使得Page中未使用空間減小,導(dǎo)致更多的Page被分配出來。當(dāng)Page被掃描時(shí),這些大量的Dead Tuple也會(huì)被掃描,從而增加了IO時(shí)間開銷。數(shù)據(jù)膨脹會(huì)帶來以下副作用:
導(dǎo)致表的存儲(chǔ)空間變大,浪費(fèi)存儲(chǔ)空間。
掃描IO開銷增加,導(dǎo)致查詢性能下降。
可通過VACUUM或VACUUM FULL命令消除數(shù)據(jù)膨脹。
執(zhí)行VACUUM命令刪除Dead Tuple來增加New Tuple可用的未使用空間量。
該方式的優(yōu)缺點(diǎn)如下:
優(yōu)點(diǎn):VACUUM相較于VACUUM FULL,在表的鎖粒度上更輕。VACUUM FULL需要ACCESS EXCLUSIVE鎖模式,該模式會(huì)阻塞其他任何對該表的類型操作。例如,執(zhí)行VACUUM FULL時(shí),SELECT操作也會(huì)被阻塞,即VACUUM FULL操作沒結(jié)束前,該表無法使用。
缺點(diǎn):VACUUM不會(huì)跨Page來整理表的存儲(chǔ)空間,無法減小磁盤上表的大小。
執(zhí)行VACUUM FULL命令刪除Dead Tuple來增加New Tuple可用的未使用空間量,同時(shí)跨Page來重新組織該表的儲(chǔ)存。
該方式的優(yōu)缺點(diǎn)如下:
優(yōu)點(diǎn):重新整理表數(shù)據(jù),讓表變成更緊湊,能減小之前由于Dead Tuple造成的表磁盤大小膨脹,可以減小磁盤上表的大小。
缺點(diǎn):重新整理表的Page儲(chǔ)存時(shí),需要ACCESS EXCLUSIVE鎖模式。該模式是排他模式,意味著其他任何對該表的操作都會(huì)被阻塞。同時(shí)由于該命令需要重新整理儲(chǔ)存的Page,所以它需要額外的儲(chǔ)存空間來儲(chǔ)存整理完的數(shù)據(jù)。