微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PostgreSQL data同步工具【pg_rewind】


@H_404_3@

一、系统

@H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@ @H_404_3@
@H_404_3@

IP@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

HOSTNAME@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

PG VERSION@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

DIR@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

OS@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

192.168.100.161@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

node1@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

9.4@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

/opt/pgsql@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

CentOS6.5_x64@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

192.168.100.162@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

node2@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

9.4@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

/opt/pgsql@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

CentOS6.5_x64@H_404_3@@H_404_3@

@H_404_3@
@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

# cat /etc/issue@H_404_3@@H_404_3@

@H_404_3@

CentOS release6.5 (Final)@H_404_3@@H_404_3@

@H_404_3@

Kernel \r on an\m@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

# uname -a@H_404_3@@H_404_3@

@H_404_3@

Linux barman2.6.32-431.11.2.el6.x86_64 #1 SMP Tue Mar 25 19:59:55 UTC 2014 x86_64 x86_64x86_64 GNU/Linux@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

# cat /etc/hosts@H_404_3@@H_404_3@

@H_404_3@

127.0.0.1@H_404_3@@H_404_3@@H_404_3@localhost.localdomain@H_404_3@@H_404_3@@H_404_3@localhost.localdomain@H_404_3@@H_404_3@@H_404_3@localhost4@H_404_3@@H_404_3@@H_404_3@localhost4.localdomain4@H_404_3@@H_404_3@@H_404_3@localhost@H_404_3@@H_404_3@@H_404_3@node1@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

::1@H_404_3@@H_404_3@@H_404_3@localhost.localdomain@H_404_3@@H_404_3@@H_404_3@localhost.localdomain@H_404_3@@H_404_3@@H_404_3@localhost6@H_404_3@@H_404_3@@H_404_3@localhost6.localdomain6@H_404_3@@H_404_3@@H_404_3@localhost@H_404_3@@H_404_3@@H_404_3@node1@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

192.168.100.161node1@H_404_3@@H_404_3@

@H_404_3@

192.168.100.162node2@H_404_3@@H_404_3@

@H_404_3@

二、安装

@H_404_3@

2.1简介@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

pg_rewind is a tool for synchronizing aPostgresql data directory with another Postgresql data directory that wasforked from the first one. The result is equivalent to rsyncing the first datadirectory with the second one. The advantage of pg_rewind over rsync is thatpg_rewind uses the WAL to determine changed data blocks,and does not requirereading through all files in the cluster. That makes it a lot faster when thedatabase is large and only a small portion of it differs between the clusters.@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

注意:@H_404_3@@H_404_3@

@H_404_3@

pg_rewind@H_404_3@@H_404_3@同步数据不像@H_404_3@@H_404_3@rsync@H_404_3@@H_404_3@,一般情况下使用@H_404_3@@H_404_3@rsync@H_404_3@@H_404_3@做同步时需要扫描整个文件,当数据量不大时扫描时间相对来说可以忽略或接受,但是当数据量达几百@H_404_3@@H_404_3@G@H_404_3@@H_404_3@甚至上@H_404_3@@H_404_3@T@H_404_3@@H_404_3@时扫描将会耗时很长,为了改进目前的同步机制,因此在@H_404_3@@H_404_3@pg_rewind@H_404_3@@H_404_3@中不再对所有同步文件进行扫描,而是仅从@H_404_3@@H_404_3@wal@H_404_3@@H_404_3@的@H_404_3@@H_404_3@timeline@H_404_3@@H_404_3@获取相关信息,定位到哪些@H_404_3@@H_404_3@blocks@H_404_3@@H_404_3@需要同步并对@H_404_3@@H_404_3@blocks@H_404_3@@H_404_3@进行标记,之后再将需要同步的@H_404_3@@H_404_3@blocks@H_404_3@@H_404_3@进行拷贝。@H_404_3@@H_404_3@

@H_404_3@

pg_rewind@H_404_3@@H_404_3@要求能够扫描到需要的@H_404_3@@H_404_3@wal@H_404_3@@H_404_3@,若需要的@H_404_3@@H_404_3@wal@H_404_3@@H_404_3@不在@H_404_3@@H_404_3@pg_xlog@H_404_3@@H_404_3@中则去归档中查找(该功能尚未支持,目前需要手动将缺少的@H_404_3@@H_404_3@wal@H_404_3@@H_404_3@从归档中拷贝到@H_404_3@@H_404_3@pg_xlog@H_404_3@@H_404_3@)@H_404_3@@H_404_3@

@H_404_3@

2.2要求@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

在使用@H_404_3@@H_404_3@pg_rewind@H_404_3@@H_404_3@时,需要开启以下数据库功能(@H_404_3@@H_404_3@2@H_404_3@@H_404_3@选@H_404_3@@H_404_3@1@H_404_3@@H_404_3@):@H_404_3@@H_404_3@

@H_404_3@

(@H_404_3@@H_404_3@1@H_404_3@@H_404_3@)@H_404_3@@H_404_3@data checksums@H_404_3@@H_404_3@

@H_404_3@

校验@H_404_3@@H_404_3@Pg@H_404_3@@H_404_3@数据页并标记侦测损坏的数据块。针对@H_404_3@@H_404_3@cluster@H_404_3@@H_404_3@设置。当然开启该功能会带来性能上的额外开销,因为对每个数据页都要有额外的计算,所以使用时要考虑全面权衡利弊。该功能在@H_404_3@@H_404_3@initdb@H_404_3@@H_404_3@时开启@H_404_3@@H_404_3@(-k)@H_404_3@@H_404_3@,之后不能改变(不过有一个新参数@H_404_3@@H_404_3@ignore_checksum_failure@H_404_3@@H_404_3@可以强制@H_404_3@@H_404_3@Pg@H_404_3@@H_404_3@在检测到损坏数据的时候继续执行事务,但要保证数据块的头信息没有损坏)。@H_404_3@@H_404_3@

@H_404_3@
  1. wal_log_hints@H_404_3@@H_404_3@

    是@H_404_3@Pg9.4@H_404_3@@H_404_3@中的一个新特性。@H_404_3@

    @H_404_3@@H_404_3@

    {@H_404_3@@H_404_3@本次测试选择第一种@H_404_3@}@H_404_3@@H_404_3@

@H_404_3@

2.3安装@H_404_3@@H_404_3@pg@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

Pg@H_404_3@@H_404_3@源码下载地址:@H_404_3@@H_404_3@

@H_404_3@

https://github.com/postgres/postgres@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

选择最新版本:@H_404_3@@H_404_3@9.4devel@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

yum install flex bison readline-devel zlib-devel@H_404_3@@H_404_3@

@H_404_3@

安装过程略@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

注:@H_404_3@@H_404_3@node1@H_404_3@@H_404_3@初始化数据库,@H_404_3@@H_404_3@node2@H_404_3@@H_404_3@仅安装数据库软件。初始化时加入@H_404_3@@H_404_3@-k@H_404_3@@H_404_3@参数。@H_404_3@@H_404_3@

@H_404_3@

2.4编译安装@H_404_3@@H_404_3@pg_rewind@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

# unzip pg_rewind-master.zip@H_404_3@@H_404_3@

@H_404_3@

# mv pg_rewind-master postgres-master/contrib/@H_404_3@@H_404_3@

@H_404_3@

# cd postgres-master/contrib/pg_rewind-master/@H_404_3@@H_404_3@

@H_404_3@

# make && make install@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

也可通过@H_404_3@@H_404_3@pg@H_404_3@@H_404_3@系统管理用户编译安装,如:@H_404_3@@H_404_3@

@H_404_3@

# su - postgres@H_404_3@@H_404_3@

@H_404_3@

$ make USE_PGXS=1 top_srcdir=postgres-master@H_404_3@@H_404_3@

@H_404_3@

$ make USE_PGXS=1 top_srcdir=postgres-master install@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

验证是否安装正确:@H_404_3@@H_404_3@

@H_404_3@

$ pg_rewind --version@H_404_3@@H_404_3@

@H_404_3@

pg_rewind 0.1@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

查看是否开启校验:@H_404_3@@H_404_3@

@H_404_3@

$ pg_controldata | grep checksum@H_404_3@@H_404_3@

@H_404_3@

Data pagechecksum version:@H_404_3@@H_404_3@@H_404_3@1@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

postgres=# showdata_checksums ;@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@data_checksums@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

----------------@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@on@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

(1 row)@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

三、配置hot standby

@H_404_3@

3.1配置主节点数据库@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

$ vi postgresql.conf@H_404_3@@H_404_3@

@H_404_3@

listen_addresses= '*'@H_404_3@@H_404_3@

@H_404_3@

port = 5432@H_404_3@@H_404_3@

@H_404_3@

wal_level =hot_standby@H_404_3@@H_404_3@

@H_404_3@

max_wal_senders= 2@H_404_3@@H_404_3@

@H_404_3@

wal_keep_segments= 100@H_404_3@@H_404_3@@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

hot_standby = on@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

$ vi pg_hba.conf@H_404_3@@H_404_3@

@H_404_3@

host@H_404_3@@H_404_3@@H_404_3@all@H_404_3@@H_404_3@@H_404_3@@H_404_3@@H_404_3@all@H_404_3@@H_404_3@@H_404_3@192.168.100.0/24@H_404_3@@H_404_3@@H_404_3@trust@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

host@H_404_3@@H_404_3@@H_404_3@replication@H_404_3@@H_404_3@@H_404_3@all@H_404_3@@H_404_3@@H_404_3@192.168.100.0/24@H_404_3@@H_404_3@@H_404_3@trust@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

启动数据库:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node1 ~]$ pg_ctl restart@H_404_3@@H_404_3@

@H_404_3@

3.2设置备节点数据库@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 pgsql]$ pg_basebackup -D/opt/pgsql/data -h node1 -P@H_404_3@@H_404_3@

@H_404_3@

21099/21099 kB(100%),1/1 tablespace@H_404_3@@H_404_3@

@H_404_3@

NOTICE:@H_404_3@@H_404_3@@H_404_3@WAL archiving is not enabled; you must ensurethat all required WAL segments are copied through other means to complete thebackup@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

配置@H_404_3@@H_404_3@recovery.conf@H_404_3@@H_404_3@:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 data]$ cat recovery.conf@H_404_3@@H_404_3@

@H_404_3@

standby_mode ='on'@H_404_3@@H_404_3@

@H_404_3@

primary_conninfo= 'host=node1 user=postgres port=5432'@H_404_3@@H_404_3@

@H_404_3@

recovery_target_timeline= 'latest'@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

启动备库:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 data]$ pg_ctl start@H_404_3@@H_404_3@

@H_404_3@

四、切换模拟

@H_404_3@

4.1模拟主库故障@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

[postgres@node1 ~]$ pg_ctl stop -m f@H_404_3@@H_404_3@

@H_404_3@

4.2提升备库状态@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 ~]$ pg_ctl promote@H_404_3@@H_404_3@

@H_404_3@

4.3更新数据@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 ~]$ createdb pgbench@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 ~]$ pgbench -i -s 10 pgbench@H_404_3@@H_404_3@

@H_404_3@

4.4将@H_404_3@@H_404_3@node1@H_404_3@@H_404_3@@H_404_3@恢复为@H_404_3@@H_404_3@standby@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

同步数据:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node1 ~]$ pg_rewind -D /opt/pgsql/data/--source-server='host=node2 user=postgres port=5432'@H_404_3@@H_404_3@

@H_404_3@

The serversdiverged at WAL position 0/30000C8 on timeline 1.@H_404_3@@H_404_3@

@H_404_3@

No rewindrequired.@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

[postgres@node1 ~]$ vi /opt/pgsql/data/recovery.conf@H_404_3@@H_404_3@

@H_404_3@

primary_conninfo= 'host=node2 user=postgres port=5432'@H_404_3@@H_404_3@

@H_404_3@

recovery_target_timeline= 'latest'@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

启动@H_404_3@@H_404_3@node1@H_404_3@@H_404_3@上的数据库:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node1 ~]$ pg_ctl start@H_404_3@@H_404_3@

@H_404_3@

4.4将@H_404_3@@H_404_3@node1@H_404_3@@H_404_3@@H_404_3@恢复为@H_404_3@@H_404_3@master@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

停止@H_404_3@@H_404_3@node2@H_404_3@@H_404_3@:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 ~]$ pg_ctl stop -m f@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

提升@H_404_3@@H_404_3@node1@H_404_3@@H_404_3@状态:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node1 ~]$ pg_ctl promote@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

在@H_404_3@@H_404_3@node1@H_404_3@@H_404_3@上做一些更新:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node1 ~]$ pgbench -s 10 -T 60 pgbench@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

恢复@H_404_3@@H_404_3@node2@H_404_3@@H_404_3@为@H_404_3@@H_404_3@standby@H_404_3@@H_404_3@:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 ~]$ pg_rewind -D /opt/pgsql/data/--source-server='host=node1 user=postgres port=5432'@H_404_3@@H_404_3@

@H_404_3@

The serversdiverged at WAL position 0/12ACCC30 on timeline 2.@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 ~]$ mv /opt/pgsql/data/recovery.done/opt/pgsql/data/recovery.conf@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 ~]$ vi /opt/pgsql/data/recovery.conf@H_404_3@@H_404_3@

@H_404_3@

修改@H_404_3@@H_404_3@node2@H_404_3@@H_404_3@为@H_404_3@@H_404_3@node1@H_404_3@@H_404_3@)@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

启动@H_404_3@@H_404_3@node2@H_404_3@@H_404_3@上的数据库:@H_404_3@@H_404_3@

@H_404_3@

[postgres@node2 ~]$ pg_ctl start@H_404_3@@H_404_3@

@H_404_3@

server starting@H_404_3@@H_404_3@

@H_404_3@

五、基本原理

@H_404_3@

The basic idea is to copy everything fromthe new cluster to the old cluster,@H_404_3@@H_404_3@

@H_404_3@

except for the blocks that we kNow to bethe same.@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

1. Scan the WAL log of the old cluster,starting from the last checkpoint before@H_404_3@@H_404_3@

@H_404_3@

the point where the new cluster's timelinehistory forked off from the old cluster.@H_404_3@@H_404_3@

@H_404_3@

For each WAL record,make a note of thedata blocks that were touched. This yields@H_404_3@@H_404_3@

@H_404_3@

a list of all the data blocks that werechanged in the old cluster,after the new@H_404_3@@H_404_3@

@H_404_3@

cluster forked off.@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

2. copy all those changed blocks from thenew cluster to the old cluster.@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

3. copy all other files like clog,conffiles etc. from the new cluster to old cluster.@H_404_3@@H_404_3@

@H_404_3@

Everything except the relation files.@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

4. Apply the WAL from the new cluster,@H_404_3@starting from the checkpoint created at@H_404_3@@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

failover@H_404_3@@H_404_3@. (pg_rewind doesn't actually apply the WAL,it just creates abackup@H_404_3@@H_404_3@@H_404_3@

@H_404_3@

label file indicating that when Postgresqlis started,it will start replay@H_404_3@@H_404_3@

@H_404_3@

from that checkpoint and apply all the requiredWAL)@H_404_3@@H_404_3@

@H_404_3@

@H_404_3@@H_404_3@

@H_404_3@

六、参考文献

@H_404_3@

https://github.com/vmware/pg_rewind@H_404_3@

@H_404_3@

http://michael.otacoo.com/postgresql-2/postgres-module-highlight-pg_rewind-to-recycle-a-postgres-master-into-a-slave/@H_404_3@

@H_404_3@

七、license

@H_404_3@

pg_rewind can be distributed under theBSD-style Postgresql license@H_404_3@@H_404_3@

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