PostgreSQL備份和恢復(fù)

PostgreSQL備份和恢復(fù)

原創(chuàng)沒刮胡子 最后發(fā)布于2019-07-18 14:05:10 閱讀數(shù) 190? 收藏

展開

1.簡介

由于數(shù)據(jù)庫中包含著有價值的數(shù)據(jù)躯肌,PostgreSQL數(shù)據(jù)庫應(yīng)當(dāng)被定期地備份清女。雖然過程相當(dāng)簡單拴袭,但清晰地理解其底層技術(shù)和假設(shè)是非常重要的拥刻。

2.PostgreSQL數(shù)據(jù)備份方式

按照備份后的文件類型劃分為

物理備份:文件系統(tǒng)級別的備份

邏輯備份:備份后的文件是sql文件或特定格式的導(dǎo)出文件

按照備份過程中是否停止數(shù)據(jù)庫服務(wù)劃分為

冷備份

熱備份

按照備份是否是完整的數(shù)據(jù)庫劃分為

全量備份:備份是完整的數(shù)據(jù)庫

增量備份:備份是上一次全量備份后數(shù)據(jù)庫改變的內(nèi)容

有三種不同的基本方法來備份PostgreSQL數(shù)據(jù):

1、SQL轉(zhuǎn)儲 *

2、文件系統(tǒng)級備份 *

3、連續(xù)歸檔 *

每一種都有其優(yōu)缺點

2.1. SQL轉(zhuǎn)儲

用到的工具是pg_dump和pg_dumpall擒贸。

SQL 轉(zhuǎn)儲方法的思想是創(chuàng)建一個由SQL命令組成的文件介劫,當(dāng)把這個文件回饋給服務(wù)器時,服務(wù)器將利用其中的SQL命令重建與轉(zhuǎn)儲時狀態(tài)一樣的數(shù)據(jù)庫誉碴。 PostgreSQL為此提供了工具pg_dump。這個工具的基本用法是:

pg_dump dbname > outfile

1

正如你所見成黄,pg_dump把結(jié)果輸出到標(biāo)準(zhǔn)輸出思瘟。我們后面將看到這樣做有什么用處潮太。 盡管上述命令會創(chuàng)建一個文本文件,pg_dump可以用其他格式創(chuàng)建文件以支持并行 和細粒度的對象恢復(fù)控制奇钞。

pg_dump是一個普通的PostgreSQL客戶端應(yīng)用(盡管是個相當(dāng)聰明的東西)景埃。這就意味著你可以在任何可以訪問該數(shù)據(jù)庫的遠端主機上進行備份工作。但是請記住 pg_dump不會以任何特殊權(quán)限運行完慧。具體說來,就是它必須要有你想備份的表的讀 權(quán)限脾歧,因此為了備份整個數(shù)據(jù)庫你幾乎總是必須以一個數(shù)據(jù)庫超級用戶來運行它(如果你沒有足夠的特權(quán) 來備份整個數(shù)據(jù)庫,你仍然可以使用諸如-n schema 或-t table選項來備份該數(shù)據(jù)庫中你能夠 訪問的部分)蚕冬。

要聲明pg_dump連接哪個數(shù)據(jù)庫服務(wù)器,使用命令行選項-hhost和-p port旁蔼。 默認主機是本地主機或你的PGHOST環(huán)境變量指定的主機伞租。 類似地葵诈,默認端口是環(huán)境變量PGPORT或(如果PGPORT不存在)內(nèi)建的默認值。 (服務(wù)器通常有相同的默認值泞坦,所以還算方便。)

和任何其他PostgreSQL客戶端應(yīng)用一樣豌熄, pg_dump默認使用與當(dāng)前操作系統(tǒng)用戶名同名的數(shù)據(jù)庫用戶名進行連接。 要使用其他名字,要么聲明-U選項焕济,要么設(shè)置環(huán)境變量PGUSER。請注意pg_dump的連接也要通過客戶認證機制上鞠。

pg_dump對于其他備份方法的一個重要優(yōu)勢是,pg_dump的輸出可以很容易地在新版本的PostgreSQL中載入谴咸,而文件級備份和連續(xù)歸檔都是極度的服務(wù)器版本限定的血巍。pg_dump也是唯一可以將一個數(shù)據(jù)庫傳送到一個不同機器架構(gòu)上的方法述寡,例如從一個32位服務(wù)器到一個64位服務(wù)器。

由pg_dump創(chuàng)建的備份在內(nèi)部是一致的掀序, 也就是說,轉(zhuǎn)儲表現(xiàn)了pg_dump開始運行時刻的數(shù)據(jù)庫快照换吧,且在pg_dump運行過程中發(fā)生的更新將不會被轉(zhuǎn)儲。pg_dump工作的時候并不阻塞其他的對數(shù)據(jù)庫的操作贯莺。 (但是會阻塞那些需要排它鎖的操作,比如大部分形式的ALTER TABLE)

2.1.1. 從轉(zhuǎn)儲中恢復(fù)

pg_dump生成的文本文件可以由psql程序讀取。 從轉(zhuǎn)儲中恢復(fù)的常用命令是:

psql dbname < infile

1

其中infile就是pg_dump命令的輸出文件潭兽。這條命令不會創(chuàng)建數(shù)據(jù)庫dbname,你必須在執(zhí)行psql前自己從template0創(chuàng)建(例如怒坯,用命令createdb -T template0 dbname)剔猿。psql支持類似pg_dump的選項用以指定要連接的數(shù)據(jù)庫服務(wù)器和要使用的用戶名酷含。 非文本文件轉(zhuǎn)儲可以使用pg_restore工具來恢復(fù)。

在開始恢復(fù)之前,轉(zhuǎn)儲庫中對象的擁有者以及在其上被授予了權(quán)限的用戶必須已經(jīng)存在媚赖。如果它們不存在,那么恢復(fù)過程將無法將對象創(chuàng)建成具有原來的所屬關(guān)系以及權(quán)限(有時候這就是你所需要的,但通常不是)番捂。

默認情況下,psql腳本在遇到一個SQL錯誤后會繼續(xù)執(zhí)行。你也許希望在遇到一個SQL錯誤后讓psql退出,那么可以設(shè)置ON_ERROR_STOP變量來運行psql彭谁,這將使psql在遇到SQL錯誤后退出并返回狀態(tài)3:

psql --set ON_ERROR_STOP=on dbname < infile

1

不管怎樣则奥,你將只能得到一個部分恢復(fù)的數(shù)據(jù)庫。作為另一種選擇,你可以指定讓整個恢復(fù)作為一個單獨的事務(wù)運行管闷,這樣恢復(fù)要么完全完成要么完全回滾。這種模式可以通過向psql傳遞-1或–single-transaction命令行選項來指定。在使用這種模式時呕臂,注意即使是很小的一個錯誤也會導(dǎo)致運行了數(shù)小時的恢復(fù)被回滾。但是,這仍然比在一個部分恢復(fù)后手工清理復(fù)雜的數(shù)據(jù)庫要更好阐虚。

pg_dump和psql讀寫管道的能力使得直接從一個服務(wù)器轉(zhuǎn)儲一個數(shù)據(jù)庫到另一個服務(wù)器成為可能,例如:

pg_dump -h host1 dbname | psql -h host2 dbname

1

重要

pg_dump產(chǎn)生的轉(zhuǎn)儲是相對于template0。這意味著在template1中加入的任何語言侮叮、過程等都會被pg_dump轉(zhuǎn)儲避矢。結(jié)果是,如果在恢復(fù)時使用的是一個自定義的template1,你必須從template0創(chuàng)建一個空的數(shù)據(jù)庫审胸,正如上面的例子所示亥宿。

一旦完成恢復(fù)砂沛,在每個數(shù)據(jù)庫上運行ANALYZE是明智的舉動烫扼,這樣優(yōu)化器就有有用的統(tǒng)計數(shù)據(jù)了。

2.1.2. 使用pg_dumpall

pg_dump每次只轉(zhuǎn)儲一個數(shù)據(jù)庫尺上,而且它不會轉(zhuǎn)儲關(guān)于角色或表空間(因為它們是集簇范圍的)的信息材蛛。為了支持方便地轉(zhuǎn)儲一個數(shù)據(jù)庫集簇的全部內(nèi)容,提供了pg_dumpall程序怎抛。pg_dumpall備份一個給定集簇中的每一個數(shù)據(jù)庫卑吭,并且也保留了集簇范圍的數(shù)據(jù),如角色和表空間定義马绝。該命令的基本用法是:

