此轉儲方法的理念是生成一個包含 SQL 命令的檔案,當將這些命令重新饋送到伺服器時,將重新建立資料庫,使其恢復到轉儲時的狀態。PostgreSQL為此目的提供了實用程式 pg_dump。該命令的基本用法是
pg_dumpdbname
>dumpfile
正如您所見,pg_dump 將其結果寫入標準輸出。下面我們將看到這如何有用。雖然上面的命令建立了一個文字檔案,但 pg_dump 可以建立其他格式的檔案,這些格式允許並行處理和更精細地控制物件的恢復。
pg_dump 是一個常規的 PostgreSQL 客戶端應用程式(儘管是一個特別聰明的應用程式)。這意味著您可以從任何能夠訪問資料庫的遠端主機執行此備份過程。但請記住,pg_dump 不會以特殊許可權執行。特別是,它必須具有對您想要備份的所有表的讀取訪問許可權,因此為了備份整個資料庫,您幾乎總是需要以資料庫超級使用者的身份執行它。(如果您沒有足夠的許可權來備份整個資料庫,您仍然可以使用 -n
或 schema
-t
等選項備份您有權訪問的資料庫部分。)table
要指定 pg_dump 應該聯絡哪個資料庫伺服器,請使用命令列選項 -h
和 host
-p
。預設主機是本地主機,或者您的 port
PGHOST
環境變數指定的任何內容。同樣,預設埠由 PGPORT
環境變數指示,或者在沒有該變數的情況下,由編譯時預設值指示。(方便的是,伺服器通常具有相同的編譯時預設值。)
與其他任何 PostgreSQL 客戶端應用程式一樣,pg_dump 預設將以與當前作業系統使用者名稱相同的資料庫使用者名稱進行連線。要覆蓋此設定,請指定 -U
選項或設定環境變數 PGUSER
。請記住,pg_dump 連線受常規客戶端身份驗證機制(在第 20 章中描述)的約束。
pg_dump 相對於後面描述的其他備份方法的一個重要優點是,pg_dump 的輸出通常可以重新載入到較新版本的 PostgreSQL 中,而檔案級備份和連續歸檔都與伺服器版本高度相關。pg_dump 也是在將資料庫傳輸到不同機器架構(例如從 32 位伺服器遷移到 64 位伺服器)時唯一可行的方法。
pg_dump 建立的轉儲是內部一致的,這意味著轉儲代表了 pg_dump 開始執行時資料庫的快照。pg_dump 在工作時不會阻止資料庫上的其他操作。(例外情況是那些需要以獨佔鎖執行的操作,例如大多數形式的 ALTER TABLE
。)
pg_dump 建立的文字檔案旨在由 psql 程式使用其預設設定進行讀取。恢復文字轉儲的通用命令形式是
psql -Xdbname
<dumpfile
其中 dumpfile
是由 pg_dump 命令輸出的檔案。此命令不會建立 dbname
資料庫,因此您必須在執行 psql 之前從 template0
建立它(例如,使用 createdb -T template0
)。為確保 psql 以其預設設定執行,請使用 dbname
-X
(--no-psqlrc
)選項。psql 支援類似於 pg_dump 的選項,用於指定要連線的資料庫伺服器和要使用的使用者名稱。有關更多資訊,請參閱 psql 參考頁。
應使用 pg_restore 實用程式恢復非文字檔案轉儲。
在恢復 SQL 轉儲之前,所有擁有物件或在轉儲資料庫中被授予物件許可權的使用者必須已存在。如果不存在,則恢復將無法以原始所有權和/或許可權重新建立物件。(有時這就是您想要的,但通常不是。)
預設情況下,SQL 錯誤發生後,psql 指令碼將繼續執行。您可能希望執行 psql 並將 ON_ERROR_STOP
變數設定為更改此行為,並使 psql 在發生 SQL 錯誤時以退出狀態 3 退出
psql -X --set ON_ERROR_STOP=ondbname
<dumpfile
無論哪種方式,您只會得到一個部分恢復的資料庫。或者,您可以指定整個轉儲應作為單個事務恢復,這樣恢復就會完全完成或完全回滾。此模式可以透過將 -1
或 --single-transaction
命令列選項傳遞給 psql 來指定。使用此模式時,請注意,即使是微小的錯誤也可能回滾已執行數小時的恢復。但是,這可能仍然比手動清理複雜的資料庫(在部分恢復的轉儲之後)更好。
pg_dump 和 psql 能夠讀寫管道,這使得可以直接將資料庫從一個伺服器轉儲到另一個伺服器,例如
pg_dump -hhost1
dbname
| psql -X -hhost2
dbname
pg_dump 生成的轉儲是相對於 template0
的。這意味著透過 template1
新增的任何語言、過程等也將由 pg_dump 轉儲。因此,在恢復時,如果您使用的是自定義的 template1
,則必須從 template0
建立空資料庫,如上面的示例所示。
在恢復備份後,明智的做法是對每個資料庫執行 ANALYZE
,以便查詢最佳化器擁有有用的統計資訊;有關更多資訊,請參閱第 24.1.3 節和第 24.1.6 節。有關如何高效地將大量資料載入到 PostgreSQL 中的更多建議,請參閱第 14.4 節。
pg_dump 一次只能轉儲一個數據庫,並且不轉儲有關角色或表空間的資訊(因為這些是叢集範圍的,而不是每個資料庫的)。為了方便地轉儲資料庫叢集的全部內容,提供了 pg_dumpall 程式。pg_dumpall 會備份給定叢集中的每個資料庫,並保留叢集範圍的資料,如角色和表空間定義。該命令的基本用法是
pg_dumpall > dumpfile
生成的轉儲可以使用 psql 進行恢復
psql -X -f dumpfile
postgres
(實際上,您可以指定任何現有的資料庫名稱作為起點,但如果您正在載入到一個空叢集,則通常應使用 postgres
。)恢復 pg_dumpall 轉儲時,始終需要資料庫超級使用者訪問許可權,因為這是恢復角色和表空間資訊所必需的。如果您使用了表空間,請確保轉儲中的表空間路徑適合新安裝。
pg_dumpall 的工作方式是發出命令來重新建立角色、表空間和空資料庫,然後為每個資料庫呼叫 pg_dump。這意味著雖然每個資料庫將是內部一致的,但不同資料庫的快照不是同步的。
可以使用 pg_dumpall 的 --globals-only
選項單獨轉儲叢集範圍的資料。這對於在單獨的資料庫上執行 pg_dump 命令時完全備份叢集是必需的。
某些作業系統有最大檔案大小限制,這在建立大型 pg_dump 輸出檔案時會導致問題。幸運的是,pg_dump 可以寫入標準輸出,因此您可以使用標準的 Unix 工具來解決此潛在問題。有幾種可能的方法:
使用壓縮轉儲。 您可以使用您喜歡的壓縮程式,例如 gzip
pg_dumpdbname
| gzip >filename
.gz
使用以下命令重新載入:
gunzip -cfilename
.gz | psqldbname
或
catfilename
.gz | gunzip | psqldbname
使用 split
。 split
命令允許您將輸出分割成對底層檔案系統大小可接受的更小檔案。例如,建立 2 GB 的塊:
pg_dumpdbname
| split -b 2G -filename
使用以下命令重新載入:
catfilename
* | psqldbname
如果使用 GNU split,則可以將它與 gzip 一起使用:
pg_dump dbname
| split -b 2G --filter='gzip > $FILE.gz'
可以使用 zcat
進行恢復。
使用 pg_dump 的自定義轉儲格式。 如果 PostgreSQL 是在安裝了 zlib 壓縮庫的系統上構建的,則自定義轉儲格式在寫入輸出檔案時將壓縮資料。這將產生與使用 gzip
相似的轉儲檔案大小,但它還有一個額外的優點,即可以有選擇地恢復表。以下命令使用自定義轉儲格式轉儲資料庫:
pg_dump -Fcdbname
>filename
自定義格式的轉儲不是用於 psql 的指令碼,而是必須使用 pg_restore 進行恢復,例如:
pg_restore -ddbname
filename
有關詳細資訊,請參閱 pg_dump 和 pg_restore 參考頁。
對於非常大的資料庫,您可能需要將 split
與其他兩種方法之一結合使用。
使用 pg_dump 的並行轉儲功能。 要加快大型資料庫的轉儲速度,可以使用 pg_dump 的並行模式。這將同時轉儲多個表。您可以使用 -j
引數控制並行度。並行轉儲僅支援“目錄”存檔格式。
pg_dump -jnum
-F d -fout.dir
dbname
您可以使用 pg_restore -j
來並行恢復轉儲。這適用於任何“自定義”或“目錄”存檔模式的存檔,無論它是否是用 pg_dump -j
建立的。
如果您在文件中看到任何不正確的內容、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用此表單報告文件問題。