前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pgcopydb的使用

pgcopydb的使用

原创
作者头像
保持热爱奔赴山海
发布2024-06-27 14:57:59
590
发布2024-06-27 14:57:59
举报
文章被收录于专栏:饮水机管理员饮水机管理员

https://github.com/dimitri/pgcopydb

https://pgcopydb.readthedocs.io/en/latest/

https://www.modb.pro/db/519767

pgcopydb 随后将 pg_dump 和 pg_restore 用于流程的架构部分,并实现自己的数据复制多进程流部分。此外,pgcopydb 绕过 pg_restore 索引构建并在内部驱动它,以便可以同时构建所有索引。

pgcopydb 既实现了数据库的基本副本,也实现了变更数据捕获,以允许将更改从源数据库重播到目标数据库。

变更数据捕获功能是使用 Postgres 逻辑解码基础架构和 wal2json 插件实现的。

pgcopydb follow命令为逻辑解码插件wal2json实现了逻辑复制客户端。

pgcopydb clone --follow命令实现了完整的在线迁移解决方案

请注意,与离线迁移相比,在线迁移涉及的复杂性要大得多。首先实施离线迁移始终是一个好主意。

安装

yum install pgcopydb

我刚开始是使用yum安装成功,但是在使用过程中遇到问题,不清楚是哪里问题。

因此后续的演示,都是使用docker方式

代码语言:txt
复制
docker pull ghcr.io/dimitri/pgcopydb:latest

$ docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb --version
08:31:07.196 1 INFO   Running pgcopydb version 0.16.22.g00caf45 from "/usr/local/bin/pgcopydb"
pgcopydb version 0.16.22.g00caf45
compiled with PostgreSQL 16.3 (Debian 16.3-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
compatible with Postgres 11, 12, 13, 14, 15, and 16

$ docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb --help
\08:31:13.113 1 INFO   Running pgcopydb version 0.16.22.g00caf45 from "/usr/local/bin/pgcopydb"
pgcopydb: pgcopydb tool
usage: pgcopydb [ --verbose --quiet ]

Available commands:
  pgcopydb
    clone     Clone an entire database from source to target
    fork      Clone an entire database from source to target
    follow    Replay changes from the source database to the target database
    snapshot  Create and export a snapshot on the source database
  + compare   Compare source and target databases
  + copy      Implement the data section of the database copy
  + dump      Dump database objects from a Postgres instance
  + restore   Restore database objects into a Postgres instance
  + list      List database objects from a Postgres instance
  + stream    Stream changes from the source database
    ping      Attempt to connect to the source and target instances
    help      Print help message
    version   Print pgcopydb version

常用使用命令

clone和fork

因为历史原因,clone和fork实际上是等价的。

工作流程:

以下工作流程解释了如何在两个不同的 PostgreSQL 服务器之间使用 pgcopydb 进行数据库复制。

pgcopydb 首先使用来自源服务器的自定义格式(不是纯文本)的 pg_dump 生成仅模式备份。它将在两个文件中 a) 前数据部分 b) 后数据部分

pre-data 节文件将使用 pg_restore 命令在目标服务器中恢复。它在目标服务器中创建所有 PostgreSQL 对象。

pgcopydb 从源服务器获取所有表的列表,并在专用子进程中为每个表执行从源到目标的复制过程。它将对所有表执行,直到所有数据都被复制过来。

一个辅助进程与第 3 点中提到的主复制进程同时启动。该进程负责将所有大对象从源复制到目标。

在第 3 点提到的每个复制表子过程中,只要复制表数据,pgcopydb 就会获取索引列表并在目标服务器中并行创建它们。

正如我们在上一节中讨论的那样,索引创建将并行执行。

一旦创建了数据和索引,就会对每个目标表执行 Vacuum 分析。

现在,pgcopydb 获取序列列表并在目标服务器中相应地更新值。

最后,将在目标数据库中创建包含外键约束的 post-data 部分。

最重要的是,成功完成使数据库从源恢复到目标成功。

