MySQL与分布式

分布式

发布日期:2022-09-15

MySQL与分布式

MySQL数据库在分布式场景下的应用。

一、主从复制

当我们使用MySQL的时候,也可以采取主从复制的策略,它的实现思路基本和Redis相似,也是采用增量复制的方式,MySQL会在运行的过程中,会记录二进制日志,所有的DML和DDL操作都会被记录进日志中,主库只需要将记录的操作复制给从库,让从库也运行一次,那么就可以实现主从复制。但是注意它不会在一开始进行全量复制,所以最好再开始主从之前将数据库的内容保持一致

和之前一样,一旦我们实现了主从复制,那么就算主库出现故障,从库也能正常提供服务,并且还可以实现读写分离等操作。这里我们就使用Docker 容器环境来搭建一主一从的环境。

测试环境:

  1. Windows10 Pro
  2. Docker Desktop
  3. 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

image-20220915101039483

3.使用SQLyog测试是否能正常连接

image-20220915103730023

4.修改MySQL配置文件

1
2
# 查看所有容器运行的状态
docker ps -a

image-20220915103709217

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线程是处于重连状态,会等待主库重新恢复运行。