postgresql AutoVacuum系統自動清理進程

來源:互聯網
上載者:User

標籤:表示   方式   51cto   details   brief   conf   規則   ffffff   返回   

來源:50426692

《PostgreSQL資料庫核心分析》第2章PostgreSQL的體繫結構,本章從宏觀上對PostgreSQL的控制和處理流程進行了簡要介紹,說明了各個模組之間是如何協同工作,以使得整個資料庫系統能夠穩定、正確地處理使用者的各種操作和請求的。至於每個模組是如何各司其職,其內部具體是如何運作的,將會在後續的章節進行專門的介紹。本節為大家介紹AutoVacuum系統自動清理進程。

AD:51CTO 網+首屆APP創新評選大賽火暖開機——超百萬資源等你拿!

 

2.5.5  AutoVacuum系統自動清理進程

在PostgreSQL資料庫中,對錶元組的UPDATE或DELETE操作並未立即刪除舊版本的資料,表中的舊元組只是被標識為刪除狀態,並未立即釋放空間。這種處理對於擷取多版本並發控制是必要的,如果一個元組的版本仍有可能被其他事務看到,那麼就不能刪除元組的該版本。當事務提交後,到期元組版本將對事務不再有效,因而其佔據的空間必須回收以供其他新元組使用,以避免對磁碟空間增長的無休止的需求,此時對資料庫的清理工作通過運行VACUUM來實現。從PostgreSQL 8.1開始,PostgreSQL資料庫引入一個額外的可選輔助進程AutoVacuum(系統自動清理進程),自動執行VACUUM和ANALYZE命令,回收被標識為刪除狀態記錄的空間,更新表的統計資訊。

在PostgreSQL資料庫系統設定檔中,與系統自動清理相關的主要相關參數如下:

autovacuum:是否啟動系統自動清理功能,預設值為on。

autovacuum_max_workers:設定系統自動清理背景工作處理序的最大數量。

autovacuum_naptime:設定兩次系統自動清理操作之間的間隔時間。

autovacuum_vacuum_threshold和autovacuum_analyze_threshold:設定當表上被更新的元組數的閾值超過這些閾值時分別需要執行vacuum和analyze。

autovacuum_vacuum_scale_factor和autovacuum_analyze_scale_factor:設定表大小的縮放係數。

autovacuum_freeze_max_age:設定需要強制對資料庫進行清理的XID上限值。

AutoVacuum系統自動清理進程中包含兩種不同的處理進程:AutoVacuum Launcher和AutoVacuum Worker。AutoVacuum Launcher進程為監控進程,用於收集資料庫運行資訊,根據資料庫選擇規則選中一個資料庫,並調度一個AutoVacuum Worker進程執行清理操作。在AutoVacuum Launcher進程中,選擇資料庫的規則如下:首先由於資料庫事務XID是32位整數且遞增分配,當超過最大值時會從頭開始計數使用,而事務XID的大小表示事務開始的時間,事務XID重新計數使用會使資料庫中部分交易資料丟失,因此當XID超過配置的autovacuum_freeze_max_age時,強制對該資料庫進行清理並更新事務XID;其次,若無強制清理操作,則選擇資料庫列表中最早未執行過自動清理操作的資料庫。Launcher進程會定時(或者被訊號驅動)選擇資料庫並調度Worker進程去執行清理工作。

AutoVacuum中的AutoVacuum Worker進程執行實際的清理任務,Launcher進程中維護有Worker進程列表。Worker進程列表由三種不同狀態的進程列表構成,即閒置Worker進程列表、正在啟動的Worker進程、運行中的Worker進程列表。Launcher進程在不同狀態之間的切換實現了Worker進程的調度工作。首先,在初始化階段建立的運行記憶體上下文中,建立長度為autovacuum_max_workers的空閑Worker進程描述資訊列表,而正在啟動Worker進程和運行中的Worker進程的列表被置為空白。如果Launcher進程需要一個Worker進程,空閑Worker進程列表不為空白且當前沒有正在啟動中的Worker進程,則開始一個啟動Worker進程的操作,即向Postmaster進程發送啟動訊息,從空閑Worker進程列表中取出一個進程描述資訊,設定為啟動中狀態。Launcher進程中只允許存在一個啟動中狀態的Worker進程,啟動中的Worker進程如果逾時(逾時時間由autovacuum_naptime設定)將被取消並重新開始啟動Worker進程的迴圈。如果Worker啟動成功,將啟動成功的Worker進程資訊添加到運行中的Worker進程列表中。運行中的Worker進程即串連上根據規則選中的資料庫。

在啟動成功的Worker進程串連資料庫成功後,將遍曆該資料庫中的表,根據對錶的清理規則選擇要執行的表和在該表上執行的操作。對錶的操作分為VACUUM和ANALYZE兩種,對選中的表如果上次VACUUM之後的到期元組的數量超過了“清理閾值”(vacuum threshold),那麼就清理該表,清理閾值是定義為:

清理閾值=清理基本閾值+清理縮放係數 *元組數

這裡的清理基本閾值是autovacuum_vacuum_threshold,清理的縮放係數是autovacuum_vacuum_scale_factor,元組的數目可以從統計收集器裡面擷取。這是一個部分精確的計數,由每次UPDATE和DELETE操作更新。

