postgreSQL 時間線

“時間線”(Timeline)是PG一個很有特色的概念,在備份恢復方面的文檔裏面時有出現。但針對這個概念的詳細解釋卻很少,也讓人不太好理解,我們在此仔細解析一下。

時間線的引入

爲了理解引入時間線的背景,我們來分析一下,如果沒有時間線,會有什麼問題?先舉個將數據庫恢復到以前時間點的例子。假設在一個數據庫的運行過程 中,DBA在週三12:00AM刪掉了一個關鍵的表,但是直到週五中午才發現這個問題。這個時候DBA拿出最初的數據庫備份,加上存在歸檔目錄的日誌文 件,將數據庫恢復到週三11:00AM的時間點,這樣就能正常啓動和運行。但是,DBA後來意識到這樣恢復是不對的,想恢復到週四8:00AM的數據,這 時會發現無法做到:因爲在數據庫不斷運行中,會產生與舊的WAL文件重名的文件,這些文件進入歸檔目錄時,會覆蓋原來的舊日誌,導致恢復數據庫需要的 WAL文件丟失。爲了避免這種情況,需要區分原始數據庫歷史生成的WAL文件和完成恢復之後繼續運行產生的(重名的)新WAL文件。整個過程如圖1所示:

無時間線數據庫恢復

爲了解決這個問題,PostgreSQL引入了時間線的概念。每當歸檔文件恢復完成後,創建一個新的時間線用來區別新生成的WAL記錄。WAL文件名由時間線和日誌序號組成,源碼實現如下:

#define XLogFileName(fname, tli, log, seg)    \
    snprintf(fname, XLOG_DATA_FNAME_LEN + 1, "%08X%08X%08X", tli, log, seg)

例如:

$ ls -100000002.history00000003.history
00000003000000000000001A
00000003000000000000001B

時間線ID號是WAL文件名組成之一,因此一個新的時間線不會覆蓋由以前的時間線生成的WAL。如圖2所示,每個時間線類似一個分支,在當前時間線的操作不會對其他時間線WAL造成影響,有了時間線,我們就可以恢復到之前的任何時間點。

有時間線數據庫恢復

 

What happens at a end of recovery?

  • End of recovery means the point where the database opens up for writing
  • New timeline is chosen
  • A timeline history file is written
  • The partial last WAL file on the previous timeline is copied with the new timeline's ID
  • A checkpoint record is written on the new timeline

Example: End of recovery

複製代碼

LOG:  database system was interrupted; last known up at 2013-01-30 21:45:14 EET
LOG:  starting archive recovery
LOG:  redo starts at 13/E00000C8
LOG:  could not open file "pg_xlog/0000000100000013000000E4": No 
such file or directory
LOG:  redo done at 13/E3D389A0
LOG:  last completed transaction was at log time 2013-01-30 21:45:20+02LOG:  selected new timeline ID: 2LOG:  archive recovery complete
LOG:  database system is ready to accept connections

複製代碼

First WAL file with new timeline

Timeline history file

複製代碼

0000000100000013000000E1
0000000100000013000000E2
0000000100000013000000E3
0000000100000013000000E4
0000000100000013000000E500000002.history
0000000200000013000000E3
0000000200000013000000E4
0000000200000013000000E5

複製代碼

Timeline history file

 

新時間線的出現場景

新的時間線會在什麼情況下出現呢?

    1、即時恢復(PITR)

   配置recovery.conf文件:

 restore_command = 'cp /mnt/server/archivedir/%f %p' //從歸檔目錄恢復日誌
 recovery_target_time = '2015-7-16 12:00:00 ' //指定歸檔時間點,如沒指定恢復到故障前的最後一完成的事務
 recovery_target_timeline = 'latest' //指定歸檔時間線,’latest’代表最新的時間線分支,如沒指定恢復到故障前的pg_control裏面的時間線
 standby_mode = ‘off’ //打開後將會以備庫身份啓動,而不是即時恢復

設置好recovery.conf文件後,啓動數據庫,將會產生新的timeline,而且會生成一個新的history文件。恢復的默認行爲是沿着與當前基本備份相同的時間線恢復。如果你想恢復到某些時間線,你需要指定的recovery.conf目標時間線 recovery_target_timeline ,不能恢復到早於基本備份分支的時間點。

    2、standby promote

搭建一個PG主備,然後停止主庫,在備庫機器執行:

 $ pg_ctl promote –D $PGDATA

這時候備庫將會升爲主備,同時產生一個新的timeline,同樣生成一個新的history文件。

history文件

每次創建一個新的時間線,PostgreSQL都會創建一個“時間線歷史”文件,文件名類似.history,它裏面的內容是 由原時間線history文件的內容再追加一條當前時間線切換記錄。假設數據庫恢復啓動後,切換到新的時間線ID=5,那麼文件名就是 00000005.history ,該文件記錄了自己從什麼時間哪個時間線什麼原因分出來的,該文件可能含有多行記錄,每個記錄的內容格式如下:

* <parentTLI> <switchpoint> <reason>
 *
 *      parentTLI       ID of the parent timeline *      switchpoint     XLogRecPtr of the WAL position where the switch happened *      reason          human-readable explanation of why the timeline was changed

例如:

$ cat 00000004.history1    0/140000C8    no recovery target specified2    0/19000060    no recovery target specified3    0/1F000090    no recovery target specified

當數據庫在從包含多個時間線的歸檔中恢復時,這些history文件允許系統選取正確的WAL文件,當然,它也能像WAL文件一樣被歸檔到WAL歸檔目錄裏。歷史文件只是很小的文本文件,所以保存它們的代價很小。

當我們在recovery.conf指定目標時間線tli進行恢復時,程序首先尋找.history文件,根據.history文件裏面記錄的時間線分支關係,找到從pg_control裏面的startTLI到tli之間的所有時間線對應的日誌文件,再進行恢復。

總結

PG中通過timeline機制能夠方便地實現數據庫恢復到任意時間點,這對我們數據庫備份有重要的作用。我們可以在數據庫的使用中合理地備份和歸檔我們的數據,一旦數據出現丟失或損壞,我們都能有條不紊的使用timeline機制恢復出來我們需要的數據。

 

參考:

http://mysql.taobao.org/monthly/2015/07/03/

https://wiki.postgresql.org/images/e/e5/FOSDEM2013-Timelines.pdf

轉載:https://www.cnblogs.com/xiaotengyi/p/4665990.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章