小美好在哪拍的:日常數據庫維護工作

来源:百度文库 编辑:中财网 时间:2024/05/05 09:33:35
日常數據庫維護工作
Table of Contents
21.1. 日常清理
21.1.1. 恢復磁盤空間
21.1.2. 更新規劃器統計
21.1.3. 避免事務 ID 重疊造成的問題
21.2. 經常重建索引
21.3. 日志文件維護

為了保持所安裝的 PostgreSQL 服務器平穩運行, 我們必須做一些日常性的維護工作。我們在這裡討論的這些工作都是經常重復的事情, 可以很容易地使用標準的 Unix 工具,比如cron 腳本來實現。 不過,設置合適的腳本以及檢查它們是否成功執行則是數據庫管理員的責任,

一件很明顯的維護工作就是經常性地創建數據的備份拷貝。 如果沒有最近的備份,那麼你就沒有從災難中恢復的機會(比如磁盤壞了,失火,誤刪了表等等)。 可以在PostgreSQL 裡面使用的備份和恢復機制在 Chapter 22 裡面有比較詳細的討論。

其它主要的維護範疇的工作包括週期性的 "vacuuming" (清理)數據庫。 這個工作我們在 Section 21.1裡討論。

其它需要週期性注意的東西是日志文件的管理。 我們在 Section 21.3 裡討論了這個問題。

PostgreSQL 和其它數據庫產品比較起來是低維護量的。 但是,適當在這些任務上放一些注意將更加能夠確保我們的愉快工作和獲取對這個系統富有成效的經驗。

21.1. 日常清理

由于以下幾個原因,必須週期性運行 PostgreSQL 的 VACUUM 命令︰

  1. 恢復那些由已更新的或已刪除的行佔據的磁盤空間.

  2. 更新 PostgreSQL 查詢規劃器使用的數據統計信息.

  3. 避免因為事務 ID 重疊造成的老舊數據的丟失.

對上面每個條件進行 VACUUM 操作的頻率和範圍因 不同的節點而不同.因此,數據庫管理員必須理解這些問題並且 開發出合適的維護策略.本節的重點就放在解釋這些高級別的問題; 至于命令語法的細節,請參閱 VACUUM 命令手冊頁.

從 PostgreSQL 7.2 開始, VACUUM 的標準形式可以和普通的數據庫操作 (selects, inserts, updates, deletes, 但不包括表定義的修改)。 因此日常的清理也不再象以前的版本那樣具有幹擾性, 也不再那麼特別要求安排在每天的低使用的時間裡進行.

21.1.1. 恢復磁盤空間

在正常的 PostgreSQL 操作裡, 對一行的UPDATEDELETE並未立即刪除舊版本的數據行。 這個方法對于獲取多版本並行控制的好處是必要的(參閱 Chapter 12): 如果一個行的版本仍有可能被其它事務看到,那麼你就不能刪除它。 但到了最後,不會有任何事務對過期的或者已經刪除的元組感興趣。 而它佔據的空間必須為那些新的元組使用而回收, 以避免對磁盤空間增長的無休止的需求。這件事是通過運行 VACUUM 實現的。

很明顯,那些經常更新或者刪除元組的表需要比那些較少更新的表清理的更頻繁一些。 所以,設置一個週期性的 cron 任務清理那些選定的表,而忽略那些已經知道變化比較少的表. 這個方法只是在你擁有大量更新頻繁的表和大量很少更新的表的時候有意義 --- 清理一個小表的額外開銷根本不值得擔心.

標準形式的 VACUUM 最適合用于維護相當程度的磁盤用量的穩定狀態。 標準形式的 VACUUM 找出舊的元組並且把它們的空間標記為可以在表內再次使用, 不過它沒有特別努力地縮小這個表文件並且把它們歸還給操作系統。 如果你需要把磁盤空間歸還給操作系統,那麼你可以使用 VACUUM FULL --- 不過如果釋放的磁盤空間又會很快再次被分配又怎樣? 如果維護更新頻繁的表,那麼中等頻率的多次標準 VACUUM 運行方法比很低頻率的 VACUUM FULL 更好。

對于大多數節點而言,我們推薦的習慣是在一天中的低使用的時段安排一次整個數據庫的 VACUUM, 必要時外加對更新頻繁的表的更經常的清理。 (如果你的集群中有多個數據庫,別忘記對每個庫進行清理;vacuumdb 腳本可能會幫你的忙。) 在日常回收空間的清理中,使用簡單的 VACUUM, 而不要用 VACUUM FULL

如果你知道自己剛刪除掉一個表中大部分的行,那麼我們建議使用VACUUM FULL, 這樣該表的穩定態尺寸可以因為VACUUM FULL更富侵略性的方法而顯著減小。

如果你有一個表,它的內容經常被完全刪除,那麼可以考慮用 TRUNCATE,而不是後面跟著 VACUUMDELETE

21.1.2. 更新規劃器統計