pg_dumpall > outfile

1

轉(zhuǎn)儲的結(jié)果可以使用psql恢復(fù):

psql -f infile postgres

1

(實際上豆赏,你可以指定恢復(fù)到任何已有數(shù)據(jù)庫名,但是如果你正在將轉(zhuǎn)儲載入到一個空集簇中則通常要用(postgres)富稻。在恢復(fù)一個pg_dumpall轉(zhuǎn)儲時常常需要具有數(shù)據(jù)庫超級用戶訪問權(quán)限掷邦,因為它需要恢復(fù)角色和表空間信息。如果你在使用表空間椭赋,請確保轉(zhuǎn)儲中的表空間路徑適合于新的安裝抚岗。

pg_dumpall工作時會發(fā)出命令重新創(chuàng)建角色、表空間和空數(shù)據(jù)庫哪怔,接著為每一個數(shù)據(jù)庫pg_dump宣蔚。這意味著每個數(shù)據(jù)庫自身是一致的,但是不同數(shù)據(jù)庫的快照并不同步认境。

集簇范圍的數(shù)據(jù)可以使用pg_dumpall的–globals-only選項來單獨轉(zhuǎn)儲胚委。如果在單個數(shù)據(jù)庫上運行pg_dump命令,上述做法對于完全備份整個集簇是必需的叉信。

2.1.3. 處理大型數(shù)據(jù)庫

在一些具有最大文件尺寸限制的操作系統(tǒng)上創(chuàng)建大型的pg_dump輸出文件可能會出現(xiàn)問題亩冬。幸運地是,pg_dump可以寫出到標(biāo)準(zhǔn)輸出硼身,因此你可以使用標(biāo)準(zhǔn)Unix工具來處理這種潛在的問題硅急。有幾種可能的方法:

使用壓縮轉(zhuǎn)儲。. 你可以使用你喜歡的壓縮程序佳遂,例如gzip:

pg_dump dbname | gzip > filename.gz

1

恢復(fù):

gunzip -c filename.gz | psql dbname

1

或者:

cat filename.gz | gunzip | psql dbname

1

使用split营袜。. split命令允許你將輸出分割成較小的文件以便能夠適應(yīng)底層文件系統(tǒng)的尺寸要求。例如讶迁,讓每一塊的大小為1兆字節(jié):

pg_dump dbname | split -b 1m - filename

1

恢復(fù):

cat filename* | psql dbname

1

使用pg_dump的自定義轉(zhuǎn)儲格式连茧。. 如果PostgreSQL所在的系統(tǒng)上安裝了zlib壓縮庫,自定義轉(zhuǎn)儲格式將在寫出數(shù)據(jù)到輸出文件時對其壓縮巍糯。這將產(chǎn)生和使用gzip時差不多大小的轉(zhuǎn)儲文件啸驯,但是這種方式的一個優(yōu)勢是其中的表可以被有選擇地恢復(fù)。下面的命令使用自定義轉(zhuǎn)儲格式來轉(zhuǎn)儲一個數(shù)據(jù)庫:

pg_dump -Fc dbname > filename

1

自定義格式的轉(zhuǎn)儲不是psql的腳本祟峦,只能通過pg_restore恢復(fù)罚斗,例如:

pg_restore -d dbname filename

1

詳情請參閱pg_dump和pg_restore。

對于非常大型的數(shù)據(jù)庫宅楞,你可能需要將split配合其他兩種方法之一進行使用针姿。

使用pg_dump的并行轉(zhuǎn)儲特性。. 為了加快轉(zhuǎn)儲一個大型數(shù)據(jù)庫的速度厌衙,你可以使用pg_dump的并行模式距淫。它將同時轉(zhuǎn)儲多個表。你可以使用-j參數(shù)控制并行度婶希。并行轉(zhuǎn)儲只支持“目錄”歸檔格式榕暇。

pg_dump -j num -F d -f out.dir dbname

1

你可以使用pg_restore -j來以并行方式恢復(fù)一個轉(zhuǎn)儲。它只能適合于“自定義”歸檔或者“目錄”歸檔喻杈,但不管歸檔是否由pg_dump -j創(chuàng)建彤枢。

2.2. 文件系統(tǒng)級別備份(冷備份)

文件系統(tǒng)級別備份策略是直接復(fù)制PostgreSQL用于存儲數(shù)據(jù)庫中數(shù)據(jù)的文件。你可以采用任何你喜歡的方式進行文件系統(tǒng)備份筒饰。

數(shù)據(jù)庫集簇說明:

在磁盤上初始化一個數(shù)據(jù)庫存儲區(qū)域稱之為一個數(shù)據(jù)庫集簇(SQL標(biāo)準(zhǔn)使用的術(shù)語是目錄集簇)缴啡。一個數(shù)據(jù)庫集簇是被一個運行數(shù)據(jù)庫服務(wù)器的單一實例所管理的多個數(shù)據(jù)庫的集合。

在文件系統(tǒng)術(shù)語中瓷们,一個數(shù)據(jù)庫集簇是一個單一目錄业栅,所有數(shù)據(jù)都將被存儲在其中。我們稱它為數(shù)據(jù)目錄或數(shù)據(jù)區(qū)域换棚。在哪里存儲你的數(shù)據(jù)完全由你選擇式镐。沒有默認的位置,不過/usr/local/pgsql/data或/var/lib/pgsql/data位置比較流行固蚤。

你的數(shù)據(jù)庫集簇的文件系統(tǒng)位置由-D選項指定娘汞,例如:

$ initdb -D /usr/local/pgsql/data

1

作為-D選項的一種替換方案,你可以設(shè)置環(huán)境變量PGDATA夕玩。

2.2.1備份數(shù)據(jù)庫集簇文件

示例

tar -cf backup.tar /usr/local/pgsql/data

1

限制

文件系統(tǒng)級別備份數(shù)據(jù)的方法有兩個限制你弦,使得這種方法不實用:

1.為了得到一個可用的備份,數(shù)據(jù)庫服務(wù)器必須被關(guān)閉燎孟。例如阻止所有連接這樣的不徹底的措施是不起作用的(部分原因是tar和類似工具無法得到文件系統(tǒng)狀態(tài)的一個原子的快照禽作,還有服務(wù)器內(nèi)部緩沖的原因)不用說,在恢復(fù)數(shù)據(jù)之前你也需要關(guān)閉服務(wù)器揩页。

2.如果你已經(jīng)深入地了解了數(shù)據(jù)庫的文件系統(tǒng)布局的細節(jié)旷偿,你可能會有興趣嘗試通過相應(yīng)的文件或目錄來備份或恢復(fù)特定的表或數(shù)據(jù)庫。這種方法也不會起作用,因為包含在這些文件中的信息只有配合提交日志文件(pg_xact/)才有用萍程,提交日志文件包含了所有事務(wù)的提交狀態(tài)幢妄。一個表文件只有和這些信息一起才有用。當(dāng)然也不可能只恢復(fù)一個表及相關(guān)的pg_xact數(shù)據(jù)茫负,因為這會導(dǎo)致數(shù)據(jù)庫集簇中所有其他表變得無用蕉鸳。因此文件系統(tǒng)備份只適合于完整地備份或恢復(fù)整個數(shù)據(jù)庫集簇*。

2.2.2一致快照

另一種文件系統(tǒng)備份方法是創(chuàng)建一個數(shù)據(jù)目錄的“一致快照”忍法,如果文件系統(tǒng)支持此功能(并且你相信它的實現(xiàn)正確)潮尝。典型的過程是創(chuàng)建一個包含數(shù)據(jù)庫的卷的“凍結(jié)快照”,然后從該快照復(fù)制整個數(shù)據(jù)目錄(如上饿序,不能是部分復(fù)制)到備份設(shè)備勉失,最后釋放凍結(jié)快照。即使在數(shù)據(jù)庫服務(wù)器運行時原探,這種方式也有效戴质。但是,以這種方式創(chuàng)建的備份保存的文件看起來就像數(shù)據(jù)庫沒有被正確關(guān)閉時的狀態(tài)踢匣。因此告匠,當(dāng)你從備份數(shù)據(jù)上啟動數(shù)據(jù)庫服務(wù)器時,它會認為上一次的服務(wù)器實例崩潰了并嘗試重放WAL日志离唬。這不是問題后专,只是需要注意(當(dāng)然WAL文件必須要包括在備份中)。你可以在拍攝快照之前執(zhí)行一次CHECKPOINT以便節(jié)省恢復(fù)時間输莺。

如果你的數(shù)據(jù)庫跨越多個文件系統(tǒng)戚哎,可能沒有任何方式可以對所有卷獲得完全同步的凍結(jié)快照。例如嫂用,如果你的數(shù)據(jù)文件和WAL日志放置在不同的磁盤上型凳,或者表空間在不同的文件系統(tǒng)中,可能沒有辦法使用快照備份嘱函,因為快照必須是同步的甘畅。在這些情況下,一定要仔細閱讀你的文件系統(tǒng)文檔以了解其對一致快照技術(shù)的支持往弓。

如果沒有可能獲得同步快照疏唾,一種選擇是將數(shù)據(jù)庫服務(wù)器關(guān)閉足夠長的時間以建立所有的凍結(jié)快照。另一種選擇是執(zhí)行一次連續(xù)歸檔基礎(chǔ)備份函似,因為這種備份對于備份期間發(fā)生的文件系統(tǒng)改變是免疫的槐脏。這要求在備份過程中允許連續(xù)歸檔,恢復(fù)時使用連續(xù)歸檔恢復(fù)撇寞。

2.2.3 rsync

使用rsync來執(zhí)行一次文件系統(tǒng)備份顿天,是先在數(shù)據(jù)庫服務(wù)器運行時執(zhí)行rsync堂氯,然后關(guān)閉數(shù)據(jù)庫服務(wù)器足夠長時間來做一次rsync --checksum (–checksum是必需的,因為rsync的文件修改 時間粒度只能精確到秒)牌废。第二次rsync會比第一次快祖灰,因為它只需要傳送相對很少的數(shù)據(jù),由于服務(wù)器是停止的畔规,所以最終結(jié)果將是一致的。這種方法允許在最小停機時間內(nèi)執(zhí)行一次文件系統(tǒng)備份恨统。

2.2.4小結(jié)

這種備份方式需要關(guān)閉數(shù)據(jù)庫叁扫,然后拷貝數(shù)據(jù)文件的完整目錄⌒舐瘢恢復(fù)數(shù)據(jù)庫時莫绣,只需將數(shù)據(jù)目錄復(fù)制到原來的位置。該方式實際工作中很少使用悠鞍。

一個文件系統(tǒng)備份通常會比一個SQL轉(zhuǎn)儲體積更大(例如pg_dump不需要轉(zhuǎn)儲索引的內(nèi)容对室,而是轉(zhuǎn)儲用于重建索引的命令)。但是咖祭,做一次文件系統(tǒng)備份可能更快掩宜。

2.3. 連續(xù)歸檔和時間點恢復(fù)(PITR)

2.3.1.整體介紹

在任何時間,PostgreSQL在數(shù)據(jù)集簇目錄的pg_wal/子目錄下都保持有一個預(yù)寫式日志(WAL)么翰。這個日志存在的目的是為了保證崩潰后的安全:如果系統(tǒng)崩潰牺汤,可以“重放”從最后一次檢查點以來的日志項來恢復(fù)數(shù)據(jù)庫的一致性。該日志的存在也使得第三種備份數(shù)據(jù)庫的策略變得可能:我們可以把一個文件系統(tǒng)級別的備份和WAL文件的備份結(jié)合起來浩嫌。當(dāng)需要恢復(fù)時檐迟,我們先恢復(fù)文件系統(tǒng)備份,然后從備份的WAL文件中重放來把系統(tǒng)帶到一個當(dāng)前狀態(tài)码耐。這種方法比之前的方法管理起來要更復(fù)雜追迟,但是有其顯著的優(yōu)點。

優(yōu)點:

1.我們不需要一個完美的一致的文件系統(tǒng)備份作為開始點骚腥。備份中的任何內(nèi)部不一致性將通過日志重放(這和崩潰恢復(fù)期間發(fā)生的并無顯著不同)來修正敦间。因此我們不需要文件系統(tǒng)快照功能,只需要tar或一個類似的歸檔工具束铭。

2. 由于我們可以結(jié)合一個無窮長的WAL文件序列用于重放每瞒,可以通過簡單地歸檔WAL文件來達到連續(xù)備份。這對于大型數(shù)據(jù)庫特別有用纯露,因為在其中不方便頻繁地進行完全備份剿骨。

3.并不需要一直重放WAL項一直到最后。我們可以在任何點停止重放埠褪,并得到一個數(shù)據(jù)庫在當(dāng)時的一致快照浓利。這樣挤庇,該技術(shù)支持時間點恢復(fù):在得到你的基礎(chǔ)備份以后,可以將數(shù)據(jù)庫恢復(fù)到它在其后任何時間的狀態(tài)贷掖。

4.如果我們連續(xù)地將一系列WAL文件輸送給另一臺已經(jīng)載入了相同基礎(chǔ)備份文件的機器嫡秕,我們就得到了一個熱備份系統(tǒng):在任何時間點我們都能提出第二臺機器,它差不多是數(shù)據(jù)庫的當(dāng)前副本苹威。

注意:

pg_dump和pg_dumpall不會產(chǎn)生文件系統(tǒng)級別的備份昆咽,并且不能用于連續(xù)歸檔方案。這類轉(zhuǎn)儲是邏輯的并且不包含足夠的信息用于WAL重放牙甫。

就簡單的文件系統(tǒng)備份技術(shù)來說掷酗,這種方法只能支持整個數(shù)據(jù)庫集簇的恢復(fù),卻無法支持其中一個子集的恢復(fù)窟哺。另外泻轰,它需要大量的歸檔存儲:一個基礎(chǔ)備份的體積可能很龐大,并且一個繁忙的系統(tǒng)將會產(chǎn)生大量需要被歸檔的WAL流量且轨。盡管如此浮声,在很多需要高可靠性的情況下,它是首選的備份技術(shù)旋奢。

要使用連續(xù)歸檔(也被很多數(shù)據(jù)庫廠商稱為“在線備份”)成功地恢復(fù)泳挥,你需要一個從基礎(chǔ)備份時間開始的連續(xù)的歸檔WAL文件序列。為了開始至朗,在你建立第一個基礎(chǔ)備份之前羡洁,你應(yīng)該建立并測試用于歸檔WAL文件的過程。對應(yīng)地爽丹,我們首先討論歸檔WAL文件的機制筑煮。

2.3.2.建立WAL歸檔

抽象地來說,一個運行中的PostgreSQL系統(tǒng)產(chǎn)生一個無窮長的WAL記錄序列粤蝎。系統(tǒng)從物理上將這個序列劃分成WAL 段文件真仲,通常是每個16MB(段尺寸在構(gòu)建PostgreSQL時可修改)。段文件會被分配一個數(shù)字名稱以便反映它在整個抽象WAL序列中的位置初澎。在沒有使用WAL歸檔時秸应,系統(tǒng)通常只創(chuàng)建少量段文件,并且通過重命名不再使用的段文件為更高的段編號來“回收”它們碑宴。系統(tǒng)假設(shè)內(nèi)容位于最后一個檢查點之前的段文件是無用的且可以被回收软啼。

在歸檔WAL數(shù)據(jù)時,我們需要在每一段被填充滿時捕捉其內(nèi)容延柠,并且在段文件被回收重用之前保存該數(shù)據(jù)祸挪。依靠應(yīng)用和可用的硬件,有很多不同的方法來“保存數(shù)據(jù)”:我們可以將段文件拷貝到一個已掛載的位于另一臺機器上的NFS目錄贞间,或者將它們寫出到一個磁帶驅(qū)動器(確保你有辦法標(biāo)識每個文件的原始文件名)贿条,或者將它們批量燒錄到CD上雹仿,或者其他什么方法。為了向數(shù)據(jù)庫管理員提供靈活性整以,PostgreSQL不對如何歸檔做任何假設(shè)胧辽。取而代之的是,PostgreSQL讓管理員聲明一個shell命令來拷貝一個完整的段文件到它需要去的地方公黑。 該命令可以簡單得就是一個cp邑商,或者它可以調(diào)用一個復(fù)雜的 shell 腳本 — 所有都由你決定。

要啟用WAL歸檔凡蚜,需設(shè)置wal_level配置參數(shù)為replica或更高人断,設(shè)置archive_mode為on,并且使用archive_command配置參數(shù)指定一個shell命令番刊。實際上,這些設(shè)置總是被放置在postgresql.conf文件中影锈。在archive_command中芹务,%p會被將要歸檔的文件路徑所替代,而%f只會被文件名所替代(路徑名是相對于當(dāng)前工作目錄而言的鸭廷,即集簇的數(shù)據(jù)目錄)枣抱。修改postgresql.conf文件,如果你需要在命令中嵌入一個真正的%字符,可以使用%%辆床。最簡單的命令類似于:

archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'? # Unix

archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"'? # Windows

1

2

它將把 WAL 段拷貝到目錄/mnt/server/archivedir(這個只是一個例子佳晶,并非我們建議的方法,可能不能在所有系統(tǒng)上都正確運行)讼载。在%p和%f參數(shù)被替換之后轿秧,實際被執(zhí)行的命令看起來可能是:

test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065

1

對每一個將要被歸檔的新文件都會生成一個類似的命令。

歸檔命令將在運行PostgreSQL服務(wù)器的同一個用戶的權(quán)限下執(zhí)行咨堤。因為被歸檔的一系列WAL 文件實際上包含你的數(shù)據(jù)庫里的所有東西,所以你應(yīng)該確保自己的歸檔數(shù)據(jù)不會被別人窺探; 比如荒吏,歸檔到一個沒有組或者全局讀權(quán)限的目錄里涛碑。

有一點很重要:當(dāng)且僅當(dāng)歸檔命令成功時,它才返回零退出凸克。在得到一個零值結(jié)果之后议蟆,PostgreSQL將假設(shè)該文件已經(jīng)成功歸檔, 因此它稍后將被刪除或者被新的數(shù)據(jù)覆蓋萎战。但是咐容,一個非零值告訴PostgreSQL該文件沒有被歸檔; 因此它會周期性的重試直到成功蚂维。

歸檔命令通常應(yīng)該被設(shè)計成拒絕覆蓋已經(jīng)存在的歸檔文件疟丙。這是一個非常重要的安全特性颖侄, 可以在管理員操作失誤(比如把兩個不同的服務(wù)器的輸出發(fā)送到同一個歸檔目錄)的時候保持你的歸檔的完整性。

我們建議你首先要測試你準(zhǔn)備使用到歸檔命令享郊,以保證它實際上不會覆蓋現(xiàn)有的文件览祖, 并且在這種情況下它返回非零狀態(tài)。以上Unix中的命令例子通過包含一個獨立的test步驟來保證這一點炊琉。

在設(shè)計你的歸檔環(huán)境時展蒂,請考慮一下如果歸檔命令不停失敗會發(fā)生什么情況, 因為有些情況要求操作者的干涉苔咪,或者是歸檔空間不夠了锰悼。你應(yīng)該確保任何錯誤情況或者任何要求操作員干涉的情況都會被正確報告, 這樣才能迅速解決這些問題团赏。否則pg_wal/目錄會不停地被WAL段文件填充箕般, 直到問題解決(如果包含pg_wal/的文件系統(tǒng)被填滿,PostgreSQL將會做一次致命關(guān)閉舔清。不會有未提交事務(wù)被丟失丝里,但是數(shù)據(jù)庫將會保持離線直到你釋放一部分空間)。

歸檔命令的速度并不要緊体谒,只要它能跟上你的服務(wù)器生成 WAL 數(shù)據(jù)的平均速度即可杯聚。即使歸檔進程稍微落后,正常的操作也會繼續(xù)進行抒痒。 如果歸檔進程慢很多幌绍,就會增加災(zāi)難發(fā)生的時候丟失的數(shù)據(jù)量。這同時也意味著pg_wal/目錄包含大量未歸檔的段文件故响, 并且可能最后超出了可用磁盤空間傀广。我們建議你監(jiān)控歸檔進程,確保它是按照你的期望運轉(zhuǎn)的彩届。

在寫自己的歸檔命令的時候主儡,你應(yīng)該假設(shè)被歸檔的文件名最長為64個字符并且可以包含 ASCII 字母、數(shù)字以及點的任意組合惨缆。 我們不需要保持原始的相對路徑(%p)糜值,但是有必要保持文件名(%f)。

請注意盡管 WAL 歸檔允許你恢復(fù)任何對你的PostgreSQL數(shù)據(jù)庫中數(shù)據(jù)所做的修改坯墨, 但它不會恢復(fù)對配置文件的修改(即postgresql.conf寂汇、pg_hba.conf 和 pg_ident.conf),因為這些文件都是手工編輯的捣染,而不是通過 SQL 操作來編輯的骄瓣。 所以你可能會需要把你的配置文件放在一個日常文件系統(tǒng)備份過程可處理的位置。

歸檔命令只會為完成的WAL段調(diào)用耍攘。因此如果你的服務(wù)器產(chǎn)生了一點點WAL流量(或者在產(chǎn)生時有寬松的周期)榕栏,從一個事務(wù)完成到它被安全地記錄在歸檔存儲中之間將會有較長的延遲畔勤。要為未歸檔數(shù)據(jù)設(shè)置一個年齡限制,你可以設(shè)置archive_timeout來強制要求服務(wù)器按照其設(shè)定的頻度切換到一個新的WAL段扒磁。注意由于強制切換而被歸檔的文件還是具有和完全歸檔的文件相同的長度庆揪。因此設(shè)置一個很短的archive_timeout是很不明智的 — 它會膨脹你的歸檔存儲。將archive_timeout設(shè)置為1分鐘左右通常是合理的妨托。

同樣缸榛,如果你希望確保一個剛剛完成的事務(wù)能被盡快歸檔,可以使用pg_switch_xlog進行一次手動段切換兰伤。

當(dāng)wal_level為minimal時内颗,一些SQL命令被優(yōu)化為避免記錄WAL日志。在這些語句的其中之一的執(zhí)行過程中如果打開了歸檔或流復(fù)制敦腔,WAL中將不會包含足夠的信息用于歸檔恢(崩潰恢復(fù)不受影響)均澳。出于這個原因,wal_level只能在服務(wù)器啟動時修改符衔。但是找前,archive_command可以通過重載配置文件來修改。如果你希望暫時停止歸檔柏腻,一種方式是將archive_command設(shè)置為空串('')纸厉。這將導(dǎo)致WAL文件積累在pg_wal/中系吭,直到一個可用的archive_command被重新建立五嫂。

2.3.3.制作一個基礎(chǔ)備份

執(zhí)行一次基礎(chǔ)備份最簡單的方法是使用pg_basebackup工具。它將會以普通文件或一個tar歸檔的方式創(chuàng)建一個基礎(chǔ)備份肯尺。如果需要比pg_basebackup更高的靈活性沃缘,你也可以使用低級API來制作一個基礎(chǔ)備份。

沒有必要關(guān)心創(chuàng)建一個基礎(chǔ)備份所需的時間则吟。但是槐臀,如果你正常地運行停用了full_page_writes的服務(wù)器,你可能會注意到備份運行時的性能下降氓仲,因為full_page_writes在備份模式期間會被實際強制實施水慨。

要使用備份,你將需要保留所有在文件系統(tǒng)備份期間及之后生成的WAL段文件敬扛。為了便于你做這些晰洒,基礎(chǔ)備份過程會創(chuàng)建一個備份歷史文件,它將被立刻存儲到WAL歸檔區(qū)域啥箭。該文件以文件系統(tǒng)備份中你需要的第一個WAL段文件命名谍珊。例如,如果開始的WAL文件是0000000100001234000055CD急侥,則備份歷史文件將被命名為0000000100001234000055CD.007C9330.backup.(文件名的第二部分表明WAL文件中的一個準(zhǔn)確位置砌滞,一般可以被忽略)侮邀。一旦你已經(jīng)安全地歸檔了文件系統(tǒng)備份和在備份過程中被使用的WAL段文件(如備份歷史文件中所指定的) ,所有名字在數(shù)字上低于備份歷史文件中記錄值的已歸檔WAL段對于恢復(fù)文件系統(tǒng)備份就不再需要了贝润,并且可以被刪除绊茧。但是你應(yīng)該考慮保持多個備份集以絕對保證你能恢復(fù)你的數(shù)據(jù)。

備份歷史文件是一個很小的文本文件题暖。它包含你指定給pg_basebackup的標(biāo)簽字符串按傅,以及備份的起止時間以及起止WAL段。如果你使用該標(biāo)簽來標(biāo)識相關(guān)轉(zhuǎn)儲文件胧卤,則已歸檔的歷史文件足以說明需要哪個轉(zhuǎn)儲文件進行恢復(fù)唯绍。

由于你不得不保存最后一次基礎(chǔ)備份之后的所有歸檔WAL文件,基礎(chǔ)備份之間的間隔通常應(yīng)該根據(jù)你希望在歸檔WAL文件上花費的存儲空間來設(shè)定枝誊。你也應(yīng)該考慮你準(zhǔn)備花多長時間來進行恢復(fù)况芒,如果需要恢復(fù) — 系統(tǒng)將不得不重放所有那些WAL段,如果這些WAL段覆蓋了最后一次基礎(chǔ)備份以后的很長時間叶撒,重放過程將會花費一些時間绝骚。

2.3.4.使用低級API制作一個基礎(chǔ)備份

使用低級API制作一個基礎(chǔ)備份的過程比pg_basebackup方法要包含更多的步驟,但相對要更簡單祠够。很重要的一點是压汪,這些步驟要按照順序執(zhí)行,并且在執(zhí)行下一步之前要驗證上一步是否成功古瓤。

可以用非排他或者排他的方法來制作低級基礎(chǔ)備份止剖。我們推薦非排他方法,而排他的方法已經(jīng)被廢棄并且最終將被去除落君。

2.3.4.1. 制作一個非排他低級備份

非排他低級備份允許其他并發(fā)備份運行(既包括那些使用同樣的 備份 API 開始的備份穿香,也包括那些使用 pg_basebackup開始的備份)。

1.確保WAL歸檔被啟用且正在工作绎速。

2.作為一個具有運行 pg_start_backup 權(quán)利的用戶(超級用戶皮获,或者被授予在該 函數(shù)上 EXECUTE 的用戶)連接到服務(wù)器(不在乎是哪個數(shù)據(jù)庫)并且發(fā)出命令:

SELECT pg_start_backup('label', false, false);

1

其中l(wèi)abel是用來唯一標(biāo)識這次備份操作的任意字符串。調(diào)用 pg_start_backup的連接必須被保持到備份結(jié)束纹冤,否則備份 將被自動中止洒宝。

默認情況下,pg_start_backup可能需要較長的時間完成萌京。 這是因為它會執(zhí)行一個檢查點雁歌,并且該檢查點所需要的 I/O 將會分散到一段 顯著的時間上,默認情況下是你的檢查點間隔(見配置參數(shù) checkpoint_completion_target)的一半枫夺。這通常 是你所想要的将宪,因為它可以最小化對查詢處理的影響。如果你想要盡可能快地 開始備份,請把第二個參數(shù)改成true较坛, 這將使用盡可能多的I/O發(fā)出即時檢查點印蔗。

第三個參數(shù)為false會告訴pg_start_backup 開始一次非排他基礎(chǔ)備份。

3.使用任何趁手的文件系統(tǒng)備份工具(例如tar或者 cpio丑勤,不是pg_dump 或者pg_dumpall)執(zhí)行備份华嘹。當(dāng)你做這些 時,不需要也不值得停止正常的數(shù)據(jù)庫操作法竞。

4.在同一個連接中耙厚,發(fā)出命令:

SELECT * FROM pg_stop_backup(false);

1

這會終止備份模式。在主服務(wù)器上岔霸,它還自動切換到下一個 WAL 段薛躬。 在備服務(wù)器上,無法自動切換WAL段呆细,因此您可能希望在主服務(wù)器上運行 pg_switch_wal以執(zhí)行手動切換型宝。 切換的原因是讓備份間隔期間寫入的最后一個WAL段文件準(zhǔn)備歸檔。

pg_stop_backup將返回一個具有三個值的行絮爷。這些域的 第二個應(yīng)該被寫入到該備份根目錄中名為backup_label的 文件趴酣。第三個域應(yīng)該被寫入到一個名為tablespace_map 的文件,除非該域為空坑夯。這些文件對該備份正常工作來說是至關(guān)重要的岖寞, 不能被隨意修改。

一旦備份期間活動的 WAL 段文件被歸檔柜蜈,備份就完成了仗谆。由 pg_stop_backup的第一個返回值標(biāo)識的文件是構(gòu)成一個 完整備份文件集合所需的最后一個段。在主服務(wù)器上跨释,如果 archive_mode被啟用胸私,并且wait_for_archive參數(shù)為true厌处,則直到最后一個段被歸檔前pg_stop_backup都不會 返回鳖谈。在備用服務(wù)器上,為了使pg_stop_backup等待阔涉, archive_mode必須是always缆娃。 從你已經(jīng)配置好archive_command之后這些文件的 歸檔就會自動發(fā)生。在大部分情況下瑰排,這些歸檔會很快發(fā)生贯要,但是建議你監(jiān)控你的歸檔系統(tǒng)確保沒有延遲。如果歸檔進程由于歸檔命令的失敗而落后椭住,它將會持續(xù)重試直到歸檔成功并且備份完成崇渗。如果你希望對 pg_stop_backup的執(zhí)行給出一個時間限制,可以設(shè)置一個 合適的statement_timeout值,但要注意如果 pg_stop_backup因此而中止會致使備份可能失效宅广。

如果備份進程監(jiān)視并確保備份所需的所有WAL段文件已成功歸檔葫掉,則可以將 wait_for_archive參數(shù)(默認為true)設(shè)置為false以使 停止備份記錄寫入WAL后,pg_stop_backup立即返回跟狱。 默認情況下俭厚,pg_stop_backup將一直等到所有WAL歸檔完畢, 這可能需要一些時間驶臊。必須謹慎使用此選項:如果未正確監(jiān)控WAL歸檔挪挤, 則備份可能未包括所有WAL文件,因此將不完整且無法恢復(fù)关翎。

2.3.4.2. 制作一個排他低級備份

一個排他備份的處理絕大部分都和非排他備份相同扛门,但是在一些關(guān)鍵步驟上 不同。這種類型的備份只能在主服務(wù)器上進行纵寝,并且不允許并發(fā)備份尖飞。

1.確保 WAL 歸檔被啟用且正常工作。

2.作為一個具有運行 pg_start_backup 權(quán)利的用戶(超級用戶店雅,或者被授予在該 函數(shù)上 EXECUTE 的用戶)連接到服務(wù)器(不在乎是哪個數(shù)據(jù)庫)并且發(fā)出命令:

SELECT pg_start_backup('label');

1

這里label是任何你希望用來唯一標(biāo)識這個備份操作的字符串政基。 pg_start_backup在集簇目錄中創(chuàng)建一個關(guān)于備份信息的 備份標(biāo)簽文件,也被稱為backup_label闹啦, 其中包括了開始時間和標(biāo)簽字符串沮明。該函數(shù)也會在集簇目錄中創(chuàng)建一個 名為tablespace_map的表空間映射文件, 如果在pg_tblspc/中有一個或者多個表空間符號鏈接存在窍奋, 該文件會包含它們的信息荐健。如果你需要從備份中恢復(fù),這兩個文件對于備份的 完整性都至關(guān)重要琳袄。

默認情況下江场,pg_start_backup會花費很長時間來完成。這是因為它會執(zhí)行一個檢查點窖逗,而檢查點所需要的I/O在相當(dāng)一段時間內(nèi)將會被傳播址否,默認情況下這段時間是內(nèi)部檢查點間隔的一半。這通常是你所希望的碎紊,因為它能將對查詢處理的影響最小化佑附。如果你要盡快開始備份,可使用:

SELECT pg_start_backup('label', true);

1

這會使檢查點盡可能快地被完成仗考。

使用任何方便的文件系統(tǒng)備份工具執(zhí)行備份音同,例如tar 或cpio(不是pg_dump 或pg_dumpall)。在此期間秃嗜,不需要也 不值得停止正常的數(shù)據(jù)庫操作权均。

注意顿膨,如果服務(wù)器在備份期間崩潰,直到從PGDATA 目錄手動刪除backup_label文件叽赊,才可能重新啟動虽惭。

4.再次以具有運行 pg_stop_backup 權(quán)利的用戶(超級用戶,或者已經(jīng)被授予 該函數(shù)上 EXECUTE 的用戶)連接到數(shù)據(jù)庫并且發(fā)出命令:

SELECT pg_stop_backup();

1

該函數(shù)終止備份模式蛇尚,并且執(zhí)行一個自動切換到下一個WAL段芽唇。 進行切換的原因是將在備份期間生成的最新WAL段安排為可歸檔。

5.一旦備份期間活動的WAL段文件被歸檔取劫,你的工作就完成了匆笤。 pg_stop_backup的結(jié)果所標(biāo)識的文件是構(gòu)成一個完整備份 文件組所需的最新段。如果archive_mode被啟用谱邪,直到最 新段被歸檔pg_stop_backup都不會返回炮捧。由于你已經(jīng)配置了 archive_command,這些文件的歸檔過程會自動發(fā)生惦银。在 大部分情況下這會很快發(fā)生咆课,但還是建議你監(jiān)控你的歸檔系統(tǒng)來確保不會有 延遲。如果歸檔處理由于歸檔命令的錯誤而延遲扯俱,它會保持重試直到歸檔成 功和備份完成书蚪。如果你希望在pg_stop_backup的執(zhí)行上 設(shè)置一個時間限制,可對statement_timeout設(shè) 置一個合適的值迅栅,但要注意如果pg_stop_backup因此而 中止會致使備份可能失效殊校。

2.3.4.3. 備份數(shù)據(jù)目錄

如果被拷貝的文件在拷貝過程中發(fā)生變化,某些文件系統(tǒng)備份工具會發(fā)出警告或錯誤读存。在建立一個活動數(shù)據(jù)庫的基礎(chǔ)備份時为流,這種情況是正常的,并非一個錯誤让簿。然而敬察,你需要確保你能夠把它們和真正的錯誤區(qū)分開。例如尔当,某些版本的rsync為“消失的源文件”返回一個獨立的退出碼莲祸,且你可以編寫一個驅(qū)動腳本來將該退出碼接受為一種非錯誤情況。同樣居凶,如果一個文件在被tar復(fù)制的過程中被截斷虫给,某些版本的GNU tar會返回一個與致命錯誤無法區(qū)分的錯誤代碼藤抡。幸運的是侠碧,如果一個文件在備份期間被改變,版本為1.16及其后的GNU tar將會退出并返回1缠黍,而對于其他錯誤返回2弄兜。在版本1.23及其后的GNU tar中,你可以使用警告選項--warning=no-file-changed --warning=no-file-removed來隱藏相關(guān)的警告消息。

確認你的備份包含數(shù)據(jù)庫集簇目錄(例如/usr/local/pgsql/data)下的所有文件替饿。如果你使用了不在此目錄下的表空間语泽,注意也把它們包括在內(nèi)(并且確保你的備份將符號鏈接歸檔為鏈接,否則恢復(fù)過程將破壞你的表空間)视卢。

不過踱卵,你應(yīng)當(dāng)從備份中忽略集簇的pg_wal/子目錄中的文件。這種微小的調(diào)整是值得的据过,因為它降低了恢復(fù)時的錯誤風(fēng)險惋砂。如果pg_wal/是一個指向位于集簇目錄之外其他地方的符號鏈接就很容易安排了,這是一種出于性能原因的常見設(shè)置绳锅。你可能也希望排除postmaster.pid和postmaster.opts西饵,它們記錄了關(guān)于postmaster運行的信息,但與最終使用這個備份的postmaster無關(guān)(這些文件可能會使pg_ctl搞混淆)鳞芙。

從備份中忽略集簇的pg_replslot/子目錄中的文件通常也是個好主意眷柔,這樣 主控機上存在的復(fù)制槽不會成為備份的一部分。否則原朝,后續(xù)用該備份創(chuàng)建一個后備機可能會導(dǎo)致該 后備機上的WAL文件被無限期保留驯嘱,并且在啟用了熱后備反饋的情況下可能導(dǎo)致主控機膨脹,因為使用 那些復(fù)制槽的客戶端將繼續(xù)連接到主控機(而不是后備機)并且繼續(xù)更新其上的槽喳坠。即使該備份是要被 用來創(chuàng)建一個新的主控機宙拉,拷貝復(fù)制槽也不是特別有用,因為這些槽的內(nèi)容在新主控機上線時很可能已 經(jīng)過時丙笋。

pg_dynshmem/谢澈、pg_notify/、pg_serial/御板、pg_snapshots/锥忿、pg_stat_tmp/和pg_subtrans/目錄的內(nèi)容()(但不是目錄本身)可以從備份中省略, 因為它們將在postmaster啟動時初始化怠肋。如果設(shè)置了 stats_temp_directory并且是在數(shù)據(jù)目錄下敬鬓, 那么也可以省略該目錄的內(nèi)容。

任何以pgsql_tmp開頭的文件或目錄都可以從備份中省略笙各。 這些文件在postmaster啟動時被刪除钉答,并且根據(jù)需要重新創(chuàng)建目錄。

備份標(biāo)簽文件包含你指定給pg_start_backup的標(biāo)簽字符串杈抢,以及 pg_start_backup被運行的時刻和起始WAL文件的名字数尿。 在發(fā)生混亂的情況下就可以在備份文件中查看并準(zhǔn)確地決定該轉(zhuǎn)儲文件來 自于哪個備份會話。表空間映射文件包括存在于目錄pg_tblspc/ 中的符號鏈接名稱以及每一個符號鏈接的完整路徑惶楼。這些文件不僅是為了供參考右蹦, 它們的存在和內(nèi)容對于系統(tǒng)恢復(fù)過程的正確操作是至關(guān)重要诊杆。

在服務(wù)器停止時也可以創(chuàng)建一個備份。在這種情況下何陆,你顯然不能使用 pg_start_backup或pg_stop_backup晨汹, 并且因此你只能依靠你的自己的策略來跟蹤哪個備份是哪個, 以及相關(guān)WAL文件應(yīng)該走回到什么程度贷盲。通常最好遵循上面的連續(xù)歸檔過程淘这。

2.3.5. 使用一個連續(xù)歸檔備份進行恢復(fù)

你需要從備份進行恢復(fù),其過程如下:

1.如果服務(wù)器仍在運行巩剖,停止它慨灭。

2.如果你具有足夠的空間,將整個集簇數(shù)據(jù)目錄和表空間復(fù)制到一個臨時位置球及,稍后你將用到它們氧骤。注意這種預(yù)防措施將要求在你的系統(tǒng)上有足夠的空閑空間來保留現(xiàn)有數(shù)據(jù)庫的兩個拷貝。如果你沒有足夠的空間吃引,你至少要保存集簇的pg_wal子目錄的內(nèi)容筹陵,因為它可能包含在系統(tǒng)垮掉之前還未被歸檔的日志。

3.移除所有位于集簇數(shù)據(jù)目錄和正在使用的表空間根目錄下的文件和子目錄镊尺。

4.從你的文件系統(tǒng)備份中恢復(fù)數(shù)據(jù)庫文件朦佩。注意它們要使用正確的所有權(quán)恢復(fù)(數(shù)據(jù)庫系統(tǒng)用戶,不是rootB)并且使用正確的權(quán)限语稠。如果你在使用表空間,你應(yīng)該驗證pg_tblspc/中的符號鏈接被正確地恢復(fù)弄砍。

5.移除pg_wal/中的任何文件仙畦,這些是來自于文件系統(tǒng)備份而不是當(dāng)前日志,因此可以被忽略音婶。如果你根本沒有歸檔pg_wal/慨畸,那么以正確的權(quán)限重建它。注意如果以前它是一個符號鏈接衣式,請確保你也以同樣的方式重建它寸士。

6.如果你有在第2步中保存的未歸檔WAL段文件,把它們拷貝到pg_wal/(最好是拷貝而不是移動它們碴卧,這樣如果在開始恢復(fù)后出現(xiàn)問題你任然有未修改的文件)弱卡。

7.在集簇數(shù)據(jù)目錄中創(chuàng)建一個恢復(fù)命令文件recovery.conf。你可能還想臨時修改pg_hba.conf來阻止普通用戶在成功恢復(fù)之前連接住册。

8.啟動服務(wù)器婶博。服務(wù)器將會進入到恢復(fù)模式并且進而根據(jù)需要讀取歸檔WAL文件〗缁。恢復(fù)可能因為一個外部錯誤而被終止凡蜻,可以簡單地重新啟動服務(wù)器搭综,這樣它將繼續(xù)恢復(fù)垢箕』ǎ恢復(fù)過程結(jié)束后,服務(wù)器將把recovery.conf重命名為recovery.done(為了阻止以后意外地重新進入恢復(fù)模式)条获,并且開始正常數(shù)據(jù)庫操作忠荞。

9.檢查數(shù)據(jù)庫的內(nèi)容來確保你已經(jīng)恢復(fù)到了期望的狀態(tài)。如果沒有帅掘,返回到第1步委煤。如果一切正常,通過恢復(fù)pg_hba.conf為正常來允許用戶連接修档。

所有這些的關(guān)鍵部分是設(shè)置一個恢復(fù)配置文件碧绞,它描述你希望如何恢復(fù)以及恢復(fù)要運行到什么程度。你可以使用recovery.conf.sample(通常在安裝的share/目錄中)作為一個原型吱窝。你絕對必須在recovery.conf中指定的是restore_command讥邻,它告訴PostgreSQL如何獲取歸檔WAL文件段。與archive_command相似院峡,這也是一個shell命令字符串兴使。它可以包含%f(將被期望的日志文件名替換)和%p(將被日志文件被拷貝的目標(biāo)路徑名替換)。(路徑名是相對于當(dāng)前工作目錄的照激,即集簇的數(shù)據(jù)目錄)发魄。如果你需要在命令中嵌入一個真正的%字符,可以寫成%%俩垃。最簡單的命令類似于:

restore_command = 'cp /mnt/server/archivedir/%f %p'

1

它將從目錄/mnt/server/archivedir中拷貝之前歸檔的WAL段励幼。當(dāng)然,你可以使用更復(fù)雜的口柳,甚至是一個要求操作者裝載合適磁帶的shell腳本赏淌。

重要的是命令在失敗時返回非零退出狀態(tài)。該命令將被調(diào)用來請求不在歸檔中的文件啄清, 在這種情況下它應(yīng)該返回非零值六水。這不是一種錯誤情況。一種例外是該命令被一個信號(除了被用作數(shù) 據(jù)庫服務(wù)器關(guān)閉動作一部分的SIGTERM)終止或者被shell的錯誤 (例如命令未找到)終止辣卒,那樣恢復(fù)將中止并且服務(wù)器將不會啟動掷贾。

并非所有被請求的文件都是WAL段文件,你也許還會請求一些具有.backup或 .history后綴的文件荣茫。還要注意的是想帅,%p路徑的基本名字將會和%f 不同,但不要期望它們可以互換啡莉。

歸檔中找不到的WAL段可以在pg_wal/中看到港准,這使得可以使用最近未歸檔的段旨剥。但是,在歸檔中可用的段將會被優(yōu)先于pg_wal/中的文件被使用浅缸。

通常轨帜,恢復(fù)將會處理完所有可用的WAL段,從而將數(shù)據(jù)庫恢復(fù)到當(dāng)前時間點(或者盡可能接近給定的可 用WAL段)衩椒。因此蚌父,一個正常的恢復(fù)將會以一個“文件未找到”消息結(jié)束,錯誤消息的準(zhǔn)確文 本取決于你選擇的restore_command毛萌。你也可能在恢復(fù)的開始看到一個針對名稱類 似于00000001.history文件的錯誤消息苟弛。這也是正常的并且不表示在簡單恢復(fù)情況中的問題。

如果你希望恢復(fù)到之前的某個時間點(例如阁将,恢復(fù)到幼稚的DBA丟棄了你主要的交易表之前)膏秫,只需要 在recovery.conf中指定要求的停止點。你可以使用日期/時間做盅、命名恢復(fù)點或一個 指定事務(wù)ID的結(jié)束時間來定義停止點(也被稱為“恢復(fù)目標(biāo)”)缤削。在這種寫法中,只有日期/時 間和命名恢復(fù)點選項非常有用言蛇,因為沒有工具可以幫助你準(zhǔn)確地確定要用哪個事務(wù)ID僻他。

注意

停止點必須位于基礎(chǔ)備份的完成時間之后,即pg_stop_backup的完成時間腊尚。在備份過程中你不能使用基礎(chǔ)備份來恢復(fù)(要恢復(fù)到這個時間吨拗,你必須回到你之前的基礎(chǔ)備份并且從這里開始前滾)。

如果恢復(fù)找到被破壞的WAL數(shù)據(jù)婿斥,恢復(fù)將會停止于該點并且服務(wù)器不會啟動劝篷。在這種情況下,恢復(fù)進程需要從開頭重新開始運行民宿,并指定一個在損壞點之前的“恢復(fù)目標(biāo)”以便恢復(fù)能夠正常完成娇妓。如果恢復(fù)由于一個外部原因失敗,例如一個系統(tǒng)崩潰或者WAL歸檔變?yōu)椴豢稍L問活鹰,則該次恢復(fù)可以被簡單地重啟并且它將會從幾乎是上次失敗的地方繼續(xù)哈恰。恢復(fù)重啟工作起來很像普通操作時的檢查點:服務(wù)器周期性地強制把它的所有狀態(tài)寫到磁盤中志群,然后更新pg_control文件來說明已經(jīng)處理過的WAL數(shù)據(jù)着绷,這樣它們就不會被再次掃描。

