3.1 复制概述
复制是指将主数据库的DDL 和 DML 操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。
MySQL支持一台主库同时向多台从库进行复制, 从库同时也可以作为其他从服务器的主库,实现链状复制。
3.2 复制原理
Mysql 中有一种日志叫做 bin 日志(二进制日志)。这个日志会记录下所有修改了数据库的SQL 语句(insert,update,delete,create/alter/drop table, grant 等等)。
主从复制的原理其实就是把主服务器上的 bin 日志复制到从服务器上执行一遍,这样从服务器上的数据就和主服务器上的数据相同了。
从上层来看,复制分成三步:
- Master 主库在事务提交时,会把数据变更作为时间 Events 记录在二进制日志文件 Binlog 中。
- 主库推送二进制日志文件 Binlog 中的日志事件到从库的中继日志 Relay Log 。
- slave重做中继日志中的事件,将改变反映它自己的数据。
详细过程:
- 主节点必须启用二进制日志,记录任何修改了数据库数据的事件。
- 从节点开启一个线程(I/O Thread)把自己扮演成 mysql 的客户端,通过 mysql 协议,请求主节点的二进制日志文件中的事件
- 主节点启动一个线程(dump Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则主节点就会从第一个日志文件中的第一个事件一个一个发送给从节点。
- 从节点接收到主节点发送过来的数据把它放置到中继日志(Relay log)文件中。并记录该次请求到主节点的具体哪一个二进制日志文件内部的哪一个位置(主节点中的二进制文件会有多个,在后面详细讲解)。
- 从节点启动另外一个线程(sql Thread ),把 Relay log 中的事件读取出来,并在本地再执行一次。
复制中线程的作用:
-
从节点:
-
I/O Thread: 从 Master 节点请求二进制日志事件,并保存于中继日志中。
-
Sql Thread: 从Relay log 中读取日志事件并在本地完成重放。
-
-
主节点:
- Dump Thread:为每个 Slave 的 I/O Thread 启动一个 dump 线程,用于向从节点发送二进制事件。
思考:从节点需要建立二进制日志文件吗?
看情况,如果从节点需要作为其他节点的主节点时,是需要开启二进制日志文件的。这种情况叫做级联复制。如果只是作为从节点,则不需要创建二进制文件。
3.3 复制优势
MySQL 复制的优点主要包含以下三个方面:
- 主库出现问题,可以快速切换到从库提供服务。
- 可以在从库上执行查询操作,从主库中更新,实现读写分离,降低主库的访问压力。
- 可以在从库中执行备份,以避免备份期间影响主库的服务。
主从复制配置过程:
-
主节点:
启用二进制日志。
为当前节点设置一个全局唯一的server_id。
创建有复制权限的用户账号 REPLIACTION SLAVE ,REPLIATION CLIENT。 -
从节点:
启动中继日志。
为当前节点设置一个全局唯一的server_id。
使用有复制权限的用户账号连接至主节点,并启动复制线程。
注意前提:
- 防火墙是关闭的
- 我这里是两台电脑测试的,需要把VM虚拟机两台网络模式改为桥接模式,然后在Linux中测试是否可以ping通,如果双方互通网络是没毛病的
master(主库)
- 在master 的配置文件(/etc/my.cnf)中,配置如下内容:
#mysql 服务ID,保证整个集群环境中唯一
server-id=1
#mysql binlog 日志的存储路径和文件名
log-bin=/var/lib/mysql/mysqlbin
# 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed
# 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7
# 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M
#是否只读,1 代表只读, 0 代表读写
read-only=0
#忽略的数据, 指不需要同步的数据库(mysql库一般不同步)
binlog-ignore-db=mysql
#指定同步的数据库
#binlog-do-db=db01
- 执行完毕之后,需要重启Mysql:
service mysqld restart
-
创建同步数据的账户,并且进行授权操作:
在主库创建一个复制帐号,这个帐号是给从库的IO线程建立连接到主库时用的,从库会用这个帐号连接主库并读取主库的二进制日志:
grant replication slave on *.* to 'zhr123'@'192.168.107.49' identified by '123abc';
flush privileges;
账号:自定义
IP端口:指定子端口
密码:自定义(如果密码不成功,需要改一下策略)
-
解决办法:
- 进入mysql,输入命令:mysql -root -p
- 查看 mysql 初始的密码策略,
输入语句 “ SHOW VARIABLES LIKE ‘validate_password%’; ” 进行查看, - 首先需要设置密码的验证强度等级,设置 validate_password_policy 的全局参数为 LOW 即可,
输入设值语句 “ set global validate_password_policy=LOW; ” 进行设值, - 当前密码长度为 8 ,如果不介意的话就不用修改了,按照通用的来讲,设置为 6 位的密码,设置 validate_password_length 的全局参数为 6 即可,
输入设值语句 “ set global validate_password_length=6; ” 进行设值, - 现在可以为 mysql 设置简单密码了,只要满足六位的长度即可
-
查看master状态:
show master status;
字段含义:
File : 从哪个日志文件开始推送日志文件
Position : 从哪个位置开始推送日志
Binlog_Ignore_DB : 指定不需要同步的数据库
slave(从库)
- 在 slave 端配置文件中,配置如下内容:
#mysql服务端ID,唯一
server-id=2
#指定binlog日志
log-bin=/var/lib/mysql/mysqlbin
read_only = 1
- 执行完毕之后,需要重启Mysql:
service mysqld restart;
- 执行如下指令 :
change master to master_host= '主库IP', master_user='主库账号',
master_password='主库密码', master_log_file='mysqlbin.000001', master_log_pos=413;
指定当前从库对应的主库的IP地址,用户名,密码,从哪个日志文件开始的那个位置开始同步推送日志。
- 开启同步操作
start slave;
show slave status\G
输出结果中应该看到 I/O 线程和 SQL 线程都是 YES
, 就表示成功。
执行此过程后,在主服务上操作的修改数据的操作都会在从服务器中执行一遍,这样就保证了数据的一致性。
- 停止同步操作(如果中间出错重新测试上面步骤,需要先关闭同步操作再重新来一遍)
stop slave;
验证同步操作
- 在主库中创建数据库,创建表,并插入数据 :
create database db01;
use db01;
create table user(
id int(11) not null auto_increment,
name varchar(50) not null,
sex varchar(1),
primary key (id)
)engine=innodb default charset=utf8;
insert into user(id,name,sex) values(null,'Tom','1');
insert into user(id,name,sex) values(null,'Trigger','0');
insert into user(id,name,sex) values(null,'Dawn','1');
- 在从库中查询数据,进行验证 :
在从库中,可以查看到刚才创建的数据库:
在该数据库中,查询user表中的数据:
好了这篇笔记到此结束啦!!!