使用pg_dump和pg_restore將自建PostgreSQL數(shù)據(jù)庫(kù)遷移至RDS PostgreSQL
如果您準(zhǔn)備將自建PostgreSQL數(shù)據(jù)庫(kù)的指定數(shù)據(jù)庫(kù)遷移到RDS PostgreSQL實(shí)例,同時(shí)您已經(jīng)熟悉pg_dump和pg_restore工具,暫時(shí)不希望了解和使用阿里云提供的其他遷移服務(wù)(RDS PostgreSQL一鍵上云功能或數(shù)據(jù)傳輸DTS服務(wù))時(shí),您可以參考本文檔完成數(shù)據(jù)庫(kù)遷移工作。
前提條件
已創(chuàng)建與自建PostgreSQL大版本相同的RDS PostgreSQL實(shí)例,具體操作,請(qǐng)參見(jiàn)創(chuàng)建RDS PostgreSQL實(shí)例。
說(shuō)明使用pg_dump和pg_restore遷移數(shù)據(jù)庫(kù)時(shí),建議自建PostgreSQL與RDS PostgreSQL實(shí)例的大版本相同,以避免兼容問(wèn)題。
您可以在自建PostgreSQL數(shù)據(jù)庫(kù)所在的服務(wù)器中,使用
psql --version
命令查詢(xún)自建數(shù)據(jù)庫(kù)的版本。如果您需要升級(jí)大版本,可以在遷移完成后,使用大版本升級(jí)功能進(jìn)行升級(jí),更多信息,請(qǐng)參見(jiàn)升級(jí)數(shù)據(jù)庫(kù)大版本。
如果自建的PostgreSQL數(shù)據(jù)庫(kù)服務(wù)器位于阿里云ECS,建議在與ECS相同的地域和VPC中創(chuàng)建RDS PostgreSQL實(shí)例。使用內(nèi)網(wǎng)連接進(jìn)行數(shù)據(jù)遷移將更快速且更安全。
RDS PostgreSQL實(shí)例已配置白名單,允許自建PostgreSQL數(shù)據(jù)庫(kù)所在服務(wù)器訪問(wèn),具體操作,請(qǐng)參見(jiàn)設(shè)置白名單。
RDS PostgreSQL實(shí)例已創(chuàng)建高權(quán)限賬號(hào),具體操作,請(qǐng)參見(jiàn)創(chuàng)建賬號(hào)。
已獲取RDS PostgreSQL實(shí)例的連接地址和端口,具體操作,請(qǐng)參見(jiàn)查看或修改連接地址和端口。
說(shuō)明如果自建PostgreSQL數(shù)據(jù)庫(kù)的服務(wù)器是阿里云ECS,且與RDS PostgreSQL在同一地域同一VPC,則獲取RDS PostgreSQL實(shí)例的內(nèi)網(wǎng)連接地址和端口,否則,獲取外網(wǎng)地址和端口。
自建PostgreSQL數(shù)據(jù)庫(kù)已創(chuàng)建superuser權(quán)限的管理員賬號(hào)。
自建PostgreSQL數(shù)據(jù)庫(kù)所在服務(wù)器已安裝pg_dump和pg_restore。
說(shuō)明在本地安裝自建PostgreSQL時(shí),默認(rèn)安裝pg_dump和pg_restore。您可以通過(guò)
pg_dump --version
和pg_restore --version
命令查詢(xún)。
操作步驟
本方案適合于單庫(kù)遷移。如果需要遷移多個(gè)庫(kù)或整個(gè)自建PostgreSQL數(shù)據(jù)庫(kù),請(qǐng)參照如下方案處理。
將自建PostgreSQL數(shù)據(jù)庫(kù)中的部分庫(kù)一次性遷移到RDS PostgreSQL時(shí),建議使用數(shù)據(jù)庫(kù)傳輸DTS進(jìn)行遷移,更多信息,請(qǐng)參見(jiàn)使用DTS將自建PostgreSQL遷移至RDS PostgreSQL。
將整個(gè)自建PostgreSQL數(shù)據(jù)庫(kù)遷移上云時(shí),建議使用RDS PostgreSQL提供的一鍵上云功能,更多信息,請(qǐng)參見(jiàn)一鍵上云。
步驟一:確認(rèn)待遷移數(shù)據(jù)庫(kù)的相關(guān)信息
連接自建PostgreSQL數(shù)據(jù)庫(kù),在psql命令行中,使用\l
查詢(xún)數(shù)據(jù)庫(kù)列表信息,確認(rèn)待遷移數(shù)據(jù)庫(kù)的Owner、Encoding、Collate和Ctype信息。
本文以遷移testdb
數(shù)據(jù)庫(kù)為例,Owner為testuser
、Encoding為UTF8
、Collate為en_US.UTF-8
、Ctype為en_US.UTF-8
。
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =Tc/postgres +
| | | | | | | postgres=CTc/postgres
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
testdb | testuser | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
(4 rows)
步驟二:遷移用戶(hù)
連接自建PostgreSQL數(shù)據(jù)庫(kù)所在的服務(wù)器,使用如下命令導(dǎo)出待遷移數(shù)據(jù)庫(kù)的Owner用戶(hù)
testuser
。pg_dumpall -g -h 127.0.0.1 -p 5432 -U testuser
返回結(jié)果示例:
說(shuō)明在返回結(jié)果中的Roles部分,即可看到導(dǎo)出用戶(hù)
testuser
的相關(guān)權(quán)限語(yǔ)句。-- -- PostgreSQL database cluster dump -- SET default_transaction_read_only = off; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; -- -- Roles -- CREATE ROLE postgres; ALTER ROLE postgres WITH SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS; CREATE ROLE testuser; ALTER ROLE testuser WITH SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS PASSWORD 'SCRAM-SHA-256$4096:0IEvNqWupQsGcaoDS3SX****3U='; -- -- User Configurations -- -- -- PostgreSQL database cluster dump complete --
使用高權(quán)限賬號(hào)連接RDS PostgreSQL實(shí)例,具體操作,請(qǐng)參見(jiàn)連接PostgreSQL實(shí)例。
修改獲取的
testuser
用戶(hù)的相關(guān)權(quán)限SQL語(yǔ)句(將SUPERUSER
修改為rds_SUPERUSER
),在RDS PostgreSQL實(shí)例中創(chuàng)建與自建PostgreSQL權(quán)限相同的賬號(hào)。CREATE ROLE testuser; ALTER ROLE testuser WITH rds_SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS PASSWORD 'SCRAM-SHA-256$4096:0IEvNqWupQsGcaoDS3SX****3U=';
步驟三:在RDS PostgreSQL中創(chuàng)建目標(biāo)數(shù)據(jù)庫(kù)
使用高權(quán)限賬號(hào)連接RDS PostgreSQL實(shí)例。
使用如下SQL語(yǔ)句,創(chuàng)建目標(biāo)數(shù)據(jù)庫(kù),需要確保與自建PostgreSQL中待遷移數(shù)據(jù)庫(kù)具有相同字符集、Collate和Ctype。例如步驟一中獲取的Encoding為
UTF8
、Collate為en_US.UTF-8
、Ctype為en_US.UTF-8
。CREATE DATABASE <目標(biāo)數(shù)據(jù)庫(kù)的名稱(chēng)> WITH OWNER <數(shù)據(jù)庫(kù)Owner名稱(chēng)> TEMPLATE template0 ENCODING 'UTF8' LC_CTYPE 'en_US.UTF-8' LC_COLLATE 'en_US.UTF-8';
說(shuō)明目標(biāo)數(shù)據(jù)庫(kù)名稱(chēng)可以與自建PostgreSQL中待遷移數(shù)據(jù)庫(kù)名稱(chēng)不同。
目標(biāo)數(shù)據(jù)庫(kù)的Owner必須與自建PostgreSQL中遷移數(shù)據(jù)庫(kù)Owner相同。
步驟四:數(shù)據(jù)遷移
本文提供如下數(shù)據(jù)遷移方案,任選其一即可。
如果您的自建PostgreSQL數(shù)據(jù)庫(kù)所在服務(wù)器可以直接連接RDS PostgreSQL數(shù)據(jù)庫(kù),則推薦使用在線遷移方式。
如果您的自建PostgreSQL數(shù)據(jù)庫(kù)所在服務(wù)器無(wú)法直接連接RDS PostgreSQL數(shù)據(jù)庫(kù),則推薦使用離線遷移方式,先使用pg_dump導(dǎo)出文件,然后將文件拷貝到能連接RDS PostgreSQL的主機(jī),最后使用pg_restore導(dǎo)入。
在線遷移
配置密碼文件。更多信息,請(qǐng)參見(jiàn)The Password File。
在自建PostgreSQL數(shù)據(jù)庫(kù)所在服務(wù)器執(zhí)行如下命令創(chuàng)建并編輯.pgpass文件,用于存儲(chǔ)密碼。
vi ~/.pgpass
按
i
進(jìn)入編輯模式,輸入如下密碼相關(guān)內(nèi)容。說(shuō)明格式為
host:port:dbname:username:password
。dbname和username必須小寫(xiě),因?yàn)镻ostgreSQL元數(shù)據(jù)默認(rèn)使用小寫(xiě)字母存儲(chǔ), 除非您的數(shù)據(jù)庫(kù)和用戶(hù)在創(chuàng)建時(shí)使用雙引號(hào)包括并且大寫(xiě)。
RDS PostgreSQL連接地址:5432:目標(biāo)數(shù)據(jù)庫(kù)名:目標(biāo)數(shù)據(jù)庫(kù)Owner用戶(hù)名:密碼 127.0.0.1:5432:自建PostgreSQL待遷移數(shù)據(jù)庫(kù)名:superuser用戶(hù)名:密碼
按
Esc
,輸入:wq
退出編輯模式。修改
.pgpass
文件權(quán)限。chmod 700 ~/.pgpass
在自建PostgreSQL數(shù)據(jù)庫(kù)所在服務(wù)器執(zhí)行如下命令遷移數(shù)據(jù)。
nohup pg_dump -F p -h 127.0.0.1 -p 5432 -U <自建數(shù)據(jù)庫(kù)superuser用戶(hù)> -d <待遷移數(shù)據(jù)庫(kù)> --no-tablespaces | time psql -h <RDS PostgreSQL實(shí)例連接地址> -p 5432 -U <目標(biāo)數(shù)據(jù)庫(kù)Owner用戶(hù)名> --single-transaction <目標(biāo)數(shù)據(jù)庫(kù)> > ./pg.dump.log 2>&1 &
說(shuō)明您可以查看pg.dump.log文件檢查是否存在錯(cuò)誤日志,如果該文件為空,則表示遷移成功,可以前往RDS PostgreSQL實(shí)例查看遷移后的數(shù)據(jù)。
上述命令中設(shè)置了
--single-transaction
選項(xiàng),在恢復(fù)數(shù)據(jù)庫(kù)時(shí)將所有操作封裝在一個(gè)事務(wù)中,確保恢復(fù)操作要么全部成功,要么全部失敗,因此解決報(bào)錯(cuò)后可以直接重新導(dǎo)入。
離線遷移
在自建PostgreSQL數(shù)據(jù)庫(kù)所在服務(wù)器執(zhí)行如下命令導(dǎo)出文件。
nohup pg_dump -F c -h 127.0.0.1 -p 5432 -U <自建數(shù)據(jù)庫(kù)superuser用戶(hù)> -d <待遷移數(shù)據(jù)庫(kù)> --no-tablespaces -f ./pg.dump > ./pg.dump.log 2>&1 &
說(shuō)明等待導(dǎo)出完成,檢查pg.dump.log文件,確認(rèn)沒(méi)有報(bào)錯(cuò)。
將
pg.dump
文件拷貝到可以連接RDS PostgreSQL實(shí)例的主機(jī)上,執(zhí)行如下命令導(dǎo)入文件。說(shuō)明使用此方案時(shí),需要為RDS PostgreSQL實(shí)例配置白名單,允許該主機(jī)訪問(wèn)RDS PostgreSQL,具體操作,請(qǐng)參見(jiàn)設(shè)置白名單。
單線程導(dǎo)入。
pg_restore -h <RDS PostgreSQL連接地址> -p 5432 -U <目標(biāo)數(shù)據(jù)庫(kù)Owner用戶(hù)名> -d <目標(biāo)數(shù)據(jù)庫(kù)> --no-tablespaces --single-transaction pg.dump >./pg.restore.log
說(shuō)明耐心等待導(dǎo)入結(jié)束,您可以查看
pg.restore.log
文件檢查是否存在錯(cuò)誤日志,如果該文件為空,則表示遷移成功,可以前往RDS PostgreSQL實(shí)例查看遷移后的數(shù)據(jù)。上述命令中設(shè)置了
--single-transaction
選項(xiàng),在恢復(fù)數(shù)據(jù)庫(kù)時(shí)將所有操作封裝在一個(gè)事務(wù)中,確保恢復(fù)操作要么全部成功,要么全部失敗,因此解決報(bào)錯(cuò)后可以直接重新導(dǎo)入。
多線程并行導(dǎo)入。
pg_restore -h <RDS PostgreSQL連接地址> -p 5432 -U <目標(biāo)數(shù)據(jù)庫(kù)Owner用戶(hù)名> -d <目標(biāo)數(shù)據(jù)庫(kù)> --no-tablespaces -j <并行線程數(shù)> pg.dump >./pg.restore.log 2>&1 &
說(shuō)明并行參數(shù)
-j
和--single-transaction
參數(shù)不能同時(shí)使用。參數(shù)
-j
的取值范圍為正整數(shù),但推薦的最大值為系統(tǒng)CPU核心數(shù)的兩倍或四倍。這樣可以確保充分利用系統(tǒng)資源,同時(shí)避免過(guò)多的并行任務(wù)導(dǎo)致資源競(jìng)爭(zhēng)和性能下降。因?yàn)榇朔绞轿词褂?code data-tag="code" code-type="xCode" class="code">--single-transaction參數(shù)進(jìn)行事務(wù)封裝,因此一旦恢復(fù)過(guò)程中報(bào)錯(cuò),則在解決報(bào)錯(cuò)后,需要在RDS PostgreSQL側(cè)清空目標(biāo)數(shù)據(jù)庫(kù)下的所有表,再重新開(kāi)始導(dǎo)入,以確保數(shù)據(jù)一致性。
相關(guān)文檔
本文涉及的命令均可根據(jù)業(yè)務(wù)需求配置更多相關(guān)參數(shù),具體詳見(jiàn)如下官方文檔:
本方案適合于單庫(kù)遷移。如果需要遷移多個(gè)庫(kù)或整個(gè)自建PostgreSQL數(shù)據(jù)庫(kù),請(qǐng)參照如下方案處理。
將自建PostgreSQL數(shù)據(jù)庫(kù)中的部分庫(kù)一次性遷移到RDS PostgreSQL時(shí),建議使用數(shù)據(jù)庫(kù)傳輸DTS進(jìn)行遷移,更多信息,請(qǐng)參見(jiàn)使用DTS將自建PostgreSQL遷移至RDS PostgreSQL。
將整個(gè)自建PostgreSQL數(shù)據(jù)庫(kù)遷移上云時(shí),建議使用RDS PostgreSQL提供的一鍵上云功能,更多信息,請(qǐng)參見(jiàn)一鍵上云。