喵♂呜 的博客

一个刚毕业就当爹的程序猿 正在迷雾中寻找道路...

PgSql基于异步流复制的热备份

由于之前Slony-I的同步存在无法修改字段的问题 (有可能是我配置的问题) 这里用官方的WAL日志流同步复制


Standby 数据库搭建

pg_basebackup 基础备份

pg_basebackup 的作用 用于PG数据库的基础备份 也可从备份库上做基础备份

从 Standby 备份需要注意以下事项

  • 备份中没有备份历史文件
  • 备份过程中 Standby 被提升为主库 则备份会失败
  • 要求主库打开 “full_page_writes” 参数 并且 WAL 日志不能被其他工具去除 full-page writes 信息

pg_basebackup 命令使用方式如下

1
pg_basebackup [option...]

pg_basebackup 参数说明

  • -D directory 或者 –pgdata=directory 用于指定备份的目录
  • -F format 或 –format=format 指定输出格式 可选参数 [p/plain,t/tar]
    • 参数 p 或者 plain 代表原样复制
    • 参数 t 或者 tar 代表打包到 tar 文件
  • -x 或 -xlog 备份时会把备份中产生的 xlog 文件也自动备份出来 用于恢复数据库时保持数据完整

    这个选项需要设置 postgresql.confwal_keep_segments 确保日志不会被覆盖

  • -X method 或 -xlog-method=method 可选参数 [f/fetch,s/stream]
    • 参数 f 或 fetch 其意义与 -x 参数是一样的
    • -s 或 -stream 表示的意思也相近 代表同步开始后启动一个流复制连接从主库接受 WAL 日志

      这种方式避免了使用 -X f 时 主库上的 WAL 日志有可能被覆盖而导致失败的问题
      但是这种方式需要与主库建立两个连接 因此 postgresql.confmax_wal_senders 参数至少要设置为2或者大于2

  • -z 或 –gzip 仅能与 tar 输出模式配合 表示输出的包是经过 GZIP 压缩的 输出格式为 *.tar.gz
  • -Z level 或 –compress-level 指定 GZIP 的压缩级别 可选 1-9 其中9是最高压缩率 但是也最占用CPU
  • -c fast|spread 或 –checkpoint=fast|spread 设置 checkpoint 的模式是 fast 还是 spread
  • -l label 或 –label=label 用于指定备份的标志 可以为任意字符串
  • -P 或 –process 允许备份中实时打印备份进度
  • -v 或 –verbose 详细模式 和 -P 一起使用 还会打印当前备份文件信息
  • -V 或 –version 打印 pg_basebackup 的版本
  • -? 或 –help 显示帮助信息

同时也支持数据库连接的参数 -h -p -s -U -w -W 等参数

配置数据库 打开流复制

修改 $PGDATA/postgresql.conf

1
2
wal_level = hot_standby #设置日志级别
max_wal_senders = 5 #设置值为大于0的即可

然后重启服务器 pg_ctl -D $PGDATA -l logfile restart

在备份机上生成基础备份

1
2
pg_basebackup -h 172.30.16.6 -U slony -F p -P -x -R -D $PGDATA
56248/56248 kB (100%), 1/1 tablespace

由于同步的时候指定了 -R 参数 所以数据目录下会生成 recovery.conf

1
2
3
cat $PGDATA/recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=slony host=172.30.16.6 port=5432 sslmode=disable sslcompression=1'

启动 Standby

备份库上启动之前需要开始 hot_standby 模式 修改 $PGDATA/postgresql.conf 下的 hot_standby = on
启动服务器 pg_ctl -D $PGDATA -l logfile start

测试同步

表同步测试

在 主机上 psql -U postgresql master 进入 msater 数据库查看表

1
2
3
4
5
6
master=# \d
List of relations
Schema | Name | Type | Owner
--------+-----------+-------+-------
public | synctable | table | slony
(1 row)

可以看到只有一张之前用 Slony 同步测试时的表
现在我们新建一个表 standbytest

1
2
3
4
5
6
7
CREATE TABLE public.standbytest
(
id integer NOT NULL,
content text,
CONSTRAINT standbytest_pkey PRIMARY KEY (id)
);
CREATE TABLE // 提示成功

现在我们到 备份机器上查看

1
2
3
4
5
6
7
master=# \d
List of relations
Schema | Name | Type | Owner
--------+-------------+-------+------------
public | standbytest | table | postgresql
public | synctable | table | slony
(2 rows)

可以看到表已经复制过来了

表字段同步测试

查询表 standbytest 的字段

1
2
3
4
master=# select * from standbytest;
id | content
----+---------
(0 rows)

现在我们在主库新增一个 time 字段

1
ALTER TABLE "public"."standbytest" ADD COLUMN "time" timestamp;

然后到备份机上查询表结构

1
2
3
4
master=# select * from standbytest;
id | content | time
----+---------+------
(0 rows)

可以看到字段已经添加了

表数据同步测试(略)

流程与上面一致 测试成功


查看同步状态

1
2
3
4
5
master=# select pid,state,client_addr,sync_priority,sync_state from pg_stat_replication;
pid | state | client_addr | sync_priority | sync_state
------+-----------+-------------+---------------+------------
19843 | streaming | 172.30.16.7 | 0 | async
(1 row)

注意

和 Slony-I 一样备份库是不允许修改数据的 如果进行操作会提示操作失败
cannot excute XXXXXX in a read-only transaction

欢迎关注我的其它发布渠道