将 PostgreSQL 数据库复制到另一台服务器
Posted
技术标签:
【中文标题】将 PostgreSQL 数据库复制到另一台服务器【英文标题】:Copying PostgreSQL database to another server 【发布时间】:2010-11-17 06:53:25 【问题描述】:我希望将生产 PostgreSQL 数据库复制到开发服务器。最快、最简单的方法是什么?
【问题讨论】:
【参考方案1】:如果您更熟悉 GUI,可以使用 pgAdmin 软件。
连接到您的源服务器和目标服务器 右键单击源数据库 > 备份 右键单击目标服务器 > 创建 > 数据库。使用与源db相同的属性(右键>属性可以看到源db的属性) 右键单击创建的数据库 > 恢复。【讨论】:
我试过这个,但它不会复制外国关系【参考方案2】:这里是一个使用pg_basebackup
的例子
我选择这条路线是因为它备份了整个数据库集群(用户、数据库等)。
我在此处将其作为解决方案发布,因为它详细说明了我必须采取的每一步,请在阅读此处的其他答案并进行更多研究后随时添加建议或改进。
对于 Postgres 12 和 Ubuntu 18.04,我必须执行以下操作:
在当前运行数据库的服务器上:
更新pg_hba.conf
,对我来说位于/etc/postgresql/12/main/pg_hba.conf
添加以下行(将 192.168.0.100 替换为要将数据库复制到的服务器的 IP 地址)。
host replication postgres 192.168.0.100/32 trust
更新postgresql.conf
,对我来说位于/etc/postgresql/12/main/postgresql.conf
。添加以下行:
listen_addresses = '*'
重启 postgres:
sudo service postgresql 重启
在您要将数据库集群复制到的主机上:
sudo service postgresql 停止
sudo su root
rm -rf /var/lib/postgresql/12/main/*
退出
sudo -u postgres pg_basebackup -h 192.168.0.101 -U postgres -D /var/lib/postgresql/12/main/
sudo service postgresql 启动
大图-停止服务,删除数据目录中的所有内容(我的在/var/lib/postgreql/12
)。此目录的权限为drwx------
,用户和组为postgres
。我只能以root
的身份执行此操作,即使使用sudo -u postgres
也不行。我不确定为什么。确保您在要将数据库复制到的新服务器上执行此操作!您正在删除整个数据库集群。
确保将 IP 地址从 192.168.0.101
更改为您从中复制数据库的 IP 地址。使用pg_basebackup
从原始服务器复制数据。启动服务。
更新 pg_hba.conf
和 postgresql.conf
以匹配原始服务器配置 - 在您进行任何更改之前添加 replication
行和 listen_addresses
行(在我的照顾下,我必须添加本地登录的功能通过 md5 到 pg_hba.conf)。
请注意,max_wal_senders
和 wal_level
的注意事项可在 documentation 中找到。我不必为此做任何事情。
【讨论】:
有可能以pg_dumpall -C -h localhost -U postgres | psql -h second.server.com -U postgres
运行一些,然后覆盖主机“second.server.com”中的旧数据库、旧模式、旧角色、旧任何...?【参考方案3】:
pg_basebackup
现在似乎是更好的方法,尤其是对于大型数据库。
您可以从具有相同或更旧主要版本的服务器复制数据库。或more precisely:
pg_basebackup
适用于相同或旧主要版本(低至 9.1)的服务器。但是,WAL 流模式 (-X stream
) 仅适用于服务器版本 9.3 及更高版本,当前版本的 tar 格式模式 (--format=tar
) 仅适用于服务器版本 9.5 或更高版本。
为此,您需要在源服务器上:
listen_addresses = '*'
能够从目标服务器连接。为此,请确保端口 5432 已打开。
至少 1 个可用的复制连接:max_wal_senders = 1
(-X fetch
)、2
用于 -X stream
(PostgreSQL 12 的默认值)或更多。
wal_level = replica
或更高级别才能设置max_wal_senders > 0
。
host replication postgres DST_IP/32 trust
在pg_hba.conf
。这将向DST_IP
机器上的任何人授予对pg
集群的访问权限。您可能想求助于更安全的选择。
更改 1、2、3 需要重新启动服务器,更改 4 需要重新加载。
在目标服务器上:
# systemctl stop postgresql@VERSION-NAME
postgres$ pg_basebackup -h SRC_IP -U postgres -D VERSION/NAME --progress
# systemctl start postgresql@VERSION-NAME
【讨论】:
您能否在答案中提供更多详细信息,例如示例? 这仅适用于两台机器具有相同 PG 版本的情况。 使用不同数据库版本进行开发和生产的可能性很小。上次我与我的一位队友进行了一些不愉快的谈话,因为她试图提交一个问题,即在我们当时在生产中使用 9.5 时某些代码无法与 PG 9.6 一起使用。基本备份要快得多。如果需要,那么 pg_upgrade 就是要走的路。 您可能想要迁移到更新的版本,并且不想停止 PostgreSQL。 很有可能,每当您升级数据库时,您会先在 dev 和 staging 上升级它,然后再在生产环境中升级。【参考方案4】:您不需要创建中间文件。你可以这样做
pg_dump -C -h localhost -U localuser dbname | psql -h remotehost -U remoteuser dbname
或
pg_dump -C -h remotehost -U remoteuser dbname | psql -h localhost -U localuser dbname
使用psql
或pg_dump
连接到远程主机。
对于大型数据库或慢速连接,转储文件和传输压缩文件可能会更快。
正如 Kornel 所说,无需转储到中间文件,如果您想压缩工作,可以使用压缩隧道
pg_dump -C dbname | bzip2 | ssh remoteuser@remotehost "bunzip2 | psql dbname"
或
pg_dump -C dbname | ssh -C remoteuser@remotehost "psql dbname"
但此解决方案还需要在两端都获得会话。
注意: pg_dump
用于备份,psql
用于恢复。因此,此答案中的第一个命令是从本地复制到远程,第二个命令是从远程复制到本地。更多 -> https://www.postgresql.org/docs/9.6/app-pgdump.html
【讨论】:
不需要中间文件 - 你可以使用压缩的 SSH 隧道或简单的管道:pg_dump | bzip2 | ssh "bunzip2 | pg_restore" 如果你使用bzip2,关闭ssh压缩以加快传输! 如果我将数据从生产拉到开发中,我该如何进行压缩工作?我已经建立了从开发到生产的 SSH 连接。那么是ssh remoteuser@remotehost "pg_dump -C dbname | bzip2" | bunzip2 | psql dbname
吗?
这就是我所做的: (1) pg_dump -C -h remotehost -U remoteuser x | psql -h localhost -U localuser (2) dropdb y (3) psql -U postgres -c 'ALTER DATABASE "x" RENAME TO "y"'
如果两台服务器都要求输入密码,则不能使用此命令。根据墨菲定律,他们会同时询问,输入的密码总是会出错(只确认了两次)。【参考方案5】:
接受的答案是正确的,但如果你想避免交互输入密码,你可以使用这个:
PGPASSWORD=export_db_password pg_dump --create -h export_db_host -U export_db_user export_db_name | PGPASSWORD=import_db_password psql -h import_db_host -U import_db_user import_db_name
【讨论】:
这是我唯一找到此信息的地方,好提示 是否要为这个命令添加多线程? 如果你使用 postgres 的 ip public 连接,你必须添加选项 -p 来指定主机的端口 例如:-h export_db_host -p export_db_port跨度> 你也可以使用 --dbname=import_db_host 来指定数据库名称 我可以在powershell中使用这个语法吗?我需要把密码放在引号里吗? @zoran【参考方案6】:转储您的数据库:pg_dump database_name_name > backup.sql
将您的数据库导入回来:psql db_name < backup.sql
【讨论】:
【参考方案7】:让我分享一个 Linux shell 脚本,将您的表数据从一台服务器复制到另一台 PostgreSQL 服务器。
Reference taken from this blog:
用于 PostgreSQL 服务器之间数据迁移的 Linux Bash Shell 脚本:
#!/bin/bash
psql \
-X \
-U user_name \
-h host_name1 \
-d database_name \
-c "\\copy tbl_Students to stdout" \
| \
psql \
-X \
-U user_name \
-h host_name2 \
-d database_name \
-c "\\copy tbl_Students from stdin"
我只是在迁移数据;请在您的目标/第二个数据库服务器上创建一个空白表。
这是一个实用程序脚本。此外,您可以修改脚本以供通用使用,例如为 host_name、database_name、table_name 等添加参数
【讨论】:
【参考方案8】:我费了很大的劲,最终让我使用 Rails 4 的方法是:
在您的旧服务器上
sudo su - postgres
pg_dump -c --inserts old_db_name > dump.sql
我必须使用 postgres linux 用户来创建转储。我还必须使用 -c 来强制在新服务器上创建数据库。 --inserts 告诉它使用 INSERT() 语法,否则对我不起作用:(
然后,在新服务器上,simpy:
sudo su - postgres
psql new_database_name < dump.sql
为了在服务器之间传输 dump.sql 文件,我只是使用“cat”打印内容,然后使用“nano”复制粘贴内容来重新创建它。
另外,我在两个数据库上使用的角色不同,所以我必须查找并替换转储中的所有所有者名称。
【讨论】:
【参考方案9】:使用要备份的数据库名称运行此命令,以转储数据库。
pg_dump -U user-name source_db -f dumpfilename.sql
eg. pg_dump -U postgres mydbname -f mydbnamedump.sql
现在将此转储文件 scp 到您要复制数据库的远程计算机。
eg. scp mydbnamedump.sql user01@remotemachineip:~/some/folder/
在远程机器上,在 ~/some/folder 中运行以下命令来恢复数据库。
psql -U user-name -d desintation_db-f dumpfilename.sql
eg. psql -U postgres -d mynewdb -f mydbnamedump.sql
【讨论】:
如果无法连接到 psql,如何备份?有没有一种文件系统方法来实现这一点?例如:如果您的服务器配置/exe 感染了病毒?【参考方案10】:如果您希望在版本之间迁移(例如,您更新了 postgres 并在 localhost:5432 上运行 9.1,在 localhost:5434 上运行 9.3),您可以运行:
pg_dumpall -p 5432 -U myuser91 | psql -U myuser94 -d postgres -p 5434
查看migration docs。
【讨论】:
我多次被要求输入 (myuser91/postgres)-密码,有没有办法让我只需要输入一次密码? @MartinWeber 根据本文档创建一个 ,pgpass 文件postgresql.org/docs/9.4/static/libpq-pgpass.html 如果他们有相同的端口怎么办? 如果它们在不同的服务器上,可以使用-h来指定主机。【参考方案11】:使用pg_dump,然后使用psql 或pg_restore - 取决于您选择 -Fp 还是 -Fc 选项来 pg_dump。
使用示例:
ssh production
pg_dump -C -Fp -f dump.sql -U postgres some_database_name
scp dump.sql development:
rm dump.sql
ssh development
psql -U postgres -f dump.sql
【讨论】:
-Fp
和-Fc
有什么区别
-F, --format=c|d|t|p
输出文件格式(自定义、目录、tar、纯文本(默认))【参考方案12】:
pg_dump the_db_name > the_backup.sql
然后将备份复制到您的开发服务器,使用以下命令恢复:
psql the_new_dev_db < the_backup.sql
【讨论】:
有人告诉我这可能有问题 - 权限问题导致转储或还原在触发时终止? @rmbarnes:如果有问题 - 它们必须被修复。如果不详细了解这个“某人”做了什么 - 没有人可以证实或否认这一说法。 在 pg_dump 中使用 --no-owner 标志。这跳过了这个问题,这篇文章的第一次编辑使用了它——但后来我想你可能需要对原始数据库更精确的保真度。 对我来说,上述方法的工作方式如下:pg_dump -C -h host -U username db_name > /any_directory/dump_schema_and_data_file 。对于从文件恢复:psql -h host -U username db_name 这让我省了不少事。我使用谷歌驱动器在机器之间移动文件。由于我已经在新机器上拥有数据库(但为空白),因此我遇到了很多重复的键错误。但是,这是一个开发环境,它们并没有造成任何伤害。以上是关于将 PostgreSQL 数据库复制到另一台服务器的主要内容,如果未能解决你的问题,请参考以下文章