Postgresql主从复制

  1. 主备数据库启动,备库启动wal_receiver进程,wal进程向主库发送连接请求;
  2. 主库收到连接请求后启动wal_sender进程,并与wal_receiver进程建立tcp连接;
  1. 备库wal_receiver进程发送最新的wal lsn 给主库;
  2. 主库进行lsn 对比,定期向备库发送心跳信息,来确认备库的可用性,并且将没有传递的wal日志文件进行发送,同时调用SyncRepWaitForLSN()函数来获取锁存器,并且等待备库响应;锁存器的释放时机和主备同步模式的选择有关;
  1. 备库调用操作系统write()函数将wal文件写入缓存,然后调用操作系统fsync()函数将WAL刷新到磁盘,然后进行WAL文件回放;同时备库向主库返回ack确认信息,ack信息中包含write_lsn、flush_lsn、replay_lsn,用以告知主库当前的WAL日志在备库的应用位置以及状态,相关位置信息可以通过pg_stat_replication视图查看;
  2. 如果启用了hot_standby_feedback参数,备库会定期向主库发送xmin信息,用以保证主库不会vacuum掉备库需要的元组信息;

 

 

主:

# 修改配置文件
vim postgresql.conf
	wal_level = hot_standby			# 修改WAL日志信息的输出级别
  max_wal_senders = 10				# 设置最大的WAL发送进程数量,一个流复制的备库通常只消耗主库一个发送进程,必须小于max_connections
  wal_keep_segments = 512			# 设置WAL日志文件的保留数量,默认单个WAL文件的大小为16M,这里就是512*16MB=8GB
	  logging_collector = on			# 开启日志
  log_directory = 'pg_log'		# 设置日志路径
  log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'		# 设置日志文件名
  synchronous_commit = off		# 关闭同步提交,只能为off,否则主库会一直等待备机响应,当备机故障时主机也会出现问题

# 创建复制用户
create user repl replication login password'123456';

# 修改用户认证文件
vim pg_hba.conf 
	# 添加以下配置,考虑到主备角色互换,建议pg_hba.conf主备一样
  host	replication		repl	192.168.10.128/32		md5
  host	replication		repl	192.168.10.129/32		md5

从:

# 测试一下从服务器能否连接主服务器数据库
psql -U postgres -h 192.168.10.128
# 连接成功后停掉从库服务,清空从节点数据
rm -rf xxx/data/*
# 从主节点拷贝数据到从节点
pg_basebackup -h 192.168.10.128 -U repl -D xxx/data -X stream -P
# 复制share目录下的recovery.conf.sample文件,并修改recovery.conf
cp $PGHOME/share/recovery.conf.sample $PGDATA/recovery.conf
vim recovery.conf
	standby_mode = 'on'
  recovery_target_timeline = 'latest'
  primary_conninfo = 'host=192.168.10.128 port=5432 user=repl password=123456'
  
# 注意修改备库配置文件,因为是从主库复制过来的
  hot_standby = on   #在备份的同时允许查询
  max_standby_streaming_delay = 30s #可选,流复制最大延迟
  wal_receiver_status_interval = 10s #可选,从向主报告状态的最大间隔时间
  hot_standby_feedback = on #可选,查询冲突时向主反馈
  max_connections = 1000 #默认参数,非主从配置相关参数,表示到数据库的连接数,一般从库做主要的读服务时,设置值需要高于主库
  
注意:data目录权限应是0700

主备切换:

停掉主库
pg_ctl promote 从库执行切换,执行后发现recovery.conf变为recovery.done文件
mv recovery.done recovery.conf 在原主库执行,修改其中的主库信息
启动原主库

 

同步模式:

PG提供了5种同步模式,由synchronous_commit参数控制;

  • off:对于本机的WAL日志不用写入磁盘就可以提交,是异步模式,存在数据丢失风险;
  • local:不管有没有备库,只需要保证本机的WAL日志刷到磁盘就行了;
  • remote_write:等待主库日志刷新到磁盘,同时日志传递到备库的操作系统缓存中,不需要刷盘就能提交,不能避免操作系统崩溃;
  • on:如果没有备库,则表示WAL日志需要刷新到磁盘中才能提交;如果存在同步备库(synchronous_standby_name不为空),则需要等待远程备库也刷新到磁盘,主库才能提交;
  • remote_apply:PG高版本的功能,备库刷盘并且回放成功后,事务被标记为可见,用于做负载均衡,读写分离等;

 

 

  • 主从切换流程
1.在A做checkpoint,三次
postgres=# checkpoint ;


2.修改A的pg_hba.conf并reload
注释下面一行
#host all all 0.0.0.1/0 md5

重新加载pg_hba.conf
/data/postgres/pgsql/bin/pg_ctl reload -D /stage/data

3.在A上kill当前用户连接
postgres=# select pg_terminate_backend(pid) from pg_stat_activity where usename<>'postgres';
pg_terminate_backend
----------------------
(0 rows)

4、停止备机B、D
注释crontab
/data/postgres/pgsql/bin/pg_ctl stop -D /stage/data

5.等待主备状态一致
执行几次checkpoint;
select * from pg_stat_replication;

在原主建表插入数据验证一致性

create table tbase_test09(id int,dt date);

INSERT INTO public.tbase_test09 VALUES (100,now());

#等待A和C上xlog一致,即最后一个xlog的md5sum的值完全一致,再进行第6步

6.停止主机A

注释crontab
/data/postgres/pgsql/bin/pg_ctl stop -D /stage/data

7.提升C为主机
/data/postgres/pgsql/bin/pg_ctl promote -D /stage/data
查看是否能正常访问和读写是否正常
posted @ 2021-09-09 11:32  酸萝卜别吃  阅读(664)  评论(0编辑  收藏  举报