代码语言:txt
复制
参数:
  --source                      Postgres URI to the source database
  --target                      Postgres URI to the target database
  --dir                         Work directory to use
  --table-jobs                  Number of concurrent COPY jobs to run
  --index-jobs                  Number of concurrent CREATE INDEX jobs to run
  --restore-jobs                Number of concurrent jobs for pg_restore
  --large-objects-jobs          Number of concurrent Large Objects jobs to run
  --split-tables-larger-than    Same-table concurrency size threshold
  --split-max-parts             Maximum number of jobs for Same-table concurrency
  --estimate-table-sizes        Allow using estimates for relation sizes
  --drop-if-exists              On the target database, clean-up from a previous run first
  --roles                       Also copy roles found on source to target
  --no-role-passwords           Do not dump passwords for roles
  --no-owner                    Do not set ownership of objects to match the original database  默认会把表(或其它object)的同步账号授权信息,如果用户在目标pg上不存在则会报错
  --no-acl                      Prevent restoration of access privileges (grant/revoke commands).  不同步相关表(或其它object)的账号授权信息
  --no-comments                 Do not output commands to restore comments
  --no-tablespaces              Do not output commands to select tablespaces
  --skip-large-objects          Skip copying large objects (blobs)
  --skip-extensions             Skip restoring extensions
  --skip-ext-comments           Skip restoring COMMENT ON EXTENSION
  --skip-collations             Skip restoring collations
  --skip-vacuum                 Skip running VACUUM ANALYZE
  --skip-analyze                Skip running vacuumdb --analyze-only
  --skip-db-properties          Skip copying ALTER DATABASE SET properties
  --skip-split-by-ctid          Skip spliting tables by ctid
  --requirements <filename>     List extensions requirements
  --filters <filename>          Use the filters defined in <filename>  可以基于配置文件指定需要同步或者忽略的表清单
  --fail-fast                   Abort early in case of error
  --restart                     Allow restarting when temp files exist already
  --resume                      Allow resuming operations after a failure
  --not-consistent              Allow taking a new snapshot on the source database
  --snapshot                    Use snapshot obtained with pg_export_snapshot
  --follow                      Implement logical decoding to replay changes
  --plugin                      Output plugin to use (test_decoding, wal2json)
  --wal2json-numeric-as-string  Print numeric data type as string when using wal2json output plugin
  --slot-name                   Use this Postgres replication slot name
  --create-slot                 Create the replication slot
  --origin                      Use this Postgres replication origin node name
  --endpos                      Stop replaying changes when reaching this LSN

代码语言:txt
复制
对于非docker部署的,可以使用下面这种export加载环境变量的写法:
export PGCOPYDB_SOURCE_PGURI="postgres://dts:dts@192.168.31.181:5432/db1"
export PGCOPYDB_TARGET_PGURI="postgres://dts:dts@192.168.31.181:5436/db1"
pgcopydb clone --table-jobs 4 --index-jobs 2 

# 一次性全量clone
pgcopydb clone --source postgres://dts:dts@192.168.31.181:5432/db1 --target postgres://dts:dts@192.168.31.181:5436/db1 --table-jobs 3 --index-jobs 2 --restore-jobs 2 --drop-if-exists --no-acl --verbose

注意: 在运行过一次后,会在/tmp/pgcopydb/下生成文件,如果我们再次执行上面的pgcopydb命令就会直接被直接跳过,实际上不再执行。

如果要强制重新执行,可以加上--restart参数,或者把 /tmp/pgcopydb/这个目录删除掉,下面是加了--restart的过程:

代码语言:txt
复制
pgcopydb clone --source postgres://dts:dts@192.168.31.181:5432/db1 --target postgres://dts:dts@192.168.31.181:5436/db1  --drop-if-exists  --no-acl --verbose --restart

在PG的2端上开启日志:

代码语言:txt
复制
alter system set log_statement='all';
select pg_reload_conf();

再次执行pgcopydb clone的操作,可以看到pgcopydb实际执行的过程:

源端的部分日志截取:

