1. 程式人生 > >PostgreSQL備份與恢復(全)

PostgreSQL備份與恢復(全)

www.wohedb.com  中文資料庫管理系統

 

                              PostgreSQL備份與恢復

    PostgreSQL提供了三種備份和恢復的方式:SQL dump、檔案系統複製和聯機熱備份。 每一種備份方式都有自己的優點和缺點,下面將詳細介紹。

9.1 SQL Dump
     這種備份方式產生一個文字檔案,裡面包含建立各種資料庫物件的SQL語句和每個表中的資料。另外,表上建立的索引中的資料不會被匯出,只會匯出索引的定義資訊。在恢復資料庫的時候,索引會被重建。可以使用資料庫提供的工具pg_dumpall和pg_dump來進行備份。pg_dumpall會備份一個數據庫叢集中的所有資訊和資料。pg_dump只備份資料庫叢集中的某個資料庫的資料,它不會匯出角色和表空間相關的資訊,因為這些資訊是整個資料庫叢集共用的,不屬於某個單獨的資料庫。pg_dump的基本用法如下:

pg_dump 資料庫名 > 備份檔名

pg_dump將結果寫到標準輸出中,可以用作業系統的重定向命令將結果寫到檔案中。

 

    可以在執行資料庫的機器上執行pg_dump命令,也可以在其它的機器上執行pg_dump命令。 可以使用選項-h和-p來指定執行資料庫的主機名和資料庫監聽的埠。例如:

pg_dump -h db_server1 -p 5432  product > backup_file 

該命令連線機器db_server1上在埠5432處監聽的資料庫,將資料庫product的資料備份到檔案backup_file中。如果pg_dump命令沒有使用-h和-p選項,將使用環境變數PGHOST的值作為機器名,使用環境變數PGPORT的值作為資料庫的埠。如果使用者沒有定義環境變數PGHOST,預設使用本機名作為執行資料庫的機器名。

 

     預設的情況下,pg_dump使用當前的作業系統使用者作為連線資料庫時使用的使用者。可以使用選項-U或者設定環境變數PGUSER來指定連線資料庫時使用的使用者名稱。例如:

pg_dump -U liming -h db_server1 -p 5432  product > backup_file 

該命令使用使用者liming連線機器db_server1上在埠5432處監聽的資料庫,將資料庫product的資料備份到檔案backup_file中。

 

一般情況下,應該使用超級使用者連線資料庫進行備份操作,因為超級使用者可以訪問資料庫中的任何資訊。使用普通資料使用者連線資料庫,有些表可能無法訪問。

 

執行pg_dump時,資料可以正常地執行其它操作。但ALTER TABLE這類修改資料庫物件定義的操作會受到影響,可能會長時間處於等待狀態而無法執行,所以在執行pg_dump命令時,不要在資料庫中執行修改資料庫物件定義的操作。

 

    另外要注意的是,如果資料庫中有些表使用OID來實現外來鍵約束,應當在備份資料庫時同時備份表的OID資訊,使用pg_dump時加上選項–o即可達到這個目的。

9.1.1 恢復資料庫
    pg_dump建立的備份檔案可以被工具psql識別。因此可以使用psql來讀取pg_dump建立的備份檔案,實現恢復資料庫的功能。例如:

psql dbname < backup_file

psql後面的引數dbname指定的資料庫必須已經存在。如果不存在,使用者應當先建立dbname指定的資料庫,然後再執行恢復資料的命令。psql也支援和pg_dump一樣的命令列選項,如-h和-p等。建立資料庫dbname時,必須使用template0作為模板資料庫,可以使用工具createdb建立資料庫,也可以在psql中執行SQL命令create database來建立資料庫。下面是兩個例項:

(1)createdb -T template0 dbname

