Mysql主从复制
一. 背景
- mysql服务器只有一台时,读和写所有压力都由一台数据库承担,压力大
- 数据库服务器磁盘损坏则数据丢失,单点故障
二. 解决方案
1. 介绍
MySQL主从复制是⼀个异步的复制过程,底层是基于Mysql数据库⾃带的 ⼆进制⽇志 功能。
就是⼀台或多台MySQL数据库(slave,即从库)从另⼀台MySQL数据库(master,即主库)
进⾏⽇志的复制,然后再解析⽇志并应⽤到⾃身,最终实现 从库 的数据和 主库 的数据保持
⼀致。MySQL主从复制是MySQL数据库⾃带功能,⽆需借助第三⽅⼯具。
⼆进制⽇志:
⼆进制⽇志(BINLOG)记录了所有的 DDL(数据定义语⾔)语句和 DML(数据
操纵语⾔)语句,但是不包括数据查询语句。此⽇志对于灾难时的数据恢复起着极其
重要的作⽤,MySQL的主从复制, 就是通过该binlog实现的。默认MySQL是未开启
该⽇志的。
2. 原理
当数据发生改变时,Mysql主库会将这次记录记录在binarylog日志中,从库通过I/O流将主库的日志写进自己的ralaylog日志中,从库中中的SQLthread线程会解析里面的内容,将数据变跟反映到自己的数据上。
3. 过程
- MySQL master 将数据变更写⼊⼆进制⽇志( binary log)
- slave将master的binary log拷⻉到它的中继⽇志(relay log)
- slave重做中继⽇志中的事件,将数据变更反映它⾃⼰的数据
4. 搭建
服务器:10.211.55.8
4.1 准备工作
提前准备2台服务器,并且在服务器中安装Mysql,服务器信息如下:
数据库 | IP | 数据库版本 |
---|---|---|
Master | 10.211.55.8 | 8.0.26 |
Salve | 10.211.55.7 | 8.0.26 |
并在2台服务器上做如下准备工作:1). 防⽕墙开放3306端⼝号
-
关闭防火墙
systemctl stop firewalld
-
将mysql服务开启
systemctl start mysqld
4.2 主库配置
-
编辑/etc/my.cnf配置文件
vim /etc/my.cnf
在[mysqld]选项下加入以下内容:
log-bin=mysql-log # (必须)开启mysql的二进制日志 server-id=100 # (必须)服务器唯一(唯一即可)
注意:
每个人的mysql配置文件不一样,需要自己查找,以下是一些可能的配置文件位置和命名:
/etc/mysql/mysql.conf.d/mysqld.cnf
/etc/mysql/mariadb.conf.d/50-server.cnf
/etc/my.cnf
/etc/mysql/my.cnf
/etc/mysql/mariadb.cnf
我的是打开有这个
按照英文意思可以知道,其他配置文件路径,进入my.cnf.d文件后
选择mysql-server.cnf
里面就有[mysqld]这个选项,然后将上述的内容写在里面就行。
-
重启mysql服务器
systemctl restart mysqld
-
创建数据同步的用户并授权
登录mysql,并执行如下指令:
CREATE USER '<yourname>'@'%' IDENTIFIED BY '<yourpassword>'; -- 首先,创建用户并设置密码 GRANT REPLICATION SLAVE ON *.* TO '<yourname>'@'%'; -- 授予用户复制权限 FLUSH PRIVILEGES; -- 刷新权限
注意:
上述是数据库8版本以上的写法,5的版本可以写成如下:
GRANT REPLICATION SLAVE ON *.* to '<yourname>'@'%' identified by'<yourpassword>';
-
登录Mysql数据库,查看master同步状态
执行下面SQL,记录下结果中的FILE和Position的值
show master status;
注意:
上面的SQL执行的作用是查看Master的状态,执行完此SQL后不要在执行其他任何操作
4.3 从库配置
服务器:10.211.55.7
-
进入/etc/my.cnf配置文件
vim /etc/my.cnf
将下述内容写在[mysqld]选项下
server-id=101
-
重启Mysql服务器
systemctl restart mysqld
-
进入mysql
在SQL命令行输入以下内容
change master to master_host='10.211.55.8', master_user='<yourname>', master_password='<yourpassword>', master_log_file='mysql-bin.000003', master_log_pos=961;
参数说明:
master_host : 主库的ip地址
master_user : 访问主库进行主从复制的用户名(上面在主库创建的)
master_password : 访问主库进行主从复制的用户名的密码
master_log_file : 从哪个日志文件开始同步(通过主库show master status;上述SQL语句查询的FILE字段值)
master_log_pos : 从指定⽇志⽂件的哪个位置开始同步(上述查询master状态中展示有)
-
启动slave服务
start salve;
-
查看从库状态
show salve status; /* \G : 在MySQL的sql语句后加上\G,表示将查询结果进⾏按列打印,可以使每个字段打印到单独的⾏。即将查到的结构旋转90度变成纵向*/
然后通过状态信息中的 Slave_IO_running 和 Slave_SQL_running 可以看出主从同步是否就
绪,如果这两个参数全为Yes,表示主从同步已经配置完成。
本人遇到的错误,Slave_IO_running显示connecting而不是yes,解决过程:
- 网络不通(从库ping主库)
- my.cnf配置有问题(查看主库配置,和从库访问主库的用户信息是否正确)
- 密码、file文件名、pos偏移量不对(重新show一下状态,然后修改从库)
- 防火墙没有关闭(我就是在这错的😭,通过systemctl status firewalld查看状态,开启则关闭)
- 主服务器mysql权限(查看创建的用户是否有复制的权限)
5. 测试
在navicat可视化工具中Master主库创建一个名为test的数据库,刷新一下从库Slave看是否也能出现test的数据库,如果有则成功了,失败了,就把上述流程再过一遍看哪出问题了,再慢慢解决。
可以试试下面的测试流程:
1). 在master中创建数据库itcast, 刷新slave查看是否可以同步过去
2). 在master的itcast数据下创建user表, 刷新slave查看是否可以同步过去
3). 在master的user表中插⼊⼀条数据, 刷新slave查看是否可以同步过去
补:
问chatgpt的问题和答案附:
文件过大发不出!!!