2.3.6. 時間線

將數(shù)據(jù)庫恢復(fù)到一個之前的時間點的能力帶來了一些復(fù)雜性锌云,想回到最初歷史中的某個時間荠医。你沒法這樣做,在你的數(shù)據(jù)庫在線運行期間,它重寫了某些WAL段文件彬向,而這些文件本來可以將你引向你希望回到的時間兼贡。因此,為了避免出現(xiàn)這種狀況娃胆,你需要將完成時間點恢復(fù)后生成的WAL記錄序列與初始數(shù)據(jù)庫歷史中產(chǎn)生的WAL記錄序列區(qū)分開來遍希。

要解決這個問題,PostgreSQL有一個時間線概念缕棵。無論何時當(dāng)一次歸檔恢復(fù)完成孵班,一個新的時間線被創(chuàng)建來標(biāo)識恢復(fù)之后生成的WAL記錄序列涉兽。時間線ID號是WAL段文件名的一部分招驴,因此一個新的時間線不會重寫由之前的時間線生成的WAL數(shù)據(jù)。實際上可以歸檔很多不同的時間線枷畏。雖然這可能看起來是一個無用的特性别厘,但是它常常扮演救命稻草的角色∮倒睿考慮到你不太確定需要恢復(fù)到哪個時間點的情況触趴,你可能不得不做多次時間點恢復(fù)嘗試和錯誤,直到最終找到從舊歷史中分支出去的最佳位置渴肉。如果沒有時間線衅枫,該處理將會很快生成一堆不可管理的混亂龄糊。而有了時間線,你可以恢復(fù)到任何之前的狀態(tài),包括早先被你放棄的時間線分支中的狀態(tài)悯周。

每次當(dāng)一個新的時間線被創(chuàng)建,PostgreSQL會創(chuàng)建一個“時間線歷史”文件驶鹉,它顯示了新時間線是什么時候從哪個時間線分支出來的轰驳。系統(tǒng)在從一個包含多個時間線的歸檔中恢復(fù)時,這些歷史文件對于允許系統(tǒng)選取正確的WAL段文件非常必要礁苗。因此爬凑,和WAL段文件相似,它們也要被歸檔到WAL歸檔區(qū)域试伙。歷史文件是很小的文本文件嘁信,因此將它們無限期地保存起來的代價很小,而且也是很合適的(而段文件都很大)疏叨。如果你喜歡潘靖,你可以在一個歷史文件中增加注釋來記錄如何和為什么要創(chuàng)建該時間線。當(dāng)你由于試驗的結(jié)果擁有了一大堆錯綜復(fù)雜的不同時間線時考廉,這種注釋將會特別有價值秘豹。

恢復(fù)的默認行為是沿著相同的時間線進行恢復(fù),該時間線是基礎(chǔ)備份創(chuàng)建時的當(dāng)前時間線昌粤。如果你希望恢復(fù)到某個子女時間線(即既绕,你希望回到在一次恢復(fù)嘗試后產(chǎn)生的某個狀態(tài))啄刹,你需要在recovery.conf中指定目標(biāo)時間線ID。你不能恢復(fù)到早于該基礎(chǔ)備份之前分支出去的時間線凄贩。

