為什么vacuum后表還是繼續膨脹?

      網友投稿 727 2025-03-31

      vacuum簡介 :


      對于Gaussdb中的行存表,在更新元組或者刪除元組后,舊版本的數據仍然存在,僅在元組頭信息中標記了刪除或更新的事務號(xmax)。對于更新和刪除操作頻繁的表,會存在大量垃圾數據,導致磁盤空間的浪費和查詢掃描時額外的IO開銷,需要定期執行清理操作(vacuum)來控制行存表以及表上索引的膨脹。

      vacuum 操作的內部原理:

      Vacuum 的主要步驟:

      移除死亡元組并對滿足條件的老元組執行frozen操作。

      移除指向死亡元組的索引元組,更新對應表的fsm 和 vm 文件

      FSM: free space map 空閑空間映射文件,插入數據時會根據該文件來選擇合適的page.

      VM: visibility map 可見性映射文件,后續vacuum時會根據該文件來選擇是否掃描某個page,提高vacuum效率;同時在進行index-only-scan時也會使用該文件來提高可見性判斷的效率)。

      更新統計數據pg_stat_all_tables。 Linepointer 不會被移除,用于在之后復用。

      示意圖如下:

      為什么vacuum后表還是繼續膨脹?

      vacuum 之前

      vacuum 之后

      為什么vacuum后表還是繼續膨脹

      Oldestxmin的推進

      vacuum 只能清理掉當前全局存活的最老事務(OldestXmin)之前的事務所產生的垃圾數據,所以如果仍然存在老事務的話(比如長事務或者長sql的存在),新事務所產生的垃圾數據并不會被vacuum立即清理。例如:

      會話1:新建表row_tbl并插入一條數據,起一個事務先不提交

      gaussdb=# create table row_tbl(a int, b int); CREATE TABLE gaussdb=# insert into row_tbl values(1,1); INSERT 0 1 gaussdb=# begin; BEGIN gaussdb=# SELECT txid_current_snapshot(); txid_current_snapshot ----------------------- 210115:210115: (1 row) gaussdb=# SELECT txid_current(); txid_current -------------- 210115 (1 row)

      會話2:刪除數據后做vacuum清理操作,再次插入數據,數據也沒有復用之前空間;查詢視圖可以發現垃圾數據并沒有被清理掉。

      gaussdb=# select ctid,* from row_tbl; ctid | a | b -------+---+--- (0,1) | 1 | 1 (1 row) gaussdb=# delete row_tbl; DELETE 1 gaussdb=# SELECT txid_current_snapshot(); txid_current_snapshot ----------------------- 210115:210122: (1 row) gaussdb=# vacuum row_tbl; VACUUM gaussdb=# insert into row_tbl values(2,2); INSERT 0 1 gaussdb=# select ctid,* from row_tbl; ctid | a | b -------+---+--- (0,2) | 2 | 2 (1 row) gaussdb=# select n_dead_tup, last_vacuum from pg_stat_all_tables where relname='row_tbl'; n_dead_tup | last_vacuum ------------+------------------------------- 1 | 2021-06-10 20:04:58.987631+08 (1 row)

      會話1:將會話1的事務結束再執行vacuum,查詢視圖可以發現沒有死亡元組,插入數據可以發現復用了舊的空間(即ctid是(0,1)的空間)。

      gaussdb=# SELECT txid_current_snapshot(); txid_current_snapshot ----------------------- 210136:210136: (1 row) gaussdb=# vacuum row_tbl; VACUUM gaussdb=# select n_dead_tup, last_vacuum from pg_stat_all_tables where relname='row_tbl'; n_dead_tup | last_vacuum ------------+------------------------------- 0 | 2021-06-10 20:09:10.516564+08 (1 row) gaussdb=# insert into row_tbl values(3,3); INSERT 0 1 gaussdb=# select ctid,* from row_tbl; ctid | a | b -------+---+--- (0,1) | 3 | 3 (0,2) | 2 | 2 (2 rows)

      LinePointer狀態還未處于unused

      元組被刪除后,只有當vacuum將元組的LinePointer(或者叫item pointer, 指向具體的元組)置為LP_UNUSED狀態后,該LinePointer才有可能在新插入數據時復用。

      Fsm還未生成

      插入數據時,依賴fsm文件來選擇可用的page,如果fsm沒有生成則會導致使用新的page而不是復用舊的。

      批量導入

      在舊版本Gaussdb中,對表進行批量插入數據的操作時,會直接申請新的page來插入數據。所以在某些場景下雖然vacuum后清理了臟數據,但由于業務場景以批量插入為主,導致vacuum對膨脹的控制效果并不理想。目前已經支持批量插入數據時對空間的復用。

      一些建議與總結

      盡量避免長事務,可以通過視圖pg_running_xacts查看是否有老事務沒有結束或者兩階段事務殘留

      定期做vacuum來及時回收垃圾空間

      對于已經膨脹的索引可以通過reindex來縮小大小。

      vacuum能清理垃圾數據,但無法將這些空間還給操作系統,對于已經膨脹的表只能通過vacuum full來縮小大小。

      想了解GuassDB(DWS)更多信息,歡迎微信搜索“GaussDB DWS”關注微信公眾號,和您分享最新最全的PB級數倉黑科技~

      EI智能體 Gauss AP 數據倉庫服務 GaussDB(DWS)

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:微信辦公表格軟件推薦蘋果(微信辦公表格軟件推薦蘋果手機)
      下一篇:扒一扒ELF文件
      相關文章
      国产色在线|亚洲| 久久精品国产亚洲av麻豆图片| 亚洲日本va一区二区三区| 亚洲国产高清在线精品一区| 亚洲乱码精品久久久久..| 亚洲国产成人精品久久久国产成人一区二区三区综 | 亚洲人AV在线无码影院观看| 亚洲午夜电影在线观看高清| 亚洲日本在线观看网址| 亚洲第一精品电影网| 亚洲精品午夜视频| 亚洲成AV人综合在线观看| 亚洲国产午夜电影在线入口| 亚洲伊人久久大香线蕉在观| 亚洲国产精品成人综合久久久| 亚洲日韩在线视频| 性xxxx黑人与亚洲| 亚洲乱码中文字幕在线| 亚洲s码欧洲m码吹潮| 国产亚洲福利精品一区二区| 亚洲福利视频一区二区| 亚洲高清国产拍精品青青草原 | 久久久久无码精品亚洲日韩| 亚洲AV人无码综合在线观看| 18亚洲男同志videos网站| 亚洲在成人网在线看| 色婷五月综激情亚洲综合| 亚洲色欲啪啪久久WWW综合网| 亚洲老熟女五十路老熟女bbw| 日韩欧美亚洲国产精品字幕久久久| 国产精品亚洲专区无码唯爱网| 午夜亚洲乱码伦小说区69堂| 亚洲一区精品伊人久久伊人| 亚洲性猛交XXXX| 日木av无码专区亚洲av毛片| 亚洲免费人成视频观看| 亚洲乱亚洲乱妇24p| 亚洲情a成黄在线观看| 亚洲va中文字幕无码久久不卡| 久久久久亚洲精品无码蜜桃| 久久久久se色偷偷亚洲精品av|