如果表上次被執行ANALYZE操作之後,其中到期元組的數量超過了“分析閾值”(analyze threshold),那麼就分析該表更新表統計資訊,分析閾值的定義與清理閾值相似,定義如下:

分析閾值=分析基本閾值+分析縮放係數 *元組數目

預設的閾值和伸縮係數都是從postgresql.conf裡面取得的。不過,我們可以以每個表獨立設定的方式覆蓋它,方法就是在系統資料表pg_autovacuum裡輸入資訊。pg_autovacuum表中一個元組可以用來記錄一個需要自動清理的表及其清理設定,AutoVacuum進程將使用其中的清理設定來清理該表。如果沒有特別設定該表的清理設定,AutoVacuum將使用全域設定。

1.AutoVacuum Launcher進程

通常,在入口函數StartAutoVacLauncher中執行fork操作建立Postmaster的子進程AutoVacuum Launcher,在新建立的子進程執行體中關閉從Postmaster進程中複製出的網路連接連接埠,同時進入進程AutoVacuum Launcher的執行體函數AutoVacLauncherMain,其處理流程2-12所示。

 
圖2-12  AutoVacuum Launcher處理流程

下面對其中幾個重要的步驟進行說明:

1)構建資料庫列表:調用函數rebuild_database_list完成,其步驟如下:

①建立一個Hash表,其中每一個元素代表一個資料庫,記錄了該資料庫的OID(adl_datid)、啟動worker的時間戳記(adl_next_worker)以及一個評分值(adl_score)。初始時該Hash表中沒有元素。

②將pg_database一般檔案(在PGDATA/global目錄下)中的資料庫構成一個鏈表,鏈表中的每一個節點代表一個資料庫,其中包括資料庫的OID、名稱、該資料庫的統計資訊等。

③調用pgstat_fetch_stat_dbentry來填充每個節點的統計資訊。

④對每一個統計資訊不為空白的資料庫,在Hash表中搜尋該資料庫,如果沒有找到則將該資料庫加入到Hash表中,並且將該資料庫的adl_score設定為該資料庫被加入到Hash表中時的順序號。

⑤將Hash表中的資料庫按照adl_score值升序的順序依次加入到全域變數DatabaseList所指向的鏈表中,並設定每一個資料庫的adl_next_worker值。其中第一個資料庫的adl_next_worker值設為目前時間,之後的每一個資料庫的adl_next_worker的值都比前一個增加millis_increment。millis_increment的值由autovacuum_naptime參數值除以Hash表中資料庫的個數來設定。

為什麼使用一般檔案?

在PostgreSQL的資料集簇中,提供了兩個一般檔案:pg_database和pg_auth。這兩個檔案分別記錄了pg_database系統資料表和pg_authid系統資料表中的部分資訊。如果有些還沒有啟動完畢的後台進程需要訪問這兩個系統資料表的內容,它們將會使用兩個一般檔案來進行資訊的擷取,這是由於進程還未完全啟動時是無法串連到資料庫並讀取相關係統表內容的。

在“構建資料庫列表”這一步驟由於並未串連到資料庫,因此只能用一般檔案來替代系統資料表pg_database。

2)設定進程休眠時間:根據空閑Worker和資料庫列表來計算休眠的時間,當所有Worker進程都在運行時要設定一個較長的休眠時間。而當Worker進程退出時可以喚醒休眠,同時休眠也可以被其他訊號中斷。

3)訊號處理分支中got_SIGUSR1訊號通知有Worker進程退出或者Postmaster通知有Worker啟動失敗。若是Postmaster通知Worker啟動失敗,則給Postmaster重新發送啟動Worker進程的訊息。

4)啟動Worker進程:如果當前有一個Worker正在啟動中,則再休眠一會兒等待該Worker啟動完成。如果可以開始啟動一個新的Worker,則進行以下判斷:

①如果資料庫列表不為空白,則檢查DatabaseList尾部資料庫的adl_next_worker參數,如果早於目前時間(表示該資料庫早就應該被處理)則啟動Worker進程。

②資料庫列表為空白時,立即啟動Worker進程。

2.AutoVacuum Worker進程

AutoVacuum Worker進程的入口為launch_worker函數,在該入口處調用do_start_worker建立worker進程,並且返回串連資料庫的OID。如果返回的OID為有效資料庫OID,則遍曆資料庫列表找到該OID對應的資料庫在資料庫列表中對應的節點,更新該節點的adl_next_worker域值,並將該節點移動到資料庫列表的頭部。如果遍曆資料庫列表沒有對應於該OID的節點,則調用rebuild_database_list重建資料庫列表。建立worker進程的函數體do_start_worker處理流程2-13所示。

 
圖2-13  AutoVacuum Worker進程處理流程

AutoVacuum Worker進程的處理流程和AutoVacuum Launcher進程的處理流程基本類似,選擇要進行清理的資料庫的規則如前所述:選中資料庫後遍曆資料庫中的表,根據表的統計資訊計算清理閾值和分析閾值,來確定是否要對錶執行相應的操作。

在系統進行自動清理的同時,使用者可以使用安裝目錄bin檔案夾下的vacuumdb或者vacuumlo工具對資料進行手動清理工作。vacuumdb工具清理資料庫並對資料庫執行分析操作,vacuumlo工具清理資料庫中無效的大對象。

postgresql AutoVacuum系統自動清理進程

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.