我不知道我做错了什么,但结果却大错特错,试图从documentation开始遵循程序

我按照以下命令从cmd运行:

cd G:\Postgresql_test
rsync --archive --delete --hard-links --size-only --no-inc-recursive 12pro \ 13pro postgres@ip_here::postgresupgrade

在目录Postgresql_test中,有12PRO和13PRO目录,其中有data个目录. 副本服务器上的 struct 相同,postgresupgrade是远程服务器上的G:Postgresql_test目录.

首先,在乞讨问题上有很多错误

cygwin warning:
  MS-DOS style path detected: \
  Preferred POSIX equivalent is: /cygdrive/g
  CYGWIN environment variable option "nodosfilewarning" turns off this warning.
  Consult the user's guide for more details about POSIX paths:
    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
file has vanished: "/cygdrive/g/Postgresql_test/\/$RECYCLE.BIN"
file has vanished: "/cygdrive/g/Postgresql_test/\/PostgreSQL" -- why this show catalogs that are above? directly on G:
file has vanished: "/cygdrive/g/Postgresql_test/\/Postgresql_test"
file has vanished: "/cygdrive/g/Postgresql_test/\/Postgresql_test- Copy" -- same here
file has vanished: "/cygdrive/g/Postgresql_test/\/postgres_upgrade" -- and here
file has vanished: "/cygdrive/g/Postgresql_test/\/System Volume Information"
IO error encountered -- skipping file deletion
rsync warning: some files vanished before they could be transferred (code 24) at main.c(1165) [sender=3.1.1]

几分钟后,在副本服务器上,只有12PRO目录看起来是同步的,而13PRO仅增长了几百MB(应该是几GB)

@Edit1

当我删除12Pro和13Pro之间的反斜杠时,它在控制台中没有出现错误,但结果相同.旧目录已同步,新目录未同步.

推荐答案

注意:\只是单行命令为split over two lines的语法

反斜杠(\)是一个转义字符,指示shell 程序不解释下一个字符.如果下一个字符是换行符,则shell 程序将读取该语句,并将其视为未到达末尾.这允许一条语句跨越多行.

这是一种有用的技术,可以将冗长的命令划分为包含在shell 会话窗口中的可读语句.


为了避免Cygwin和远程服务器之间潜在的路径转换问题,您可以使用相对路径.首先,在命令提示符下导航到本地计算机上的G:\Postgresql_test目录.然后,调整rsync命令以使用源目录的相对路径.

rsync --archive --delete --hard-links --size-only --no-inc-recursive 12pro/ 13pro/ postgres@ip_here:G:/Postgresql_test

Note the lack of trailing '/' in postgres@ip_here:G:/Postgresql_test.
I use the actual path instead of the rsync.conf alias postgresupgrade, but you can try with that alias if it works.

确保远程服务器上存在G:\Postgresql_test目录.

几分钟后,在复制副本上,只有12Pro目录看起来是同步的,而13Pro仅增长了几百MB(应该是几GB)

阅读你提到的"Upgrade streaming replication and log-shipping standby servers"文档,首先判断这是否真的是正确的结果:

pg_upgrade在链接模式下运行时(速度更快,使用的磁盘空间更少),它实际上不会复制旧集群中的所有数据.相反,它会创建从新集群目录到旧集群目录中实际数据文件的硬链接.这意味着新目录(在您的例子中为13pro)可能不会占用磁盘上太多的额外空间,即使它似乎包含数据的完整副本.

当您按照PostgreSQL文档中的建议使用带有--hard-links选项的rsync命令时,它应该会在备用服务器上复制此设置.也就是说,它应该在备用服务器上创建一个13pro目录,该目录还包含指向12pro目录中数据文件的硬链接.这就是文档所说的意思:"然后它在备用系统的旧集群中找到匹配的文件,并在备用系统的新集群中为它们创建链接."

因此,您所看到的可能是正确的:备用服务器上的13pro目录可能更小,因为它主要由指向12pro中数据的硬链接组成.如果您不确定,可以比较主服务器和备用服务器上12pro13pro目录的内容,看看它们看起来是否相似.


the comments中的sh4rkyy所示

原来这是目录权限的问题……

现在,这两个目录看起来很好地同步了,但随后发生了以下情况:

LOG: invalid primary checkpoint record PANIC: could not locate a valid checkpoint record

所以我用了pg_resetwal,它帮助打开了服务,但后来发生了这样的事情:

FATAL: database "postgres" does not exist DETAIL: The database subdirectory "base/13466" is missing. ERROR: could not open relation with OID 2610

这非常奇怪,因为升级后运行没有任何问题的主服务器上并不存在13466 catalog.

这应该意味着副本服务器上的PostgreSQL实例中存在不一致.