(2)create database dbname template=template0

 

    另外,在執行恢復資料的操作以前,那些擁有資料庫備份中的資料庫物件或則對這些物件有訪問許可權的資料庫的使用者必須已經在資料庫中存在,否則,恢復資料庫以後,資料庫備份中的資料庫物件的所有者會發生改變。

 

    預設的情況下,psql命令會一直執行下去直到結束,即使中間遇到SQL錯誤,恢復操作也會繼續執行。如果想讓psql在執行過程中遇到錯誤以後,停止恢復操作,可以在執行恢復操作以前,在psql中執行下面的命令:

\set ON_ERROR_STOP

 

    如果psql在執行過程中遇到錯誤,則只有一部分資料被正確地恢復,這時被恢復資料庫中的資料是不完整的。psql提供了另外一種恢復模式,在這種模式下,一旦恢復操作執行過程中遇到任何錯誤,已經恢復的資料都會自動從資料庫中被刪除。可以使用psql的命令列選項-l或--single-transaction來開啟這種模式。

在恢復操作結束以後,應該使用ANALYZE命令來重新收集查詢優化器統計資料。

9.1.2 使用pg_dumpall
    pg_dump只備份資料庫叢集中的某個資料庫的資料,它不會匯出角色和表空間相關的資訊。pg_dumpall則可以匯出整個資料庫叢集中所有的資料庫中的資料,同時也會匯出角色、使用者和表空間的定義資訊。使用pg_dumpall的一般命令格式如下:

pg_dumpall > backup_file

 

pg_dumpall也支援和pg_dump一樣的命令列選項,如-h和-p等。同樣可以使用psql來從pg_dumpall建立的備份檔案中恢復資料庫。應該使用資料庫超級使用者來進行恢復資料庫的操作。命令格式如下:

psql -f backup_file postgres

 

     pg_dumpall在執行的過程中,用postgres作為使用者名稱來連線資料庫。系統自動建立的資料庫postgres中的內容也會被匯出來,資料庫template0和template1中的內容不會被匯出來。

 

9.1.3 大型資料庫的備份和恢復
     如果資料庫的規模比較大,產生的備份檔案的大小超級了作業系統能夠允許的單個檔案的大小的最大值,可以使用壓縮和將備份檔案分成對個部分這兩個方法來解決這個問題。

(1)採用壓縮的方法,可以採用作業系統提供的任何一種壓縮工具來實現,常用的是gzip。例如:

pg_dump dbname | gzip > filename.gz

恢復時,使用下面的命令:

gunzip -c filename.gz | psql dbname

也可以使用下面的命令來恢復資料庫:

cat filename.gz | gunzip | psql dbname

 

(2)將備份檔案分成多個部分。使用作業系統的工具split來實現。例如:

pg_dump dbname | split -b 1m - filename

在這個例子中,資料庫備份被分成多個大小為1MB的檔案。

使用下面的命令進行恢復操作:

cat filename* | psql dbname

 

(3)使用pg_dump自帶的壓縮功能。這種方法產生的備份檔案也是被壓縮的,同第一種方法相比,它有一個優點,就是可以只恢復備份檔案中的某個表的資料。這種方法的命令格式如下,就是增加了選項-Fc:

pg_dump -Fc dbname > filename

不能使用psql命令恢復用這種方法備份的資料,必須使用pg_restore來進行恢復操作。命令格式如下:

pg_restore -d dbname filename

 

     對於非常大的資料庫,可以將壓縮與分割的方法同時使用(同時使用第一種和第二種方法,或者同時使用第二種和第三種方法)。

9.2檔案系統複製
    檔案系統複製這種方法是直接複製所有的資料庫檔案,存放到其它的儲存介質上。這是最簡單的備份資料庫的方法。可以使用作業系統的命令來完成備份,例如:

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

 

    複製資料檔案以前,必須關閉資料庫。這種備份方法產生的備份檔案比較大,因為索引資料也會被備份。恢復資料庫時只要把備份檔案複製到存放資料檔案的目錄中即可。

 

