?
本文檔使用 php中文網(wǎng)手冊(cè) 發(fā)布
這種轉(zhuǎn)儲(chǔ)方法是創(chuàng)建一個(gè)文本文件, 里面都是SQL命令,當(dāng)把這個(gè)文件回饋給服務(wù)器時(shí), 將重建與轉(zhuǎn)儲(chǔ)時(shí)狀態(tài)一樣的數(shù)據(jù)庫(kù)。PostgreSQL為這個(gè)用途提供了pg_dump工具。 這條命令的基本用法是:
pg_dump dbname > outfile
正如你所見(jiàn),pg_dump把結(jié)果輸出到標(biāo)準(zhǔn)輸出。 我們下面就可以看到這樣做有什么好處。
pg_dump是一個(gè)普通的PostgreSQL客戶(hù)端應(yīng)用(盡管是個(gè)相當(dāng)聰明的東西)。 這就意味著你可以從任何可以訪問(wèn)該數(shù)據(jù)庫(kù)的遠(yuǎn)端主機(jī)上面進(jìn)行備份工作。 但是請(qǐng)記住pg_dump不會(huì)以任何特殊權(quán)限運(yùn)行。 具體說(shuō)來(lái),就是它必須要有你想備份的表的讀權(quán)限, 因此,實(shí)際上你幾乎總是要成為數(shù)據(jù)庫(kù)超級(jí)用戶(hù)。
要聲明pg_dump應(yīng)該以哪個(gè)用戶(hù)身份進(jìn)行連接, 使用命令行選項(xiàng) -h host和-p port 。缺省主機(jī)是本地主機(jī)或環(huán)境變量PGHOST聲明的值。類(lèi)似的,缺省端口是環(huán)境變量PGPORT或(如果它不存在的話)編譯好了的缺省值。服務(wù)器通常都有相同的缺省,所以還算方便。
和任何其它PostgreSQL客戶(hù)端應(yīng)用一樣, pg_dump缺省時(shí)用與當(dāng)前操作系統(tǒng)用戶(hù)名同名的數(shù)據(jù)庫(kù)用戶(hù)名進(jìn)行連接。 要覆蓋這個(gè)名字,要么聲明-U選項(xiàng),要么設(shè)置環(huán)境變量PGUSER。請(qǐng)注意pg_dump的連接也和普通客戶(hù)應(yīng)用一樣要通過(guò)客戶(hù)認(rèn)證機(jī)制(在章Chapter 19里描述)。
pg_dump跟別的備份方法相比較最重要的一個(gè)優(yōu)點(diǎn)會(huì)在后面介紹, pg_dump的輸出一般可以被重新加載到PostgreSQL的新版本, 而文件級(jí)備份和連續(xù)歸檔都是特定于服務(wù)器版本的。pg_dump是把數(shù)據(jù)庫(kù)移到另一個(gè)機(jī)器架構(gòu)上的唯一方法,就像從32位到64位的服務(wù)器。
由pg_dump創(chuàng)建的備份在內(nèi)部是一致的,也就是說(shuō), 在pg_dump運(yùn)行的時(shí)候?qū)?shù)據(jù)庫(kù)進(jìn)行一次快照。 pg_dump工作的時(shí)候并不阻塞其它對(duì)數(shù)據(jù)庫(kù)的操作 (但是會(huì)阻塞那些需要排它鎖的操作,比如ALTER TABLE)。
Important: 如果你的數(shù)據(jù)庫(kù)結(jié)構(gòu)依賴(lài)于OID(比如說(shuō)用做外鍵), 那么你必須告訴pg_dump把OID也導(dǎo)出來(lái)。要導(dǎo)出OID, 可以使用-o命令行選項(xiàng)。
pg_dump生成的文本文件可以由psql程序讀取。從轉(zhuǎn)儲(chǔ)中恢復(fù)的常用命令是:
psql dbname < infile
這里的infile是pg_dump命令的輸出文件。 這條命令不會(huì)創(chuàng)建dbname數(shù)據(jù)庫(kù), 你必須在執(zhí)行psql前自己從template0創(chuàng)建(也就是用createdb -T template0dbname命令)。 psql支持類(lèi)似pg_dump的選項(xiàng)用以控制數(shù)據(jù)庫(kù)服務(wù)器位置和用戶(hù)名。 參閱psql的手冊(cè)獲取更多信息。
在開(kāi)始運(yùn)行恢復(fù)之前,目標(biāo)庫(kù)和所有在轉(zhuǎn)儲(chǔ)出來(lái)的庫(kù)中擁有對(duì)象的用戶(hù), 以及曾經(jīng)在某些對(duì)象上被賦予權(quán)限的用戶(hù)都必須已經(jīng)存在。 如果這些不存在,那么恢復(fù)將失敗,因?yàn)榛謴?fù)過(guò)程無(wú)法把這些對(duì)象恢復(fù)成原有的所有權(quán)和/或權(quán)限。 (有時(shí)候你希望恢復(fù)權(quán)限,不過(guò)通常你不需要這么做。)
缺省時(shí),psql腳本將在遇到錯(cuò)誤的時(shí)候仍然繼續(xù)執(zhí)行。 你可能希望運(yùn)行psql和變量集ON_ERROR_STOP來(lái)保證在遇見(jiàn)錯(cuò)誤的時(shí)候退出psql并返回狀態(tài)碼3:
\set ON_ERROR_STOP
不管上述哪種方法都只能得到部分恢復(fù)了的數(shù)據(jù)庫(kù)。 另外,你可以將整個(gè)恢復(fù)過(guò)程當(dāng)成一個(gè)單獨(dú)的事務(wù), 這樣就能夠保證要么全部恢復(fù)成功,要么全部回滾。 可以通過(guò)向psql傳遞-1或--single-transaction命令行參數(shù)達(dá)到此目的。 使用這個(gè)模式的時(shí)候即使一個(gè)很微小的錯(cuò)誤也將導(dǎo)致已經(jīng)運(yùn)行了好幾個(gè)小時(shí)的恢復(fù)過(guò)程回滾。 盡管如此,這種模式也比手動(dòng)清除哪些不完整的恢復(fù)數(shù)據(jù)強(qiáng)。
pg_dump和 psql可以通過(guò)管道讀寫(xiě), 這樣我們就可能從一臺(tái)主機(jī)上將數(shù)據(jù)庫(kù)目錄轉(zhuǎn)儲(chǔ)到另一臺(tái)主機(jī)上, 比如:
pg_dump -h host1 dbname | psql -h host2 dbname
Important: pg_dump生成的轉(zhuǎn)儲(chǔ)輸出是相對(duì)于template0的。 這就意味著任何加入到template1的語(yǔ)言、過(guò)程等都會(huì)經(jīng)由pg_dump轉(zhuǎn)儲(chǔ)。 這樣在恢復(fù)的時(shí)候,如果你使用的是自定義的template1, 那么你必須從template0中創(chuàng)建空的數(shù)據(jù)庫(kù),就像我們上面的例子那樣。
一旦完成恢復(fù),在每個(gè)數(shù)據(jù)庫(kù)上運(yùn)行ANALYZE是明智的舉動(dòng), 這樣優(yōu)化器就有可用的統(tǒng)計(jì)數(shù)據(jù)了。更多信息請(qǐng)參考Section 23.1.3 和Section 23.1.5 。 關(guān)于如何有效對(duì)PostgreSQL加載海量數(shù)據(jù)的信息,參考Section 14.4.
pg_dump上面的方法在備份整個(gè)數(shù)據(jù)庫(kù)集群的時(shí)候比較麻煩而且不方便。 因此我們提供了pg_dumpall程序。 pg_dumpall備份一個(gè)給出的集群中的每個(gè)數(shù)據(jù)庫(kù), 同時(shí)還確保保留像角色和表空間這樣的全局?jǐn)?shù)據(jù)狀態(tài)。 這個(gè)命令的基本用法是:
pg_dumpall > outfile
生成的轉(zhuǎn)儲(chǔ)可以用psql恢復(fù):
psql -f infile postgres
實(shí)際上,你可以聲明任意現(xiàn)有的數(shù)據(jù)庫(kù)進(jìn)行連接, 但是如果你是向一個(gè)空的數(shù)據(jù)庫(kù)集群裝載,那么postgres應(yīng)該是比較好的選擇。 恢復(fù)pg_dumpall的轉(zhuǎn)儲(chǔ)的時(shí)候通常需要數(shù)據(jù)庫(kù)超級(jí)用戶(hù)權(quán)限, 因?yàn)槲覀冃枰鼇?lái)恢復(fù)角色和表空間信息。 如果使用了表空間,需要注意轉(zhuǎn)儲(chǔ)中的表空間路徑必須適合新的安裝。
pg_dumpall作品由發(fā)出的命令來(lái)重建角色,表空間,空數(shù)據(jù)庫(kù),然后調(diào)用pg_dump為每個(gè)數(shù)據(jù)庫(kù)備份。這意味著當(dāng) 每個(gè)數(shù)據(jù)庫(kù)將在內(nèi)部是一致的,不同數(shù)據(jù)庫(kù)的快照 可能不會(huì)完全的同步。
一些操作系統(tǒng)的文件是有最大上限的,就會(huì)在創(chuàng)建大的pg_dump輸出文件時(shí) 出現(xiàn)問(wèn)題。幸運(yùn)的是,因?yàn)?span id="377j5v51b" class="APPLICATION">pg_dump輸出到標(biāo)準(zhǔn)輸出,你可以用標(biāo)準(zhǔn)的Unix工具繞開(kāi)這個(gè)問(wèn)題:
使用壓縮的轉(zhuǎn)儲(chǔ). 使用你熟悉的壓縮程序(比如 gzip):
pg_dump dbname | gzip > filename.gz
用下面命令恢復(fù):
gunzip -c filename.gz | psql dbname
或者:
cat filename.gz | gunzip | psql dbname
使用 split 工具. split命令允許用下面的方法把輸出分解成操作系統(tǒng)可以接受的大小。 比如,讓每個(gè)塊大小為 1MB :
pg_dump dbname | split -b 1m - filename
用下面命令恢復(fù):
cat filename* | psql dbname
使用pg_dump自定義的轉(zhuǎn)儲(chǔ)格式. 如果PostgreSQL是在一個(gè)安裝了zlib壓縮庫(kù)的系統(tǒng)上制作的, 那么自定義轉(zhuǎn)儲(chǔ)格式將在寫(xiě)入輸出文件的時(shí)候壓縮數(shù)據(jù)。 它會(huì)生成和使用gzip類(lèi)似大小的轉(zhuǎn)儲(chǔ)文件, 但是還附加了一個(gè)優(yōu)點(diǎn):你可以有選擇地恢復(fù)庫(kù)中的表。 下面的命令用自定義轉(zhuǎn)儲(chǔ)格式轉(zhuǎn)儲(chǔ)一個(gè)數(shù)據(jù)庫(kù):
pg_dump -Fc dbname > filename
自定義格式的轉(zhuǎn)儲(chǔ)不是腳本,不能用于psql , 而是需要使用pg_restore轉(zhuǎn)儲(chǔ)。例如:
pg_restore -d dbname filename
請(qǐng)參考pg_dump和pg_restore的手冊(cè)獲取細(xì)節(jié)。
對(duì)于每一個(gè)大型數(shù)據(jù)庫(kù)來(lái)說(shuō),你可能需要把split和另外兩個(gè)方法之一來(lái)結(jié)合使用。