PostgreSQL 18 preview - pg_upgrade大版本升级支持swap选项(仅移动文件)
PostgreSQL 18 preview - pg_upgrade大版本升级支持swap选项(移动文件)
PostgreSQL 18 preview, 使用pg_upgrade升级大版本时, 如果新集群和老集群的数据文件放在同一个文件系统内, 使用swap选项(类似mv data)移动旧集群数据文件到新集群目录中, 比copy和hard link都快.
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=626d7236b65da50423df7de035e86f273cd36b49
pg_upgrade: Add --swap for faster file transfer.
author Nathan Bossart <[email protected]>
Tue, 25 Mar 2025 21:02:35 +0000 (16:02 -0500)
committer Nathan Bossart <[email protected]>
Tue, 25 Mar 2025 21:02:35 +0000 (16:02 -0500)
commit 626d7236b65da50423df7de035e86f273cd36b49
tree caa5496310260ed60cb6da76c84f042a2802ae27 tree
parent 9c49f0e8cd7d59e240f5da88decf2d62d8a4ad0d commit | diff
pg_upgrade: Add --swap for faster file transfer.
This new option instructs pg_upgrade to move the data directories
from the old cluster to the new cluster and then to replace the
catalog files with those generated for the new cluster. This mode
can outperform --link, --clone, --copy, and --copy-file-range,
especially on clusters with many relations.
However, this mode creates many garbage files in the old cluster,
which can prolong the file synchronization step if
--sync-method=syncfs is used. To handle that, we recommend using
--sync-method=fsync with this mode, and pg_upgrade internally uses
"initdb --sync-only --no-sync-data-files"for file synchronization.
pg_upgrade will synchronize the catalog files as they are
transferred. We assume that the database files transferred from
the old cluster were synchronized prior to upgrade.
This mode also complicates reverting to the old cluster, so we
recommend restoring from backup upon failure during or after file
transfer. We did consider teaching pg_upgrade how to generate a
revert script for such failures, but we decided against it due to
the rarity of failing during file transfer, the complexity of
generating the script, and the potential for misusing the script.
The new mode is limited to clusters located in the same file
system. With some effort, we could probably support upgrades
between different file systems, but this mode is unlikely to offer
much benefit if we have to copy the files across file system
boundaries.
It is also limited to upgrades from version 10 or newer. There are
a few known obstacles for using swap mode to upgrade from older
versions. For example, the visibility map format changed in v9.6,
and the sequence tuple format changed in v10. In fact, swap mode
omits the --sequence-data option in its uses of pg_dump and instead
reuses the old cluster's sequence data files. While teaching swap
mode to deal with these kinds of changes is surely possible (and we
may have to deal with similar problems in the future, anyway), it
doesn't seem worth the effort to support upgrades from
long-unsupported versions.
Reviewed-by: Greg Sabino Mullane <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://postgr.es/m/Zyvop-LxLXBLrZil%40nathan
AI 解读
这个补丁为 pg_upgrade 工具引入了一个新的选项 --swap,用于加速文件传输。以下是对其内容的详细解读和分析:
1. 补丁的核心功能
(1) 新选项 --swap 的作用
核心机制:
--swap模式通过以下步骤完成数据迁移:这种方式避免了传统复制或硬链接操作,特别是在包含大量关系(relations)的集群中性能更优。
将旧集群的数据目录直接移动到新集群的位置。 使用新集群生成的系统表(catalog 文件)替换旧集群的系统表。
适用场景:
适用于位于同一文件系统的旧集群和新集群之间的升级。 对于大规模数据库集群, --swap可能比现有的--link、--clone、--copy和--copy-file-range更快。
2. 优势与限制
(1) 优势
性能提升:
直接移动文件目录,避免了跨文件系统的复制操作。 在文件系统支持高效重命名(rename)操作时,性能尤为显著。 简化文件同步:
内部使用 initdb --sync-only --no-sync-data-files确保文件同步的完整性。假设旧集群的数据文件在升级前已经同步完毕,因此只需同步新生成的系统表文件。
(2) 限制
垃圾文件问题:
--swap模式会在旧集群中留下大量垃圾文件(如被替换的旧系统表文件)。如果使用 --sync-method=syncfs,这些垃圾文件可能导致文件同步步骤变慢。推荐使用 --sync-method=fsync来优化性能。回滚复杂性:
由于旧集群的文件被直接移动到新集群位置,回滚变得复杂。 官方建议在失败时从备份恢复,而不是尝试回滚。 考虑到文件传输阶段失败的概率较低,以及生成回滚脚本的复杂性和潜在误用风险,最终决定不支持自动生成回滚脚本。 文件系统限制:
--swap仅支持位于同一文件系统的集群升级。如果需要跨文件系统升级,则需要复制文件,这会削弱 --swap的性能优势。版本限制:
仅支持从 PostgreSQL 10 或更高版本升级。 较老版本存在一些兼容性障碍(例如 v9.6 的可见性映射格式变化,v10 的序列元组格式变化)。 --swap模式省略了--sequence-data选项,而是直接复用旧集群的序列数据文件。支持从长期未维护的版本升级被认为成本过高,因此未实现。
3. 实现细节
(1) 文件同步优化
pg_upgrade内部调用initdb --sync-only --no-sync-data-files来同步新生成的系统表文件。假设旧集群的数据文件在升级前已经同步,因此无需再次同步整个数据集。
(2) 回滚策略
由于 --swap模式直接修改了文件系统结构,传统的回滚方法不再适用。推荐用户在升级失败时从备份恢复,而不是尝试手动回滚。
(3) 兼容性处理
对于较老版本的 PostgreSQL(如 9.6 及以下),由于格式变化较多,支持 --swap模式需要额外的工作量。鉴于这些版本早已停止支持,官方认为投入资源解决兼容性问题的性价比不高。
4. 讨论与权衡
(1) 性能 vs 复杂性
--swap模式的性能优势明显,但其复杂性(如垃圾文件处理、回滚困难)也需要权衡。官方选择了推荐备份恢复而非自动生成回滚脚本,这是一种务实的折中方案。
(2) 文件系统边界
--swap的设计假设旧集群和新集群位于同一文件系统,这是为了利用高效的文件移动操作。如果需要跨文件系统升级,则需要复制文件,这会削弱 --swap的性能优势,因此未支持跨文件系统。
(3) 版本支持
限制最低支持版本为 PostgreSQL 10 是基于兼容性和开发成本的综合考虑。 对于未来可能遇到的类似格式变化问题,官方保留了解决的可能性,但目前未优先处理。
5. 社区反馈与评审
评审者:
Greg Sabino Mullane 和 Robert Haas 对该补丁进行了评审,并提出了改进建议。 讨论链接:
Discussion Thread 社区态度:
该补丁得到了积极评价,尤其是在大规模集群升级场景下的性能提升。 同时也认可了对回滚复杂性和版本兼容性的权衡决策。
6. 总结
这个补丁通过引入 --swap 选项,为 pg_upgrade 提供了一种更快的文件传输模式,特别适合大规模集群升级。尽管存在一些限制(如文件系统边界、版本兼容性、回滚复杂性),但其性能优势和实用性使其成为一种有价值的补充。