一、主从复制概述
1、介绍:
主从复制是指将主数据库的 DDL 和 DML 操作写入到二进制日志中,将二进制日志传送到从库服务器,然后在从库上对这些日志重新执行(重做),从而使得从库和主库的数据保持同步。
MySQL支持一台主库同时向多台从库进行复制,从库同时也可以作为其他从服务器的主库(链状复制)。
2、优点:
MySQL 复制的优点主要包含以下三个方面:
① 主库出现问题,可以快速切换到从库提供服务。
② 实现读写分离,降低主库的访问压力。
③ 可以在从库中执行备份,以避免备份期间影响主库服务。
3、原理:
① Master 主库在事务提交时,会把数据变更记录在二进制日志文件 Binlog 中。
② 从库的IO线程读取主库Binlog日志中的事务,并写入到从库的中继日志Relay log中。
③ 从库的SQL线程读取中继日志Relay log中的事务,并在从库上执行,从而实现主从同步。
二、主从复制实现
1、环境准备:
准备好两台服务器之后,分别安装MySQL,关闭防火墙,并完成基础的初始化准备(安装、 密码配置等操作)工作。
master:10.1.1.10
slave:10.1.1.20
2、主库配置:
(1) 修改配置文件:
vim /etc/my.cnf
#mysq1 服务ID,用于在主从复制中标识服务器的唯一身份,保证整个集群环境中唯一。取值范围:1-2^32-1,默认为1
server-id=1
#是否只读,1 代表只读,0 代表读写
read-only=0
#忽略的数据,指不需要同步的数据库
#binlog-ignore-db=mysql
#指定同步的数据库
#binlog-do-db=db01
systemctl restart mysqld
(2) 创建远程连接账号并授权:
① 创建远程连接的用户名为itcast,密码为6666,可让任意主机连接。从库可通过此用户名和密码登录主库,获取binlog日志。
CREATE USER 'itcast'@'%' IDENTIFIED WITH mysql_native_password BY'6666' ;
如果报这个错误:
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
则要先修改mysql的密码策略:
set global validate_password.policy=0;
set global validate_password.length=4;
② 为'itcast'@'%'用户分配主从复制权限:
GRANT REPLICATION SLAVE ON *.* TO 'itcast'@'%';
(3) 查看二进制日志坐标:
show master status ;
file:事务写到了哪个文件
position:事务写到了文件的哪个位置
从库需要从binlog.000006的663之后开始主从复制。
3、从库配置:
(1) 修改配置文件:
vim /etc/my.cnf
#mysql 服务ID,保证整个集群环境中唯一,取值范围:1 – 2^32-1,和主库不一样即可
server-id=2
#是否只读,1 代表只读, 0 代表读写
read-only=1
systemctl restart mysqld
(2) 设置连接主库的信息:
CHANGE REPLICATION SOURCE TO SOURCE_HOST='10.1.1.10', SOURCE_USER='itcast', SOURCE_PASSWORD='6666', SOURCE_LOG_FILE='binlog.000006', SOURCE_LOG_POS=663;
(3) 开启主从同步:
start replica ; #8.0.22之后
start slave ; #8.0.22之前
(4) 查看主从同步状态:
show replica status\G ; #8.0.22之后
show slave status\G ; #8.0.22之前
4、验证主从同步:
在主库上创建数据库、表,并插入数据:
create database itcast;
use itcast;
create table tb_user(
id int(11) not null,
name varchar(50) not null,
sex varchar(1),
primary key (id)
)engine=innodb default charset=utf8;
insert into tb_user(id,name,sex) values(1,'Tom','1');
insert into tb_user(id,name,sex) values(2,'Trigger','0');
insert into tb_user(id,name,sex) values(3,'Dawn','1');
验证从库是否同步数据: