PostgreSQL恢復備份WAL(Write-Ahead Logging)主從


參考

http://www.postgres.cn/docs/11/app-pg-dumpall.html

http://www.postgres.cn/docs/11/continuous-archiving.html

http://www.postgres.cn/docs/11/recovery-target-settings.html

http://www.postgres.cn/docs/11/runtime-config-wal.html

http://m.blog.chinaunix.net/uid-20665047-id-5817656.html

http://m.blog.chinaunix.net/uid-20665047-id-5817656.html

http://www.postgres.cn/docs/11/continuous-archiving.html#BACKUP-ARCHIVING-WAL

https://blog.csdn.net/yaoqiancuo3276/article/details/80826073

http://www.postgres.cn/docs/11/runtime-config-replication.html

http://www.postgres.cn/docs/11/warm-standby.html#STREAMING-REPLICATION

https://lihaoquan.me/2018/9/29/postgresql-master-slave-ha.html

全量備份

我們要做實時恢復,就需要對數據庫做增量備份,也就是記錄每次數據庫的操作。恢復的時候,就按照記錄,一條條的把數據還原到正確的地方。但是不管怎么樣,都需要有一個基准,也就是從一個初始狀態開始,按照操作記錄,一條條的恢復。

pg_basebackup

pg_basebackup的作用相當於是把數據庫目錄下的相關數據文件拷貝到一個地方。

只能用這個做全量備份或是自己拷貝所有的數據庫文件,不可以使用pg_dump、pg_dumpall或者navicat的備份工具備份。因為pg_dump等只是把數據庫的表備份出來。postgresql的還原需要數據庫目錄中的一些信息。這也是與mysql不一樣的地方。

mysql是在當前數據的基礎上,一條條的執行binlog中的命令。而postgresql是在數據庫文件記錄的當前狀態下,向前同步到對應的狀態。比如同步了第幾條wal日志信息,還有哪些信息沒同步,需要同步到第幾個。如果僅僅是把數據庫的表導出來,這個無法做還原,因為數據庫當前狀態一直是最新的狀態,就算把數據改回原來的數據,對於數據庫來說,只不過是更新了新的數據,並不認為是回退到了原來的某個時間點。

pg_basebackup -D /home/postgres/basebackup/

把數據全備份到指定目錄

pg_dump

pg_dump dbname > dbback1

把數據庫名字是dbname的數據備份到dbback1中,上面的語句並沒有指定用戶名和密碼,是因為在postgres自己的用戶下,默認配置是peer訪問權限,也就是在自己用戶下,不需要輸入密碼。

psql db_payserver < dbback1

把原來備份的數據還原。

db_dumpall

db_dumpall備份的數據更多。這個是把整個數據庫備份。每個單獨的數據庫調用的是db_dump。但是它還額外備份了一些其他信息,其中包括

所有數據庫公用的全局對象(pg_dump不保存這些對象),數據庫角色和表空間都會被轉儲。包括適數據庫用戶和組、表空間以及適合所有數據庫的訪問權限等屬性。

pg_dumpall需要多次連接到PostgreSQL服務器(每個數據庫一次)。如果你使用口令認證,可能每次都會要求口令。這種情況下使用一個~/.pgpass會比較方便。

pg_dumpall > dball
psql -f dball

打開歸檔

與mysql的binlog類似,postgresql也會保留對數據庫的操作日志,這也是時間點恢復的基礎。同樣需要我們配置相關參數打開。

修改配置

vim /etc/postgresql/11/main/postgresql.conf
wal_level = logical                     # minimal, replica, or logical
                                        # (change requires restart)
archive_mode = on               # enables archiving; off, on, or always
                                # (change requires restart)
archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'           # command to use to archive a logfile segment
                                # placeholders: %p = path of file to archive
                                #               %f = file name only
                                # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
# e.g. 'copy "%p" d:\\pg_xlog_archive\\%f'

配置解釋

wal_level-設置wal log需要記錄哪些信息,minimal記錄的信息不全,不能恢復數據。所以信息需要是replica或是更高的logical。這個等級就是記錄的信息越來越多。

archive_mode-是否打開歸檔

archive_command-這個是當postgresql完成一個歸檔的時候,運行的命令。postgresql與mysql一樣會記錄每一次數據庫操作,放到一個文件中。這個文件是有大小限制的,默認16m的時候就會換一個文檔。當發生這個操作的時候,就會運行archive_command指定的命令。我們可以把當前的文檔拷貝到一個地方備份起來。test的目的是不要覆蓋已有的文件

wal_level是設置wal日志的模式,postgresql不管有沒有設置,都會有wal日志。