2.3.7.操作實例

2.3.7.1. 單機熱備份

可以使用PostgreSQL的備份功能來產(chǎn)生單機熱備份誓军。這些備份不能被用于時間點恢復(fù),然而備份和恢復(fù)時要比使用pg_dump轉(zhuǎn)儲更快(它們也比pg_dump轉(zhuǎn)儲更大疲扎,所以在某些情況下速度優(yōu)勢可能會被否定)昵时。

在基礎(chǔ)備份的幫助下,產(chǎn)生一個單機熱備份最簡單的方式是使用 pg_basebackup工具椒丧。如果你在調(diào)用它時使用了 -X參數(shù)壹甥,使用該備份所需的所有預(yù)寫式日志將會被自動包含在該備份中,并且恢復(fù)該備份也不需要特殊的動作壶熏。

如果在復(fù)制備份文件時需要更多靈活性句柠,也可以使用一個較低層的處理來創(chuàng)建單機熱備份。要為低層 單機熱備份做準(zhǔn)備棒假,確保將wal_level設(shè)置為replica或更高溯职, archive_mode設(shè)置為on,并且設(shè)置一個archive_command帽哑,該命令只當(dāng)一個開關(guān)文件存在時執(zhí)行歸檔谜酒。例如:

wal_level = 'replica'

archive_mode = ‘on'

archive_command = 'test ! -f /var/lib/pgsql/backup_in_progress || (test ! -f /var/lib/pgsql/archive/%f && cp %p /var/lib/pgsql/archive/%f)'

1

2

3

該命令在/var/lib/pgsql/backup_in_progress存在時執(zhí)行歸檔,否則會安靜地返回0值退出狀態(tài)(讓PostgreSQL能回收不需要的WAL文件)妻枕。

通過這樣的準(zhǔn)備僻族,可以使用一個如下所示的腳本來建立備份:

touch /var/lib/pgsql/backup_in_progress

psql -c "select pg_start_backup('hot_backup');"

tar -cf /var/lib/pgsql/backup.tar /var/lib/pgsql/data/

psql -c "select pg_stop_backup();"

rm /var/lib/pgsql/backup_in_progress

tar -rf /var/lib/pgsql/backup.tar /var/lib/pgsql/archive/

1

2

3

4

5

6

開關(guān)文件 /var/lib/pgsql/backup_in_progress首先被創(chuàng)建,這使對于未完成WAL文件的歸檔操作發(fā)生佳头。備份完成之后開關(guān)文件會被刪除鹰贵。歸檔的WAL文件則被加入到備份中,這樣基礎(chǔ)備份和所有需要的WAL文件都是同一個tar文件的組成部分康嘉。請記住在你的備份腳本中加入錯誤處理碉输。

2.3.7.2. 壓縮的歸檔日志

如果擔(dān)心歸檔存儲的尺寸,你可以使用gzip來壓縮歸檔文件:

archive_command = 'gzip < %p > /var/lib/pgsql/archive/%f'

1

那么在恢復(fù)時你將需要使用gunzip:

restore_command = 'gunzip < /mnt/server/archivedir/%f > %p'

1

2.3.7.3. archive_command腳本

很多人選擇使用腳本來定義他們的archive_command亭珍,這樣他們的postgresql.conf項看起來非常簡單:

archive_command = 'local_backup_script.sh "%p" "%f"'

1

任何時候如果你希望在歸檔處理中使用多個命令敷钾,明智的方法是使用一個獨立的腳本文件。這可以使腳本更為復(fù)雜肄梨,它可以使用一種流行的腳本語言來編寫阻荒,例如bash 或perl。

需要在一個腳本內(nèi)解決的需求例子包括:

? 將數(shù)據(jù)拷貝到安全的場外數(shù)據(jù)存儲

? 批處理WAL文件众羡,這樣它們可以每三小時被傳輸一次侨赡,而不是一次一個

? 與其他備份和恢復(fù)軟件交互

? 與監(jiān)控軟件交互以報告錯誤

提示

在使用一個`archive_command`腳本時,最好啟用`logging_collector`。任何從該腳本被寫到stderr的消息將出現(xiàn)在數(shù)據(jù)庫服務(wù)器日志中羊壹,這允許在復(fù)雜配置失敗后能更容易被診斷蓖宦。

1

2

2.3.8.警告

連續(xù)歸檔技術(shù)存在一些限制:

如果一個CREATE DATABASE命令在基礎(chǔ)備份時被執(zhí)行,然后在基礎(chǔ)備份進行時CREATE DATABASE所復(fù)制的模板數(shù)據(jù)庫被修改油猫,恢復(fù)中可能會導(dǎo)致這些修改也被傳播到已創(chuàng)建的數(shù)據(jù)庫中稠茂。這當(dāng)然是我們不希望的。為了避免這種風(fēng)險情妖,最好不要在創(chuàng)建基礎(chǔ)備份時修改任何模板數(shù)據(jù)庫睬关。

CREATE TABLESPACE命令會WAL以其字面絕對路徑記錄,并且因此將在重放時以相同的絕對路徑來創(chuàng)建表空間毡证。當(dāng)日志在一臺不同的機器上被重放時电爹,這可能也不是我們希望的。即使日志在同一臺機器上被重放也是危險的情竹,就算是恢復(fù)到一個新的數(shù)據(jù)目錄重放過程也會覆蓋原來表空間的內(nèi)容藐不。為了避免這種潛在的陷阱匀哄,最佳做法是在創(chuàng)建或丟棄表空間后創(chuàng)建一個新的基礎(chǔ)備份秦效。

還需要注意的是,默認的WAL格式相當(dāng)龐大涎嚼,因為它包括了很多磁盤頁快照阱州。這些頁快照被設(shè)計用于支持崩潰恢復(fù),因為我們可能需要修復(fù)斷裂的磁盤頁法梯。依靠你的系統(tǒng)硬件和軟件苔货,頁斷裂的風(fēng)險可能會小到可以忽略,在此種情況下你可以通過使用full_page_writes參數(shù)關(guān)閉頁快照來顯著降低歸檔日志的總?cè)萘苛⒀啤jP(guān)閉頁快照并不會阻止使用日志進行PITR操作夜惭。一個未來的開發(fā)點是通過移除不需要的頁拷貝來壓縮歸檔的WAL數(shù)據(jù),即使full_page_writes為on铛绰。同時诈茧,管理員可能希望通過盡可能增大檢查點間隔參數(shù)來減少WAL中包含的頁快照數(shù)量。

參考:

https://www.postgresql.org/docs/10/different-replication-solutions.html

https://edu.csdn.net/course/play/25603/307048

https://edu.csdn.net/course/play/25785/313742

https://edu.csdn.net/course/play/25125/292196

————————————————

版權(quán)聲明:本文為CSDN博主「沒刮胡子」的原創(chuàng)文章捂掰,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議敢会,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/somken/article/details/96428979

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末这嚣,一起剝皮案震驚了整個濱河市鸥昏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌姐帚,老刑警劉巖吏垮,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡膳汪,警方通過查閱死者的電腦和手機像樊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旅敷,“玉大人生棍,你說我怎么就攤上這事∠彼” “怎么了涂滴?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長晴音。 經(jīng)常有香客問我柔纵,道長,這世上最難降的妖魔是什么锤躁? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任搁料,我火速辦了婚禮,結(jié)果婚禮上系羞,老公的妹妹穿的比我還像新娘郭计。我一直安慰自己,他們只是感情好椒振,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布昭伸。 她就那樣靜靜地躺著,像睡著了一般澎迎。 火紅的嫁衣襯著肌膚如雪庐杨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天夹供,我揣著相機與錄音,去河邊找鬼填渠。 笑死揭蜒,一個胖子當(dāng)著我的面吹牛屉更,可吹牛的內(nèi)容都是我干的瑰谜。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼职车!你這毒婦竟也來了鹊杖?” 一聲冷哼從身側(cè)響起积瞒,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤茫孔,失蹤者是張志新(化名)和其女友劉穎缰贝,沒想到半個月后揩瞪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡壹将,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了承粤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仙粱。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡伐割,死狀恐怖隔心,靈堂內(nèi)的尸體忽然破棺而出帜慢,到底是詐尸還是另有隱情唯卖,我是刑警寧澤密幔,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布胯甩,位于F島的核電站偎箫,受9級特大地震影響淹办,放射性物質(zhì)發(fā)生泄漏怜森。R本人自食惡果不足惜副硅,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一恐疲、第九天 我趴在偏房一處隱蔽的房頂上張望培己。 院中可真熱鬧省咨,春花似錦茸炒、人聲如沸壁公。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妥色。三九已至,卻和暖如春吮便,著一層夾襖步出監(jiān)牢的瞬間许师,已是汗流浹背微渠。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人攻臀。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓刨啸,卻偏偏與公主長得像设联,于是被迫代替她去往敵國和親离例。 傳聞我的和親對象是個殘疾皇子艘包,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容