The first error message, LOG: invalid primary checkpoint record PANIC: could not locate a valid checkpoint record个, references an issue with the Write-Ahead Log (WAL) files, which are used by PostgreSQL for recovery. That can occur when there are issues during the data copying process, perhaps due to errors or interruptions.
See also "PostgreSQL Write-Ahead Logging (WAL) Trade-offs: Bounded vs. Archived vs. Replication Slots" by Thom Brown.

您使用的命令pg_resetwal(以前的pg_resetxlog)是一个在紧急情况下清除或调整WAL文件的实用程序.但是,它是最后的工具,使用它可能会导致一些数据丢失.

The second error message, FATAL: database "postgres" does not exist DETAIL: The database subdirectory "base/13466" is missing. ERROR: could not open relation with OID 2610个, indicates that the postgres database cannot be found on your replica server. The detail part suggests that the subdirectory corresponding to the postgres database, i.e., base/13466, is missing.

现在,为什么它指的是主服务器中不存在的文件夹13466:PostgreSQL for each 数据库使用unique OID (Object Identifier),这些OID用作保存数据库文件的目录的名称.这些OID在主服务器和复制副本服务器之间可能不同.

考虑到这些问题,我建议:

  • 验证rsync命令是否已成功完成且没有任何错误.确保正确复制了所有必要的文件.
  • 验证副本服务器上的权限.确保PostgreSQL服务具有访问数据文件所需的读/写权限.
  • try 使用pg_basebackup实用程序重新初始化复制副本.该实用程序将确保将所有必要的文件正确复制到备用服务器.

OP在 comments 中添加了:

除了许可问题,我还得承认我的另一个疏漏.副本上的13目录在rsync之前不是空的,我在initdb之后还没有清理它.

Now I finally completed successfully rsync upgrade.
However, a new problem came up. I have an additional tablespace that is located in "d:\tablespace_d", I rsynced this tablespace successfully, but pg_tablespace_location shows "pg_tblspc/16400" so when I want to query a table it throws an error "could not open file pg_tblspc/16400/PG_13_202010141/16403/2461". I can't find how to change the path of this tblspc.

mklink /D P:\Postgresql\13pro\data\pg_tblspc\16400 D:\tablespace_d:这似乎是可行的,我可以毫无错误地从这个表空间查询表. 但是当我想判断pg_tablespace_location(oid)的时候,它会抛出ERROR: could not read symbolic link "pg_tblspc/16400": Invalid argument

/J而不是/D,pg_tablespace_location(oid)显示正确的pg_tablespace_location,并且表格是可访问的

注意:函数pg_tablespace_location(oid)用于获取表空间的目录位置.但当您使用符号链接(mklink /D)时,似乎PostgreSQL在读取它时遇到了困难并抛出了一个错误.

如您所见,使用Junction(mklink /J)而不是符号链接可能会有所帮助.Windows中的连接类似于Unix/Linux中的硬链接,通常用于目录.

在您的示例中,命令为:

mklink /J P:\Postgresql\13pro\data\pg_tblspc\16400 D:\tablespace_d

创建指向D:\tablespace_d的交点P:\Postgresql\13pro\data\pg_tblspc\16400.当被访问时,它就像你在访问D:\tablespace_d一样,似乎PostgreSQL可以正确地解释这一点.

作为一般建议,您应该始终致力于使PostgreSQL数据目录(包括表空间)在您的系统中尽可能保持一致,以避免此类问题.在实际场景中,最好在设置数据库之前规划数据目录和表空间,以避免创建符号链接或连接.

Postgresql相关问答推荐

环境变量在Bash应用程序中没有出现

函数返回查询执行plpgsql时不存在列

此PostgreSQL汇总分组不适用于窗口表达式

Postgis超过2个表的查询在运行时爆炸

多克.波斯格雷斯.PgAdmin4

postgres 不同类型的更新

PostgreSQL 中的 Datum 数据类型是什么以及它的用途是什么?

返回行值和行计数的总和

INSERT 语句返回策略违规(USING 表达式)

如何在不同的行中显示两列,避免重复并省略空条目

我在try 访问我的数据库表时在 postgresql 中收到 aclcheck_error 错误

如何在 PostgreSQL 的回归测试中测试 TYPE 发送和接收函数

如何 Select 任意行的相邻行(在 sql 或 postgresql 中)?

如何让 Flask SQLAlchemy 重用数据库连接?

从左连接更新 Postgres

在 PL/pgSQL 中声明行类型变量

如何使用 Node.js 和 Postgresql 找到最后一个插入 ID?

根据 Helm 图表设置值

在 postgres 中导出为 CSV 并使用 GZIP 压缩

在 PostgreSQL 中使用 CASE 一次影响多个列