postgresql流复制
简介??从PostgreSQL 9.0开始,基于预写日志(Write Ahead Log,WAL)的可读复制(PITR)更是成为了官方提供的异步主从复制(Master-Slave Replication)解决方案,该方案拥有如下优点: 实现原理??主服务器在接受到每个事务请求时,将数据改动用预写日志(WAL)记录。具体而言,事务采用两段提交(Two Phase Commit),即先将改动写入预写日志,然后再实际改动数据库。这样可以保证预写日志的时间戳永远不落后于数据库,即便是正在写入时服务器突然崩溃,重启以后也可以依据预写日志将数据恢复,因为预写日志保留了比数据库记录中更新的版本。PostgreSQL的异步复制解决方案正是利用了预写日志,将预写日志从主服务器(Master Sever)传输到备用服务器(Standby Server),然后在备用服务器上回放(Replay)出预写日志中记录改动,从而实现主从复制。PostgreSQL使用了两种方式传输预写日志:存档式(archive)和流式(streaming)。 环境说明
需求:master和slave作为主从流复制,当master宕机后,slave切换为新主继续服务;然而当master恢复故障后,作为从重新加入主从流复制。 master配置主的基本配置请参考http://www.52php.cn/article/p-wxaybmrj-bau.html,以下是需更改添加的地方。 postgres=# create user rep replication password 'reptest';
CREATE ROLE
postgres=# du
List of roles
Role name | Attributes | Member of -----------+------------------------------------------------+-----------
postgres | Superuser,Create role,Create DB,Replication | {}
rep | Replication | {}
2.设置pg_hba.conf #允许slave访问
vim pg_hba.conf
host replication rep 10.10.10.61/8 md5
3.设置主库postgresql.conf wal_level = hot_standby # write ahead log,流复制时为hot_standby
hot_standby = on
max_wal_senders = 2 # 流复制的最大连接数
wal_keep_segments = 16 # 流复制保留的最大xlog数
其中为了在备机服务器上开启“只读”查询,wal_level必须设置成“hot_standby”. 但是,如果你一直不会在stand-by模式下连接到备机,你可以选择“archive”,archive模式只会将主上的wal日志记录备份到备用服务器上。 4.重启数据库 pg_ctl restart -D /data/pgsql/data
或者
pg_ctl stop -D /data/pgsql/data -m fast
pg_ctl start -D /data/pgsql/data -m fast
slave配置1.创建数据目录 mkdir -p /data/pgsql/data
chown -R postgres.postgres data
chmod 700 data
2.使用pg_backendup生成备库 -bash-4.2$ pg_basebackup -D /data/pgsql/data -Fp -Xs -v -P -h 10.10.10.60 -p 5432 -U rep
Password:
transaction log start point: 0/2000020
pg_basebackup: starting background WAL receiver
20154/20154 kB (100%),1/1 tablespace
transaction log end point: 0/20000E0
pg_basebackup: waiting for background process to finish streaming...
pg_basebackup: base backup completed
-bash-4.2$ ls /data/pgsql/data/
backup_label global pg_hba.conf pg_multixact pg_serial pg_stat_tmp pg_tblspc PG_VERSION postgresql.conf
base pg_clog pg_ident.conf pg_notify pg_snapshots pg_subtrans pg_twophase pg_xlog
此时表空间目录和$PGDATA目录已经复制过来了。 3.配置recovery.conf -bash-4.2$ rpm -ql postgresql-server |grep recovery /usr/share/pgsql/recovery.conf.sample
-bash-4.2$ cp /usr/share/pgsql/recovery.conf.sample /data/pgsql/data/recovery.conf #添加如下几行
vim recovery.conf
standby_mode = on
trigger_file = '/data/pgsql/pg.trigger'
primary_conninfo = 'host=10.10.10.60 port=5432 user=rep password=reptest'
其中: pg_ctl start -D /data/pgsql/data
测试流复制1.查看主库 -bash-4.2$ ps -ef |grep postgres
postgres 3585 23019 0 10:37 pts/0 00:00:00 psql
postgres 3730 1 0 11:23 pts/0 00:00:00 /usr/bin/postgres -D /data/pgsql/data
postgres 3731 3730 0 11:23 ? 00:00:00 postgres: logger process
postgres 3733 3730 0 11:23 ? 00:00:00 postgres: checkpointer process
postgres 3734 3730 0 11:23 ? 00:00:00 postgres: writer process
postgres 3735 3730 0 11:23 ? 00:00:00 postgres: wal writer process
postgres 3736 3730 0 11:23 ? 00:00:00 postgres: autovacuum launcher process
postgres 3737 3730 0 11:23 ? 00:00:00 postgres: stats collector process
postgres 4066 3730 0 13:40 ? 00:00:00 postgres: wal sender process rep 192.168.3.141(47146) streaming 0/3000A38
postgres 4069 23019 0 13:42 pts/0 00:00:00 ps -ef
postgres 4070 23019 0 13:42 pts/0 00:00:00 grep --color=auto postgres
root 23018 21245 0 Apr01 pts/0 00:00:00 su - postgres
postgres 23019 23018 0 Apr01 pts/0 00:00:00 -bash
确认主库中进程有“postgres: wal sender process” -bash-4.2$ ps -ef |grep postgres
root 694 19367 0 11:27 pts/0 00:00:00 psql -h 192.168.3.139 -U postgres -W
root 724 19367 0 11:57 pts/0 00:00:00 su - postgres
postgres 725 724 0 11:57 pts/0 00:00:00 -bash
postgres 1069 1 0 14:13 pts/0 00:00:00 /usr/bin/postgres -D /data/pgsql/data
postgres 1070 1069 0 14:13 ? 00:00:00 postgres: logger process
postgres 1071 1069 0 14:13 ? 00:00:00 postgres: startup process recovering 000000010000000000000003
postgres 1072 1069 0 14:13 ? 00:00:00 postgres: checkpointer process
postgres 1073 1069 0 14:13 ? 00:00:00 postgres: writer process
postgres 1074 1069 0 14:13 ? 00:00:00 postgres: stats collector process
postgres 1075 1069 0 14:13 ? 00:00:00 postgres: wal receiver process streaming 0/3000AD0
postgres 1078 725 0 14:15 pts/0 00:00:00 ps -ef
postgres 1079 725 0 14:15 pts/0 00:00:00 grep --color=auto postgre
确定备库进程中有”postgres: wal receiver process” 3.执行如下命令查看快照,它返回主库记录点、备库记录点;主库每增加一条写入,记录点的值就会加1。 postgres=# select txid_current_snapshot();
txid_current_snapshot -----------------------
1894:1894:
(1 row)
postgres=# create database testdb;
CREATE DATABASE
postgres=# select txid_current_snapshot();
txid_current_snapshot -----------------------
1895:1895:
(1 row)
4.查看主备同步状态 postgres=# select * from pg_stat_replication;
pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | state | sent_location | write_location | flush_location | replay_locat
ion | sync_priority | sync_state ------+----------+---------+------------------+---------------+-----------------+-------------+-------------------------------+-----------+---------------+----------------+----------------+-------------
----+---------------+------------
4066 | 16385 | rep | walreceiver | 192.168.3.141 | | 47146 | 2016-04-08 13:40:53.375562+08 | streaming | 0/3000B68 | 0/3000B68 | 0/3000B68 | 0/3000B68
| 0 | async
(1 row)
字段state显示的同步状态有:startup(连接中)、catchup(同步中)、streaming(同步);字段sync_state显示的模式有:async(异步)、sync(同步)、potential(虽然现在是异步模式,但是有可能升级到同步模式) 5.主库添加数据 postgres=# create table t1(id int4,create_time timestamp(0) without time zone);
CREATE TABLE postgres=# insert into t1 values(1,now());
INSERT 0 1 postgres=# select * from t1;
id | create_time
----+---------------------
1 | 2016-04-08 13:53:50
(1 row)
6.在从库查看数据 postgres=# c testdb
postgres=# select * from t1;
id | create_time ----+---------------------
1 | 2016-04-08 13:53:50
(1 row)
主从库数据同步,则流复制成功。 7.从库插入数据 postgres=# insert into t1 values(2,now());
ERROR: cannot execute INSERT in a read-only transaction
备库上执行insert语句会报错,因为备库是只读的。 主从切换1.模拟主机故障 -bash-4.2$ pg_ctl stop -D /data/pgsql/data -m fast
waiting for server to shut down.... done
server stopped
2.提升备库状态 -bash-4.2$ pg_ctl promote -D /data/pgsql/data
server promoting
3.查看状态 postgres=# select pg_is_in_recovery();
pg_is_in_recovery
-------------------
f
(1 row)
主库返回f,备库返回t 原master恢复为从我们以新master和新slave称呼 #新master
postgres=# insert into t1 values(2,now());
postgres=# insert into t1 values(3,now());
2.查看两台数据库服务器的pg_xlog; #新master
-bash-4.2$ ll total 81928
-rw-------. 1 postgres postgres 16777216 Apr 8 12:45 000000010000000000000002 -rw-------. 1 postgres postgres 16777216 Apr 8 16:09 000000010000000000000003 -rw-------. 1 postgres postgres 16777216 Apr 11 09:22 000000020000000000000003 -rw-------. 1 postgres postgres 16777216 Apr 11 10:24 000000020000000000000004 -rw-------. 1 postgres postgres 16777216 Apr 12 09:16 000000020000000000000005 -rw-------. 1 postgres postgres 56 Apr 8 16:10 00000002.history drwx------. 2 postgres postgres 4096 Apr 8 12:45 archive_status
#新slave
-bash-4.2$ ll total 49156
-rw-------. 1 postgres postgres 16777216 Apr 8 12:12 000000010000000000000001 -rw-------. 1 postgres postgres 16777216 Apr 8 12:12 000000010000000000000002 -rw-------. 1 postgres postgres 16777216 Apr 8 15:37 000000010000000000000003 drwx------. 2 postgres postgres 4096 Apr 1 09:22 archive_status
区别是新主上多出来的日志就是我们新插入数据后生成的日志 host replication rep 10.10.10.60/8 md5
4.查看主从pg_controldata输出 #新master
-bash-4.2$ pg_controldata /data/pgsql/data
pg_control version number: 922
Catalog version number: 201204301
Database system identifier: 6268391932590681930
Database cluster state: in production
pg_control last modified: Mon 11 Apr 2016 04:36:25 PM CST
Latest checkpoint location: 0/5002E68
Prior checkpoint location: 0/5002DD0
Latest checkpoint's REDO location: 0/5002E30
Latest checkpoint's TimeLineID: 2
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID: 0/1899
Latest checkpoint's NextOID: 16390
Latest checkpoint's NextMultiXactId: 1
Latest checkpoint's NextMultiOffset: 0
Latest checkpoint's oldestXID: 1879
Latest checkpoint's oldestXID's DB: 1
Latest checkpoint's oldestActiveXID: 1899
Time of latest checkpoint: Mon 11 Apr 2016 04:36:25 PM CST
Minimum recovery ending location: 0/0
Backup start location: 0/0
Backup end location: 0/0
End-of-backup record required: no
Current wal_level setting: hot_standby
Current max_connections setting: 100
Current max_prepared_xacts setting: 0
Current max_locks_per_xact setting: 64
Maximum data alignment: 8
Database block size: 8192
Blocks per segment of large relation: 131072
WAL block size: 8192
Bytes per WAL segment: 16777216
Maximum length of identifiers: 64
Maximum columns in an index: 32
Maximum size of a TOAST chunk: 1996
Date/time type storage: 64-bit integers
Float4 argument passing: by value
Float8 argument passing: by value
#新slave
-bash-4.2$ pg_controldata /data/pgsql/data
pg_control version number: 922
Catalog version number: 201204301
Database system identifier: 6268391932590681930
Database cluster state: shut down in recovery
pg_control last modified: Mon 11 Apr 2016 04:06:39 PM CST
Latest checkpoint location: 0/3014EB8
Prior checkpoint location: 0/3014EB8
Latest checkpoint's REDO location: 0/3014EB8
Latest checkpoint's TimeLineID: 1
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID: 0/1897
Latest checkpoint's NextOID: 16390
Latest checkpoint's NextMultiXactId: 1
Latest checkpoint's NextMultiOffset: 0
Latest checkpoint's oldestXID: 1879
Latest checkpoint's oldestXID's DB: 1
Latest checkpoint's oldestActiveXID: 0
Time of latest checkpoint: Fri 08 Apr 2016 03:37:07 PM CST
Minimum recovery ending location: 0/3014F18
Backup start location: 0/0
Backup end location: 0/0
End-of-backup record required: no
Current wal_level setting: hot_standby
Current max_connections setting: 100
Current max_prepared_xacts setting: 0
Current max_locks_per_xact setting: 64
Maximum data alignment: 8
Database block size: 8192
Blocks per segment of large relation: 131072
WAL block size: 8192
Bytes per WAL segment: 16777216
Maximum length of identifiers: 64
Maximum columns in an index: 32
Maximum size of a TOAST chunk: 1996
Date/time type storage: 64-bit integers
Float4 argument passing: by value
Float8 argument passing: by value
从输出结果我们得出Latest checkpoint’s TimeLineID 新主为2,因为我们由从切换为新master并且新插入了数据,而新slave仍为1 5.配置新slave的recovery.conf -bash-4.2$ rpm -ql postgresql-server |grep recovery
/usr/share/pgsql/recovery.conf.sample
-bash-4.2$ cp /usr/share/pgsql/recovery.conf.sample /data/pgsql/data/recovery.conf
添加如下几行
standby_mode = on
trigger_file = '/data/pgsql/pg.trigger'
primary_conninfo = 'host=10.10.10.61 port=5432 user=rep password=rep'
#新增如下一行
recovery_target_timeline = 'latest'
6.启动新从 pg_ctl start -D /data/pgsql/data
7.查看日志pg_log scp 00000002* test@10.10.10.60:/data/pgsql/data/pg_xlog
9.重启新slave数据库 pg_ctl restart -D /data/pgsql/data
10.查看新slave数据是否同步 -bash-4.2$ psql
psql (9.2.15)
Type "help" for help.
postgres=# select * from t1;
id | create_time ----+---------------------
1 | 2016-04-08 13:53:50
2 | 2016-04-11 10:27:23
3 | 2016-04-11 10:33:17
(3 rows)
postgres=# select pg_is_in_recovery(); pg_is_in_recovery
------------------- t (1 row)
由上看出新slave和新master同步,并且状态正常,切换成功。 #新master
postgres=# select pg_current_xlog_location(); pg_current_xlog_location
-------------------------- 0/50227C8 (1 row) #新slave postgres=# select pg_last_xlog_receive_location(); pg_last_xlog_receive_location -------------------------------
0/50227C8
(1 row)
postgres=# select pg_last_xlog_replay_location();
pg_last_xlog_replay_location ------------------------------
0/50227C8
(1 row)
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |