目录
1.MySQL主从复制是什么
2.MySQL主从复制的意义
3.MySQL主从复制原理
4.数据同步一致性问题
5.实现方式
1.MySQL主从复制是什么
MySQL主从复制就是指数据可以从一台MySQL的主节点复制到一个或多个从节点。
MySQL默认采用异步复制方式,这样从节点不用一直访问主服务器来更新数据,数据更新可以仅复制特点的数据库、表等。
2.MySQL主从复制的意义
1)为了实现读写分离,让主服务器负责写,从服务器负责读。这样可以保证当主库更新数据进行锁表时也可以读取数据。主从复制是读写分离的前提。
2)做数据的热备。可以备份数据。当主节点挂掉了,还可以访问从节点的数据。
3)降低磁盘的I/O访问频率,提高单个机器的I/O性能。
3.MySQL主从复制原理
简单来说,MySQL主从复制主要依靠两个二进制文件:Binary Log和Relay log,还有两个进程:I/O Thread和SQL Thread实现。
如下图所示:
当主服务器(master)发生数据更新时,会将其(data changes)写入Binary log的日志文件中;从服务器(slave)会定时对Binary log进行探测,判断其是否发送改变:如果改变,则启动从服务器中的 I/O Thread线程,读取Binary log文件中的内容,并将其写入至自己的Relay log日志文件中;然后使用SQL thread读取Relay log中的内容,最后进行replay,逐一解析为sql语句执行,复制数据库数据。过程完成后,I/O Thread和SQL thread进入休眠,直至下一次唤起。
关于Binary log记录的data changes,有以下两种类型选择:
- statement:每一条数据更新都会记录到binary log中。(即记录sql语句)
- row:基于行的复制,仅记录哪条记录被修改了,修改成什么样。(即记录数据的修改行为)
4.数据同步一致性问题
由于网络传输中会存在主从延迟,可能会导致用户从从服务器上读取的数据不是主服务器上最新的数据的问题,即主从同步中的数据不一致性问题。从数据一致性弱到强,有以下三种方式:
- 异步复制:主服务器执行事务后直接提交,不等待从服务器的确认通知。(数据一致性较弱,主服务器提交时刻t1到从服务器复制完成时刻t2之间读取数据,就会存在一致性问题)
- 半同步复制:主服务器执行事务后等待至少一个从服务器接收到了binary log并写入中继日志后后,得到确认通知(ack)后认为写操作完了,再返回给客户端。
- 组复制:基于Paxos协议的状态机复制。即将多个节点组成一个复制组。在执行读写事务时,需要一致性协议层的同意(即同意的节点数>N/2 +1),才可以提交;在执行只读事务时则不需要经过组内同意。
5.实现方式
本次案例以linux操作系统为例:
首先,需要准备两个ip地址,分别安装同一版本的MySQL。否则,进行数据复制时可能会导致错误。
服务器 | ip地址 | mysq版本 |
master | 192.168.0.200:3306 | 5.7 |
slave | 192.168.0.201:3306 | 5.7 |
(1)进入主数据库,创建用户,并且给该用户(seven)授予REPLICATION SLAVE权限
GRANT REPLICATION SLAVE ON *.* to 'seven'@'%' identified by 'Root@123456';
修改配置文件(在/conf/my.cnf文件):
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8
## 设置server_id, 同一个局域网中需要唯一
server_id=101
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
(请注意server_id唯一;修改完成后重启mysql)
进入Mysql master,记录以下数据:
(2)进入从服务器,修改配置:
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8
## 设置server_id, 同一个局域网内需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,以备slave作为其它数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复,1032是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## slave设置只读(具有super权限的用户除外)
read_only=1
(server_id必须不一致,同理,配置完成后重启mysql)
然后,在从服务器中设置主库地址及同步位置:
change master to master_host='masterd的ip',master_user='刚刚创建的用户名',master_password='Root@123456',master_log_file='masterd的file(show master status中查得)',master_log_pos=154;
参数说明:
- master_host : 主数据库的IP地址
- master_user : 访问主库进行主从复制的用户名(上面创建并赋予slave权限的)
- master_password : 访问主库进行主从复制的用户名对应的密码(请注意密码对应)
- master_log_file : 从哪个日志文件开始同步
- master_log_pos : 从指定日志文件的哪个位置开始同步
(注意:master_log_file和master_log_pos的值都为刚刚截图记录的值)
最后,在从服务器开启主从复制:
start slave;
主从复制即成功。
(3)我们可以在从机查看主从复制状态:
show slave status \G
Slave_IO_Running和Slave_SQL_Running两个参数都为yes,即成功。