PostgreSQL 的查詢規劃器依賴一些有關表內容的統計信息用以為查詢生成好的規劃。 這些統計是通過ANALYZE 命令獲得的,你可以直接調用這條命令, 也可以把它當做 VACUUM 裡的一個可選步驟來調用。 擁有合理準確的統計是非常重要的,否則,選擇了惡劣的規劃很可能降低數據庫的性能。

和為了回收空間做清理一樣,經常更新統計信息也是對更新頻繁的表更有用。 不過,即使是更新非常頻繁的表,如果它的數據的統計分布並不經常改變,那麼也不需要更新統計信息。 一條簡單的拇指定律就是想想表中字段的最大很最小值改變的幅度。 比如,一個包含行更新時間的 timestamp 字段將是隨著行的追加和更新穩定增長最大值的; 這樣的字段可能需要比那些包含訪問網站的 URL 的字段更頻繁一些更新統計信息。 那些 URL 字段可能改變得一樣頻繁,但是其數值的統計分布的改變相對要緩慢得多。

我們可以在特定的表,甚至是表中特定的字段上運行 ANALYZE, 所以如果你的應用有需求的話,我們是可以對某些信息更新得比其它信息更頻繁的。 不過,在實際中,這種做法的有用性是值得懷疑的。 從 PostgreSQL 7.2 開始, ANALYZE 是一項相當快的操作,即時在大表上也很快, 因為它使用了統計學上的隨機採樣的方法進行行採樣, 而不是把每一行都讀取進來。因此,每隔一段時間對整個數據庫運行一便這條命令可能更簡單。

提示: 盡管用 ANALYZE 按字段進行挖掘的方式可能不是很實用, 但你可能還是會發現值得按字段對 ANALYZE 收集的統計信息的詳細級別進行調整。 那些經常在WHERE子句裡使用的字段如果有非常不規則的數據分布, 那麼就可能需要比其它字段更細致的數據圖表.參閱 ALTER TABLE SET STATISTICS

我們對大多數節點都建議在每天的低使用時段安排一次數據庫範圍的 ANALYZE: 這個任務可以有效地和每天的 VACUUM 組合在一起。 不過,這對那些表統計信息改變相對緩慢的節點可能會過于誇張, 而且少一些的 ANALYZE 也足夠了。

21.1.3. 避免事務 ID 重疊造成的問題

PostgreSQL 的 MVCC 事務語意依賴于比較事務 ID(XID)的數值: 一條帶有大于當前事務的 XID 的插入 XID 的行版本是"屬于未來的", 並且不應為當前事務可見。但是因為事務 ID 的大小有限(在我們寫這些的時候是 32 位),如果一次集群如果運行的時間很長(大于 4 千兆次事務), 那麼它就要受到事務 ID 重疊的折磨︰XID 計數器回到零位, 然後突然間所有以前的事務就變成看上去是在將來的 --- 這意味著它們的輸出將變得可見。 簡而言之,可怕的數據丟失,(實際上數據仍然在那裡,但是如果你無法獲取數據,這麼說也只是幸災樂禍。)

在 PostgreSQL 7.2 之前, 防禦 XID 重疊的唯一辦法就是至少每4千兆事務就重新做一次initdb。 這種做法對高流量的節點而言當然不是令人滿意的做法,所以我們設計了更好的方法。 新的方法允許某個服務器仍然保持運行狀態,不需要 initdb 或者任何類型的重啟。 代價就是下面這樣的維護要求: 數據庫中的每個表都必須在每十億次事務中至少清理一次

從實際角度出發,這個要求不算一個很繁重的要求, 但是因為如果我們沒能滿足這個要求的後果是全部數據的丟失(而不僅僅是磁盤空間的浪費或者性能的下降), 我們制作了一些特殊的東西來幫助數據庫管理員跟蹤自上次VACUUM 以來的時間。本節剩餘的部分給出這些細節。

XID 比較的新方法剝離出兩個特殊的 XID,數字 1 和 2 (BootstrapXIDFrozenXID)。 這兩個 XID 總是被認為表任何普通的 XID 舊。普通的 XID(那些大于 2 的)使用模-231運算進行比較。 這就意味著對于每個普通的 XID,總是有二十億個 XID 是"更舊"以及二十億個 XID"更新"; 表達這個意思的另外一個方法是普通的 XID 空間是沒有終點的環。 因此,一旦一條元組帶著特定的普通 XID 創建出來,那麼該元組 將在以後的二十億次事務中表現得是"在過去",而不管我們說的是哪個普通 XID。 如果該元組在超過二十億次事務之後仍然存在, 那麼它就會突然變成在將來的元組。為了避免數據丟失,老的元組必須在到達二十億次事務的年齡之前的某個時候賦予 XID FrozenXID。 一旦它被賦予了這個特殊的 XID,那麼它們在所有普通事務面前表現為 "在過去",而不管事務 ID 是否重疊, 因此這樣的元組直到刪除之前都會完好,不管要保存多長時間.這個 XID 的重新賦值是VACUUM 控制的.

