searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

PgSQL主备流复制搭建

2023-08-08 06:39:27
43
0

1. 主库配置

1.1. 创建访问用户

 

1.2. 修改主库配置文件pg_hba.conf

pg_hba.conf配置文件中添加从库网段和流复制权限

第一行表示允许所有用户连接所有db,第二行表示只允许repl用户连接replication(特指流复制)。

后面的scram-sha-256表示密码加密验证的算法,推荐用这个,比md5安全。

 

1.3. 修改主库配置文件postgresql.conf

  1. 过滤默认 postgresql.conf 配置文件中的注释内容
grep -Ev '^$|^\s*#' postgresql.conf
  1. 备份原始配置文件到 postgresql.conf.bak
mv postgresql.conf postgresql.conf.bak
  1. 创建新的同名空文件postgresql.conf,并进行如下修改
vim postgresql.conf
listen_addresses = '*'

#最大连接数,从库的max_connections必须要大于主库的
max_connections = 100

# 添加如下配置项
# 设置主pgsql为生成wal的主机,9.6开始没有hot_standby(热备模式)
wal_level = replica
max_wal_senders = 32 # 同步最大的进程数量
wal_sender_timeout = 60s # 流复制主机发送数据的超时时间

# 默认值为“80MB”,该值通常太小,很容易导致备库失效,也需要设置得大一些
min_wal_size = 800MB

主库配置完成,pg_ctl restart 重启。

 

2. 从库配置

2.1. 从库同步主库数据

从库无需初始化(无需执行initdb),通过从主库同步数据

-h 启动的主库数据库地址
-p 主库数据库端口
-U 流复制用户
-W 使用密码验证,要用repl的密码 pg_basebackup 的 -W 使用密码验证;小写 -w 是免密登陆,主库的 pg_hba.conf 中流复制 METHOD 选择 trust
-Fp 备份输出正常的数据库目录
-Xs 使用流复制的方式进行复制
-Pv 输出复制过程的详细信息
-R 为备库创建recovery.conf文件。但是pgsql 10以后的新版本的pgsql不需要这个文件了。-R则是用于创建用于replication的配置文件,其实就是生成$PGDATA/standby.signal文件。如果执行pg_basebackup的时候忘记加-R这个参数了,可以手动在备库的$PGDATA下touch standby.signal
同时在postgresql.auto.conf中生成对应的primary_conninfo参数信息
-D 指定创建的备库的数据库目录

 

完成:

 

2.2. 修改从库配置文件postgresql.conf

从库同步了主库的数据,包括配置文件,需要修改

 

2.3. 创建standby.signal

创建 standby.signal 文件,声明从库。该文件只是一个标识文件,它的存在就是告诉数据库,当我们执行pg_ctl start启动的时候,当前库的角色是standby,不是primary角色。

vim $PGDATA/standby.signal

# 写入
# 声明从库
standby_mode = on

确认数据目录权限,避免踩坑。

chown -R postgres.postgres $PGDATA

 

3. 确认主从同步效果

  1. 主库查看

sync_state字段:

async:异步流复制

sync:同步流复制

 

  1. 从库查看
ps aux | grep receiver

# 返回结果
postgres: walreceiver   streaming 0/3000148

 

4. 将异步转为同步

按上述配置流复制的过程,就已经是异步流复制了

 

4.1. 修改从库配置文件postgresql.conf

在 primary_conninfo 字段信息加上 application_name=slave ,其 中 slave 是为从库起的应用名称

修改完配置后重启从库

pg_ctl restart

 

4.2. 修改主库配置文件postgresql.conf

配置 synchronous_standby_names = 'slave' 属性,其中 slave 与上述从库配置中 primary_conninfo 的 application_name 一致即可。也可以使用 '*' 代替具体应用名 称,设置所有从库为同步模式。

vim $PGDATA/postgresql.conf

# 添加下面语句
synchronous_standby_names = 'slave'

修改完配置后重启主库

pg_ctl restart

 

4.3. 查看主从库状态,遇到未成功转为同步流复制的问题

  1. 主库查看
select pid,application_name,state,client_addr,sync_priority,sync_state from pg_stat_replication;

问题: 可以看到上述配置修改并没有将主从流复制模式从异步改为同步 ,sync_state仍然是asyncapplication_name仍然是walreceiver而不是slave。

 

  1. 从库查看
select conninfo from pg_stat_wal_receiver;

# 返回结果
user=repl password=******** dbname=replication host=10.0.0.2 port=5432 fallback_application_name=walreceiver sslmode=disable sslcompression=0 gssencmode=disable krbsrvname=postgres targe
t_session_attrs=any

可以看到从库状态中conninfo字段中并没有application_name字段内容。

 

  1. 解决方法

(1) 忽略从库定义的application_name=slave直接将主库的synchronous_standby_names字段值设置为 '*'。完成修改之后重启主库并查询主库状 态可以看到流复制模式已经修改为了 sync 的同步模式。

synchronous_standby_names = '*'代表匹配任意主机,也就是任意主机返回就可以提交

