MySQL主从复制
基本介绍
MySQL 主从复制是一个异步的复制过程,底层是基于 Mysql 数据库自带的 二进制日志 功能。
一台或多台 MySQL 数据库(slave,即 从库 )从另一台 MySQL 数据库( master,即 主库 )进行日志的复制,然后再解析日志并应用到自身,最终实现 从库 的数据和 主库 的数据保持一致。
MySQL主从复制是MySQL数据库自带功能,无需借助第三方工具。
二进制日志:
二进制日志(BINLOG)记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但是不包括数据查询语句。此日志对于灾难时的数据恢复起着极其重要的作用,MySQL的主从复制,就是通过该 binlog 实现的。默认 MySQL 是未开启该日志的。
MySQL复制过程分成三步:
- MySQL master 将数据变更写入二进制日志(binary log)
- slave 将 master 的 binary log 拷贝到它的中继日志(relay log)
- slave重做中继日志中的事件,将数据变更反映它自己的数据
配置步骤
主库配置
修改配置文件 /etc/my.conf
,在最下面增加配置:
log-bin=mysql-bin #[必须]启用二进制日志
server-id=200 #[必须]服务器唯一ID(唯一即可)
然后重启 mysql
:
systemctl restart mysqld
然后登入到 mysql
中,执行:
//mysql8授权用户需要先创建,创建和授权同一条语句的话会报错,mysql8默认使用的是sha256_password我这里是修改了加密插件为mysql_native_password
CREATE USER 'songjian'@'%' IDENTIFIED WITH mysql_native_password BY 'Root@123456';
//再授权
GRANT ALL PRIVILEGES ON *.* TO 'songjian'@'%'WITH GRANT OPTION;
//刷新
flush privileges;
注:上面 SQL 的作用是创建一个用户 songjian ,密码为 Root@123456 ,并且给 songjian 用户授予R EPLICATION SLAVE 权限。常用于建立复制时所需要用到的用户权限,也就是 slave 必须被 master 授权具有该权限的用户,才能通过该用户复制。
查看一下主库的状态:
show master status;
从库配置
修改Mysql数据库的配置文件/etc/my.cnf,在后面追加:
server-id=201 #[必须]服务器唯一ID
然后,重启mysql服务
systemctl restart mysqld
登入mysql,执行下面sql:
//执行前先停下slave
stop slave;
//这是从库和主库连接的关键一步,host是主库的ip,user是前面创建的slave用户,file和pos是主库show master status的信息
change master to
master_host='192.168.223.130',master_user='songjian',master_password='Root@123456',
master_log_file='mysql-bin.000001',master_log_pos=1345;
//执行后启动slave
start slave;
执行后,来看看从库状态:
show slave status;
重点看上图中的 slave_IO_Running
和 Slaving_SQL_Running
是否正常运行(yes)
如果主从数据库同步不了,就从库执行下
show slave status\G;
如果是
Slave_IO_Running: No
,那么,很可能是主从库 server-id 重复了,或者是防火墙端口没开通;
如果是Slave_SQL_Running: No
,那么我们可以通过跳过错误和手动同步来解决。
Bug解决
主从复制的Bug主要是两个,一个是 Slave_SQL_Running:no
,另一个是 slave_io_running:no
。
Slave_SQL_Running:no
执行:
stop slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE;
start slave;
show slave status\G
即可修复。
Slave_IO_Running:no
查看主服务器:
show master status\G
查看从服务器:
show slave status\G
如果发现对应的二进制日志文件不同,则修改:
slave stop;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000026', MASTER_LOG_POS=0;
slave start;
show slave status\G
到此问题就解决了!