VACUUM 的正常策略是給任何其普通 XID 有超過十億次已過去事務行版本重新賦值為 FrozenXID。 這個策略保留了原來的插入 XID 直到該數值不再令人感興趣為止。 (實際上,大多數行版本將可能在還沒有"凍結"之前就完成生存和消亡了)。 在這個策略下,任何表在兩次 VACUUM 運行之間的最大的安全間隔是十億次事務: 如果你等的時間更長,那麼最後就可能就會有一條不夠老的行版本在重新賦值時變成比二十億次事務更老, 並因此重疊到了未來 --- 也就是說,你失去它了。(當然,它在另外二十億次事務之後會重新出現,不過那樣也無濟于事。)

因為上面的原因,我們需要週期性地運行 VACUUM, 所以很難有哪個表會到十億次事務還沒有清理過。但是,為了幫助管理員確保滿足了這個要求, VACUUM 在系統表pg_database 裡存儲了事務 ID 統計。 尤其是一個數據庫的 pg_database 行中的 datfrozenxid 字段在任何數據庫範圍的清理操作(也就是沒有聲明任何表的VACUUM)之後將會被更新。 這個字段裡存儲的數值是該 VACUUM 命令使用的凍結終止的 XID。 系統保證在該數據庫中所有比這個終止 XID 老的普通 XID 都被 FrozenXID 代替。 檢查這個信息的一個便利的方法是執行下面的查詢

SELECT datname, age(datfrozenxid) FROM pg_database;

age 字段用于測量從中止 XID 到當前事務的 XID 的數目。

使用了這種標準的凍結策略,對一個剛清理過的數據庫而言, age 字段將從十億處開始。當age到達二十億次的時候, 數據庫必須再次清理以避免事務標識重疊造成的問題。 我們建議的策略是至少每半個十億次(5億次)事務清理一次數據庫, 這樣就可以保證足夠的安全邊界範圍.為了幫助滿足這條規則, 如果有任何 pg_database 記錄顯示出超過15億次事務的 age, 那麼每次數據庫範圍的VACUUM 都會自動發出一條警告,比如:

play=# VACUUM;WARNING:  Some databases have not been vacuumed in 1613770184 transactions.        Better vacuum them within 533713463 transactions,        or you may have a wraparound failure.VACUUM

帶著 FREEZE 選項的 VACUUM 使用了更大膽的凍結策略: 如果行版本已經老得被所有打開的事務看做是良好的, 那麼就都凍結.特別是如果在一個空閒的數據庫上運行 VACUUM FREEZE,那麼就保證該數據庫中所有的行版本都被凍結。 因此,只要該數據庫沒有其它的變化,那麼它就不需要後續的清理以避免事務 ID 重疊問題。 這個技巧被 initdb 用于準備 template0數據庫。 我們也應該用這個方法對所有在 pg_database表裡標記著 datallowconn = false的數據庫進行初始化, 因為我們還沒有任何便利的方法清理一個你無法聯接的數據庫。 請注意,VACUUM 將忽略那些pg_database 記錄裡有 datallowconn = false 條件的有關未清理數據庫的自動警告信息。 以避免給出關于這些數據庫的虛假的警告信息; 因此,確保這樣的數據庫的正常凍結是你的責任。


PrevHomeNext字符集支持
教务主任日常都作些什么工作? 文字编辑日常的工作? pos日常的维护工作 POS的日常维护工作有那些? pos日常的维护工作?急啊 谁有关于员工工作日常规范的内容啊? 单证员 是什么工作类的?日常做什么? 请问酒店普通的前台接待,日常的工作内容是什么?还有日常的操守规定是什么?(详细) 如何更有效地使用电脑和互联网服务日常的工作学习和生活 做人事工作如何才能摆脱日常事务的困扰,进而有效地对人力资源进行开发? 日常收银工作中:常见错款有哪些?如何查找?简述错款原则? 请问一间小公司的出纳日常要做的工作有哪些? 请问两冲程摩托车发动机的工作原理及日常维护维修的方法 国美门店业务副经理日常有什么工作啊,需要什么知识和能力 日常行政工作需要注意什么?? 有经验的老兄们能传授一二吗?? 从事特许加盟的区域管理者的日常营运工作通常如何开展? 一般网络公司的"网络工程师"日常都有哪些工作? 我现在在做业务助理,请教大家业务助理日常的工作有哪些? 郁闷中,给别人工作只能够日常开销,但是存不下钱. 请问行政文员的日常行政工作都有哪些?具体些,谢谢!(急用) (一)某复印机销售公司日常销售、收款和库存的数据和工作流程如下: 怎么翻译担任某人高级秘书,负责日常事务联络安排与陪同工作. 谁能帮我描述一下物流主管的岗位职能和日常的工作 请问有设计工作经验的哥哥姐姐,日常的设计工作常用的软件有哪些