MySQL主从复制
概述
主从复制原理
1.在每个事务更新数据完成之前, Master在二进制日志中记录这些改变. 写入二进制日志完成后, Master通知存储引擎提交事务.
2.Slave将Master的二进制日志复制到其中继日志. 首先, Slave开始一个工作线程-I/O线程, I/O线程在Master上打开一个普通的连接, 然后开始Binlog dump process. Binlog dump process从Master的二进制日志中读取事件, 如果已经跟上Master, 它会睡眠并等待Master产生新的事件. I/O线程将这些事件写入中继日志.
3.SQL slave thread(SQL从线程)处理该过程的最后一步. SQL线程从中继日志读取事件, 并重放其中的事件而更新Slave的数据, 使其与Master中的数据一致. 只要该线程与I/O线程保持一致, 中继日志通常会位于Os的缓存中, 所以中继日志的开销很小.
注:复制过程有一个很重要的限制, 即复制在Slave上是串行化的, 也就是说Master上的并行更新操作不能在Slave上并行操作.
MySQL支持的复制类型
1.基于语句的复制
在主服务器上执行的SQL语句, 在从服务器上执行同样的语句, MySQL默认采用基于语句的复制, 效率比较高.
2.基于行的复制
把改变的内容复制过去, 而不是把命令在从服务器上执行一遍.
3.混合类型的复制
默认采用基于语句的复制, 一旦发现基于语句无法精确复制时, 就会采用基于行的复制.
建立时间同步环境
为了保证业务环境的实时同步, 需要建立时间同步环境.
MySQL主服务器
1.安装NTP
1 | yum -y install ntp |
2.配置NTP
1 | vim /etc/ntp.conf |
阿里云时间服务器 ntp1.aliyun.com ntp2.aliyun.com ntp3.aliyun.com ntp4.aliyun.com ntp5.aliyun.com ntp6.aliyun.com ntp7.aliyun.com
3.重启服务并设置为开机启动
1 | 立即同步时间 |
MySQL从服务器
1.安装NTPdate
1 | yum -y install ntpdate |
2.配置NTP
1 | vim /etc/ntp.conf |
3.重启服务并设置为开机启动
1 | systemctl restart ntpd |
修改主服务器
1.修改配置文件后并重启
1 | vim /etc/my.cnf |
2.登录mysql, 给服务器授权.
1 | mysql -u root -p[密码] |
+-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000001 | 4035 | | | | +-------------------+----------+--------------+------------------+-------------------+
注: 主服务器要关闭防火墙让从服务器访问, 或者对指定主机开放端口.
修改从服务器
1.修改配置文件后并重启
1 | vim /etc/my.cnf |
2.从服务器配置同步
1 | mysql -u root -p[密码] |
*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.100.10 Master_User: myslave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 4035 Relay_Log_File: localhost-relay-bin.000003 Relay_Log_Pos: 791 Relay_Master_Log_File: master-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes ...
reset slave执行时:
1.删除slave_master_info、slave_relay_log_info的表数据;
2.删除所有relay log文件, 并重新生成;
3.不会改变gtid_executed或gtid_purged的值
验证主从配置
在主服务器上创建测试数据库
1 | show slave hosts; |
在从服务器上查看测试数据库
1 | show databases; |
MySQL读写分离
简介
Atlas是由Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目. 它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上, 修改了大量bug, 添加了很多功能特性.
主要功能
1.读写分离
2.从库负载均衡
3.IP过滤
4.自动分表
5.DBA可平滑上下线DB
6.自动摘除宕机的DB
Atlas相对于官方MySQL-Proxy的优势:
1.将主流程中所有Lua代码用C重写, Lua仅用于管理接口.
2.重写网络模型、线程模型
3.实现了真正意义上的连接池
4.优化了锁机制, 性能提高数十倍.
配置读写分离
MySQL-Master | 192.168.100.10/24 |
MySQL-Slave1 | 192.168.100.20/24 |
MySQL-Slave2 | 192.168.100.30/24 |
MySQL+Atlas | 192.168.100.40/24 |
MySQL-Master、Slave1、Slave2.
配置权限给Atlas
1 | grant all on *.* to '用户名'@'192.168.100.%' identified by '密码'; |
MySQL-Atlas
1.下载Atlas并上传到当前目录下
2.安装Atlas软件, 安装好后会在/usr/local/mysql-proxy
目录下生成文件夹.
1 | rpm -ivh Atlas-2.2.1.el6.x86_64.rpm |
bin: 可执行文件 |__ encrypt --对MySQL密码进行加密处理 |__ mysql-proxy --MySQL自身的读写分离代理 |__ mysql-proxyd --属于360, 管理服务的启动、重启、停止. lib: 库及Atlas的依赖项 log: 日志文件 conf: 配置文件 |__ test.cnf
3.对MySQL的密码进行加密
1 | bin/encrypt 密码 |
4.编辑test.cnf配置文件
1 | vim conf/test.cnf |
5.重启Atlas软件
1 | bin/mysql-proxyd test start |
检测读写分离
1.用Yum安装MySQL后并登陆MySQL
1 | yum -y install mysql |
+-------------+---------------------+-------+------+ | backend_ndx | address | state | type | +-------------+---------------------+-------+------+ | 1 | 192.168.100.10:3306 | up | rw | | 2 | 192.168.100.20:3306 | up | ro | | 3 | 192.168.100.30:3306 | up | ro | +-------------+---------------------+-------+------+
2.在MySQL-Master上创建一个表
1 | create database db_test; |
3.停止MySQL-Slave1、MySQL-Slave2的复制.
1 | stop slave; |
4.在MySQL-Master上插入一条数据
1 | use db_test; |
5.分别在MySQL-Slave1、MySQL-Slave2中插入一条数据
1 | # MySQL-Slave1 |
6.在MySQL-Atlas上测试读操作
1 | # 代理登陆MySQL |
MySQL-MMM高可用
MMML(Master-Master replication manager for MySQL, MySQL主主复制管理器)是一套支持双主故障切换和双主日常管理的脚本程序.
MMM使用Perl语言开发, 主要用来监控和管理MySQL Master-Master(双主)复制, 这套脚本程序一方面实现了故障切换的功能, 另一方面其内部附加的工具脚本也可以实现多个Slave的read负载均衡.
MMM提供了自动和手动两种方式移除一组服务器中复制延迟较高的服务器的虚拟ip. 同时它还可以备份数据, 实现两节点之间的数据同步等, 但MMM无法完全保证数据的一致性.
mmm_mon
: 监控进程, 负责所有的监控工作, 决定和处理所有节点角色活动. 此脚本需要在监管机上运行.mnm_agent
: 运行在每个MySQL服务器上的代理进程, 完成监控的探针工作和执行简单的远端服务设置. 此脚本需要在被监管机上运行.mmm_control
: 一个简单的脚本, 提供管理mmm_mond
进程的命令.
mysal-mmm的监管端会提供多个虚拟IP(VIP), 包括一个可写VIP, 多个可读VIP, 通过监管的管理, 这些IP会绑定在可用MySQL之上, 当某一台MySQL宕机时, 监管会将VIP迁移至其他MySQL.
MMM高可用搭建
MySQL-Master1 | 192.168.100.10/24 |
MySQL-Master2 | 192.168.100.20/24 |
MySQL-Slave1 | 192.168.100.30/24 |
MySQL-Slave2 | 192.168.100.40/24 |
MySQL+Atlas+monitor | 192.168.100.50/24 |
配置MySQL主主复制
1.全部都安装上MySQL
二进制安装MySQL-5.7.30
2.配置Master1、2和Slave1、2的my.cnf文件
1 | vim /etc/my.cnf |
注: 如果是虚拟机克隆出来的话, 需删除auto.cnf文件后重启.
1 | systemctl stop mysqld |
3.配置Master1、2的主主模式
1 | # MySQL-Master1 |
Master1: +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000003 | 1076 | | | | +-------------------+----------+--------------+------------------+-------------------+ Master2: +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000002 | 615 | | | | +-------------------+----------+--------------+------------------+-------------------+
4.查看Master1、2的主从状态
1 | start slave; |
Master1: *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.100.20 Master_User: myslave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000002 Read_Master_Log_Pos: 615 Relay_Log_File: localhost-relay-bin.000002 Relay_Log_Pos: 321 Relay_Master_Log_File: master-bin.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes ... Master2: *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.100.10 Master_User: myslave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000003 Read_Master_Log_Pos: 1076 Relay_Log_File: localhost-relay-bin.000002 Relay_Log_Pos: 321 Relay_Master_Log_File: master-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes ...
5.测试主主同步, 在Master2中新建一个库.
1 | create database db_test; |
6.回到Master1中进行查看
1 | show databases; |
配置MySQL主从复制
1.查看Master1的状态值
1 | show master status; |
+-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000003 | 1249 | | | | +-------------------+----------+--------------+------------------+-------------------+
2.配置Slave1、2为Master1的从库
1 | change master to master_host='192.168.100.10', master_user='myslave', master_password='123456', master_log_file='master-bin.000003', master_log_pos=1249; |
配置MySQL-MMM
1.全部都安装上MMM
1 | wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo |
2.在Master1、2和Slave1、2上授权monitor访问
1 | # 监控用户授权 |
3.修改每台的mmm_common.conf
文件
1 | vim /etc/mysql-mmm/mmm_common.conf |
4.修改Master1、2和Slave1、2上的mmm_agent.conf
文件, 不同的主机为不同的值.
1 | vim /etc/mysql-mmm/mmm_agent.conf |
5.修改monitor上的mmm_mon.conf
文件
1 | vim /etc/mysql-mmm/mmm_mon.conf |
6.启动代理和监控
1 | # monitor |
7.配置读写分离
(1).Master1、2和Slave1、2配置权限给Atlas
1 | grant all on *.* to 'Atlas'@'192.168.100.%' identified by '密码'; |
(2).安装Atlas软件
1 | wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm |
(3).将配置权限的密码进行加密
1 | cd /usr/local/mysql-proxy/ |
(4).编辑test.cnf配置文件
1 | vim conf/test.cnf |
(5).重启Atlas软件
1 | bin/mysql-proxyd test start |
(6).检查读写分离
1 | mysql -h192.168.100.50 -uuser -ppwd -P2345 |
+-------------+---------------------+-------+------+ | backend_ndx | address | state | type | +-------------+---------------------+-------+------+ | 1 | 192.168.100.10:3306 | up | rw | | 2 | 192.168.100.20:3306 | up | rw | | 3 | 192.168.100.30:3306 | up | ro | | 4 | 192.168.100.40:3306 | up | ro | +-------------+---------------------+-------+------+
7.在monitor上检查群集状态
1 | mmm_control checks all |
db4 ping [last change: 2020/08/25 17:12:14] OK db4 mysql [last change: 2020/08/25 17:12:14] OK db4 rep_threads [last change: 2020/08/25 17:12:14] OK db4 rep_backlog [last change: 2020/08/25 17:12:14] OK: Backlog is null db2 ping [last change: 2020/08/25 17:12:14] OK db2 mysql [last change: 2020/08/25 17:20:52] OK db2 rep_threads [last change: 2020/08/25 17:26:04] OK db2 rep_backlog [last change: 2020/08/25 17:12:14] OK: Backlog is null db3 ping [last change: 2020/08/25 17:12:14] OK db3 mysql [last change: 2020/08/25 17:12:14] OK db3 rep_threads [last change: 2020/08/25 17:12:14] OK db3 rep_backlog [last change: 2020/08/25 17:12:14] OK: Backlog is null db1 ping [last change: 2020/08/25 17:12:14] OK db1 mysql [last change: 2020/08/25 17:16:21] OK db1 rep_threads [last change: 2020/08/25 17:12:14] OK db1 rep_backlog [last change: 2020/08/25 17:12:14] OK: Backlog is null
8.在monitor上查看群集状态
1 | mmm_control show |
db1(192.168.100.10) master/ONLINE. Roles: writer(192.168.100.12) db2(192.168.100.20) master/ONLINE. Roles: db3(192.168.100.30) slave/ONLINE. Roles: reader(192.168.100.35) db4(192.168.100.40) slave/ONLINE. Roles: reader(192.168.100.34)
(*1)关闭SeLinux子安全系统, 让agent访问数据.
1 | setenforce 0 |
# Warning: agent on host db1 is not reachable # Warning: agent on host db2 is not reachable # Warning: agent on host db3 is not reachable # Warning: agent on host db4 is not reachable
(*2)如果出现此状态, 则对所有主机进行时间同步.
1 | yum -y install ntpdate |
db1(192.168.100.10) master/AWAITING_RECOVERY. Roles: db2(192.168.100.20) master/AWAITING_RECOVERY. Roles: db3(192.168.100.30) slave/AWAITING_RECOVERY. Roles: db4(192.168.100.40) slave/AWAITING_RECOVERY. Roles:
测试MySQL-MMM
1.故障转移切换
(1)停止Master1的MySQL服务
1 |
|
2.模拟主主故障插入数据测试, 虚拟ip地址漂移, 存在延10秒左右.
1 | # monitor |
3.在monitor中查看群集状态
1 | systemctl start mysqld |
# 关闭状态 db2(192.168.100.20) master/HARD_OFFLINE. Roles: # 正在恢复 db2(192.168.100.20) master/AWAITING_RECOVERY. Roles: # 已恢复在线状态 db2(192.168.100.20) master/ONLINE. Roles:
4.在Master1中查看数据是否同步
1 | mysql -uroot -p[密码] |
5.模拟主从故障
1 | # Slave1 |