pgcopydb: 复制 PostgreSQL 数据库到目标服务器

三月 28, 2024

简介pgcopydb程序是一个工具,可以将 PostgreSQL 数据库逻辑复制到目标 PostgreSQL 服务器。

本文包含以下部分:

  1. 介绍
  2. 如何复制 Postgres 数据库
  3. pgcopydb 的主要特性
  4. 目录

介绍

pgcopydb 项目是一个开源软件项目。开发活动在 Github 上进行,并且是公开的:欢迎每个人通过创建问题、拉取请求、提供反馈等方式参与贡献。

请记住,第一步是实际去使用pgcopydb命令,然后阅读整个完整的可用文档,然后以一种友善和礼貌的方式向社区进行交流 —— 就像你期望人们在提到你时使用的方式一样。

如何复制 Postgres 数据库

pgcopydb 是一种自动将 PostgreSQL 数据库复制到另一台服务器的工具。pgcopydb 的主要应用场景是迁移到新的 Postgres 系统,无论是新硬件、新架构还是新的 Postgres 主要版本。

这个想法来自于在两个正在运行的 Postgres 服务器之间运行pg_dump -jN | pg_restore -jN。为了尽快将数据库复制到另一台服务器,用户会希望使用pg_dump的并行选项,并且仍然能够将数据流式传输到尽可能多的pg_restore任务上。遗憾的是,这种方法无法直接使用 pg_dump 和 pg_restore 来实现,请参阅绕过 TABLE DATA 的中间文件。

使用pgcopydb时,可以通过以下简单的命令行实现并行和流式处理:

$ export PGCOPYDB_SOURCE_PGURI="postgres://user@source.host.dev/dbname"
$ export PGCOPYDB_TARGET_PGURI="postgres://role@target.host.dev/dbname"

$ pgcopydb clone --table-jobs 4 --index-jobs 4

有关该命令实现原理以及许多其他支持选项的详细信息,请参阅 pgcopydb clone 的手册页。

pgcopydb 的主要特性

  • 绕过中间文件

    在带上-jobs选项使用pg_dumppg_restore时,表数据首先被复制到磁盘上的文件,然后再次读取并发送到目标服务器。pgcopydb 避免了这些步骤,而是将 COPY 缓冲区数据从源端流式传输到目标端,无需中间处理。

  • 使用 COPY FREEZE

    Postgres 有一个优化,在导入过程中,将导入行标记为已冻结,以减少迁移后的 vacuum 工作,这对应 VACUUM 命令的 FREEZE 选项。pgcopydb 使用了该选项,除非采用了对同一表进行并发处理。

  • 并发创建索引

    在表上创建索引时,Postgres 必须进行完整的顺序扫描才能读取到所有行。在 Postgres 8.3 中实现了 synchronize_seqscans 优化,从而单个这样的磁盘读取,能够馈送到不同客户端会话中同时运行的多个 SQL 命令。pgcopydb 通过同时在同一表上运行多个 CREATE INDEX 命令来利用这一点。该并发数受--index-jobs选项限制。

  • 同一表上的并发

    迁移非常大的表时,对表进行分区并运行多个 COPY 命令,使用不重叠的 WHERE 子句分发源数据,可能会有所帮助。pgcopydb 使用split-table-larger-than选项实现了该方法。

  • 数据变更捕获

    将数据库迁移到新的 Postgres 服务器的最简单、最安全的方法,需要有一个维护窗口时间,具体取决于要迁移的数据大小。有时,业务需要减少迁移产生的停机时间窗口。对于这些高级和复杂的情况,pgcopydb 使用 Postgres 逻辑解码底层 API 实现了一个完整的复制解决方案,该 API 从 Postgres 9.4 开始可用。可以查阅pgcopydb fork --follow命令的参考手册。

目录