代码语言:txt
复制
2024-06-27 14:15:06.266 CST [84892] LOG:  statement: SELECT pg_is_in_recovery()
2024-06-27 14:15:06.276 CST [84893] LOG:  statement: BEGIN
2024-06-27 14:15:06.276 CST [84893] LOG:  statement: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE
2024-06-27 14:15:06.277 CST [84893] LOG:  statement: select pg_export_snapshot()
2024-06-27 14:15:06.278 CST [84893] LOG:  statement: select current_setting('server_version'),        current_setting('server_version_num')::integer
2024-06-27 14:15:06.278 CST [84893] LOG:  statement: SET client_encoding TO 'UTF-8'
2024-06-27 14:15:06.279 CST [84893] LOG:  statement: SET extra_float_digits TO 3
2024-06-27 14:15:06.279 CST [84893] LOG:  statement: SET statement_timeout TO 0
2024-06-27 14:15:06.279 CST [84893] LOG:  statement: SET default_transaction_read_only TO off
2024-06-27 14:15:06.280 CST [84893] LOG:  statement: SET idle_in_transaction_session_timeout TO 0
2024-06-27 14:15:06.392 CST [84895] LOG:  statement: BEGIN
2024-06-27 14:15:06.394 CST [84895] LOG:  execute <unnamed>: select has_database_privilege(current_database(), $1);
2024-06-27 14:15:06.394 CST [84895] DETAIL:  parameters: $1 = 'create'
2024-06-27 14:15:06.394 CST [84895] LOG:  execute <unnamed>: select has_database_privilege(current_database(), $1);
2024-06-27 14:15:06.394 CST [84895] DETAIL:  parameters: $1 = 'temp'
2024-06-27 14:15:06.394 CST [84895] LOG:  statement: select current_setting('search_path')
2024-06-27 14:15:06.395 CST [84895] LOG:  statement: set local search_path to pgcopydb, "$user", public
......省略部分......
2024-06-27 14:15:07.002 CST [84926] LOG:  statement: copy (SELECT a,b FROM ONLY sm1.t1) to stdout
2024-06-27 14:15:07.003 CST [84923] LOG:  statement: copy (SELECT a FROM ONLY public.ttt) to stdout
2024-06-27 14:15:07.004 CST [84928] LOG:  statement: copy (SELECT a,b,c FROM ONLY public.t5) to stdout
2024-06-27 14:15:07.018 CST [84926] LOG:  statement: COMMIT
2024-06-27 14:15:07.019 CST [84923] LOG:  statement: COMMIT
2024-06-27 14:15:07.028 CST [84928] LOG:  statement: COMMIT
2024-06-27 14:15:07.440 CST [84933] LOG:  unexpected EOF on client connection with an open transaction
2024-06-27 14:15:07.633 CST [84893] LOG:  statement: COMMIT

目标端的部分日志截取:

代码语言:txt
复制
......省略部分......
2024-06-27 14:15:06.699 CST [84902] LOG:  statement: BEGIN
2024-06-27 14:15:06.699 CST [84902] LOG:  statement: COMMIT
2024-06-27 14:15:06.772 CST [84904] LOG:  statement: DROP TABLE IF EXISTS  public.t2, public.t1, public.t3, sm3.t1, sm1.t1, public.ttt, public.t5 CASCADE
2024-06-27 14:15:06.849 CST [84906] LOG:  statement: SELECT pg_catalog.set_config('search_path', '', false);
2024-06-27 14:15:06.849 CST [84906] LOG:  statement: SELECT pg_catalog.pg_is_in_recovery()
2024-06-27 14:15:06.850 CST [84906] LOG:  statement: --
	-- PostgreSQL database dump
	--
2024-06-27 14:15:07.387 CST [84959] LOG:  statement: -- Dumped from database version 15.4 - Percona Distribution
2024-06-27 14:15:07.387 CST [84959] LOG:  statement: -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg110+1)
......省略部分......
2024-06-27 14:15:06.865 CST [84906] LOG:  statement: SET default_tablespace = ''
2024-06-27 14:15:06.865 CST [84906] LOG:  statement: SET default_table_access_method = heap;
2024-06-27 14:15:06.866 CST [84906] LOG:  statement: CREATE TABLE public.t1 (
	    b integer NOT NULL
	);
2024-06-27 14:15:06.867 CST [84906] LOG:  statement: ALTER TABLE public.t1 OWNER TO postgres;
2024-06-27 14:15:06.868 CST [84906] LOG:  statement: CREATE SEQUENCE public.t1_b_seq
	    AS integer
	    START WITH 1
	    INCREMENT BY 1
	    NO MINVALUE
	    NO MAXVALUE
	    CACHE 1;
......省略部分......
2024-06-27 14:15:07.423 CST [84968] LOG:  statement: SET client_min_messages = warning;
2024-06-27 14:15:07.423 CST [84968] LOG:  statement: SET row_security = off;
2024-06-27 14:15:07.423 CST [84968] LOG:  statement: 
2024-06-27 14:15:07.423 CST [84968] LOG:  statement: --
	-- PostgreSQL database dump complete
	--

copy

copy里面又可以分为很多。

copy roles

代码语言:txt
复制
docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb copy roles --source postgres://dts:dts@192.168.31.181:5432/db1 --target postgres://dts:dts@192.168.31.181:5436/db1 --verbose

copy extensions   

代码语言:txt
复制
docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb copy extensions --source postgres://dts:dts@192.168.31.181:5432/db1 --target postgres://dts:dts@192.168.31.181:5436/db1 --verbose

copy schema

代码语言:txt
复制
docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb copy schema --source postgres://dts:dts@192.168.31.181:5432/db1 --target postgres://dts:dts@192.168.31.181:5436/db1 --verbose

这里copy schema执行遇到了报错,原因未知

copy data

代码语言:txt
复制
copy data
等价于下面的几个组合步骤:
$ pgcopydb copy table-data # 该命令从源数据库获取表列表,并在源数据库上运行 COPY TO 命令,然后直接使用 COPY FROM 命令将结果发送到目标数据库,完全避免使用磁盘。