(2) 通过 psql 修改备库的系统设置,新值为上一步保存的conninfo字段信息加上application_name=slave

pg 启动会先加载postgresql.auto.conf中的配置项,仅修改postgresql.conf会出现修改失效情况。

alter system set primary_conninfo = 'application_name=slave host=10.0.0.2 port=5432 user=repl password=***********'

也可以在postgresql.auto.conf文件中的primary_conninfo的值里添加以下语句:

application_name=slave

使用此方法,主库仍配置synchronous_standby_names = 'slave',推荐使用这个方法,synchronous_standby_names这个参数可以有更多自定义的方式实现主备同步的不同状态。

从库retart,主库reload, 查询状态,完成。

 

5. 同步流复制的问题(实验)

同步流复制模式中,由于主库提交事务时需等待至少一个备库接收WAL并返回确认信息后主库才向客户端返回成功,一方面保障了数据的完整性,另一方面对于一主一备的同步流复制环境存在一个典型的问题,具体表现为如果备库宕机,主库上的写操作将处于等待状态

将备库停掉模拟备库故障,在主库上查询数据不受影响:

postgres=#SELECT * FROM test_sr LIMIT 1;
id
--------
1
(1 row)

在主库上尝试插入一条记录,命令被阻塞:

postgres=# INSERT INTO test_sr (id)VALUES (5);
 
--注意这里命令被阻塞。

这时主库上的INSERT语句一直处于等待状态,也就是说同步备库宕机后,主库上的读操作不受影响,写操作将处于阻塞状态,因为主库上的事务需收到至少一个备库接收WAL后的返回信息才会向客户端返回成功,而此时备库已经停掉了,主库上收不到备库发来的确认信息。

通常一主一备的情况下不会采用同步复制方式,因为备库宕机后同样对生产系统造成严重影响。

 

解决方案:

  1. 一主多备,提高系统可用性

PostgreSQL支持一主多从的流复制架构,比如一主两从,将其中一个备库设为同步备库,另一个备库设为异步备库,当同步备库宕机后异步备库升级为同步备库,同时主库上的读写操作不受影响。

  1. 出现这个问题后,改同步为异步。
-- 将参数synchronous_standby_names = 'slave' 的值设置为空字符串
synchronous_standby_names = ' '

-- 重新加载pg
-- 这个操作不会影响连接的客户端。主库继续进行事务处理
-- 会保持客户端与相应的后端进程之间的所有会话。
pg_ctl reload

0条评论
0 / 1000
Toliatong
4文章数
0粉丝数
Toliatong
4 文章 | 0 粉丝
原创

PgSQL主备流复制搭建

2023-08-08 06:39:27
43
0

1. 主库配置

1.1. 创建访问用户

 

1.2. 修改主库配置文件pg_hba.conf

pg_hba.conf配置文件中添加从库网段和流复制权限

第一行表示允许所有用户连接所有db,第二行表示只允许repl用户连接replication(特指流复制)。

后面的scram-sha-256表示密码加密验证的算法,推荐用这个,比md5安全。

 

1.3. 修改主库配置文件postgresql.conf

  1. 过滤默认 postgresql.conf 配置文件中的注释内容
grep -Ev '^$|^\s*#' postgresql.conf
  1. 备份原始配置文件到 postgresql.conf.bak
mv postgresql.conf postgresql.conf.bak
  1. 创建新的同名空文件postgresql.conf,并进行如下修改
vim postgresql.conf
listen_addresses = '*'

#最大连接数,从库的max_connections必须要大于主库的
max_connections = 100

# 添加如下配置项
# 设置主pgsql为生成wal的主机,9.6开始没有hot_standby(热备模式)
wal_level = replica
max_wal_senders = 32 # 同步最大的进程数量
wal_sender_timeout = 60s # 流复制主机发送数据的超时时间

# 默认值为“80MB”,该值通常太小,很容易导致备库失效,也需要设置得大一些
min_wal_size = 800MB

主库配置完成,pg_ctl restart 重启。

 

2. 从库配置

2.1. 从库同步主库数据

从库无需初始化(无需执行initdb),通过从主库同步数据

-h 启动的主库数据库地址
-p 主库数据库端口
-U 流复制用户
-W 使用密码验证,要用repl的密码 pg_basebackup 的 -W 使用密码验证;小写 -w 是免密登陆,主库的 pg_hba.conf 中流复制 METHOD 选择 trust
-Fp 备份输出正常的数据库目录
-Xs 使用流复制的方式进行复制
-Pv 输出复制过程的详细信息
-R 为备库创建recovery.conf文件。但是pgsql 10以后的新版本的pgsql不需要这个文件了。-R则是用于创建用于replication的配置文件,其实就是生成$PGDATA/standby.signal文件。如果执行pg_basebackup的时候忘记加-R这个参数了,可以手动在备库的$PGDATA下touch standby.signal
同时在postgresql.auto.conf中生成对应的primary_conninfo参数信息
-D 指定创建的备库的数据库目录

 

完成:

 

2.2. 修改从库配置文件postgresql.conf

