将 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.confpostgresql.conf 以匹配原始服务器配置 - 在您进行任何更改之前添加 replication 行和 listen_addresses 行(在我的照顾下,我必须添加本地登录的功能通过 md5 到 pg_hba.conf)。

请注意,max_wal_senderswal_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 > 0host replication postgres DST_IP/32 trustpg_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

使用psqlpg_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 数据库复制到另一台服务器的主要内容,如果未能解决你的问题,请参考以下文章

将 .bak 数据库文件从备份位置移动到另一台服务器

如何将弹性搜索索引或日志从一个弹性搜索服务器复制到另一台?

scp 将数据从一台linux服务器复制到另一台linux服务器

将文件从一台服务器复制到另一台服务器时权限被拒绝

PostgreSql基于Standby的异步流主从复制

可以将 perl 模块从一台 Linux 机器复制到另一台机器吗?