MySQL与分布式
MySQL数据库在分布式场景下的应用。
一、主从复制
当我们使用MySQL的时候,也可以采取主从复制的策略,它的实现思路基本和Redis相似,也是采用增量复制的方式,MySQL会在运行的过程中,会记录二进制日志,所有的DML和DDL操作都会被记录进日志中,主库只需要将记录的操作复制给从库,让从库也运行一次,那么就可以实现主从复制。但是注意它不会在一开始进行全量复制,所以最好再开始主从之前将数据库的内容保持一致。
和之前一样,一旦我们实现了主从复制,那么就算主库出现故障,从库也能正常提供服务,并且还可以实现读写分离等操作。这里我们就使用Docker 容器环境来搭建一主一从的环境。
测试环境:
- Windows10 Pro
- Docker Desktop
- MySQL version 5.7
1.拉取镜像
1
docker pull mysql:5.7
2.分别启动主从两个容器
1
2
# Master 主节点
docker run --name mysql03 -p 3312:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
1
2
# Slave 从节点
docker run --name mysql04 -p 3313:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
3.使用SQLyog测试是否能正常连接
4.修改MySQL配置文件
1
2
# 查看所有容器运行的状态
docker ps -a
1
2
3
4
5
6
7
8
9
10
11
12
# 进入MySQL容器内部
docker exec -it 62a84271ef9d /bin/bash
# 修改MySQL中的配置文件
cd /etc/mysql/mysql.conf.d/
# 创建mysqld.cnf文件
vim mysqld.cnf
# 如果不能使用VIM,需要手动安装
yum install -y vim
1
2
3
4
5
6
7
# Master 主节点-mysqld.cnf配置
[mysqld]
## 注意要id要唯一
server-id=103
## 开启二进制日志功能
log-bin=mysql-bin
配置完成之后重启mysql,然后重复上述步骤创建从节点-MySQL
1
2
3
4
5
6
7
8
# Slave 从节点-mysqld.cnf配置
[mysqld]
## 注意要id要唯一
server-id=104
# 开始二进制日志功能 以备Slave作为其他Slave的Master节点时使用
log-bin=mysql-slave-bin
# 配置中继日志
relay_log=edu-mysql-relay-bin
5.在主节点MySQL数据库上创建对应的账户,一会方便从库进行访问
# 在Master主节点数据库上创建 mysql03
create user test identified with mysql_native_password by '123456';
# 配置主库 主库只需要为我们刚刚创建的用户分配主从复制权限即可
grant replication slave on *.* to test;
# 刷新权限
flush privileges;
# 重启mysql
6.主从数据库进行连接
1
2
3
4
5
6
7
8
9
# 查看主库相关信息
show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
主库就配置完成,接着配置从库
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# 配置从库
# 进入数据库
mysql -uroot -p123456
# 先停止主从服务
stop slave;
# 连接主库
change master to master_host='172.30.210.68',
master_user='test',
master_password='123456',
master_port=3312,
# 这个是在 show master status中获取的-File
master_log_file='mysql-bin.000002',
# 这个是在 show master status中获取的-Position
master_log_pos=154,
master_connect_retry=30;
# 查看连接信息
show slave status\G;
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.30.210.68
Master_User: test
Master_Port: 3312
Connect_Retry: 30
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 154
Relay_Log_File: edu-mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 154
Relay_Log_Space: 531
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 103
Master_UUID: 4d728767-349b-11ed-af2d-0242ac110004
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
最关键的是下面的Replica_IO_Running和Replica_SQL_Running必须同时为Yes才可以,实际上从库会创建两个线程,一个线程负责与主库进行通信,获取二进制日志,暂时存放到一个中间表(Relay_Log)中,而另一个线程则是将中间表保存的二进制日志的信息进行执行,然后插入到从库中。
6.最后配置完成,我们测试一下在主库进行操作是否会同步到从库中:
# 在主库创建一个数据库
create database yyds02;
查看从库数据库,发现已经同步到从库中了,我们在测试一下创建表和插入输入:
use yyds02;
CREATE TABLE test(
id INT PRIMARY KEY,
NAME VARCHAR(255) NULL,
passwd VARCHAR(255) NULL
);
# 添加一条数据
INSERT INTO test(id,NAME,passwd) VALUES(0,"Xiaomijio","0525");
添加的数据依旧正常同步到从库中。
这样我们的MySQL主从就搭建完成了,那么如果主机此时挂了会怎么样?
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Reconnecting after a failed master event read
Master_Host: 172.30.210.68
Master_User: test
Master_Port: 3312
Connect_Retry: 30
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 835
Relay_Log_File: edu-mysql-relay-bin.000002
Relay_Log_Pos: 1001
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
可以看到IO线程是处于重连状态,会等待主库重新恢复运行。