如何在服务器之间的文件系统级别复制 PostgreSQL 数据库

Cer*_*rin 4 postgresql postgresql-9.5

我在磁盘故障的服务器上有一个大型 PostgreSQL 数据库。pg_dump由于磁盘错误,我无法运行。

我有另一台具有相同操作系统(Ubuntu 16.04)和相同版本的 PostgreSQL (9.5.6) 的服务器。如何将原始数据库文件复制到新服务器?我不在乎读取错误是否会损坏数据库的某些部分,因为我有识别和修复这些问题的方法,但是我需要先复制数据才能修复它。据我所知,读取错误并不多,但即使有一个也会停止 pg_dump。

关于这个主题的维基页面很少,它建议进行“文件系统级复制”,但没有提及如何实际执行此操作。

编辑:我使用 rsync 复制我的数据目录 ( /var/lib/postgresql/9.5/main) 和配置目录 ( /etc/postgresql/9.5/main)。运行sudo service postgresql start无错误新的服务器运行,但尝试通过连接sudo -u postgres psql的回报:

psql: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
Run Code Online (Sandbox Code Playgroud)

并且日志显示:

2017-05-23 15:13:08 EDT [14604-1] [unknown]@[unknown] LOG:  incomplete startup packet
2017-05-23 15:13:08 EDT [14603-2] LOG:  MultiXact member wraparound protections are now enabled
2017-05-23 15:13:08 EDT [14602-1] LOG:  database system is ready to accept connections
2017-05-23 15:13:08 EDT [14608-1] LOG:  autovacuum launcher started
2017-05-23 15:13:43 EDT [14602-2] LOG:  received fast shutdown request
2017-05-23 15:13:43 EDT [14602-3] LOG:  aborting any active transactions
2017-05-23 15:13:43 EDT [14608-2] LOG:  autovacuum launcher shutting down
2017-05-23 15:13:43 EDT [14605-1] LOG:  shutting down
2017-05-23 15:13:45 EDT [14605-2] LOG:  database system is shut down
2017-05-23 21:33:29 EDT [27345-1] FATAL:  could not load server certificate file "/etc/ssl/certs/ssl-cert-snakeoil.pem": No such file or directory
Run Code Online (Sandbox Code Playgroud)

这个缺少的证书是什么,我该如何解决?

编辑:我按照这些说明修复了 SSL 错误,现在我的所有文件似乎都已传输。

我的数据库似乎在很大程度上可以访问。我发现的唯一问题是当我进行完全真空时,出现错误:

ERROR:  could not open file "base/106800/107273": No such file or directory
Run Code Online (Sandbox Code Playgroud)

我该如何解决?我意识到这是文件损坏,可能是由于该文件在 rsync 期间无法读取造成的。我如何用空白值“填充”它以便真空可以继续?清空特定表时发生错误,并且可以重新生成该表中的数据。

Cer*_*rin 5

这是我最终必须编写以传输所有文件的脚本,这些文件旨在从目标服务器运行。

#!/bin/bash
set -i

# Ensure databases on both servers are stopped.
sudo service postgresql stop
ssh -t myuser@oldserver "sudo service postgresql stop"

# Ensure our user owns postgres's files so our rsync call can access them.
ssh -t myuser@oldserver "sudo chown -R myuser:myuser /etc/postgresql"
ssh -t myuser@oldserver "sudo chown -R myuser:myuser /var/lib/postgresql"

# Copy down all the files.
sudo rsync --progress -azv --delete myuser@oldserver:/etc/postgresql/9.5/main/ /etc/postgresql/9.5/main
sudo rsync --progress -azv --delete myuser@oldserver:/var/lib/postgresql/9.5/main/ /var/lib/postgresql/9.5/main

# Fix permissions.
ssh -t myuser@oldserver "sudo chown -R postgres:postgres /etc/postgresql"
ssh -t myuser@oldserver "sudo chown -R postgres:postgres /var/lib/postgresql"
sudo chown -R postgres:postgres /etc/postgresql
sudo chown -R postgres:postgres /var/lib/postgresql

# Fix a missing ssl cert that pg uses for connections.
cd /etc/ssl/certs
sudo make-ssl-cert generate-default-snakeoil --force-overwrite

# Bring the server back up.
sudo service postgresql start
Run Code Online (Sandbox Code Playgroud)

Rsync的报道一些错误,但我浏览我的数据库,通过psqlpgadmin3到目前为止一切看起来是正确的。

我在这里找到的 SSL 错误的修复。

  • 当您遇到读取错误时, rsync 几乎肯定不会正确运行。它要么截断文件,要么通过省略不可读的数据来缩短它们。要在 Unix 系统上复制包含读取错误的文件,您应该使用带有选项 conv=noerror conv=sync 的“dd”命令。有关详细信息,请参阅“man 1 dd”。 (2认同)

Eva*_*oll 2

首先,如果由于磁盘错误而无法运行pg_dump,则复制数据库几乎肯定不起作用。

也就是说,这当然值得尝试。将驱动器安装为只读。跑步

SHOW data_directory;
Run Code Online (Sandbox Code Playgroud)

无论返回什么,将该目录复制(cp或最好rsync)到新磁盘。跑步

SELECT version();
Run Code Online (Sandbox Code Playgroud)

获取使用相同主版本号和次版本号的PostgreSQL 集群版本。然后尝试启动服务器并查看是否有效。