PostgreSQL流复制-主从切换
主从复制
1. 基于文件的日志传送
创建一个高可用性(HA)集群配置可采用连续归档,集群中主服务器工作在连续归档模式下,备服务器工作在连续恢复模式下(1台或多台可随时接管主服务器),备持续从主服务器读取WAL文件。
连续归档不需要对数据库表做任何改动,可有效降低管理开销,对主服务器的性能影响也相对较低。
直接从一个数据库服务器移动WAL记录到另一台服务器被称为日志传送,PostgreSQL通过一次一文件(WAL段)的WAL记录传输实现了基于文件的日志传送。
1、日志传送所需的带宽取根据主服务器的事务率而变化;
2、日志传送是异步的,即WAL记录是在事务提交后才被传送,那么在一个窗口期内如果主服务器发生灾难性的失效则会导致数据丢失,还没有被传送的事务将会被丢失;
3、数据丢失窗口可以通过使用参数archive_timeout进行限制,可以低至数秒,但同时会增加文件传送所需的带宽。
2. 流复制
PostgreSQL在9.x之后引入了主从的流复制机制,所谓流复制,就是备服务器通过tcp流从主服务器中同步相应的数据,主服务器在WAL记录产生时即将它们以流式传送给备服务器,而不必等到WAL文件被填充。
1、默认情况下流复制是异步的,这种情况下主服务器上提交一个事务与该变化在备服务器上变得可见之间客观上存在短暂的延迟,但这种延迟相比基于文件的日志传送方式依然要小得多,在备服务器的能力满足负载的前提下延迟通常低于一秒;
2、在流复制中,备服务器比使用基于文件的日志传送具有更小的数据丢失窗口,不需要采用archive_timeout来缩减数据丢失窗口;
3、将一个备服务器从基于文件日志传送转变成基于流复制的步骤是:把recovery.conf文件中的primary_conninfo设置指向主服务器;设置主服务器配置文件的listen_addresses参数与认证文件即可
一、主从环境
- 操作系统
Red Hat Enterprise Linux Server release 7.4 (Maipo)
- PostgresSQL版本
PostgreSQL 9.6
- 主机
主机名 IP 端口 角色
pg_master 172.26.32.144 1521 主库
pg_slave 172.26.32.145 1521 从库
二 、主库配置
安装postgresql
只有主库进行初始化,备库只安装
主库配置
-
使用postgres用户登陆数据库,创建复制用户
psql -p 1521 -d postgres
#首先需要配置一个账号进行主从同步。
设置密码,登录和备份权限
postgres=#create role replica login replication encrypted password ‘replica’; -
认证文件pg_hba.conf
#配置从库可以采用replica账号进行同步
host replication replica 172.26.32.0/24 md5
这样,就设置了replica这个用户可以从172.26.32.0/24 对应的网段进行流复制请求。 -
主库配置文件postgresql.conf
listen_addresses = ‘*’
max_connections = 1000 # 这个设置要注意下,从库的max_connections必须要大于主库的
wal_level = replica # 这个是设置主为wal的主机
max_wal_senders = 32 # 这个设置了可以最多有几个流复制连接,差不多有几个从,就设置几个
wal_keep_segments = 20 # 设置流复制保留的最多的xlog数目
wal_sender_timeout = 60s # 设置流复制主机发送数据的超时时间
archive_mode = on
archive_command = ‘cp %p /opt/pg/pg_archive/%f’
wal_log_hints = on
full_page_writes = on
hot_standby = on #说明这台机器不仅仅是用于数据归档,也用于数据查询
修改完,要创建刚刚配置的一些目录结构:
mkdir -p /opt/pg/pg_archive
chown -R pg:pg /opt/pg/pg_archive
5.配置.pgpass
su - pg
chmod 0600 .pgpass
vim ~/.pgpass
172.26.32.144:5432:replication:replica:replica
172.26.32.145:5432:replication:replica:replica
6.配置recovery文件(主库recovery.done,从库recovery.conf)
vim /opt/pg/pg_data/recovery.done
standby_mode = on #指明从库身份
primary_conninfo = ‘host=172.26.32.145 port=1521 user=replica password=replica’ # 这个说明这台机器对应从库的信息
recovery_target_timeline = ‘latest’ #同步到最新数据
生产环境加载配置:
pg_ctl reload -D /opt/pg/pg_data
7. 重启数据库服务
systemctl restart postgresql-9.6
pg_ctl restart -D /opt/pg/pg_data 只有在root下systemctl restart postgresql-9.6启动数据库生成的进程文件postmaster.opts postmaster.pid以后这个命令才能启动成功
pg_ctl -D /opt/pg/pg_data -l logfile restart
三、从库配置
从库安装完成后,不初始化,若已经初始化,删除其data目录
4.创建pg文件夹及给与权限
mkdir -p /opt/pg/pg_data
chown -R pg:pg pg_data
5、变更服务,指定刚才创建的数据文件夹,修改变量
cp /usr/lib/systemd/system/postgresql-9.6.service /usr/lib/systemd/system/postgresql-9.6.servicebak 所以第一次启动需要root启动
vi /usr/lib/systemd/system/postgresql-9.6.service
User=pg
Group=pg
Environment=PGDATA=/opt/pg/pg_data
- 基础备份(主库需索表,只读不能写)
[pg@pg_slave ~]#
在从库上执行ip是主库地址
测试能否登陆 psql -h 172.26.32.144 -p 1521 -U replica -d postgres
这时候会把主节点那边的数据文件都拷贝过来了。
在从库上执行
pg_basebackup -h 172.26.32.144 -p 1521 -U replica -F p -P -D /opt/pg/pg_data
ls 这回看到数据,文件都已经备份过来了
会缺少两个文件postmaster.opts postmaster.pid 这两个文件必须是在root下必须用这个命令systemctl restart postgresql-9.6启动数据库然后生成的进程文件
备注:
-h,主库主机,-p,主库服务端口;
-U,复制用户;
-F,p是默认输出格式,输出数据目录和表空间相同的布局,t表示tar格式输出;
-P,同–progress,显示进度;
-D,输出到指定目录;
因为主库采用的是md5认证,这里需要密码认证。
3.修改recovery文件
mv recovery.done recovery.conf
vim recovery.conf
standby_mode = on
primary_conninfo = ‘host=172.26.32.144 port=5432 user=replica password=replica’ # 这个说明这台机器对应主库的信息
recovery_target_timeline = ‘latest’ # 这个说明这个流复制同步到最新的数据
4.创建pg_archive目录
mkdir -p /opt/pg/pg_archive
chown -R pg:pg /opt/pg/pg_archive
cd /var/run/
chown -R pg:pg postgresql
5. 配置pgpass
vi .pgpass
172.26.32.144:1521:replication:replica:replica
172.26.32.145:1521:replication:replica:replica
配置从库postgresql.conf中也有几个地方要进行修改
max_connections = 1000 # 一般查多于写的应用从库的最大连接数要比较大
hot_standby = on # 说明这台机器不仅仅是用于数据归档,也用于数据查询
max_standby_streaming_delay = 30s # 数据流备份的最大延迟时间
wal_receiver_status_interval = 1s # 多久向主报告一次从的状态,当然从每次数据复制都会向主报告状态,这里只是设置最长的间隔时间
hot_standby_feedback = on # 如果有错误的数据复制,是否向主进行反馈
因为流复制方式从库安装了pg库,需要把以前的数据目录删除,所以启动会报错:
启动pg数据库报错:
[root@localhost ~]# systemctl status postgresql-9.6.service
鈼[0m postgresql-9.6.service - PostgreSQL 9.6 database server
Loaded: loaded (/usr/lib/systemd/system/postgresql-9.6.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Fri 2020-11-06 10:36:26 CST; 3h 13min ago
Docs: https://www.postgresql.org/docs/9.6/static/
Process: 20719 ExecStartPre=/usr/pgsql-9.6/bin/postgresql96-check-db-dir ${PGDATA} (code=exited, status=217/USER)
Main PID: 20674 (code=exited, status=1/FAILURE)
Nov 06 10:36:26 localhost.localdomain systemd[1]: Starting PostgreSQL 9.6 database server…
Nov 06 10:36:26 localhost.localdomain systemd[20719]: Failed at step USER spawning /usr/pgsql-9.6/bin/postgresql96-check-db-dir: No such process
Nov 06 10:36:26 localhost.localdomain systemd[1]: postgresql-9.6.service: control process exited, code=exited status=217
Nov 06 10:36:26 localhost.localdomain systemd[1]: Failed to start PostgreSQL 9.6 database server.
Nov 06 10:36:26 localhost.localdomain systemd[1]: Unit postgresql-9.6.service entered failed state.
Nov 06 10:36:26 localhost.localdomain systemd[1]: postgresql-9.6.service failed.
解决:
权限的问题,授权一下:
chmod 700 /opt/pg/pg_data
再次启动:正常了
解决方案2:很有可能是以前安装过PostgreSQL ,那就是需要删除/var/lib/pgsql
rm -rf /var/lib/pgsql
在启动正常。