UNVDB主从配置

udb主库配置

配置登录授权

cat /data/udb/ud_hba.conf
...host    replication     all      0.0.0.0/0          md5

配置文件解释。添加主库同步配置

cat /data/udb/unvdbsvr.conf
...
##主库同步配置
recovery_target_timeline = 'latest'
primary_conninfo = 'hostaddr=192.168.2.82 port=5678 user=rep password=同步用户的密码'
#配置主库连接信息 连接到主库的IP地址、端口号、用户名和密码。
hot_standby = on #启用热备
...

重启生效配置

[root@udb-81 tmp]# systemctl restart unvdb

添加同步用户

unvdb=# create role rep login replication encrypted password 'rep';
CREATE ROLE

udb从库配置

从库备份主库数据

不备份的话会连接不上主库

[udb@udb-82 data]$ ud_basebackup -D /data/udb -F p --checkpoint=fast -P -h 192.168.2.81 -p 5678 -U rep
Password: 输入主库rep用户的密码
26280/26280 kB (100%), 1/1 tablespace

此时所有配置和数据都会从主库备份过来,需要修改主库连接信息

[udb@udb-82 udb]$ vim /data/udb/unvdbsvr.conf 
...
##主库连接信息
primary_conninfo = 'hostaddr=192.168.2.81 port=5678 user=rep password=rep' #配置主库连接信息
hot_standby = on #启用热备
...

开启从库标志

[udb@udb-82 udb]$ echo "standby_mode = on" > /data/udb/standby.signal

启动服务

[root@udb-82 udb]# systemctl start unvdb

验证服务

[root@udb-82 udb]# ud_sql
ud_sql (2.4)
Type "help" for help.
unvdb=# \l
                              List of databases
   Name    | Owner | Encoding |   Collate   |    Ctype    | Access privileges 
-----------+-------+----------+-------------+-------------+-------------------
 template0 | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/unvdb         +
           |       |          |             |             | unvdb=CTc/unvdb
 template1 | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/unvdb         +
           |       |          |             |             | unvdb=CTc/unvdb
 unvdb     | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
(3 rows)

主从复制验证

主库操作

查看当前已连接的从库实例

如果没有备份主库数据的话这里不会显示有连接的用户。

unvdb=# select client_addr, sync_state from pg_stat_replication;

 client_addr  | sync_state 
--------------+------------
 192.168.2.82 | async
(1 row)
#async 表示异步同步模式

创建测试数据

unvdb=# create database test;
CREATE DATABASE
You are now connected to database "test" as user "unvdb".
test=# CREATE TABLE tb1 (id serial,time char(100),con_id int,ins_id int,select_ip char(30),server_ip char(30));
CREATE TABLE
test=# INSERT INTO  tb1(time,con_id,ins_id,select_ip,server_ip)values(now(),1,1,'aa',inet_server_addr());
INSERT 0 1
test=# select * from tb1;
 id |                                                 time                                                 | con_id | ins_id |      
     select_ip            |           server_ip            
----+------------------------------------------------------------------------------------------------------+--------+--------+------
--------------------------+--------------------------------
  1 | 2022-08-22 15:46:37.108717+08                                                                        |      1 |      1 | aa   
                          | ::1/128                       
(1 row)

#添加test库和tb1表,记录id,时间,连接id,插入id,查询服务器IP,写入服务器IP 用于后面负载均衡等数据验证

从库操作

test=# create database b;
ERROR:  cannot execute CREATE DATABASE in a read-only transaction

从库不能写入操作

unvdb=# \l
                              List of databases
   Name    | Owner | Encoding |   Collate   |    Ctype    | Access privileges 
-----------+-------+----------+-------------+-------------+-------------------
 template0 | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/unvdb         +
           |       |          |             |             | unvdb=CTc/unvdb
 template1 | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/unvdb         +
           |       |          |             |             | unvdb=CTc/unvdb
 test      | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 unvdb     | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
(4 rows)
unvdb=# \c test;
You are now connected to database "test" as user "unvdb".
test=# select * from tb1;
 id |                                                 time                                                 | con_id | ins_id |      
     select_ip            |           server_ip            
----+------------------------------------------------------------------------------------------------------+--------+--------+------
--------------------------+--------------------------------
  1 | 2022-08-22 15:46:37.108717+08                                                                        |      1 |      1 | aa   
                          | ::1/128                       
(1 row)

此时从库已经有了主库的数据。 同步配置成功。

从节点提升为主节点

背景:当主节点down机后,需要手动将从节点提升为主节点。

注意:操作前做好数据备份

检查当前节点状态

[root@udb-82 data]# ud_controldata -D /data/udb/ | grep -i 'database cluster state'
Database cluster state:               in archive recovery
#in archive recovery说明为从节点

提升为主节点

ud_ctl promote -D /data/udb/

将从节点提升为主节点

[root@udb-82 tmp]# ud_sql  #进入udb
ud_sql (2.4)
Type "help" for help.
unvdb=# create database d82_1;

此时可以进行写操作,说明已提升为主节点

当原主节点恢复后需要以从节点身份运行,此时需要进行数据修复补充

下面修复节点并配置为从节点

ud_rewind方式修复

[root@udb-81 tmp]# su udb
[udb@udb-81 tmp]$ ud_rewind --target-uddata=/data/udb --source-server='host=192.168.2.82 port=5678 user=unvdb dbname=unvdb password=数据库管理员密码'
ud_rewind: servers diverged at WAL location 0/11000000 on timeline 4
ud_rewind: rewinding from last common checkpoint at 0/10000140 on timeline 4
ud_rewind: Done!
echo "standby_mode = on" > /data/udb/standby.signal
vi unvdbsvr.conf 
修改主库连接信息
systemctl start unvdb

rsync文件同步方式修复

systemctl stop unvdb
rsync -avzP 192.168.2.82:/data/udb/ /data/udb/
echo "standby_mode = on" > /data/udb/standby.signal
vi unvdbsvr.conf 
修改主库连接信息
systemctl start unvdb

basebackup全量备份方式修复

ud_basebackup 方式,参考本章udb从库配置

异步/同步复制模式配置

异步同步介绍

异步复制:默认配置 操作在主库执行完成,立即返回结果。 从库异步执行wal_log,此时受网络和从库性能等影响,从库可能会产生延时。

同步复制: 操作在主库执行完成,需等待从库(执行或写入wal_log)完成后,再返回结果。很好的避免延时现象。 由于一个操作需要等待多个节点执行完成,所以性能大概损失10%。

查看当前复制模式

unvdb=# select client_addr, sync_state from pg_stat_replication;
 client_addr  | sync_state 
--------------+------------
 192.168.2.82 | async
(1 row)

192.168.2.82从库为async异步复制模式

主库写操作

unvdb=# create database a;
CREATE DATABASE

从库已复制数据

unvdb=# \l
                              List of databases
   Name    | Owner | Encoding |   Collate   |    Ctype    | Access privileges 
-----------+-------+----------+-------------+-------------+-------------------
 a         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 

模拟从库down机

unvdb=# create database b;
CREATE DATABASE
unvdb=# \l
                              List of databases
   Name    | Owner | Encoding |   Collate   |    Ctype    | Access privileges 
-----------+-------+----------+-------------+-------------+-------------------
 a         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 b         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 

主库写入操作正常,未受影响

同步复制,观察和异步有什么不同

unvdb=# alter system set synchronous_standby_names='*';
ALTER SYSTEM
#配置同步规则要求所有从节点。
unvdb=# select pg_reload_conf();
 pg_reload_conf 
----------------
 t
(1 row)
#重载配置生效
unvdb=# show synchronous_standby_names ;
 synchronous_standby_names 
---------------------------
 *
(1 row)
#查看同步规则
unvdb=# select client_addr, sync_state from pg_stat_replication;
 client_addr  | sync_state 
--------------+------------
 192.168.2.82 | sync
(1 row)
#此时为sync同步复制

主库写入数据

unvdb=# create database c;
CREATE DATABASE

从库正常复制

unvdb=# \l
                              List of databases
   Name    | Owner | Encoding |   Collate   |    Ctype    | Access privileges 
-----------+-------+----------+-------------+-------------+-------------------
 a         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 b         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 c         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 

关闭从库

[root@udb-82 ~]# systemctl stop unvdb

主库再次写入数据

unvdb=# create database d;
^CCancel request sent #ctrl +c强制结束
WARNING:  canceling wait for synchronous replication due to user request
DETAIL:  The transaction has already committed locally, but might not have been replicated to the standby.
CREATE DATABASE
unvdb=# \l
                              List of databases
   Name    | Owner | Encoding |   Collate   |    Ctype    | Access privileges 
-----------+-------+----------+-------------+-------------+-------------------
 a         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 b         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 c         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 d         | unvdb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 

因为此时没有存活的从节点,导致主库写操作挂起。 注意:此时主库仍然成功写了数据库,只是无法响应给客户端。

取消同步规则,快速恢复业务

unvdb=# alter system set synchronous_standby_names='';
ALTER SYSTEM
unvdb=# select pg_reload_conf();
 pg_reload_conf 
----------------
 t
(1 row)
unvdb=# show synchronous_standby_names ;
 synchronous_standby_names 
---------------------------
(1 row)
unvdb=# create database f;
CREATE DATABASE
#再次写入数据,成功。

恢复从节点,此时自动变为异步模式

unvdb=# select client_addr, sync_state from pg_stat_replication;
 client_addr  | sync_state 
--------------+------------
 192.168.2.82 | async
(1 row)

更多同步复制规则

synchronous_standby_names = ‘FIRST 2 (s1,s2,s3)’ #s1 s2为同步复制,s3为后备同步(当s1 s2故障时,s3会转为同步复制),s4等其它为异步复制

synchronous_standby_names = ‘ANY 3 (s1, s2, s3, s4)’ #s1 s2 s3 s4任意3个作为同步复制