PG主备流复制的核心部分由walsender,walreceiver和startup三个进程组成。
walsender 进程是用来发送WAL日志记录的
walreceiver 进程是用来接收WAL日志记录的
startup 进程是用来apply日志的
环境准备
操作系统:Anolis8.8
数据库版本:15.3
1、创建用户组和用户
groupadd -g 1000 postgres
useradd -u 1000 -g 1000 postgres
echo "postgres" | passwd postgres --stdin
2、创建安装和数据目录
mkdir -p /opt/pgsql /data/pgdata /data/pgbackup /data/pgarchive
3、安装依赖包软件
操作系统工具包:yum install -y vim tar lrzsz wget bzip2 unzip net-tools network-scripts telnet tree mlocate bash-completion
PG安装依赖软件:yum install -y gcc gcc-c++ make zlib-devel readline-devel python3-devel openssl-devel libxml2-devel perl-ExtUtils-Embed perl-devel
4、配置环境变量
vi /etc/profile
export PGHOME=/usr/local/pgsql
export PGDATA=/data/pgdata
export PGPORT=5432
export PGUSER=postgres
export PGDATABASE=postgres
export PGHOST=192.168.68.101 #注意:不同主机IP地址不同
export PATH=$PGHOME/bin:$PATH:.
export LD_LIBRARY_PATH=${PGHOME}/lib:${LD_LIBRARY_PATH}
export LANG=en_US.utf8
export MANPATH=/usr/local/pgsql/share/man:$MANPATH
export PS1="[`whoami`@`hostname`:"'$PWD]$'
设置共享库
/sbin/ldconfig /usr/local/pgsql/lib
5、编译安装
tar -xvf postgresql-15.3.tar.gz -C /opt/pgsql
cd /opt/pgsql/postgresql-15.3
./configure --prefix=/opt/pgsql/postgresql-15.3 --with-python --with-perl --with-openssl --with-libxml
make world -j 6
make install-world
#编译参数说明
--prefix=/opt/pgsql/postgresql-15.3 指定数据库软件安装目录
--with-blocksize=?kb 指定数据文件块大小,默认8k
--with-segsize=?GB 指定单个文件大小,默认1GB
--with-wal-segsize=?MB 指定wal日志大小,默认16MB
--with-perl,--with-python 存储过程支持所需
--with-openssl #对openssl进行扩展支持
--with-python #对python进行扩展支持
--with-perl #对perl进行扩展支持
--with-libxml #对xml进行扩展支持
6、创建目录链接
ln -sf /opt/pgsql/postgresql-15.3 /usr/local/pgsql
chown -R postgres.postgres /opt/pgsql /data/pgdata /data/pgbackup /data/pgarchive
chmod 700 /data/pgdata /data/pgbackup /data/pgarchive
7、初始化数据库
su - postgres
initdb -A md5 -D $PGDATA -E utf8 --locale=C -U postgres -W -k
#设置密码postgres,复制时需要 --data-checksums 或者设置 "wal_log_hints = on"
# -E UTF8 --locale=zh_CN.utf8 指定数据库字符编码
# -D:database cluster的主目录
# -U:指定超级用户
# -W:指定用户密码
# --waldir:指定wal日志路径
8、PG配置文件
cd $PGDATA
vi postgresql.conf
listen_addresses = '*'
logging_collector = on
wal_level = replica
wal_log_hints = on
wal_keep_size = 16
max_wal_senders = 3
wal_sender_timeout = 60s
hot_standby = on
archive_mode = on
archive_command = 'cp %p /data/pgarchive/%f'
#注意15版本里 wal_keep_segments已不存在 新增wal_keep_size和max_slot_wal_keep_size
vi pg_hba.conf
# IPv4 local connections:
host all postgres 192.168.68.101/32 trust #注意:不同主机IP地址不同
host all all 192.168.68.0/24 md5
9、启动数据库
su - postgres
pg_ctl start
su - postgres
psql -d postgres
postgres# select version();
postgres# create database testdb;
postgres# \q
主备配置(1主2从)
搭建主从复制环境,分别对主库和备库进行相应配置。
主库:192.168.68.101
同步备库:192.168.68.102
异步备库:192.168.68.103
1、主库配置(192.168.68.101)
登录主库创建复制用户
psql -d postgres
postgres=# create role rep_user login replication encrypted password 'repuserPwd123';
或者直接在操作系统命令行执行:createuser --replication -P rep_user
#create role rep_user with login replication password 'repuserPwd123';
将复制用户添加到认证文件
cd $PGDATA
vi pg_hba.conf
host replication rep_user 192.168.68.0/24 md5
新增或修改下列属性设置
synchronous_commit = on
synchronous_standby_names = 'standby01'
cd $PGDATA
Vi postgresql.conf
# 监听所有IP
listen_addresses = '*'
# 开启归档
archive_mode = on
#归档命令
archive_command = 'test ! -f /data/pgarchive/%f && cp %p /data/pgarchive/%f'
restore_command = 'cp /data/pgarchive/%f %p'
# 9.6开始没有 hot_standby(热备模式)
wal_level = replica
#最多有2个流复制连接
max_wal_senders = 3
wal_keep_size = 16
#流复制超时时间
wal_sender_timeout = 60s
# 最大连接数,据说从机需要大于或等于该值
max_connections = 100
# 同步备库列表
synchronous_commit = on
synchronous_standby_names = 'standby01'
重启数据库服务
pg_ctl restart
pg_ctl status
2、备库配置(192.168.68.102,192.168.68.103)
验证从库是否能访问主库服务
psql -h 192.168.68.101 -p 5432 -U rep_user
停止从库服务
pg_ctl stop
pg_ctl status
清空从库数据文件
rm -rf $PGDATA/*
从主库备份文件到从库
pg_basebackup -h 192.168.68.101 -p 5432 -U rep_user -D $PGDATA -Fp -Xs -R -P -v
# -R --write-recovery-conf
# -P --progress
# -v --verbose
-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文件,同时在postgresql.auto.conf中生成对应的primary_conninfo参数信息。如果执行pg_basebackup的时候忘记加-R这个参数了,可以手动在备库的$PGDATA下touch standby.signal。
-D 指定创建的备库的数据库目录。
编辑配置文件 standby.signal(在执行pg_basebackup时加了-R参数,则primary_conninfo信息已经在postgresql.auto.conf配置文件中)
修改同步备库(192.168.68.102) primary_conninfo, 添加 application_name=standby01,如下所示:
primary_conninfo = 'application_name=standby01 host=192.168.68.101 port=5432 user=rep_user password=repuserPwd123'
修改异步备库(192.168.68.103) primary_conninfo,不用修改,如下所示:
primary_conninfo = 'host=192.168.68.101 port=5432 user=rep_user password=repuserPwd123'
编辑配置文件 postgresql.conf
restore_command = 'cp /data/pgarchive/%f %p'
recovery_target_timeline = latest
max_standby_streaming_delay = 30s
wal_receiver_status_interval = 10s
hot_standby_feedback = on
#说明恢复到最新状态
restore_command = 'cp /data/pgarchive/%f %p'
recovery_target_timeline = latest
#大于主节点,正式环境应当重新考虑此值的大小
max_connections = 120
#说明这台机器不仅用于数据归档,还可以用于数据查询
hot_standby = on
#流备份的最大延迟时间
max_standby_streaming_delay = 30s
#向主机汇报本机状态的间隔时间
wal_receiver_status_interval = 10s
#出现错误复制,向主机反馈
hot_standby_feedback = on
启动备库服务
pg_ctl start
pg_ctl status
pg_controldata | grep cluster
3、复制验证
分别在主从库执行:pg_controldata, 主库状态为:in production, 从库状态为:in archive recovery
pg_controldata | grep cluster
登录主库执行如下查询:
select usename, application_name, client_addr, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn from pg_stat_replication;
select usename, application_name, client_addr, client_port, state, sync_state from pg_stat_replication;
登录备库执行如下查询:
select * from pg_stat_wal_receiver;
show synchronous_commit;
show synchronous_standby_names;
show primary_conninfo;
登录主库创建数据库、表等对象,在查看从库是否已经同步:
#主库101
create database testdb;
\l
\c testdb
create table t1 (id int primary key, name varchar(30));
\dt
insert into t1 values(1, '张三'), (2, '李四');
select * from t1;
#从库102
\l
\c testdb
\dt
select * from t1;
注:备库为只读模式
#从库103
\l
\c testdb
\dt
select * from t1;
注:备库为只读模式
4、主备判断方式
主备库角色的判断,可以通过数据库或则操作系统层的多种方法进行实现。
数据库层面
# 通过系统函数查看(f为主库,t为备库:如果恢复仍在进行中为true)
select pg_is_in_recovery();
# 查看只读事务模式
show transaction_read_only;
操作系统层面
# 操作系统上查看WAL发送进程或WAL接收进程(看walsender或者walreceiver)
ps -ef | grep "wal" | grep -v "grep"
ps -ef | grep postgres
# 查看数据库控制文件信息(返回in production表示为主库,返回in archive recovery表示是备库)
pg_controldata | grep cluster
# 12以前的版本还可以检查是否存在recovery.conf配置文件
# 查看备库落后主库多少字节的WAL日志
select pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_flush_lsn(),write_lsn)) delay_wal_size,* from pg_stat_replication ;
# 查看备库接收WAL日志和应用WAL日志的状态:
select * from pg_last_wal_receive_lsn();
select * from pg_last_wal_replay_lsn();
select * from pg_last_xact_replay_timestamp();




