04、Mycat实战:数据库准备

https://www.cnblogs.com/gl-developer/p/6170423.html

docker 安装两个数据库并设置主从备份

1.创建数据库配置文件

因为实验室机房限制无法准备多个机器,此处使用docker创建数据库模拟多个机器,可以在宿主机上创建配置文件目录,本次采用如下两个s目录用于存放配置文件

  • Master:/root/db1/my.cnf
  • Slave: /root/db2/my.cnf

Master配置文件如下:

[mysqld]
## 同一局域网内注意要唯一
server-id=100  
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin

Slave配置文件如下:

和配置Master(主)一样,在Slave配置文件my.cnf中添加如下配置:

[mysqld]
## 设置server_id,注意要唯一
server-id=101  

## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin

## relay_log配置中继日志
relay_log=edu-mysql-relay-bin  

2 拉取镜像并创建数据库

  • docker pull mysql:5.7
  • docker run --name db1 -p 3316:3306 -v /root/db1/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
  • docker run --name db2 -p 3326:3306 -v /root/db2/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
[root@mycat ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql

69692152171a: Pull complete 
1651b0be3df3: Pull complete 
951da7386bc8: Pull complete 
0f86c95aa242: Pull complete 
37ba2d8bd4fe: Pull complete 
6d278bb05e94: Pull complete 
497efbd93a3e: Pull complete 
a023ae82eef5: Pull complete 
e76c35f20ee7: Pull complete 
e887524d2ef9: Pull complete 
ccb65627e1c3: Pull complete 
Digest: sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

[root@mycat db1]# docker run --name db1 -p 3316:3306 -v /root/db1/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
9eb8623c5497eb8abb16494e1820095043fb00ac69a8ec15646176e88372ba3d
[root@mycat db1]# docker run --name db2 -p 3326:3306 -v /root/db2/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
81acbc129d8317d152dcceeed1140c6948d40c25c7c8cacfaf30788e0239a63f
[root@mycat db1]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
81acbc129d83   mysql:5.7   "docker-entrypoint.s…"   5 seconds ago    Up 2 seconds    33060/tcp, 0.0.0.0:3326->3306/tcp, :::3326->3306/tcp   db2
9eb8623c5497   mysql:5.7   "docker-entrypoint.s…"   19 seconds ago   Up 17 seconds   33060/tcp, 0.0.0.0:3316->3306/tcp, :::3316->3306/tcp   db1

Master对外映射的端口是3316,Slave对外映射的端口是3326。因为docker容器是相互独立的,每个容器有其独立的ip,所以不同容器使用相同的端口并不会冲突。

3 使用客户端工具测试

*

4.MySQL主从复制原理

1、为什么需要主从复制?

1、 在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作;

2、 做数据的热备;

3、 架构的扩展业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能;

2、什么是mysql的主从复制?

MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。

3、mysql复制原理

原理:

(1)master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;

(2)slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件

(3)同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。

也就是说:

  • 从库会生成两个线程,一个I/O线程,一个SQL线程;
  • I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;
  • 主库会生成一个log dump线程,用来给从库I/O线程传binlog;
  • SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;

注意:

1–master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。

2–slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。

3–Mysql复制至少需要两个Mysql的服务,当然Mysql服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。

4–Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)

5–master和slave两节点间时间需同步

4、延时问题

mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生的日志写进binlog,由于binlog是顺序写,所以效率很高,slave的sql thread线程将主库的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是随机的,不是顺序,所以成本要高很多,另一方面,由于sql thread也是单线程的,当主库的并发较高时,产生的DML数量超过slave的SQL thread所能处理的速度,或者当slave中有大型query语句产生了锁等待,那么延时就产生了。

解决方案:

1、 业务的持久化层的实现采用分库架构,mysql服务可平行扩展,分散压力;

2、 单个库读写分离,一主多从,主写从读,分散压力这样从库压力比主库高,保护主库;

3、 服务的基础架构在业务和mysql之间加入memcache或者redis的cache层降低mysql的读压力;

4、 不同业务的mysql物理上放在不同机器,分散压力;

5、 使用比主库更好的硬件设备作为slave,mysql压力小,延迟自然会变小;

6、 使用更加强劲的硬件设备;

*

5 配置主从复制

在Master数据库创建数据同步用户,授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。

通过docker exec -it db1 /bin/bash命令进入到Master容器内部执行mysql客户端执行如下脚本。

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';

在Master进入mysql,执行show master status;

mysql> show master status  ;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      617 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)

File和Position字段的值后面将会用到,在后面的操作完成之前,需要保证Master库不能做任何操作,否则将会引起状态变化,File和Position字段的值变化。

退出master数据库,回到宿主机执行docker命令查看两个容器的ip

mysql> exit
Bye
root@9eb8623c5497:/# exit
exit

[root@mycat ~]# docker inspect --format '{
   
     { .NetworkSettings.IPAddress }}'  db1 
172.17.0.2

[root@mycat ~]# docker inspect --format '{
   
     { .NetworkSettings.IPAddress }}'  db2
172.17.0.3
[root@mycat ~]# 

在Slave 中进入 mysql,执行change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos= 2830, master_connect_retry=30;

命令说明:

master_host :Master机器的地址,此处指的是容器的独立ip(生产上应该是Master机器的ip),可以通过如下命令查询容器的ip

docker inspect --format='{
   
     {.NetworkSettings.IPAddress}}' 容器名称|容器id

master_port:Master的端口号,指的是容器的端口号

master_user:用于数据同步的用户

master_password:用于同步的用户的密码

master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值

master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值

master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒

在Slave 中的mysql终端执行show slave status \G;用于查看主从同步状态。

[root@mycat ~]# docker exec -it db2 /bin/bash
root@81acbc129d83:/# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.34-log MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000003', master_log_pos= 617, master_connect_retry=30;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 172.17.0.2
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 617
               Relay_Log_File: edu-mysql-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: No
            Slave_SQL_Running: No
              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: 617
              Relay_Log_Space: 154
              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: NULL
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: 0
                  Master_UUID: 
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: 
           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)

ERROR: 
No query specified

mysql> 

正常情况下,SlaveIORunning 和 SlaveSQLRunning 都是No,因为我们还没有开启主从复制过程。使用start slave开启主从复制过程,然后再次查询主从同步状态show slave status \G;

mysql> start slave ;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.2
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 617
               Relay_Log_File: edu-mysql-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000003
             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: 617
              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: 100
                  Master_UUID: 0be39b8d-ccec-11eb-9573-0242ac110002
             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)

ERROR: 
No query specified

mysql> 

SlaveIORunning 和 SlaveSQLRunning 都是Yes,说明主从复制已经开启。此时可以测试数据同步是否成功。

使用start slave开启主从复制过程后,如果SlaveIORunning一直是Connecting,则说明主从复制一直处于连接状态,这种情况一般是下面几种原因造成的,我们可以根据 Last_IO_Error提示予以排除。

1、 网络不通;

检查ip,端口
2、 密码不对;

检查是否创建用于同步的用户和用户密码是否正确
3、 pos不对;

检查Master的 Position

6.测试主从复制

测试主从复制方式就十分多了,最简单的是在Master创建一个数据库,然后检查Slave是否存在此数据库。

*

7.安装在宿主机上安装mysql客户端,测试连通性

  • yum install -y mysql
  • mysql -uroot -p123456 -h 172.17.0.2 -P 3306
  • mysql -uroot -p123456 -h 172.17.0.3 -P 3306
[root@mycat bin]# yum install mysql
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * epel: mirrors.neusoft.edu.cn
base                                                                                                                                                                    | 3.6 kB  00:00:00     
docker-ce-stable                                                                                                                                                        | 3.5 kB  00:00:00     
extras                                                                                                                                                                  | 2.9 kB  00:00:00     
updates                                                                                                                                                                 | 2.9 kB  00:00:00     
(1/2): extras/7/x86_64/primary_db                                                                                                                                       | 242 kB  00:00:00     
(2/2): updates/7/x86_64/primary_db                                                                                                                                      | 8.8 MB  00:00:01     
正在解决依赖关系
There are unfinished transactions remaining. You might consider running yum-complete-transaction, or "yum-complete-transaction --cleanup-only" and "yum history redo last", first to finish them. If those don't work you'll have to try removing/installing packages by hand (maybe package-cleanup can help).
--> 正在检查事务
---> 软件包 mariadb.x86_64.1.5.5.68-1.el7 将被 安装
--> 解决依赖关系完成

依赖关系解决

===============================================================================================================================================================================================
 Package                                      架构                                        版本                                                 源                                         大小
===============================================================================================================================================================================================
正在安装:
 mariadb                                      x86_64                                      1:5.5.68-1.el7                                       base                                      8.8 M

事务概要
===============================================================================================================================================================================================
安装  1 软件包

总下载量:8.8 M
安装大小:49 M
Is this ok [y/d/N]: y
Downloading packages:
mariadb-5.5.68-1.el7.x86_64.rpm                                                                                                                                         | 8.8 MB  00:00:01     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  正在安装    : 1:mariadb-5.5.68-1.el7.x86_64                                                                                                                                              1/1 
  验证中      : 1:mariadb-5.5.68-1.el7.x86_64                                                                                                                                              1/1 

已安装:
  mariadb.x86_64 1:5.5.68-1.el7                                                                                                                                                                

完毕!
[root@mycat bin]# mysql -uroot -p123456 -h 172.17.0.2 -P 3306
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.34-log MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testdb             |
+--------------------+
5 rows in set (0.00 sec)

MySQL [(none)]> exit
Bye
[root@mycat bin]# mysql -uroot -p123456 -h 172.17.0.3 -P 3306
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.7.34-log MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testdb             |
+--------------------+
5 rows in set (0.00 sec)

MySQL [(none)]> 

关注公众号,获取等多资讯
*

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: