Chapter 22. 備份和恢復

Table of Contents
22.1. SQL 轉儲
22.1.1. 從轉儲中恢復
22.1.2. 使用 pg_dumpall
22.1.3. 處理大資料庫
22.1.4. 注意
22.2. 文件系統級別的備份
22.3. 在線備份以及即時恢復(PITR)
22.3.1. 設置 WAL 歸檔
22.3.2. 進行一次基礎備份
22.3.3. 從在線備份中恢復
22.3.4. 時間線
22.3.5. 注意
22.4. 在不同版本之間遷移

和任何包含珍貴資料的東西一樣,PostgreSQL 資料庫也應該經常備份。儘管這個過程相當簡單, 但是我們還是應該理解做這件事所用的一些技巧和假設。

備份 PostgreSQL 資料有三種完全不同的方法:

每種備份都有自己的優點和缺點。

22.1. SQL 轉儲

SQL 轉儲的方法採用的主意是建立一個文本文件,這個文本裡面都是 SQL 命令,當把這個文件回饋給伺服器時,將重建與轉儲時狀態一樣的資料庫。 PostgreSQL 為這個用途提供了應用工具 pg_dump。這條命令的基本用法是:

pg_dump dbname > outfile

正如您所見,pg_dump 把結果輸出到標準輸出。 我們下面就可以看到這樣做有什麼好處。

pg_dump 是一個普通的 PostgreSQL 客戶端應用(儘管是個相當聰明的東西。)這就意味著您可以從任何可以訪問該資料庫的遠端主機上面進行備份工作。 但是請記住 pg_dump 不會以任何特殊權限執行。具體說來, 就是它必須要有您想備份的資料表的讀權限,因此,實際上您幾乎總是要成為資料庫超級用戶。

要聲明 pg_dump 應該以哪個用戶身份進行連線,使用命令行選項 -h host-p port。 預設主機是本地主機或您的環境變量PGHOST聲明的值。 類似,預設連接埠是環境變量PGPORT或(如果它不存在的話)編譯好了的預設值。 (伺服器通常有相同的預設,所以還算方便。)

和任何其他 PostgreSQL 客戶端應用一樣, pg_dump 預設時用與目前操作系統用戶名同名的資料庫用戶名進行連線。 要覆蓋這個名字,要麼聲明 -U 選項, 要麼設置環境變量PGUSER。 請注意 pg_dump 的連線也和普通客戶應用一樣要透過客戶認證機制(在 Chapter 19)裡描述。

pg_dump 建立的備份在內部是一致的, 也就是說,在pg_dump執行的時候對資料庫的更新將不會被轉儲。 pg_dump 工作的時候並不阻塞其他的對資料庫的操作。 (但是會阻塞那些需要排它鎖的操作,比如 VACUUM FULL。)

Important: 如果您的資料庫結構依賴於 OID (比如說用做外鍵),那麼您必須告訴 pg_dump 把 OID 也倒出來。 要倒 OID,可以使用 -o 命令行選項。 預設時也不會轉儲"大對像"。如果您使用大對象,請參考 pg_dump 的命令手冊頁。

22.1.1. 從轉儲中恢復

pg_dump 生成的文本文件可以由 psql 程序讀取。 從轉儲中恢復的常用命令是

psql dbname < infile

這裡的 infile 就是您給pg_dump命令的 outfile參數。這條命令不會建立資料庫 dbname,您必須在執行psql 前自己從template0建立(也就是說,用命令 createdb -T template0 dbname)。 psql 支援類似 pg_dump 的選項用以控制資料庫伺服器位置和用戶名。 參閱 psql 的手冊獲取更多訊息。

在開始執行恢復之前,目標庫和所有在轉儲出來的庫中擁有對象的用戶, 以及曾經在某些對像上被賦予權限的用戶都必須已經存在。 如果這些不存在,那麼恢復將失敗,因為恢復過程無法把這些對像恢復成原有的所有權和/或權限。 (有時候您希望恢復權限,不過通常您不需要這麼做。)

一旦完成恢復,在每個資料庫上執行 ANALYZE 是明智的舉動, 這樣優化器就有有用的統計資料了。您總是可以執行 vacuumdb -a -zVACUUM ANALYZE 所有資料庫;這個等效於手工執行 VACUUM ANALYZE

pg_dumppsql 可以透過管道讀寫, 這樣我們就可能從一台主機上將資料庫目錄轉儲到另一台主機上,比如

pg_dump -h host1 dbname | psql -h host2 dbname

Important: pg_dump生成的轉儲輸出是相對於template0的。這就意味著任何 加入到template1的語言,過程等都會經由 pg_dump 轉儲。結果是,在恢復的時候,如果您使用的是客戶化的template1, 那麼您必須從template0中建立空的資料庫,就像我們上面的例子那樣。

有關如何有效地向 PostgreSQL 裡裝載大量資料的建議, 請參考 Section 13.4

22.1.2. 使用 pg_dumpall

上面的方法在備份整個資料庫集群的時候比較麻煩而且不方便。因此我們提供了 pg_dumpall 程序。 pg_dumpall 備份一個給出的集群中的每個資料庫,同時還確保保留象用戶和組這樣的全局資料狀態。 這個命令的基本用法是:

pg_dumpall > outfile

生成的轉儲可以用 psql 恢復:

psql template1 < infile

(實際上,您可以聲明任意現有的資料庫進行連接,但是如果您是向一個空的資料庫裝載,那麼 template1 是您唯一的選擇。) 恢復pg_dumpall的轉儲的時候通常需要資料庫超級用戶權限,因為我們需要它來恢復用戶和組訊息。

22.1.3. 處理大資料庫

因為 PostgreSQL 允許資料表的大小大於您的系統允許的最大文件大小, 可能把資料表轉儲到一個文件會有問題,因為生成的文件很可能比您的系統允許的最大文件大。 因為 pg_dump 輸出到標準輸出,您可以用標準的 Unix 工具繞開這個問題:

使用壓縮的轉儲. 使用您熟悉的壓縮程序,比如說 gzip

pg_dump dbname | gzip > filename.gz

用下面命令恢復:

createdb dbname
gunzip -c filename.gz | psql dbname

或者

cat filename.gz | gunzip | psql dbname

使用 split。. split 命令允許您 您用下面的方法把輸出分解成操作系統可以接受的大小。 比如,讓每個塊大小為 1 兆字元:

pg_dump dbname | split -b 1m - filename

用下面命令恢復:

createdb dbname
cat filename* | psql dbname

使用客戶化轉儲格式. 如果PostgreSQL是在一個安裝了zlib 壓縮庫的系統上製作的, 那麼客戶化轉儲格式將在寫入輸出文件的時候壓縮資料。 它會生成和使用 gzip 類似大小的轉儲文件, 但是還附加了一個優點:您可以有選擇地恢復庫中的資料表。 下面的命令用客戶化轉儲格式轉儲一個資料庫:

pg_dump -Fc dbname > filename

客戶化格式的轉儲不是腳本,不能用於 psql, 而是需要使用 pg_restore 轉儲。 請參考 pg_dumppg_restore 的手冊獲取細節。

22.1.4. 注意

出於向下兼容的考慮,預設的時候 pg_dump 並不轉儲大對象。 要轉儲大對象,您必須使用客戶化或者 tar 輸出格式, 並且在 pg_dump 中使用-b選項。 參閱 pg_dump 手冊獲取詳細訊息。 在 PostgreSQL 源碼樹的 contrib/pg_dumplo 路徑裡也包含一個可以轉儲大對象的程序。

請熟悉一下 pg_dump 的手冊頁。