$ pgcopydb copy blobs # 该命令从源数据库获取大对象(又称 blob)列表,并将其数据部分复制到目标数据库。默认情况下,由于 的行为,该命令假定大对象元数据已得到处理 。

$ pgcopydb copy indexes # 该命令从源数据库获取索引列表,并在目标数据库上运行每个索引 CREATE INDEX 语句。索引定义的语句被修改为包括 IF NOT EXISTS,并允许跳过目标数据库上已存在的索引

$ pgcopydb copy constraints  # 该命令从源数据库获取索引列表,并在目标数据库上运行每个索引 ALTER TABLE ... ADD CONSTRAINT ... USING INDEX 语句。索引必须已经存在,如果发现目标数据库上已经存在任何约束,命令将失败

$ pgcopydb copy sequences  # 该命令从源数据库获取序列列表,然后为每个序列获取和 属性,方式与 pg_dump 在源数据库上的方式相同,然后对目标数据库上的每个序列进行调用。

$ vacuumdb -z

# copy data
docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb copy data --source postgres://dts:dts@192.168.31.181:5432/db1 --target postgres://dts:dts@192.168.31.181:5436/db1  --table-jobs 4 --index-jobs 4 --restore-jobs 4 --verbose

copy indexes

代码语言:txt
复制
docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb copy indexes --source postgres://dts:dts@192.168.31.181:5432/db1 --target postgres://dts:dts@192.168.31.181:5436/db1  --table-jobs 4 --index-jobs 4 --restore-jobs 4 --verbose

其余几个copy table-data、copy blobs 就不举例了。

compare   

该命令连接到源数据库和目标数据库并执行 SQL 查询以获取有关迁移的表、索引和序列的 Postgres 目录信息。

然后,该工具会比较所选表的模式定义或数据内容,并通过 Unix 返回代码零来报告成功。

目前,该工具在模式支持方面非常有限:它仅涵盖 pgcopydb 需要了解的数据库模式,而内容并不多。

compare实际执行的sql,可以看这篇:https://pgcopydb.readthedocs.io/en/latest/ref/pgcopydb_compare.html

比对schema

代码语言:txt
复制
注意这个是以source端为准的,也就是说如果target的表比source的多,则多出来的object不会被检测到。另外如果某个schema里面是空的,则也不会被检测到。

docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb compare schema --source postgres://dts:dts@192.168.31.181:5432/db1  --target postgres://dts:dts@192.168.31.181:5436/db1 --verbose

比对数据

代码语言:txt
复制
注意这个是以source端为准的,也就是说如果target的表比source的多,则多出来的object不会被检测到。
docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb compare data --source postgres://dts:dts@192.168.31.181:5432/db1  --target postgres://dts:dts@192.168.31.181:5436/db1 --verbose

list   

List database objects from a Postgres instance

代码语言:txt
复制
Available commands:
  pgcopydb list
    databases    List databases
    extensions   List all the source extensions to copy
    collations   List all the source collations to copy
    tables       List all the source tables to copy data from
    table-parts  List a source table copy partitions
    sequences    List all the source sequences to copy data from
    indexes      List all the indexes to create again after copying the data
    depends      List all the dependencies to filter-out
    schema       List the schema to migrate, formatted in JSON
    progress     List the progress
    
    
docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb list databases --source postgres://dts:dts@192.168.31.181:5432/db1

docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb list extensions --source postgres://dts:dts@192.168.31.181:5432/db1

docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb list tables --source postgres://dts:dts@192.168.31.181:5432/db1

docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb list sequences --source postgres://dts:dts@192.168.31.181:5432/db1

docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb list indexes --source postgres://dts:dts@192.168.31.181:5432/db1

docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb list schema --source postgres://dts:dts@192.168.31.181:5432/db1

docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb list progress --source postgres://dts:dts@192.168.31.181:5432/db1

ping

ping连通性测试

代码语言:txt
复制
pgcopydb ping  --source postgres://dts:dts@192.168.31.181:5432/db1 --target postgres://dts:dts@192.168.31.181:5436/db1

follow

https://pgcopydb.readthedocs.io/en/latest/ref/pgcopydb_follow.html

逻辑复制

该命令使用您选择的逻辑解码插件(默认的test_decoding或wal2json )将在源数据库中注册的数据库更改重放到目标数据库中。

用法不太清楚,暂时没深入了解。

dump 、snapshot、restore、stream

用的也不多,自行查阅官方文档。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装
  • 常用使用命令
    • clone和fork
      • copy
        • compare   
          • list   
            • ping
              • follow
                • dump 、snapshot、restore、stream
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档