【CSDN 編者按】這篇文章分享了作者作為一位全棧開發者,在三周內將一個 3TB 的 PostgreSQL 數據庫從 AWS 遷移到 Azure DevOps 的過程和經驗,以及遇到的挑戰和解決方案。
原文鏈接:https://betterprogramming.pub/how-i-migrated-a-3tb-postgresql-transactional-database-ee1cf85c37bf
作者 | Geronimo Velasco譯者| 明明如月
責編 | 夏萌
出品 | CSDN(ID:CSDNnews)
在快速發展的創業環境中,小型開發團隊經常需要負責整個項目的開發工作。當擔任一家交通顧問公司的全棧開發人員時,我親自體驗了這樣的情況,并成為了一個關鍵項目的獨立負責人。隨著團隊成員開始忙于其他任務,項目中的所有挑戰都集中在我一人身上。
我們主要負責管理交通系統中的交易流程,并處理傳入的數據,以生成關鍵報告和信息。面對源源不斷涌入的新交易,我們需要一套可靠且高效的數據庫解決方案。
在忙于日常系統管理的同時,我們收到了一項突發的客戶需求:將龐大的 3 TB PostgreSQL 數據庫從 AWS 遷移到 Azure DevOps。這個需求背后的目的十分明確,即將整個系統整合到 Azure 生態系統中,從而簡化操作流程并挖掘增長潛力。
然而,時間緊迫,我們面臨著嚴峻的挑戰。客戶設定了一個很短的 Deadline,僅給我們三周的時間來完成遷移。由于我們深知成功依賴于精密的規劃、完美的執行和一定程度的創新,任務的迫切性為我們增加了額外的壓力。
在本文中,我將分享關于遷移過程的經驗和洞察。雖然我不是 PostgreSQL 的專家,但作為承擔這一復雜任務的唯一開發人員,整個過程充滿了挑戰和重要的發現。我相信,這些經驗對于那些面臨類似情況的人將具有極大的價值。遷移如此龐大的數據庫需要精心的規劃、戰略性的決策,以及深入理解所涉及的復雜性。
遷移準備
遷移的準備階段無疑是整個過程中最為復雜的部分之一。由于項目過去嘗試使用 pg_dump 遷移數據庫(當時數據庫為 2TB)而失敗,我對下一步該如何進行感到不知所措。盡管我對數據庫的整體結構和大小有基本了解,還曾針對它進行特性開發和復雜查詢編寫,但由超過 200 張表格組成的龐大結構使得任務遠比我最初設想的復雜。
要解決這個問題,首先要對整個數據庫進行全面映射。我詳細記錄了關鍵列、索引、關系、約束、觸發器、受它們影響的表格和必要的序列。這一詳細映射使我們能清晰地理解面臨的挑戰,并為遷移制定最佳方案。
此外,整個過程耗時近一周才完成,期間新交易不斷涌入,使得主數據庫的不斷增長成為了一個嚴重的問題。
由于傳統的備份和恢復手段可能會導致數據不一致,但是我們的業務非常關鍵,所以遷移期間停機不可行。
在增量備份方面的不熟悉和時間的緊迫下,我和技術主管共同分析了現狀,并設計了一種替代方案。我們的方案包括將新的交易重定向到另一個數據庫,同時我集中精力遷移現有的 3 TB 數據庫。這種方法要求我們不僅遷移 3 TB 的數據庫,還要處理新傳入交易的新數據庫。
雖然方案復雜,但這個替代方案預計將節省用于遷移較小數據庫的時間和精力。盡管遇到了挑戰,我們還是成功地完成了遷移,并將對持續運營的干擾降至最低。這次經歷讓我在高效、負責地管理大規模數據庫遷移項目方面積累了寶貴經驗。
數據庫準備策略
選擇遷移方案
在深入分析數據庫后,我對不同的遷移方案進行了探討。首先考慮的是使用 pg_dump/pg_restore方案,雖然此前的嘗試并未成功。其次考慮了使用 Pentaho,這是一款專門處理大型數據集,功能強大的數據集成工具。最后,技術負責人提出了一種使用偏移限制的手動分頁方案,在演示中引起了我的關注。
下面,我將詳細解釋這三種遷移方案,包括各自的實施過程和我們所遇到的挑戰。盡管每一種方案最初都顯得誘人,但我們最終選擇了最適合我們獨特需求的方案。
Pentaho
項目在使用 pg_dump/pg_restore失敗后,Pentaho 方案成了首選。為驗證 Pentaho 是否符合遷移需求,我進行了一次演示,試圖從一個包含近 7 億條記錄、40 列左右的龐大表中遷移數據。
在當天配置好環境后,我讓遷移任務在夜間運行,以便第二天評估其性能。
第二天一早檢查遷移進度時,我發現了IODataFileRead 等待事件,這讓我感到不安,因為這暗示了遷移正在費力地從磁盤讀取所需的數據。經過 12 個多小時,僅遷移了約 2.5 億條記錄,對此我非常納悶,于是我開始深入分析背后的原因。
我開始關注表格的龐大大小和眾多列數。顯然,數據庫默認的 8 KB 頁面大小無法處理如此龐大的表,可能導致數據庫按隨機順序獲取大量頁面,從而使數據讀取卡頓。數據庫不得不以這種低效方式檢索數千個頁面,并將它們存儲在 RAM 中再返回。這種方法大大拖慢了遷移速度。
我多次嘗試復現問題,并與類似的表格進行對比,尋找一種能使 Pentaho 方案有效的辦法。然而,不幸的是,這并沒有達到預期效果,隨著時間的流逝,找到合適方案的緊迫性也愈發增加。
盡管在這個方案上投入了四天的時間和精力,但顯然還有其他更符合我們遷移需求的選擇。因此,在截止日期臨近和需要探索其他方案的壓力下,我決定轉向下一種方案。作為此關鍵項目的負責開發者,快速適應和明智地做出決策成了關鍵。
手動分頁方法與偏移量限制的應用
在 Pentaho 數據遷移演示中,我利用空余時間探索了其他的可能方案。盡管起初對方案的成功抱有疑慮,但在探索過程中,我卻偶然發現了一些有趣的現象。
我構建了一個簡易的 NodeJS 項目,通過設置偏移量和限制值均為 100,000 條記錄的分頁方式,從一個擁有 7 億條記錄的表中獲取信息。出乎意料的是,當查詢量達到大約 2.2 億條記錄時,查詢突然變得緩慢并卡頓,觸發了引起關注的 IODataFileRead等待事件。對這一突發情況我感到困惑,便決定進行深入分析,以找出根本原因。
在我的研究過程中,我發現了一些關于偏移量的有趣事項。通過執行 EXPLAIN ANALYZE命令深入探討查詢,我進一步了解了 PostgreSQL 的執行流程,以及它在處理如此龐大的數據集時所遇到的挑戰。
查詢示例
EXPLAINANALYZESELECT* FROMtable_name offset200000limit100000;使用 OFFSET命令并不直接跳過記錄,而是獲取所有記錄,并由 PostgreSQL 進行篩選。這解釋了查詢為何減速,因為它不僅獲取了預期的 100,000 條記錄,還獲取了全部的 2.2 億條記錄,然后才進行過濾。這一觀察驗證了我的最初懷疑。
在探索備選方案時,我們考慮使用 COPY 命令的分頁方式進行備份。不幸的是,我們遇到了難題。由于數據庫表擁有包含 UUID 值的主索引,這使得通過 COPY 命令高效地進行遷移變得困難,因為 UUID 打亂了表的順序。
查詢示例
COPY (SELECT* FROMyour_table WHEREidBETWEEN1AND100) TO'/table-backup.csv'CSV HEADER;這一發現促使我們來到了一個關鍵的決策點,要求我們重新評估方案,并尋找一種哪怕受到 UUID 主索引限制也能有效工作的方法。作為一名獨立開發者,找到合適的解決方案需要創造力和技術專長的有機結合。
使用 pg_dump/pg_restore 進行遷移
經過了一周對兩種不同方案的探索和測試后,我最終決定使用 pg_dump和 pg_restore命令來執行任務。在這個階段,我深入研究了這些命令,以便更精確地理解如何充分利用它們以達到最佳性能。
然而,我們在 Azure For PostgreSQL 的靈活服務器配置方面遇到了一個顯著的挑戰,那就是無法獲得超級用戶的訪問權限。這個問題的限制在于,理想情況下遷移過程中應禁用觸發器以提高恢復速度,但由于我們缺乏必要的訪問權限,無法執行該操作。這個問題促使我必須尋找其他有效的遷移方法。
在整個過程中,我及時向客戶報告了開發的進展,因為任務的復雜性已經超出了原定的時間計劃。為了解決這些挑戰,客戶還特地聘請了一位 PostgreSQL 專家來協助我們,但即使經過兩周的共同努力,遷移依然沒有成功。因此,客戶不得不延長了項目的截止日期以適應我們所遇到的復雜情況。
兩周的深入研究和廣泛的實驗后,我成功地制定了一項全面的遷移計劃,以加速 3 TB 和較小數據庫的遷移。
- 使用 pg_dump 的 0 壓縮 (-Z 0): 為了提高速度,我在備份階段選擇了不進行壓縮。雖然這樣做增加了磁盤空間的需求,但卻加快了備份過程。
- 實現并行備份和恢復 (-j <num>): 我通過使用參數 -j <num> 來并行處理表的備份和恢復,以進一步提高性能和減少遷移時間。
- 在恢復過程中禁用觸發器 (--disable-triggers): 為了確保數據一致性和避免觸發器沖突,我在恢復階段使用了該參數來禁用觸發器。
我的具體遷移計劃包括:
- 備份數據庫模式、遷移序列,并在新服務器上創建必要的數據庫角色。
- 刪除關鍵約束,以降低不必要的 IO 操作,并加速遷移過程。
- 移除大型索引,進一步優化遷移中的 IO 操作。
- 按表或相關表組進行逐項遷移。由于沒有超級用戶權限,我仔細選擇了需要移除的關鍵關系以促進遷移。
- 在遷移信息后恢復約束,并注意表之間的關聯關系。
- 最后,成功遷移數據后恢復大型索引。
遷移計劃完成后,我與技術負責人一同審查了方案,并開始配置環境,準備啟動實際的數據庫遷移過程,從而解決了由于缺乏超級用戶權限所帶來的限制問題。
配置遷移環境
為了搭建遷移環境,我們計劃利用虛擬機(VM)來完成數據庫的備份,并在最終的數據庫中執行恢復操作。該虛擬機將與目的數據庫在同一區域內創建。為確保 Azure 資源間的安全高效通信,我們將調整必要的權限設置,使虛擬機能夠通過 Azure .NET(虛擬網絡)與數據庫連接。
相比與公共互聯網通信,使用 Azure VNET 連接資源不僅提高了通信性能,還增強了安全保障,因此更具優勢。
以下是我們準備虛擬機以進行遷移所需采取的具體步驟:
- 創建虛擬機:我們在與最終數據庫同一 Azure 區域內創建虛擬機,確保了數據傳輸的高效性和速度提升。
- 安裝 PostgreSQL:在虛擬機配置完畢后,我們對其安裝了 PostgreSQL,作為存儲數據庫備份文件和執行恢復的遷移服務器。
- 權限和網絡配置:為構建虛擬機與目的數據庫之間的安全連接,我們精心配置了相應的權限和網絡設置。通過使用 Azure VNET,我們將通信限制在虛擬網絡內部,從而降低了公共互聯網的風險,整體提高了安全性。
- 連接測試:完成 PostgreSQL 的安裝和網絡設置后,我們執行了連接測試,確認虛擬機能夠與源數據庫和目的數據庫正常通信。這一環節對確保遷移流程的順利進行是必不可少的,可以有效避免連接相關的問題。
至此,虛擬機已做好作為遷移服務器的準備,我們可以繼續推進數據庫遷移的下一步。下一階段將涉及從源數據庫提取備份、安全地傳輸至虛擬機,并在最終數據庫中執行數據恢復。
執行遷移
面對 3TB 數據的遷移任務,我按照預定計劃精心策劃并準備。在啟動任何備份或恢復操作之前,我對 postgresql.conf 的參數進行了精細調整,以提高性能并規避一些可能的問題,如自動清理。此外,我還參考了Azure 資源的推薦設置,以確保在使用 pg_dump和 pg_restore時符合最佳實踐。
在配置優化完畢后,我編寫了備份和恢復腳本,以簡化流程并消除手動輸入的需求。執行任何命令前,我反復審查腳本以確保無誤。
準備工作完成后,我通知了團隊和客戶,即將啟動遷移流程,并依據計劃逐步推進。整個遷移期間,我不斷監控進展,確保各階段均按預期進行,并通過定期與團隊溝通進展,保持各方的信息同步。
憑借周密的籌備和嚴格的計劃執行,3TB 數據庫的遷移得以平穩、高效地完成。通過配置的優化、腳本的自動化以及持續的溝通,我們共同促成了此次遷移的成功。
在遷移較小數據庫的過程中,我們通知客戶按隊列處理即將到來的交易,有效地控制了這些交易,確保數據完整無損。小型數據庫遷移結束后,我們整理了所有信息,恢復了交易接收,并在新環境中順利完成了遷移。
系統在新環境中無縫運行,這得益于所有信息的成功遷移和交易接收的恢復。我們還進行了全面的測試和驗證,確保數據完整性和一致的性能。
客戶對遷移效果非常滿意。通過戰略性的遷移管理,我們最大限度地減少了停機時間,避免了對客戶操作的重大干擾。
監控與數據完整性
在數據遷移中,數據完整性的保障和進度的實時監控是至關重要的任務。為了實現這一目標,我采用了以下三種監控手段:
- 網絡監控:通過網絡監控工具,我全面觀察了虛擬機(VM)與數據庫服務器之間的數據流動,確保信息能按照計劃遷移,并能及時找出可能阻礙遷移的網絡問題。
- PgAdmin 儀表板監控:PgAdmin 的儀表板可以提供關于 pg_restore 流程進展的實時洞見。通過對儀表板的監控,我能夠跟蹤恢復任務的執行狀況,發現任何等待事件,并實時觀察數據庫的整體健康狀態。
- 數據庫元數據查詢監控:我還定期執行了多種查詢,以檢查數據庫的元數據,確保成功遷移并核實數據完整性。其中一些關鍵的查詢包括:
- 活動和死亡元組(Live and Dead Tuples)監控:我監測表中的實時和死亡元組數量,以了解空間使用和數據分布情況。這有助于及時發現遷移過程中的數據分布和空間使用問題。
-- TO SEARCH FOR A SPECIFIC TABLE
SELECTrelname, n_live_tup, n_dead_tup FROMpg_stat_all_tables WHERErelname = 'table_name';
- 表大小查詢:通過定期檢查表的大小,我能夠跟蹤數據遷移進度,確保表數據按預期填充,并及時發現可能暗示遷移問題的任何異常。
- 數據庫大小查詢:此外,我還監控了數據庫的整體大小。
通過這些精心選擇的監控方法和查詢執行,我確信遷移過程能夠順利進行,數據完整性得到保障,并能及時發現和解決遷移過程中可能出現的任何問題。
遷移后的性能優化
通過對 postgresql.conf服務器設置進行微調,我調整了 PostgreSQL 配置的參數,從而提升了數據庫性能。雖然 Azure 會根據服務器資源自動調整 PostgreSQL 的參數,但我還是通過細致的手動優化,進一步優化了數據庫配置。
個人感悟與體驗
起初,我覺得執行遷移任務似乎是不可能完成的挑戰。盡管有團隊中的高級開發人員和軟件架構師的支持,我們過去備份數據庫的過程也充滿了困難。當客戶提出此項要求時,由于原團隊中的其他人員都已離開,而我是唯一留下的人,我知道這個責任將全部落在我身上。
坦白說,這個任務不僅讓我感到擔憂,甚至連其他團隊成員和我的技術領導也為之膽戰心驚。然而,當我想起了一位杰出的內容創作者 midudev 的建議時,我意識到這是一個挑戰自我、增長知識、提升工程師素質的絕佳機會。他指出,如果有一個項目被所有人回避,這可能正是你所需的挑戰。
因此,我決定用積極的態度迎接這一挑戰。雖然我并不是 PostgreSQL 的專家,但我曾有過遷移小型數據庫(例如 5 GB 或 20 GB)的經驗。但毫無疑問,處理一個龐大的 3 TB 事務數據庫將是一次全新的經歷。
盡管一開始我感到恐懼,但我還是決定勇敢地領導遷移工作。我欣然發現,這個挑戰激發了我最好的潛能,并成功地完成了遷移,甚至找到了優化數據庫某些方面的方法。
整個過程讓我學到了許多寶貴的知識,特別是加深了對數據庫基礎運作機制的理解。回首整個經歷,這對我的專業成長來說,是一段難忘的旅程。
現在,我對 PostgreSQL 的理解更深入了。未來我可能會考慮使用像 Barman 或 pgcopydb 這樣的專業遷移工具來實現增量備份和更高級的遷移任務。通過這些工具,能夠增加自動化和可靠性,從而減少手動遷移可能出現的錯誤。
我寫下這篇文章的目的是分享我的遷移經驗。我堅信,它可能對那些發現自己處于類似挑戰的人有所啟發和鼓勵,我的旅程和所學經驗或許能為他們提供有價值的見解。
結論
總體來說,遷移一個龐大的 3TB 數據庫既充滿挑戰性,又異常復雜。這一過程不僅要求深入掌握數據庫基礎知識,還涉及一系列精細且反復的實驗操作。盡管遭遇了一些難題,但我從中學到了許多寶貴的經驗,并對 PostgreSQL 有了更深入的理解。
對遷移過程的精確監控對于確保數據的完整性和性能來說是至關重要的一環。這一經歷不僅促進了我的專業成長,還使我成功地優化了數據庫。
展望未來,我急切希望探索其他適用于將來項目的遷移工具。我希望通過本文的分享,能鼓舞和幫助那些面臨類似挑戰的人。總之,這一遷移經歷極大地提升了我作為軟件工程師的技能,并增強了我迎接未來技術挑戰的信心與決心。
你是否也搞過類似的遷移任務?對于這種龐大的遷移任務,你有沒有更好的建議或經驗?請發表你的看法。