9.3 聯機熱備份與歸檔恢復
9.3.1 聯機熱備份
     進行聯機熱備份時,不用關閉資料庫。資料庫可以正常地執行其它操作。如果要使聯機熱備份,資料庫必須執行在歸檔模式下,將引數資料庫archive_mode設為on,然後再將引數archive_dir設成一個啟動資料庫的作業系統使用者有讀寫許可權的目錄,資料庫就會執行在歸檔模式。要使這兩個引數生效,必須重新啟動資料庫。

 

    進行聯機熱備份的步驟如下:

(1)檢查資料庫是否執行在歸檔模式下。

(2)用超級使用者連線資料庫(推薦使用psql),然後執行下面的命令:
SELECT pg_start_backup('label');

label是一個字串,用來確定建立的備份,可以選取一個有明顯的含義的名字作為label。

pg_start_backup命令可能會執行比較長的時間才會結束,因為資料庫會自動開始一個檢查點操作。

(3)使用作業系統命令(如cp),將所有的資料庫檔案複製到其它的儲存介質上。

(4)執行下面的命令結束備份操作:

SELECT pg_stop_backup();

 

    備份操作結束以後,會在pg_xlog子目錄下產生一個備份描述檔案,該檔案以“.backup”結尾,例如000000010000000000000000.004535C0.backup。注意資料庫歸檔程序會自動將備份操作產生的備份描述檔案從pg_xlog子目錄複製到存放歸檔事務日誌的目錄中(引數archive_dir指定的目錄),如果在pg_xlog目錄中找不到備份描述檔案,應該在存放歸檔事務日誌的目錄中去尋找它。恢復資料庫的時候需要使用備份描述檔案中的資訊。備份描述檔案中存放有下列資訊:

(1)開始事務日誌檔名。

(2)結束事務日誌檔名。

(3)檢查點位置。

(4)備份操作開始的時間。

(5)備份操作結束的時間。

(6)備份的名字(就是pg_start_backup命令中指定的名字)。

 

    下面是一個備份描述檔案的例項:

START WAL LOCATION: 0/4535C0 (file 000000010000000000000000)

STOP WAL LOCATION: 0/453A98 (file 000000010000000000000000)

CHECKPOINT LOCATION: 0/4535C0

START TIME: 2009-03-28 23:02:34 CST

LABEL: b1

STOP TIME: 2009-03-28 23:04:05 CST

 

從該檔案中可以看出備份操作開始的時間是2009-03-28 23:02:34,結束的時間是2009-03-28 23:04:05,備份的名字是b1,開始事務日誌的名字是 000000010000000000000000,結束事務日誌的名字也是 000000010000000000000000,檢查點的位置是0/4535C0。

 

從開始事務日誌檔案到結束事務日誌檔案之間的所有事務日誌檔案(包括這兩個事務日誌檔案)必須被儲存好,不能丟失,否則建立的資料庫備份將是無效的,不能將資料庫恢復到一個一致的狀態。

 

     備份操作在執行的過程中會在資料檔案目下產生一個名為backup_label的檔案,該檔案叫做備份標號檔案。備份標號檔案在備份操作結束以後會被系統自動刪除。在執行上面的第三步操作的過程中,必須同時複製備份標號檔案,因為恢復資料庫的時候需要使用備份標號檔案中的資訊。

 

 

9.3.2 歸檔恢復
    進行歸檔恢復以前,應該準備好一個名為recovery.conf的檔案,該檔案中包含一些恢復操作的配置引數,這些引數決定恢復操作如何進行。下面詳細介紹這些引數:

 

(1)archive_log_dir

該引數指定存放歸事務日誌的目錄,所有需要的歸檔事務日誌都應該存放在該目錄中,系統在進行恢復操作時會自動從該目錄中讀取需要的事務日誌檔案。

 

(2)recovery_target_time

該引數指定一個時間,恢復操作進行到該時間時會自動停止。該引數用來實現時間點恢復(point-In-Time Recovery)。recovery_target_time和下面的recovery_target_xid只能指定一個。

 

