# docker-mycat **Repository Path**: snitso/docker-mycat ## Basic Information - **Project Name**: docker-mycat - **Description**: docker 安装 Mycat,MySQL8 做主从复制、分库分表 - **Primary Language**: Shell - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-12-05 - **Last Updated**: 2024-10-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 使用 `Docker` 创建 `Mycat` 和 `MySQL` 主从服务器 [官方安装指南](https://github.com/MyCATApache/Mycat-Server/wiki/2.1-docker%E5%AE%89%E8%A3%85Mycat) [docker 配置参考指南](https://github.com/liuwel/docker-mycat) [双主双从配置指南](https://cloud.tencent.com/developer/article/1623821) [docker es+logstash+kibana](https://github.com/deviantony/docker-elk) ### 1. 环境 - `Mycat`: 1.6.7.6 - `MySQL`: 8.0.20 ### 2. 目录 ``` ├── compose │ ├── docker-compose.yml │ └── mycat │ └── Dockerfile ├── conf │ ├── hosts │ ├── mycat │ │ └──... │ ├── mysql-m1 │ │ └── conf.d │ │ └── docker.cnf │ ├── mysql-s1 │ │ └── conf.d │ │ └── docker.cnf │ └── mysql-s2 │ └── conf.d │ └── docker.cnf ├── logs │ ├── mycat │ │ ├── mycat.log │ │ ├── mycat.pid │ │ ├── switch.log │ │ └── wrapper.log │ ├── mysql-m1 │ ├── mysql-s1 │ └── mysql-s2 ├── mysql │ ├── mysql-m1 │ │ ├── ... │ ├── mysql-s1 │ │ ├── ... │ └── mysql-s2 │ │ ├── ... └── README.md ``` ### 3. `MySQL` 主从服务器结构 - `mysql-m1` : 主服务器 `IP:172.18.0.2` - `mysql-s1` : 从服务器 `slave1 IP:172.18.0.3` - `mysql-s2` : 从服务器 `slave2 IP:172.18.0.4` - `mycat` : `Mycat` 服务器 `IP:172.18.0.5` ### 4. `hosts` 文件添加解析 ```shell 172.18.0.2 dbm1 172.18.0.3 dbs1 172.18.0.4 dbs2 172.18.0.5 mycat 127.0.0.1 localhost ``` ### 5. `docker-compose.yml` 配置文件 ### 6. 启动容器 构建镜像 ```shell [root@192 docker-mycat]# sudo docker-compose build m1 s1 s2 ``` 运行 ```shell [root@192 docker-mycat]# docker-compose up -d dbm1 dbs1 dbs2 ``` ### 7. `MySQL` 主从配置 #### 7.1. 配置 `dbm1` 主服务器 ```shell [root@192 docker-mycat]# docker exec -it dbm1 /bin/bash root@dbm1:/# mysql -uroot -p Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.20 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. 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> ``` 创建用于主从复制的用户 slave,并给 slave 用户授予 slave 的权限 `mysql5.7` 写法是 ``` GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.18.0.%' IDENTIFIED BY '123456'; ``` `mysql8` 已经将创建账户和赋予权限的方式分开 加上 `mysql_native_password` 是因为 `mysql8` 以上版本使用 `caching_sha2_password` 加密方式 ``` mysql> CREATE USER 'slave'@'172.18.0.%' IDENTIFIED WITH mysql_native_password BY '123456'; Query OK, 0 rows affected (0.00 sec) mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'172.18.0.%'; Query OK, 0 rows affected (0.00 sec) ``` 查看 `binlog` 状态 记录 `File` 和 `Position` 状态稍后从库配置的时候会用 ```shell mysql> show master status; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000004 | 710 | | | | +-------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) ``` #### 7.2. 配置一主多从 从库 进入 dbs1 ```shell [root@192 docker-mycat]# docker exec -it dbs1 /bin/sh root@dbs1:/# mysql -uroot -p mysql> change master to master_host='dbm1',master_port=3306,master_user='slave',master_password='123456',master_log_file='master-bin.000004',master_log_pos=710; Query OK, 0 rows affected, 2 warnings (0.05 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec) ``` 进入 dbs2 ```shell sudo docker exec -it dbs2 /bin/bash root@s2:/# mysql -uroot -p mysql> change master to master_host='dbm1',master_port=3306,master_user='slave',master_password='123456',master_log_file='master-bin.000004',master_log_pos=710; Query OK, 0 rows affected, 2 warnings (0.03 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec) ``` ### 8. 测试主从 登陆主数据库 创建 test_db 数据库 (这个数据库名在稍后的 `mycat` 里面会用到) ```shell [root@192 docker-mycat]# mysql -h dbm1 -uroot -p MySQL [(none)]> create database test_db; Query OK, 1 row affected (0.01 sec) ``` 进入从库看看数据库是否创建 ```shell [root@192 docker-mycat]# mysql -uroot -p123456 -h dbs1 MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test_db | +--------------------+ 5 rows in set (0.00 sec) ``` 可以看到从库也已经创建成功了 到这里 mysql 的主从已经配置完成了 ### 9. 安装 `mycat` #### 9.1. 配置 `mycat` **重要说明**:`mycat` 在启动时依赖 `/usr/local/mycat/conf` 中的配置文件, 因此需要提前将配置文件放到挂载目录 `./conf/mycat`, 并修改好 `server.xml`,`schema.xml` 中的参数。 看下 `schama.xml` 配置文件 ```xml select user() ``` `server.xml` 配置文件 ```xml 123456 test_db test_db ``` #### 9.2. 启动 `mycat` ```shell % cd ~/docker-mycat/compose % sudo docker-compose up -d mycat ``` #### 9.3. 测试 `Mycat` > 进入 `Mycat` ```shell [root@localhost docker-mycat]# docker exec -it dbm1 /bin/sh # mysql -h mycat -umycat -P8066 -p --default_auth=mysql_native_password Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 7 Server version: 5.6.29-mycat-1.6.7.6-release-20211118155357 MyCat Server (OpenCloudDB) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. 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> show databases; +----------+ | DATABASE | +----------+ | test_db | +----------+ 1 row in set (0.00 sec) ``` > 多次执行下面的 `sql`,观察 `hostname` 的变化 ```shell mysql> select @@hostname; +------------+ | @@hostname | +------------+ | dbs1 | +------------+ 1 row in set (0.00 sec) mysql> select @@hostname; +------------+ | @@hostname | +------------+ | dbs2 | +------------+ 1 row in set (0.00 sec) ``` 测试数据 ```shell mysql> CREATE TABLE `test_table`( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '', `tittle` varchar(255) DEFAULT NULL COMMENT '' ); Query OK, 0 rows affected, 1 warning (0.09 sec) mysql> show tables; +-------------------+ | Tables_in_test_db | +-------------------+ | test_table | +-------------------+ 1 row in set (0.01 sec) mysql> INSERT INTO `test_table` VALUES (1, 'title1'); Query OK, 1 row affected (0.05 sec) mysql> INSERT INTO `test_table` VALUES (2, 'title2'); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO `test_table` VALUES (3, 'title3'); Query OK, 1 row affected (0.00 sec) mysql> select * from test_table; +----+--------+ | id | title | +----+--------+ | 1 | title1 | | 2 | title2 | | 3 | title3 | +----+--------+ 3 rows in set (0.01 sec) ``` ### 10. 问题 1. `Mycat` 连接 `dbm1` 连接失败 `mycat.log`: ```shell 2018-07-02 16:31:21.173 INFO [$_NIOREACTOR-25-RW] (io.mycat.sqlengine.SQLJob.connectionError(SQLJob.java:117)) - can't get connection for sql :select user() 2018-07-02 16:31:21.173 WARN [$_NIOREACTOR-27-RW] (io.mycat.backend.mysql.nio.MySQLConnectionAuthenticator.handle(MySQLConnectionAuthenticator.java:91)) - can't connect to mysql server ,errmsg:Client does not support authentication protocol requested by server; consider upgrading MySQL client MySQLConnection ``` 解决方式: ```shell ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; FLUSH PRIVILEGES; ALTER USER 'root'@'%' IDENTIFIED BY '123456'; ## 必须执行这个变更密码,否则会报错找不到caching_sha2_password模块 FLUSH PRIVILEGES; ``` ### 11. 配置读写分离 删掉刚刚在三个主机数据库中创建的所有数据库,关闭 `dbs2` 的主从复制 #### 11.1. 配置 `Mycat` 的 `schema.xml` 对刚才的文件 `schema.xml` 稍作修改 ```xml select user() select user() ``` 因为只有三个主机数据库,所以我将 `dbs2` 从从库中移了出来,作为一个分片数据库。 表 `employee` 根据字段 `sharding_id` 来分片 使用的分片规则是 `sharding-by-intfile`,`sharding_id` 做了一定的限制: ```xml partition-hash-int.txt ``` 可以看出,`hash_int` 规则引用了文件 `partition-hash-int.txt` 我们来看看这个文件写了什么: ``` 10000=0 10010=1 ``` 也就是说我们的 `sharding_id` 只能是这两个值 #### 11.2. 测试 ##### 11.2.1 创建数据库 先在 `dbm1` 和 `dbs2` 各创建一个数据库 `test_db` 和 表 `employee` ``` mysql> create database test_db; mysql> create table employee(id int(11) auto_increment primary key,`name` varchar(100) NOT NULL DEFAULT '',sharding_id int(11) not null); ``` 由于 `dbm1` 和 `dbs1`开启了主从,`dbs1` 会自动创建数据库和数据表 ##### 11.2.3 创建测试数据 进入 `Mycat`,向 `employee` 表添加数据 ```sql insert into employee(name,sharding_id) values('北京', 10000); insert into employee(name,sharding_id) values('天津', 10010); insert into employee(name,sharding_id) values('河北', 10000); insert into employee(name,sharding_id) values('辽宁', 10010); insert into employee(name,sharding_id) values('吉林', 10000); insert into employee(name,sharding_id) values('黑龙江', 10010); insert into employee(name,sharding_id) values('山东', 10000); insert into employee(name,sharding_id) values('江苏', 10010); insert into employee(name,sharding_id) values('上海', 10000); insert into employee(name,sharding_id) values('浙江', 10010); insert into employee(name,sharding_id) values('安徽', 10000); insert into employee(name,sharding_id) values('福建', 10010); insert into employee(name,sharding_id) values('江西', 10000); insert into employee(name,sharding_id) values('广东', 10010); insert into employee(name,sharding_id) values('广西', 10000); ``` 查询 `dbm1`: ```sql mysql> select * from employee; +----+--------+-------------+ | id | name | sharding_id | +----+--------+-------------+ | 1 | 北京 | 10000 | | 2 | 河北 | 10000 | | 3 | 吉林 | 10000 | | 4 | 山东 | 10000 | | 5 | 上海 | 10000 | | 6 | 安徽 | 10000 | | 7 | 江西 | 10000 | | 8 | 广西 | 10000 | +----+--------+-------------+ 8 rows in set (0.00 sec) ``` 查询切片 `dbs2`: ```sql mysql> select * from employee; +----+-----------+-------------+ | id | name | sharding_id | +----+-----------+-------------+ | 1 | 天津 | 10010 | | 2 | 辽宁 | 10010 | | 3 | 黑龙江 | 10010 | | 4 | 江苏 | 10010 | | 5 | 浙江 | 10010 | | 6 | 福建 | 10010 | | 7 | 广东 | 10010 | +----+-----------+-------------+ 7 rows in set (0.03 sec) ``` 查询 `dbs1`: ```sql mysql> select * from employee; +----+--------+-------------+ | id | name | sharding_id | +----+--------+-------------+ | 1 | 北京 | 10000 | | 2 | 河北 | 10000 | | 3 | 吉林 | 10000 | | 4 | 山东 | 10000 | | 5 | 上海 | 10000 | | 6 | 安徽 | 10000 | | 7 | 江西 | 10000 | | 8 | 广西 | 10000 | +----+--------+-------------+ 8 rows in set (0.00 sec) ``` 从查询结果可以看出,`dbm1` 和 `dbs1` 相同,`dbs2` 和 `dbm` 分别按分片规则做了数据存储。