前言
今天来看一看mysql的日志部分,也就是对应的管理篇。并且,我们来配置一下怎么在一台机器上使用docker来实现主从复制。
日志
错误日志
错误日志记录了mysql启动和停止的时候,以及服务器再运行过程中发生任何严重错误的相关信息,当数据库出现任何故障导致无法启动时,可以先看看错误日志里面的内容。
可以使用以下命令来查看日志位置
| 1
 | show variables like '%log_error%';
 | 
 
可以看到该错误日志的位置所在!
bin log
bin log记录了所有的ddl语句和dml语句,但不包括数据查询语句(select show)语句。
相似的,可以使用
| 1
 | show variables like '%log_bin';
 | 
 
来查看对应参数和位置,在这些参数中,用的比较多的有两个
- log_bin_basename:当前数据库服务器的- binlog日志的基础名称
- log_bin_index:- binlog的索引文件,里面记录了当前服务器关联的- binlog文件有哪些
格式

使用
| 1
 | show variables like '%binlog_format%';
 | 
 
来进行查看
| 1
2
3
4
5
6
7
 | mysql>  show variables like '%binlog_format%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set, 1 warning (0.00 sec)
 | 
 
查看
这部分很好理解,因为bin log并不是基于普通的文本进行存储的,而是以二进制的形式存储的,所以需要专门的日志查询工具进行查询。
这个工具就是mysqlbinlog

删除操作
可以使用以下这几种方式来清理日志

主从复制
什么是主从复制
主从复制时将数据库的写操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也就做重做),从而实现从库与主库之间的数据保持同步。
Mysql支持一台主库同时向多态从库进行复制,从库也可以作为其它从库的主库,从而实现链型复制。
主从复制的好处在于
- 主库出现服务,可以快速切换到从库进行服务
- 实现读写分离,降低主库的访问压力
- 可以在从库中实现备份,从而避免备份期间影响主库服务
原理
Mysql主从复制的核心就是 bin log,具体过程如下
- master主库在事务提交的时候,会把数据变更写在- bin log中
- 从库在读取主库的bin log时,写入到从库的中继日志relay log中
- slave从库重做中继日志中的事务,从而改变自己的数据。
其原理可由下图概括:

实际上,主从复制的依赖就是网络和我们之前提到的用户管理,我们在主库中保存各个从库的用户名和密码,当主库发生数据修改,例如修改表结果、存储新的数据等这些操作,就会把这些操作记录在bin log中。对于从库来说,其完成主从复制的核心是两个线程
- IOthread,读取主库的- bin log,把数据写到自己的- Relay log中
- SQLthread,读取- Relay log,然后把数据写道自己的库中
环境搭建
一般的,我们可以给两台服务器安装好mysql,并配置用户名和密码,但是我只有一台电脑,理论上一台电脑应该也可以完成这个任务。
本人使用的是WSL Ubuntu 22的版本
经过我的研究,我们还是使用docker比较好!在windows下,我们可以无缝来使用docker和wsl来实现!
镜像拉取
首先是获取对应的镜像
| 1
 | docker pull mysql:8.0.25
 | 
 
拉取下来后,就可以运行容器了
配置网络
本人之前在master和slave中发现不可以ping通,在docker里面我们可以创建一个网络,并且在启动的时候就使用这个网络启动
| 1
 | docker network create mysql-net
 | 
 
下面就可以使用这个网络选项来启动主库
| 1
2
3
4
5
6
7
8
9
 | # 主库
docker run -p 3307:3306 --name mysql-master \
--network mysql-net \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql \
-v /mydata/mysql-master/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:8.0.25
 | 
 
mysql对应的服务是3306,我们就映射到本机的3307端口,这是我们的主库。
服务配置
然后来到config目录下来完成配置
| 1
 | cd /mydata/mysql-master/conf
 | 
 
创建my.cnf,可能需要root权限
填写如下配置
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 | [mysqld]
## 设置server_id,同一局域网中需要唯一
## 在同一局域网中,可以把这个id置为对应的ip地址的最后一个一段
## 例如,加入主机的ip是 172.18.0.2,就可以把这个`ip`置为`2`
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
 | 
 
然后重新启动master
| 1
 | docker restart mysql-master
 | 
 
然后进入到master mysql中,创建slave用户
| 1
 | docker exec -it mysql-master /bin/bash # -it是以交互式的方式进入
 | 
 
登录mysql
创建和配置主库
在master中创建和配置slave
| 1
 | CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; -- 用户名是slave, 密码是123456
 | 
 
给slave用户授权
| 1
 | GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'%';
 | 
 
我们来看看主库当前有哪些用户
| 1
2
3
4
5
6
 | mysql> SELECT user, host FROM mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| root             | %         |
| slave            | %         |
 | 
 
可以看到slave用户已经成功创建了。
这里我们就不去赘述用户创建和管理了,感兴趣的可以去MySQL补全计划(一)中去详细了解。
修改密码,使之可以使用弱密码
| 1
 | ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
 | 
 
创建和配置从库
启动从库
| 1
2
3
4
5
6
7
8
 | docker run -p 3308:3306 --name mysql-slave \
--network mysql-net \
-v /mydata/mysql-slave/log:/var/log/mysql \
-v /mydata/mysql-slave/data:/var/lib/mysql \
-v /mydata/mysql-slave/conf:/etc/mysql \
-v /mydata/mysql-slave/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:8.0.25
 | 
 
启动后,进入从库
| 1
 | docker exec -it mysql-slave /bin/bash
 | 
 
进入后,我们可以先ping一下master,看看是否可以连通。
可能在ping的时候发现没有ping工具,这个现象是正常的,我们可以安装一下
| 1
2
 | apt update
apt install -y iputils-ping
 | 
 
docker内有对应的dns解析,对于一个ip,我们可以使用对应的名称作为ip地址
如果可以ping通,说明到目前为止,网络正常!然后退出!
注意,主从复制依赖于顺畅的网络环境!
对应的,我们也需要给slave创建对应的config
| 1
 | cd /mydata/mysql-slave/conf
 | 
 
创建配置文件,可能需要管理员权限
写入下面内容
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 | [mysqld]
## 设置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
 | 
 
重启服务
| 1
 | docker restart mysql-slave
 | 
 
查看主库的内容
进入主库,登录数据库后,查看当前的一些配置

注意,file和position是我们需要记录的。
查看从库
登录从库后,配置从库信息,根据上面的信息,可以进行如下配置
| 1
 | change master to master_host='mysql-master', master_user='slave', master_password='123456', master_port=3306, master_log_file='mall-mysql-bin.000004', master_log_pos=935, master_connect_retry=30;
 | 
 
配置好后,可以打开主从复制
查看从库是否开始复制

可以看到,Slave_IO_Running和Slave_SQL_Running已经正常运行了!
插入数据测试
我们登录主库,插入一些数据试试。
| 1
 | create database test01;
 | 
 
然后创建一张表
| 1
2
3
4
5
 | create table user (
	id int auto_increment,
    name varchar(50),
    age int
);
 | 
 
插入一些数据试试
| 1
 | insert into user(id, name) values (1, 'zxp1'), (2, 'zxp2');
 | 
 
查看一下
| 1
2
3
4
5
6
7
8
 | select * from user;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | zxp1 | NULL |
|  2 | zxp2 | NULL |
+----+------+------+
2 rows in set (0.00 sec)
 | 
 
可以看到,主库已经有这些数据了,如果一切顺利,那么从库也会有当前对应的数据!
主从复制总结
主从复制的主要依赖就是bin log和relay log,bin log,这个日志记录了所有的增删改操作,一般来说,**主库只开启bin log**即可。
relay log是从库的中转站,从库会把读到的bin log写入relay log中,等待Slave_SQL_Thread线程读取恢复,一般来说,如果从库后续不作为主库,那么不用开启bin log。
总结
本篇总结了日志以及主从复制的过程,后面我们来介绍一下分库分表!