(3)recovery_target_xid

該引數指定一個事務id,恢復操作進行到該事務時會自動停止。recovery_target_xid和上面的recovery_target_time只能指定一個。

 

(4)recovery_target_inclusive

該引數的值是true或false。預設值是true。它影響引數recovery_target_time和recovery_target_xid,如果它的值為true,恢復操作在指定的目標(時間或事務ID)以後停止,如果它的值為false,恢復操作在指定的目標以後停止。

 

    引數archive_log_dir必須出現在recovery.conf的檔案中,其它的引數則是可選的,如果recovery_target_xid和recovery_target_time都沒有被指定,則預設恢復到最後一個事務日誌檔案確定的資料庫的最近的狀態。如果想進行時間點恢復,應該指定引數recovery_target_time。

 

    下面是一個recovery.conf檔案的例項,所有的引數的值都必須用兩個單引號引起來:

 

archive_log_dir = '/home/yan/archive_log'

recovery_target_time = '2004-07-14 22:39:00 EST'

recovery_target_xid = '1100842'

recovery_target_inclusive = 'true'        

 

 

    下面介紹進行歸檔恢復的具體步驟:

(1)停止資料庫伺服器。將當前資料庫備份到其它目錄中。

(2)準備好recovery.conf檔案,將所有恢復操作需要的歸檔事務日誌都存放在引數archive_log_dir指定的目錄中,備份描述檔案也必須被存放在引數archive_log_dir指定的目錄中。

(3)將以前建立的資料庫備份複製到資料檔案目錄中(必須與以前的資料檔案目錄相同)。如果資料庫使用了表空間,請驗證pg_tblspc子目錄下面的每個符號連結是否有效。將準備好的recovery.conf檔案存放到資料檔案目錄中。編輯檔案pg_hba.conf,不允許任何使用者在恢復的過程中連線資料庫。

(4) 確保資料檔案目錄中存在一個名為backup_label的檔案。刪除pg_xlog子目錄中的所有檔案,重新在pg_xlog中建立一個名為archive_status的子目錄。

(5)啟動資料庫,資料庫在啟動以後將自動進行恢復操作,恢復操作成功完成以後,資料庫將自動開啟,進入正常的工作狀態。恢復操作成功以後,系統會將檔案recovery.conf重新命名為recovery.done。

(6)檢查資料庫中的內容是否正確。

 

     歸檔恢復成功結束以後,資料庫會自動開啟,進入正常的工作狀態,可以開始響應使用者的連線請求,應該修改pg_hba.conf檔案,允許使用者連線資料庫。歸檔恢復成功結束以後,在資料庫的執行日誌中會有下面的提示資訊:

……

日誌: 00000: 歸檔恢復結束。

    

    檔案backup_label在恢復操作執行結束以後會被自動重新命名為backup_label.old。確定歸檔恢復成功以後,應該刪除backup_label.old,因為它已經沒有任何作用。

9.3.3 注意事項
    進行歸檔恢復時,有下面幾個注意事項:

(1)雜湊索引上面的操作沒有被記錄到事務日誌中,歸檔恢復完成以後,必須對每個雜湊索引執行REINDEX操作。

(2)在建立資料庫備份時不要修改模板資料庫。

 

9.3.4 時間線(timeline)
     時間線是PostgreSQL獨有的概念。它是一個整數值,與歸檔恢復有關。在用initdb建立一個初始的資料庫叢集以後,該資料庫叢集的時間線是1。每進行一次歸檔恢復,就會產生一個新的時間線,新的時間線的值在上一個時間線的值的基礎上加一。每次歸檔恢復完成以後,都會產生一個時間線歷史檔案,該檔案以“.history”結尾,例如00000002.history。時間線歷史檔案首先被存放在pg_xlog目錄中,資料庫歸檔程序以後會自動將時間線歷史檔案從pg_xlog子目錄複製到存放歸檔事務日誌的目錄中(引數archive_dir指定的目錄)。