1. 概念
数据库热备:数据库热备是指为主数据库的创建、维护和监控一个或多个备用数据库,它们时刻处于开机状态,同主机保持同步。当主机失灵时,可以随时启用热备数据库来代替,以保护数据不受故障、灾难、错误和崩溃的影响。
流复制(streaming replication):PostgreSQL提供的一种服务器间的数据复制方式。这种方式下,后备服务器连接到主服务器,主服务器则在 WAL 记录产生时即将它们以流式传送给后备服务器而不必等到 WAL 文件被填充。
2. 实验环境
普通PC两台
操作系统:Linux CentOS release 6.6
软件:PostgreSQL 10.0
3. 实验过程
3.1 实验准备
两台虚拟机上都安装了PostgreSQL 10.0,它们的安装目录是:/opt/postgresql10/
在/etc/profile 中添加如下几行:
export PATH=/opt/postgresql10/bin:$PATH
export LD_LIBRARY_PATH=/opt/postgresql10/lib:$LD_LIBRARY_PATH
export PGDATA=/opt/postgresql10/data
本实验环境中,主机的IP地址为10.33.45.101,备机IP 地址为 10.33.45.102。
3.2 搭建PostgreSQL 主备环境。
3.2.1 主节点上的操作
1. 确保服务已经启动。执行命令:
su postgresql
切换用户,并执行:
pg_ctl start -D $PGDATA
启动服务。
2. 创建用于流复制的用户。执行命令:
psql -h 127.0.0.1 -p 5432 -U postgres
进入控制台,并执行如下语句创建用户:
create user repuser with login replication password 123456;
3. 修改pg_hba.conf 文件,添加如下内容,允许两台计算机上的复制用户和超级用户登录:
host replication repuser 10.33.45.101/32 md5
host replication repuser 10.33.45.102/32 md5
host all postgres 10.33.45.101/32 trust
host all postgres 10.33.45.102/32 trust
4. 在主节点的 postgresql.conf 中设置这些参数:
max_wal_senders =10
wal_level = replica
wal_log_hints = on
log_connections = on
wal_receiver_status_interval = 2s
hot_standby_feedback = on
5. 重启主节点:
pg_ctl restart -D $PGDATA
3.2.2 备节点上的操作
1. 确保服务是停止的:
su postgresql
切换用户,并执行:
pg_ctl stop -D $PGDATA
关闭服务。
2. 首先删除备节点中的数据目录 $PGDATA 中的文件:
cd $PGDATA
rm –rf *
然后执行:
pg_basebackup -d "hostaddr=10.33.45.101 port=5432 user=repuser password=123456" -D $PGDATA -v -Fp –Xs
3. 基础备份完成后,修改备节点的 postgresql.conf 文件,设置:
hot_standby = on
4. 将 /opt/postgresql10/share/ 中的 recovery.conf.sample 拷贝到 $PGDATA 下,重命名为 recovery.conf:
cp /opt/postgresql10/share/recovery.conf.sample $PGDATA/recovery.conf
并设置如下参数:
recovery_target_timeline = 'latest'
standby_mode = on
primary_conninfo = 'host=10.33.45.101 port=5432 user=repuser password=123456'
trigger_file = 'tgfile’
5. 启动备节点服务:
pg_ctl stop -D $PGDATA
3.3 主备环境检测
1. 在主节点上创建一个表,并插入数据:
postgres=# create table student (id int, name text);
CREATE TABLE
postgres=# insert into student (id, name) values (1,'tom');
INSERT 0 1
2. 在备节点上检测:
postgres=# select * from student;
id | name
----+------
1 | tom
主节点数据同步到了备机。
同时,在备节点上写数据会失败:
postgres=# insert into student (id, name) values (2,'amy');
ERROR: cannot execute INSERT in a read-only transaction
3.4 主备环境的切换
1. 激活备节点,使之成为新的主结点:
pg_ctl promote -D $PGDATA
结果是:
waiting for server to promote........ done
server promoted
2. 查看新主节点的状态:
postgres=# pg_controldata | grep cluster
Database cluster state: in production
插入一条数据:
postgres=# insert into student (id, name) values (2,'amy');
INSERT 0 1
3. 停止旧的主结点:
pg_ctl stop -m fast -D $PGDATA
结果:
waiting for server to shut down.... done
server stopped
4. 在停止的旧主结点上执行:
pg_rewind --target-pgdata $PGDATA --source-server='host=10.33.45.102 port=5432 user=postgres dbname=postgres' -P
结果如下:
connected to server
servers diverged at WAL location 0/2B000230 on timeline 4
rewinding from last common checkpoint at 0/2A000098 on timeline 4
reading source file list
reading target file list
reading WAL in target
need to copy 57 MB (total source directory size is 143 MB)
58749/58749 kB (100%) copied
creating backup label and updating control file
syncing target data directory
Done!
表示从新主节点上成功获取WAL日志。
5. 重新配置旧主结点的 recovery.conf:
standby_mode = on
primary_conninfo = 'hostaddr=10.33.45.102 port=5432 user=repuser password=123456'
6. 在旧主结点上执行下面的命令,重新启动该节点:
pg_ctl start -D $PGDATA
7. 在旧主结点上验证:
postgres=# insert into student (id, name) values (3,'lily');
ERROR: cannot execute INSERT in a read-only transaction
现在,它成为了新的备节点。
这样,我们就实现了linux下的主备节点的切换。