从库同步了主库的数据,包括配置文件,需要修改

 

2.3. 创建standby.signal

创建 standby.signal 文件,声明从库。该文件只是一个标识文件,它的存在就是告诉数据库,当我们执行pg_ctl start启动的时候,当前库的角色是standby,不是primary角色。

vim $PGDATA/standby.signal

# 写入
# 声明从库
standby_mode = on

确认数据目录权限,避免踩坑。

chown -R postgres.postgres $PGDATA

 

3. 确认主从同步效果

  1. 主库查看

sync_state字段:

async:异步流复制

sync:同步流复制

 

  1. 从库查看
ps aux | grep receiver

# 返回结果
postgres: walreceiver   streaming 0/3000148

 

4. 将异步转为同步

按上述配置流复制的过程,就已经是异步流复制了

 

4.1. 修改从库配置文件postgresql.conf

在 primary_conninfo 字段信息加上 application_name=slave ,其 中 slave 是为从库起的应用名称

修改完配置后重启从库

pg_ctl restart

 

4.2. 修改主库配置文件postgresql.conf

配置 synchronous_standby_names = 'slave' 属性,其中 slave 与上述从库配置中 primary_conninfo 的 application_name 一致即可。也可以使用 '*' 代替具体应用名 称,设置所有从库为同步模式。

vim $PGDATA/postgresql.conf

# 添加下面语句
synchronous_standby_names = 'slave'

修改完配置后重启主库

pg_ctl restart

 

4.3. 查看主从库状态,遇到未成功转为同步流复制的问题

  1. 主库查看
select pid,application_name,state,client_addr,sync_priority,sync_state from pg_stat_replication;

问题: 可以看到上述配置修改并没有将主从流复制模式从异步改为同步 ,sync_state仍然是asyncapplication_name仍然是walreceiver而不是slave。

 

  1. 从库查看
select conninfo from pg_stat_wal_receiver;

# 返回结果
user=repl password=******** dbname=replication host=10.0.0.2 port=5432 fallback_application_name=walreceiver sslmode=disable sslcompression=0 gssencmode=disable krbsrvname=postgres targe
t_session_attrs=any

可以看到从库状态中conninfo字段中并没有application_name字段内容。

 

  1. 解决方法

(1) 忽略从库定义的application_name=slave直接将主库的synchronous_standby_names字段值设置为 '*'。完成修改之后重启主库并查询主库状 态可以看到流复制模式已经修改为了 sync 的同步模式。

synchronous_standby_names = '*'代表匹配任意主机,也就是任意主机返回就可以提交

(2) 通过 psql 修改备库的系统设置,新值为上一步保存的conninfo字段信息加上application_name=slave

pg 启动会先加载postgresql.auto.conf中的配置项,仅修改postgresql.conf会出现修改失效情况。

alter system set primary_conninfo = 'application_name=slave host=10.0.0.2 port=5432 user=repl password=***********'

也可以在postgresql.auto.conf文件中的primary_conninfo的值里添加以下语句:

application_name=slave

使用此方法,主库仍配置synchronous_standby_names = 'slave',推荐使用这个方法,synchronous_standby_names这个参数可以有更多自定义的方式实现主备同步的不同状态。

从库retart,主库reload, 查询状态,完成。

 

5. 同步流复制的问题(实验)

同步流复制模式中,由于主库提交事务时需等待至少一个备库接收WAL并返回确认信息后主库才向客户端返回成功,一方面保障了数据的完整性,另一方面对于一主一备的同步流复制环境存在一个典型的问题,具体表现为如果备库宕机,主库上的写操作将处于等待状态

将备库停掉模拟备库故障,在主库上查询数据不受影响:

postgres=#SELECT * FROM test_sr LIMIT 1;
id
--------
1
(1 row)

在主库上尝试插入一条记录,命令被阻塞:

postgres=# INSERT INTO test_sr (id)VALUES (5);
 
--注意这里命令被阻塞。

这时主库上的INSERT语句一直处于等待状态,也就是说同步备库宕机后,主库上的读操作不受影响,写操作将处于阻塞状态,因为主库上的事务需收到至少一个备库接收WAL后的返回信息才会向客户端返回成功,而此时备库已经停掉了,主库上收不到备库发来的确认信息。

通常一主一备的情况下不会采用同步复制方式,因为备库宕机后同样对生产系统造成严重影响。

 

解决方案:

  1. 一主多备,提高系统可用性

PostgreSQL支持一主多从的流复制架构,比如一主两从,将其中一个备库设为同步备库,另一个备库设为异步备库,当同步备库宕机后异步备库升级为同步备库,同时主库上的读写操作不受影响。

  1. 出现这个问题后,改同步为异步。
-- 将参数synchronous_standby_names = 'slave' 的值设置为空字符串
synchronous_standby_names = ' '

-- 重新加载pg
-- 这个操作不会影响连接的客户端。主库继续进行事务处理
-- 会保持客户端与相应的后端进程之间的所有会话。
pg_ctl reload

文章来自个人专栏
PostgreSQL使用
4 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0