天天看點

資料庫核心月報 - 2015 / 10-PgSQL · 特性分析 · pg_receivexlog工具解析

最近遇到這樣一個需求:在做時間點恢複時,需要從主庫擷取最近生成的那些xlog檔案(需要擷取的xlog檔案名是已知的)。怎麼辦?一個想法是,利用scp等工具,直接從主庫下載下傳,這要求我們處理整個下載下傳過程,比較麻煩。其實pg已經為我們準備了一個xlog傳輸工具——pg_receivexlog。這個工具可能很多人都沒注意到,而且官方文檔中介紹的很少。在這裡我們為大家解析一下這個工具。

pg_receivexlog能為我們做什麼呢?它能夠從一個pg伺服器,擷取你想要的那些xlog日志檔案。初步研究後,我們可以得到以下資訊:

它以類似流式複制(streaming replication)的方式,擷取主庫的xlog檔案。這意味着你要以超級使用者或有replication權限的使用者,連接配接pg進行日志傳輸,且要在pg_hba.conf裡面,對其做權限配置。在連接配接建立後,pg伺服器會有一個獨立的wal sender程序,負責xlog的傳輸,是以<code>max_wal_senders</code>要至少為1,使我們能獲得一個wal sender。

它不會等待一個xlog檔案寫完後才開始傳輸。也就是說,正在被寫的xlog檔案,也會進行傳輸,是以可以通過這個工具實時擷取最新的xlog内容。

可以使用replication slot,通過同步replication slot的方式進行日志傳輸。這樣做的好處是,主庫在xlog傳輸完成前不會删除xlog檔案。不過可能的風險是,如果日志沒有利用slot成功傳輸,可能導緻日志堆積在pg裡面,最終把磁盤占滿。

pg安裝後的bin目錄裡面,一般包含了pg_receivexlog這個工具。可以使用下面的方式啟動它:

其中,-h -p -u -w 選項指定要連接配接的pg的主機名、端口、使用者、密碼,-d 選項指定本地的一個目錄,用于存儲下載下傳的xlog檔案。另外預設情況下,如果連接配接無法建立,或傳輸過程中連接配接意外斷開,pg_receivexlog會進行重試,如果不想重試,可以指定-n選項。

有個問題是,如何指定要傳輸哪些xlog檔案?先來看看pg_receivexlog如何确定從哪個xlog檔案開始傳輸的。從src/bin/pg_basebackup/pg_receivexlog.c 的<code>findstreamingstart</code>函數可以看出,pg_receivexlog會掃描整個-d選項指定的目錄,将掃描到的每個檔案名,去掉其timeline部分,轉換為64為整數。選取其中對應整數最大的檔案,按如下方式選擇開始下載下傳的檔案:如果這個檔案是以.partial為字尾的,則重新下載下傳此檔案和後續檔案;如果該檔案不帶.partial字尾,是一個完整的日志檔案,則從此檔案的下一個檔案(檔案名加1)開始下載下傳。如果我們需要從00000001000000000000001b到00000001000000000000001d的幾個檔案,則隻需要在-d指定的目錄裡面執行:

保證此目錄沒有其他檔案,然後按上面列出的方式啟動pg_receivexlog即可,pg_receivexlog會重新下載下傳00000001000000000000001b和後續檔案。

如何停止pg_receivexlog的執行呢?pg_receivexlog已經下載下傳了我們需要的檔案後,并不會自動停止,我們也沒有辦法指定它下載下傳到哪個檔案結束。唯一的辦法是通過ctl-c指令向它發送sigint信号來結束它。類似的,可以直接向它的程序發生kill指令:

注意,pg_receivexlog隻在成功傳輸完一個xlog檔案後,才檢查是否收到了sigint信号,是以你隻可能在一個檔案接收完成後正常結束pg_receivexlog運作。其實更暴力的辦法是直接kill -9 也是可以的。

從上面的分析可以看出,pg_receivexlog這個工具還是比較簡單易用的。除了傳輸xlog日志,可以利用它做一個日志伺服器,用來存儲歸檔的日志;還可以做為一主多備方案。由此可見,pg_receivexlog既是一個很實用的工具,也是一個可以用于更多場景的讓人充滿想象的利器。