背景
1、産品的問題點
- 當表膨脹後普通的vacuum 無法回收已經占用的磁盤空間, (僅末尾空塊可從磁盤回收).
- 使用pg_repack或vacuum full(要鎖全表, 影響業務)回收磁盤占用的空間都需要額外的磁盤來臨時存儲重組後的資料.
2、問題點背後涉及的技術原理
- 普通的vacuum隻能truncate資料檔案末尾的空block, 是以我們可以将末尾的tuple移動到前面, 進而從磁盤回收末尾的block.
- 為什麼隻能truncate資料檔案末尾的空block?
-
- 因為非末尾的block被清掉之後尋址會發生變化, 例如第二個資料塊回收掉, 那麼2号資料塊後面的資料塊的編号都需要減1, 而索引的ctid指向的是原來的編号, 是以會導緻索引不準确. 當然, 我們可以增加1個bitmap檔案存儲真空塊(已回收的中間blockid, 尋址時通過這個資料再進行block定位), 但是會增加尋址的複雜度, 性能可能下降.
3、這個問題将影響哪些行業以及業務場景
- 頻繁更新的業務
- 《DB吐槽大會,第1期 - PG MVCC》
4、會導緻什麼問題?
- 如果你的環境已經拮據到無法提供額外的磁盤空間來存放整理後的資料, 那麼将無法實施回收操作.
5、業務上應該如何避免這個坑
6、業務上避免這個坑犧牲了什麼, 會引入什麼新的問題
- 維護成本較高, 一般使用者不懂.
7、資料庫未來産品疊代如何修複這個坑
- 希望核心層支援行遷移功能.
- 希望核心層支援線上收縮表空間功能: pg_repack.
- 希望盡量避免膨脹.