VACUUM是PolarDB PostgreSQL版中一個非常重要的維護命令,主要用於清理和最佳化資料庫。其主要功能可概括為:回收儲存空間、防止事務ID回卷、更新統計資料以及提高並發效能。通過合理使用VACUUM,可以確保資料庫的高效運行和長期穩定性。 然而,在使用VACUUM命令時需保持謹慎,對資料庫效能的影響顯著,不當操作可能導致負面效果。本文分析VACUUM使用情境中常見問題,並介紹了PolarDB PostgreSQL版相應的最佳化措施。
VACUUM大表清理
問題描述與分析
資料庫大表通常佔用多個磁碟塊,進行掃描和清理操作時會產生大量的I/O操作,VACUUM的效能可能受到多種因素的限制,從而導致清理速度減緩。如果由於清理速度的原因無法及時清除垃圾資料,膨脹的大表將導致需要掃描的資料頁增多,進一步延長清理時間。
在面對大表的VACUUM操作緩慢時,常規的處理方法包括資料分布調整和參數最佳化。然而,這些手段對清理效率的提升效果較為有限。
最佳化
PolarDB PostgreSQL版的VACUUM採用非同步預讀的方法,在對大表進行清理時,通過並發I/O方式顯著提高最耗時的I/O部分的處理速度。具體而言,它將清理過程中順序讀取的塊以分組方式提前發送給並發I/O背景工作處理序進行塊讀取,從而實現了超過兩倍的清理加速。
VACUUM流程通過最佳化死元組(
Deadtuple)緩衝結構,實現快速查詢從而加快清理速度。
資料庫年齡回卷
問題描述及分析
PostgreSQL資料庫採用32位事務ID(XID)實現多版本並發控制(MVCC)。由於XID的數值空間有限(最大值為4,294,967,295),系統通過事務年齡回卷機制來防止因XID耗盡而導致的資料不可用風險。當資料庫中最舊活躍事務與最新事務的年齡差超過21億(約佔32位空間的一半)時,系統將進入事務回卷保護狀態。回捲髮生後,資料庫將宕機且不再接受新事務的寫入,此時通常需要以單一使用者模式執行VACUUM以進行修複。
最佳化
為了有效應對事務ID回卷問題,PolarDB PostgreSQL版引入了自訂控制參數,包括回卷預觸發、回卷預警以及superuser規避參數。通過預留部分事務ID,以最大限度降低因事務ID耗盡導致的宕機風險。
回卷預觸發:預設預留一定數量的事務ID,即當事務ID數量即將耗盡時,提前觸發事務ID回卷。當事務ID達到預留限制,資料庫將停止分配事務ID。
回卷預警:事務ID回卷警示閾值,當事務ID使用量超過該閾值時,繼續執行任何使用事務ID的SQL將會觸發
WARNING層級警示,提示即將觸發事務ID回卷。superuser規避參數:當觸發事務ID回卷後,superuser可以額外使用的事務ID數量。此時,superuser可以繼續使用事務ID,但會提示superuser需要在對應的資料庫中執行VACUUM FREEZE進行事務ID回收。
VACUUM TRUNCATE鎖競爭
問題描述與分析
VACUUM TRUNCATE是一種用於在VACUUM操作中釋放表末尾的空閑頁面(即不再使用的資料頁)並將這些頁面歸還給作業系統的機制。儘管該機制能夠有效減少表佔用的磁碟空間,但在實際應用中,常常引發一些顯著問題:鎖競爭和阻塞。
競爭是由於在截斷表末尾空白頁時,系統需要為表加最進階別的獨佔鎖定,這將導致以下問題:
讀寫操作被阻塞:在加鎖期間,所有對錶的讀寫操作(包括
SELECT語句)都會被阻塞,無法正常執行。DDL操作無法執行:與表結構相關的DDL操作(如添加索引、修改表結構等)在此期間也無法執行。
特別是在對高頻寫入的大表執行操作時,可能導致業務中斷,嚴重影響系統效能和可用性。常規最佳化手段主要為調整Truncate觸發參數。
最佳化
為避免VACUUM TRUNCATE帶來的鎖競爭問題,PolarDB PostgreSQL版採取了以下最佳化措施:
最佳化I/O讀取效率:採用非同步並行I/O技術,顯著減少TRUNCATE操作中I/O讀取階段的耗時,提升整體操作效率。
TRUNCATE耗時控制:支援自訂TRUNCATE階段處理時間長度。通過調節鎖表時間,可手動控制VACUUM TRUNCATE操作,避免與業務處理和VACUUM操作發生衝突,保障商務持續性。
可維護視窗配置:支援設定可維護視窗。可根據業務需求將可維護視窗設定在業務低峰期,系統自動在視窗期對錶執行VACUUM操作。能夠有效減少對業務高峰期的影響,提升系統穩定性與可靠性。