postgresql產生wal日志后,會不斷的刪除原來的wal文檔,為了可以恢復到以前更老的時間點,需要每次postgresql完成一個wal日志文件創建下一個文件的時候,把當前的文件拷貝到一個地方保存起來。歸檔的作用就是postgresql給我們提供的一個借口,可以自動的完成這個操作。

注意事項

windows下創建的目錄,用來拷貝保存wal日志。權限需要增加network service用戶組,不然會報錯沒有權限,無法拷貝數據。

重啟服務或是系統

//windows
在Computer Management->Services選擇postgres對應的服務項,右鍵,選擇重啟

//Debian
service postgresql restart

我們可以調用pg_switch_wal命令來刷新強制產生一次歸檔,看看數據是否拷貝到我們命令設置的地方。

數據還原測試

通過pg_basebackup全量本分數據庫

這就相當於做了一個還原點,從現在這個點往后的數據都可以還原

確定打開了wal日志,並設定為replica或logical

確定打開了歸檔

修改數據

第一條數據改為111

第二條數據改為222

第三條數據改為333

查看當前wal日志

SELECT pg_walfile_name(pg_current_wal_lsn())

查看當前wal詳細信息

/usr/lib/postgresql/11/bin/pg_controldata /var/lib/postgresql/11/main

手動歸檔當前wal日志

select pg_switch_wal();

手動把當前的wal刷新一下,切換到另一個新的日志。這樣就可以分析當前的日志了。因為分析正在使用的wal日志有可能會報錯。

運行這個命令或是數據庫在重啟(也就是關閉的時候)或是在系統重啟(也就是數據庫關閉的時候),都會切換日志,運行歸檔命令。

這個也可以不做,因為恢復數據的時候需要停止數據庫,這是也會歸檔wal日志。

停止數據庫

//Windows
在Computer Management->Services中選擇postgresql對應的服務,右鍵選擇stop

//Debian
service postgresql stop

把數據庫的data目錄拷貝到一個地方,防止恢復失敗的時候導致更多數據丟失

C:\Program Files\PostgreSQL\11\data
/var/lib/postgresql/11/main

上面是windows和linux下默認安裝的data目錄

清空原來的data目錄下的數據

把上面pg_basebackup備份的數據拷貝到data目錄

就相當於從備份那個點開始還原

分析日志

pg_waldump是用來分析wal日志的命令

pg_waldump 000000040000000000000010

這個命令就是導出日志的詳細信息。這個命令有可能不在系統的環境中,直接執行會報找不到命令的錯誤,可以通過find找到對應的位置。

postgresql的wal日志有一個很大的問題,就是不知道執行的是什么sql語句。這個與mysql的binlog比起來就麻煩了很多。雖然有一些方法可以導出來,但是太麻煩了。希望postgresql以后可以提供直接在日志中顯示sql語句的功能。

上面就是wal日志的詳細信息,我們可以看到COMMIT信息,還有對應的日期。COMMIT信息上面描述了這次操作的類型,比如HOT_UPDATE,就是運行了update命令,更新了數據。

我們看到中間有running xid 1205; online等信息,xid 1205就是這次運行的事務id。也就是我們修改數據庫,默認數據庫也會開啟事務,與我們自己寫的事務一樣,為了保證這次修改要么成功,要么沒修改,不存在中間狀態。

我們還原的時候可以根據這個事務id還原,就可以保證精確度。

上面修改了三次,我們看到這里有三個事務id,1205、1206、1207。所以如果還原到第二條修改,那就是1206.

拷貝wal日志到data目錄下的pg_wal

拷貝recovery.conf.sample到data目錄下,並且修改名字為recovery.conf

這里面有注釋,可以根據注釋修改,我這里只打開了兩個

restore_command = ''

recovery_target_xid = '1206'

第一個是必須要開的,就是把原來的歸檔,wal日志,拷貝到pg_wal目錄,如果提前自己拷貝進來,直接是空就好了。

第二個是按照xid的模式還原到1206個xid

啟動數據庫

我們看到數據還原到第二條修改,第三條修改還是原來的值

//Windows
在Computer Management->Services選擇postgresql服務,右鍵,選擇start

//Debian
service postgresql start

主從異步流復制

注意事項

  • 通過pg_basebackup備份過來的文件權限太多,需要設置成只能postgres自己才能訪問操作,過多的權限會導致數據庫無法啟動
  • 從widows備份過來的文件和linux下的編碼格式不匹配,無法正常啟動,會報如下錯誤

psql: FATAL:  database locale is incompatible with operating system
DETAIL:  The database was initialized with LC_COLLATE "Chinese (Simplified)_People's Republic of China.936",  which is not recognized by setlocale().
HINT:  Recreate the database with another locale or install the missing locale.

  • 如果不使用主服務器的備份,則無法啟動主從

 最終測試下來失敗,如果有知道如何主從復制,主服務器是windows,從服務器是linux,請告知。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM