前提准备
主机 |
系统 |
IP |
mysql |
mysql01 |
centos7 |
192.168.41.141 |
已部署5.7.31 |
mysql02 |
centod7 |
192.168.41.142 |
已部署5.7.31 |
原理
MySQL
中有一种日志叫做 bin日志
(二进制日志),这个日志会记录下所有修改了数据库的SQL语句。主从复制的原理其实就是从服务器
向主服务器
请求这个日志文件,主服务器
会把这个 bin日志
复制到从服务器
上执行一遍,这样从服务器
上的数据就和主服务器
上的数据相同了。
![原理图]()
- 主服务器必须启用二进制日志(log-bin),记录任何修改了数据库数据的事件;
- 从服务器开启一个线程(I/O Thread)把自己扮演成 MySQL 的客户端,通过 MySQL 协议,请求主服务器的二进制日志文件中的事件;
- 主服务器启动一个线程(Dump Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则主服务器就会从第一个日志文件中的第一个事件一个一个发送给从服务器;
- 从服务器接收到主服务器发送过来的数据把它放置到中继日志(relay log)文件中。并记录该次请求到主服务器的具体哪一个二进制日志文件内部的哪一个位置(主服务器中的二进制文件会有多个,其名结尾以6位数递增);
- 从服务器启动另外一个线程(SQL Thread),把 relay log 中的事件读取出来,并在本地再执行一次。
双主架构思路
- 两台
mysql
都可读写,互为主备
- 两台主库之间做高可用,可以采用
haproxy
、keepalived
等方案
双主配置
主要配置文件/etc/my.cnf
- 修改配置
vim /etc/my.cnf
server-id=1
log-bin=mysql-bin
auto-increment-increment=2
auto-increment-offset=1
log-slave-updates=true
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=mysql
replicate-ignore-db=sys
max_binlog_size=1024M
binlog-format=ROW
另一台配置
server-id=2
log-bin=mysql-bin
auto-increment-increment=2
auto-increment-offset=2
log-slave-updates=true
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=mysql
replicate-ignore-db=sys
max_binlog_size=1024M
binlog-format=ROW
slave_skip_errors
参数说明:
slave_skip_errors选项有四个可用值,分别为:off,all,ErorCode,ddl_exist_errors, 默认情况下该参数值是off.
mysql5.6及MySQL Cluster NDB 7.3以及后续版本增加了参数ddl_exist_errors,该参数包含一系列error code(1007,1008,1050,1051,1054,1060,1061,1068,1094,1146)
一些error code代表的错误如下:
1007:数据库已存在,创建数据库失败
1008:数据库不存在,删除数据库失败
1050:数据表已存在,创建数据表失败
1051:数据表不存在,删除数据表失败
1054:字段不存在,或程序文件跟数据库有冲突
1060:字段重复,导致无法插入
1061:重复键名
1068:定义了多个主键
1094:位置线程ID
1146:数据表缺失,请恢复数据库
1053:复制过程中主服务器宕机
1062:主键冲突 Duplicate entry '%s' for key %d
- 重启
mysql
service mysql restart
- 添加主从同步账户
grant replication slave on *.* to 'slave'@'192.168.41.142' identified by '123456';
flush privileges;
grant replication slave on *.* to 'slave'@'192.168.41.141' identified by '123456';
flush privileges;
- 查看主库状态
mysql> show master status;
+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+
| mysql-bin.000001 | 604 | | | |
+
1 row in set (0.00 sec)
- 配置同步信息
change master to master_host='192.168.41.142',master_port=3306,master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=604;
start slave;
change master to master_host='192.168.41.141',master_port=3306,master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=604;
start slave;
- 查看同步状态
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.41.141
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 604
Relay_Log_File: mysql02-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
- 测试
create database test;
CREATE TABLE `t_type` (
`type_id` INT(2) NOT NULL AUTO_INCREMENT COMMENT '资源类型id',
`type_name` VARCHAR(32) NOT NULL COMMENT '资源类型名称',
`type_remark` VARCHAR(255) DEFAULT NULL COMMENT '备注',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`type_id`),
UNIQUE KEY (type_name)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into t_type(type_name, type_remark) VALUES ('菜单资源','用于确定页面菜单资源,分多级菜单');
insert into t_type(type_name, type_remark) VALUES ('按钮资源','用于确定页面按钮资源');
insert into t_type(type_name, type_remark) VALUES ('路由资源','用于确定网关路由资源');
- 开启
MySQL5.6
之后引入的GTID
复制功能
vim /etc/my.cnf
gtid-mode=on
enforce-gtid-consistency=on
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
GTID
又叫全局事务ID
(Global Transaction ID
),是一个已提交事务的编号,并且是一个全局唯一的编号。MySQL5.6
版本之后在主从复制类型上新增了GTID复制
。
双主配置之前数据备份
使用mysqldump
命令,MySQL操作mysqldump命令详解
mysqldump -uroot -p
mysql -u root -p < /all_databases.sql