MySQL8 数据库系统内置 Replication (复制)功能,通过 Replication 功能可以快速便利的实现数据库实时备份和读写分离。
本方案基于CentOS8系统设计,建议在RedHat/CentOS系统中使用。
1. Replication 拓扑结构
Replication 由主库节点和从库节点组成,其中:
1、主库节点只能有1个,节点上部署的数据库实例即能读也能写;
2、从库节点至少有1个,根据应用场景可以部署≥2个,节点上部署的数据库实例只能读;
3、当数据写入主库节点后,主要节点将数据插入/更新/删除事务的脚本分别传输到所有的从库节点上执行,使从属节点的数据与主要节点保持一致。
因此:
各个从属节点实现了数据库的实时备份,当主要节点服务器的磁盘或文件故障时,能够避免数据损失并为主要节点提供恢复副本,提高数据安全性。
应用系统事务性的插入/更新/删除/查询类操作可以通过主要节点完成,而较高性能损耗和高并发的查询/统计/分析/导出类操作可以通过多个从属节点完成,实现读写分离,提高应用系统性能。
2.Replication 应用场景
假设有一个“人事管理系统”,主要实现了员工信息的员工信息的录入、查看、浏览、综合查询、信息导出、统计分析模块。那在使用 Replication 时,录入、查看、浏览模块使用主库节点,综合查询、信息导出和统计分析可以共同或者分别使用一个或多个从库节点。
在选用 Replication 之前,应当考量以下技术要点:
1、从数据库高可用角度分析, Replication 虽然由多个数据库节点组成,但本质来讲仍然是“单点数据库”,因为它不具备“集群数据库”典型的故障转移和负载均衡功能。
首先,当主要或从库节点发生故障时,本身并不存在故障转移机制,因此仍会造成应用系统的局部故障,比如:当主库节点故障时,应用系统的事务处理和信息管理模块也会连带故障,但复杂查询、数据导出、统计分析模块仍然可用。
其次,当主要或从库节点负载过高时,本身并不存在请求分发或分布式处理的机制,因此仍会造成应用系统的局部性能低下,比如:当业务系统产生大量事务性并发时,主库节点负载所有流量,并不会分流到从属节点上,但同样也不会影响复杂查询、数据导出、统计分析模块的性能。
因此, Replication 仅实现了在同一个应用系统中,为不同类型的模块按计划分配独立数据库节点,达到提升整体性能的目的。
2、只有一个主库节点,对于事务处理和信息管理模块的性能优化是有限的。
在 Replication 中,有且只有一个主库节点可以进行读写操作,因此对于事务处理和信息管理模块的性能优化是有限的,或者说仍然是单点数据库服务器支持的。
3、并不是所有读请求都适合使用从库节点。
在 Replication 中,各个从库节点的数据来源主要节点,并且不是与主要节点保持事务一致性的,在一些特别情况下(如:网络不稳定),有可能在极短的时间内,主要节点写入的新数据没有同步到从属节点中。比如:
事务模块在一个表单页面完成信息录入后,单击“保存”按钮将数据写入到主要节点后立即跳转到该信息的查看页面。首先数据写入使用主要节点无疑,类似于查看页面读取数据的功能,就不适合使用从属节点,应该仍然使用主要节点。因为从保存数据到查看数据的过程很短(几乎是瞬间的),所以不能够期待从属节点每次都能在读取数据之前从主要节点同步到数据,即便大多数时候可以。
综合来看,使用 Replication 的应用系统应当具备以下特点:
1、应用系统的连续运行要求一般,可以接受一定时间的宕机;
2、应用系统的整体并发量一般,但个别的查询、统计、导出类功能相对于事务处理和业务管理类功能有较大的并发或性能损耗。
3. Replication 安装部署
3.1 网络资源规划
1、主库节点:
1)操作系统:CentOS8
2)IP地址和端口号:192.168.216.20:3306
3)主机名:DB-M
4)数据库:MySQL8
2、从库节点1
1)操作系统:CentOS8
2)IP地址和端口号:192.168.216.21:3306
3)主机名:DB-S1
4)数据库:MySQL8
3、从库节点-≥2(可扩充)
1)操作系统:CentOS8
2)IP地址和端口号:192.168.216.22:3306
3)主机名:DB-S2
4)数据库:MySQL8
3.2. 安装和配置
3.2.1.主从节点数据库安装
在各个服务器上安装 MySQL8 数据库。 有关如何安装 MySQL8 数据库,请阅读文章《RedHat/CentOS8【MySQL8】安装、配置和管理》,文章地址【https://www.jianshu.com/p/b68e2120a068】。
3.2.2.主库节点配置
1、设置主库配置文件参数。
使用文本编辑器打开配置文件:
[centos@DB-M ~]$ sudo gedit /etc/my.cnf
追加或验证文件中的以下参数并保存:
[mysqld]
# 表启用 binlog (MySQL 的 Replication 通过 binlog 实现)功能,并指定日志文件的路径名称。
log-bin=binlog
# 表示二进制日志索引文件的路径与名称,一般不需设置。
# log_bin_index=mysql-bin.index
# 表示日志写入磁盘的模式。
# 当设置为0,每隔一秒更新一次到日志文件,并刷新到磁盘中。该模式下在事务提交的时候,不会主动触发写入磁盘的操作。速度最快,但当节点实例故障时会丢失上一秒钟所有事务。
# 当设置为1,默认模式,每次提交事务时更新一次到日志文件,并刷新到磁盘中。速度最慢但最安全,但当节点实例故障时会最多一个语句或者一个事务。
# 当设置为2,每次提交事务时更新一次到日志文件,但每隔一秒刷新一次到磁盘中。
innodb_flush_log_at_trx_commit=1
# 表示从当日志文件缓存的事务数达到设置值后,刷新到磁盘中。
# 当设置为0,表示由文件系统自动刷新到磁盘中。设置为0时最高效。
# 当职位为≥1,表示日志文件缓存到该事务数量时,刷新到磁盘中。设置为1时最安全。
sync_binlog=1
# 表示日志的格式。可选项包括:Row,Statement,Mixed。
# 当设置为 Row,主节点在日志中会记录每一行数据被修改的形式,然后在备节点中对相同的数据进行修改。优点是直接记录最终的数据状态,不受存储过程或触发器的影响;缺点是日志记录的数据量非常大。
# 当设置为 Statement,默认值,主节点在日志中会记录每一条 SQL 脚本,优点是日志数据量小,性能高;缺点是需要记录SQL的上下文,如果主备环境有差异,在备节点执行时会产生BUG。
# 当设置为 Mixed,主节点在日志中会根据执行的 SQL 脚本来自动确定使用 Row 或 Statement 模式。
# binlog-format=Mixed
# 表示节点实例唯一ID(正整数),设置为 1 表示主节点,设置>1表示备节点。
server_id=1
# 表示启用 binlog 的数据库,多个数据库重复设置此参数,每个数据库一行;不设置时表示所有数据库都启用 binlog 。
# binlog_do_db=binlogdb
# 表示不启用 binlog 的数据库,多个数据库重复设置此参数,每个数据库一行;不设置时表示所有数据库都启用 binlog 。
# binlog-ignore-db=ignoredb
2、重新启动数据库服务。
[centos@DB-M ~]$ sudo systemctl restart mysqld.service
3、创建 Replication 用户并授予数据库权限,记录主库状态。
[centos@DB-M ~]$ mysql -u root -p
Enter password:
# 创建 Replication 账号远程登录的策略和口令。
# 格式:create user '<账号>'@'<客户端IP策略>' identified by '<登录密码>';
# 说明:
# <客户端IP策略>可以使用通配符”%”,也可以指定具体IP地址或地址段,如:
# 允许全部远程地址访问,设置为:”%”;
# 允许IP地址访问,设置为:”192.168.0.1”;
# 允许IP地址段访问,设置为:”192.168.0.%”。
# with mysql_native_password 表示设置的口令可同时用于远程访问(不指定时用于本地访问)。
mysql> create user 'repl'@'%' identified with mysql_native_password by 'password';
# 为 Replication 账号授予数据库 Replication 权限。
mysql> grant replication slave on *.* to 'repl'@'%';
# 刷新数据库表。
mysql> flush tables with read lock;
# 查看主节点状态。
mysql>show master status\G;
# 响应信息。其中 "File" 和 "Position" 字段的数据值在配置从库节点时需要使用。
*************************** 1. row ***************************
File: binlog.000001
Position: 950
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
4、创建数据库历史快照。如果在搭建主备模式前,主库已经具有存量的数据库,则需要为主库建立快照。并将快照文件上传到从库服务器上。(可选步骤)
[centos@DB-M ~]$ mysqldump -u root -p --all-databases --master-data > snapshot.sql
[centos@DB-M ~]$ scp snapshot.sql [email protected]:~
[centos@DB-M ~]$ scp snapshot.sql [email protected]:~
3.2.3.从库节点配置
以"从库节点1"节点为例:
1、导入主库历史快照。如果在搭建主备模块前,如果主库已经具有存量的数据库。那从库需要将主库的快照文件导入,以保持当前状态与主库完全一致。(可选步骤)
[centos@DB-S1 ~]$ mysql -u root -p < snapshot.sql
Enter password:
2、设置从库配置文件参数。
使用文本编辑器打开配置文件:
[centos@DB-S1 ~]$ sudo gedit /etc/my.cnf
追加或验证文件中的以下参数并保存:
[mysqld]
# 表示节点实例唯一ID(正整数),设置>1表示备节点,必须设置>1的数值。
# 各个备节点的标识必须保持唯一性,不能重复。
server_id=2
# 表示开启超级用户(如 root 用户)的数据库只读模式。
super_read_only=on
# 表示开启普通用户的数据库只读模式。
read_only=on
3、重新启动数据库服务。
[centos@DB-S1 ~]$ sudo systemctl restart mysqld.service
4、配置从库同步参数,并启动主备同步。
[centos@DB-M ~]$ mysql -u root -p
Enter password:
# master_host:主节点IP地址;
# master_port:主节点服务端口号;
# master_user:主节点创建的具有 Replication 权限的用户账号;
# master_password:主节点创建的具有 Replication 权限的用户口令;
# master_log_file:主节点创建的 binlog 日志文件名;
# master_log_pos:主节点创建的 binlog 日志文件位置表示。
mysql>change master to master_host='192.168.0.20',master_port=3306,master_user='repl',master_password='password',master_log_file='binlog.000001',master_log_pos=950;
# 启动从库同步。
mysql>start slave;
# 查看从库状态。
mysql>show slave status\G;
# 响应信息。正常情况下 "Slave_IO_Running" 和 "Slave_SQL_Running" 都应为 Yes 。
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.20
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000001
Read_Master_Log_Pos: 950
Relay_Log_File: Slave-1-relay-bin.000006
Relay_Log_Pos: 322
Relay_Master_Log_File: binlog.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
......
注意:其他"从库"节点上全部需要按照以上步骤配置。
5、如果主库的参数发生变化或者从库的同步配置错误,从库重设同步参数方法如下:
[centos@DB-S1 ~]$ mysql -u root -p
Enter password:
# 停止从库。
mysql>stop slave;
# 修改参数。
mysql>change master to master_log_file='binlog.000001',master_log_pos=950;
# 重新启动从库。
mysql>start slave;
# 查看从库状态。
mysql>show slave status\G;
6、从库的主备模式管理:
[centos@DB-S1 ~]$ mysql -u root -p
Enter password:
# 停止从库。
mysql>stop slave;
# 修改主库参数。
mysql>change master to master_log_file='binlog.000001',master_log_pos=950;
# 启动从库。
mysql>start slave;
# 重置从库状态。
mysql>reset slave;
# 查看从库状态。
mysql>show slave status\G;