Mysql补全计划(七)

前言

今天来看一看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_indexbinlog的索引文件,里面记录了当前服务器关联的binlog文件有哪些

格式

image-20250625223515213

使用

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

image-20250625224001444

删除操作

可以使用以下这几种方式来清理日志

image-20250625224216106

主从复制

什么是主从复制

主从复制时将数据库的写操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也就做重做),从而实现从库与主库之间的数据保持同步。

Mysql支持一台主库同时向多态从库进行复制,从库也可以作为其它从库的主库,从而实现链型复制。

主从复制的好处在于

  • 主库出现服务,可以快速切换到从库进行服务
  • 实现读写分离,降低主库的访问压力
  • 可以在从库中实现备份,从而避免备份期间影响主库服务

原理

Mysql主从复制的核心就是 bin log,具体过程如下

  • master主库在事务提交的时候,会把数据变更写在bin log
  • 从库在读取主库的bin log时,写入到从库的中继日志relay log
  • slave从库重做中继日志中的事务,从而改变自己的数据。

其原理可由下图概括:

image-20250629161139720

实际上,主从复制的依赖就是网络和我们之前提到的用户管理,我们在主库中保存各个从库的用户名和密码,当主库发生数据修改,例如修改表结果、存储新的数据等这些操作,就会把这些操作记录在bin log中。对于从库来说,其完成主从复制的核心是两个线程

  • IOthread,读取主库的bin log,把数据写到自己的Relay log
  • SQLthread,读取Relay log,然后把数据写道自己的库中

环境搭建

一般的,我们可以给两台服务器安装好mysql,并配置用户名和密码,但是我只有一台电脑,理论上一台电脑应该也可以完成这个任务。

本人使用的是WSL Ubuntu 22的版本

经过我的研究,我们还是使用docker比较好!在windows下,我们可以无缝来使用dockerwsl来实现!

镜像拉取

首先是获取对应的镜像

1
docker pull mysql:8.0.25

拉取下来后,就可以运行容器了

配置网络

本人之前在masterslave中发现不可以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
vim my.cnf

填写如下配置

 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

1
mysql -uroot -p123456

创建和配置主库

在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地址

1
ping mysql-master

如果可以ping通,说明到目前为止,网络正常!然后退出!

注意,主从复制依赖于顺畅的网络环境!

对应的,我们也需要给slave创建对应的config

1
cd /mydata/mysql-slave/conf

创建配置文件,可能需要管理员权限

1
vim my.cnf

写入下面内容

 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

查看主库的内容

进入主库,登录数据库后,查看当前的一些配置

1
show master status;

image-20250629160416024

注意,fileposition是我们需要记录的。

查看从库

登录从库后,配置从库信息,根据上面的信息,可以进行如下配置

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;

配置好后,可以打开主从复制

1
start slave;

查看从库是否开始复制

image-20250629160950187

可以看到,Slave_IO_RunningSlave_SQL_Running已经正常运行了!

插入数据测试

我们登录主库,插入一些数据试试。

1
create database test01;
1
use 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 logrelay logbin log,这个日志记录了所有的增删改操作,一般来说,**主库只开启bin log**即可。

relay log是从库的中转站,从库会把读到的bin log写入relay log中,等待Slave_SQL_Thread线程读取恢复,一般来说,如果从库后续不作为主库,那么不用开启bin log

总结

本篇总结了日志以及主从复制的过程,后面我们来介绍一下分库分表!

Licensed under CC BY-NC-SA 4.0
花有重开日,人无再少年
使用 Hugo 构建
主题 StackJimmy 设计