注意:\
只是单行命令为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
中数据的硬链接组成.如果您不确定,可以比较主服务器和备用服务器上12pro
和13pro
目录的内容,看看它们看起来是否相似.
如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数据目录(包括表空间)在您的系统中尽可能保持一致,以避免此类问题.在实际场景中,最好在设置数据库之前规划数据目录和表空间,以避免创建符号链接或连接.