文章目录
- 一、MyCat 概览
- 1.1 简介
- 1.2 官网网址
- 1.3 仓库地址
- 1.4 Mycat1.x 与 Mycat2 功能对比
- 1.5 下载
- 1.5.1 先决条件
- 1.5.2 Mycat2 安装包(以下二选一)
- 1.6 Mycat2权威指南
- 1.7 原型库
- 什么是兼容性 SQL?
- 什么是 Prototype 服务器?
- 原型库实现程度(V1.21)
- 1.8 使用限制
- 网络协议
- 插入特性
- 事务特性
- 数值类型
- DDL 语句
- DML 语句
- 数据库管理语句 (Database Administration Statements)
- 高级功能
- 函数计算问题
- 二、安装
- 2.1 安装 JDK 8
- 2.2 解压配置文件模板到安装目录
- 2.3 将 Mycat2.jar 放入安装目录
- 2.4 (可选)替换最新的 Wrapper
- 2.5 创建并加载 Mycat 库配置文件
- 三、部署与配置
- 3.1 部署 Mycat 服务器
- 3.1.1 `server.json`
- 3.1.2 `state.json`
- 3.1.3 `users/Mycat用户.user.json`
- 3.1.4 `wrapper.conf`
- 3.2 配置 Mycat2 原型库(可选但建议)
- 3.2.1 `datasources/prototypeDs.datasource.json`
- 3.3 配置用户自定义的 Mycat2 集群
- 3.3.1 `clusters/集群名.cluster.json`
- 3.3.2 `datasources/集群节点.datasource.json`
- 3.3.3 `schemas/方案名.schema.json`
- 3.3.3.1 系统视图方案
- 3.3.3.2 用户自定义的方案
- 3.4 启动
- 3.5 创建 Mycat 元数据库
- 3.5.1 配置了原型库
- 3.5.2 未配置原型库
- 3.6 测试
- 3.6.1 场景1:使用原型库,用户自定义数据源用户没有建库权限
- 3.6.1.1 创建新库、新表
- 3.6.1.2 在拥有全部权限的 `testdb` 上建表
- 3.6.2 场景2:使用原型库,用户自定义数据源用户为类 `root` 的管理员
- 3.6.2.1 创建新库、新表
- 3.6.3 场景3:不使用原型库
- 3.6.4 场景4:使用第一个 MySQL 数据源作为原型库,用户自定义数据源用户没有建库权限
- 3.6.4.1 使用 `prototype` 的集群和数据源配置文件
- 3.6.5 场景5:使用第一个 MySQL 数据源作为原型库,用户自定义数据源用户为类 `root` 的管理员
- 3.6.5.1 使用 `prototype` 的集群和数据源配置文件
- 3.6.5.2 仅使用 `prototype` 的数据源配置文件
- 四、Bugs
- 4.1 `wrapper.conf` 数字类型参数配置有误,多了末尾的单位 M
一、MyCat 概览
1.1 简介
Mycat 是一种由 Java 语言编写的、使用 MySQL 数据库网络协议的、采用 GPLv3 开源协议的开源数据库中间件。
1.2 官网网址
官网网址有两个,一个是由上海云业网络科技有限公司提供,一个是由广州鼎牛网络科技有限公司提供:
- http://mycatone.top/
- http://www.mycat.org.cn/
应该都是官网,里面可能涉及一些开源社区弄出来的商业问题。至于最后谁是李逵,谁是李鬼,就不清楚了。
1.3 仓库地址
仓库地址有三个,其中一个已经失效:
- GitHub
https://github.com/MyCATApache/Mycat2 - Gitee(码云)
https://gitee.com/MycatOne/Mycat2
https://gitee.com/mirrors/Mycat2 (已失效)
由此可以看出 http://mycatone.top/ 似乎更新更及时。
1.4 Mycat1.x 与 Mycat2 功能对比
功能 | 1.6 | 2 |
---|---|---|
多语句 | 不支持 | 支持 |
blob值 | 支持一部分 | 支持 |
全局二级索引 | 不支持 | 支持 |
任意跨库join(包含复杂查询) | catlet支持 | 支持 |
分片表与分片表JOIN查询 | ER表支持 | 支持 |
关联子查询 | 不支持 | 支持一部分 |
分库同时分表 | 不支持 | 支持 |
存储过程 | 支持固定形式的 | 支持更多 |
支持逻辑视图 | 不支持 | 支持 |
支持物理视图 | 支持 | 支持 |
批量插入 | 不支持 | 支持 |
执行计划管理 | 不支持 | 支持 |
路由注释 | 支持 | 支持 |
集群功能 | 支持 | 支持更多集群类型 |
自动hash分片算法 | 不支持 | 支持 |
支持第三方监控 | 支持mycat-web | 支持普罗米斯,kafka日志等监控 |
流式合拼结果集 | 支持 | 支持 |
范围查询 | 支持 | 支持 |
单表映射物理表 | 不支持 | 支持 |
XA事务 | 弱XA | 支持,事务自动恢复 |
支持MySQL8 | 需要更改mysql8的服务器配置支持 | 支持 |
虚拟表 | 不支持 | 支持 |
joinClustering | 不支持 | 支持 |
union all语法 | 不支持 | 支持 |
BKAJoin | 不支持 | 支持 |
优化器注释 | 不支持 | 支持 |
ER表 | 支持 | 支持 |
全局序列号 | 支持 | 支持 |
保存点 | 不支持 | 支持 |
离线迁移 | 支持 | 支持(实验) |
增量迁移 | CRC32算法支持 | BINLOG追平(实验) |
安全停机 | 不支持 | 支持(实验) |
HAProxy协议 | 不支持 | 支持 |
会话粘滞 | update后select会粘滞 | update后select会粘滞且支持设置时间 |
全局表插入支持全局序列号 | 不支持 | 支持 |
全局表插入支持主表插入自增结果作为序列号 | 不支持 | 支持 |
外部调用的分片算法 | 不支持但可定制 | 支持 |
1.5 下载
1.5.1 先决条件
- JDK 8
- unzip 实用程序
yum install -y unzip
1.5.2 Mycat2 安装包(以下二选一)
建议从 http://dl.mycat.org.cn/2.0/ 处下载,因为 github 的连接因 DNS 污染导致不稳定而无法访问。
Mycat2 以 Wrapper 为壳,因而目录结构与其保持一致,仅提供核心 jar 包,不提供安装包。
- 笔者制作一个安装包。里面包含最新版的 Wrapper 与上文中的 Mycat-1.22.jar 一起,只保留了 Linux x64 平台的
lib
库,删除了其他平台的lib
或.dll
库。 - 使用 Mycat2 官网下载的安装包
-
首先是 Mycat2 最重要的核心文件
.jar
包。 -
其次是配置文件的样例模板文件。
-
(可选)最新的 Wrapper (点击即可跳转)。
笔者选用的是 Linux x86 64bit 版本的
.tar.gz
包。
-
1.6 Mycat2权威指南
- Mycat2权威指南(语雀文档) (官方文档,写得很烂,文档编撰人员语言能力不行,初学者会看得云里雾里)
- https://www.w3cschool.cn/mycat2/mycat2-vgis3kri.html (推荐,比官方文档写的好)
1.7 原型库
上图右侧的 MySQL 在 Mycat2 的配置里面叫做 原型库(Prototype) ,专门用来响应兼容性 SQL 和系统表 SQL 。
什么是兼容性 SQL?
兼容性 SQL 是指客户端或者所在应用框架运行所需必须的 SQL ,但是用户一般接触不到,它们会影响客户端的启动和运行。而 Mycat2 处理这种 SQL 时尽可能不影响用户使用。
什么是 Prototype 服务器?
Prototype 服务器 是指分库分表中间件中用于处理 MySQL 的兼容性 SQL 和系统表 SQL 的服务器。这个配置项可以指向一个服务器,也可以是一个集群,Mycat 依靠它处理非 SELECT
,INSERT
,UPDATE
,DELETE
语句。当这个服务器是与第一个存储节点是同一个服务器/集群的时候,我们一般把它称之为 0 号节点 。
原型库实现程度(V1.21)
- 如果集群中配置了名为 prototype 的集群,则使用它作为
prototype
。 - 如果数据源中存在 prototypeDs 的数据源,但是没有名为 prototype 的集群,则自动创建主数据源为 prototypeDs 的
prototype
集群。 - 如果集群和数据源中没有 prototype 也没有 prototypeDs ,则选择数据源中第一个数据源类型为
mysql
类型的数据源作为prototype
集群的主数据源。 - 上述都不适用的情况下,使用第一个数据源作为
prototype
的集群的主数据源。 - 如果没有数据源,则不处理。
1.8 使用限制
网络协议
- 一般来说仅内网使用,没有实现加密通信协议,连通外网有安全问题
- 没有后端数据库之间的数据同步服务
- 目标是兼容 MySQL 7/8 服务器,也一定程度兼容 MariaDB, 支持 MariaDB 客户端的批量
插入特性
- 网络通信协议支持 native_password 验证,其他验证方式会自动切换到验证插件
- 支持超过 16MB 的报文
- 不支持压缩协议
- 不支持加密协议通信
事务特性
- 支持强一致性(不跨库)分布式事务
- 支持保存点(
SAVEPOINT
,V1.21-2021-11-10) - 支持多语句
数值类型
Mycat2 对于单分片 SQL 没有限制,而对于跨实例的 sql 使用有符号类型处理,可以尝试在 Mycat 把建表语句的字段类型改成 DECIMAL
避开这个问题
DDL 语句
- 不支持修改拆分(分片)键
- 支持物理库的视图视为普通表来使用
- 仅普通表支持外键
DML 语句
-
DELETE
语句- 不支持涉及分布式运算的子查询。
- 不支持多表
DELETE
。
-
UPDATE
语句- 不支持涉及分布式运算的子查询。
- 不支持多表
UPDATE
。
-
SELECT
语句- 对于
FOR UPDATE
语句会把 SQL 中出现的表都加锁。 - 具体是行锁还是表锁要看 SQL 语句。
- 不支持
SELECT INTO OUTFILE
。
- 对于
数据库管理语句 (Database Administration Statements)
SET
语句- 支持
SET SESSION
级别的变量,但是不能被预处理语句引用变量,只有autocommit
变量具有正确语义 - 不支持
SET GLOBAL
级别的变量 - 不支持
SET USER
级别的变量
- 支持
SHOW
语句
所有SHOW
语句都视为 兼容性 SQL 进行处理,发往prototype
节点处理,所以不具备分布式语义
高级功能
- 不支持用户自定义数据类型(改代码), 自定义函数(改代码)
- 支持物理视图,但是不支持 Mycat 的逻辑视图
- 不支持存储过程(改代码)
- 有限支持存储过程
- 不支持游标
- 不支持触发器
函数计算问题
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP());
在 MySQL 的结果:
在 Mycat2 的结果:
在 Mycat2 里面,函数计算是有先后的,结果与 MySQL 有偏差。
二、安装
目录声明:
- Mycat2 安装包目录:
~/install_mycat
,存储所有安装包的目录。 - Mycat2 安装目录:
/var/lib/mycat
。 - (可选)Wrapper 安装目录:
/var/lib/wrapper
,这是一个软链接(或符号链接)目录。
2.1 安装 JDK 8
使用 yum
查看适合你的环境的 openjdk 包来安装:
[root@ic-source mycat]$ yum list java-1.8.0-openjdk*
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
* epel: mirrors.bfsu.edu.cn
可安装的软件包
java-1.8.0-openjdk.i686 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk.x86_64 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-accessibility.i686 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-accessibility.x86_64 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-demo.i686 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-demo.x86_64 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-devel.i686 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-devel.x86_64 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-headless.i686 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-headless.x86_64 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-javadoc.noarch 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-javadoc-zip.noarch 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-src.i686 1:1.8.0.362.b08-1.el7_9 updates
java-1.8.0-openjdk-src.x86_64
比如你的环境是 x86_64 架构的,则执行:
yum install -y java-1.8.0-openjdk.x86_64
安装完成后验证:
[root@ic-source mycat]$ java -version
java version "1.8.0_202-ea"
Java(TM) SE Runtime Environment (build 1.8.0_202-ea-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b03, mixed mode)
笔者的 JDK 是很早之前用 .tar.gz
包安装的,一直没更新。
2.2 解压配置文件模板到安装目录
# 创建 mycat 安装包目录
[root@ic-source install_mycat]$ mkdir ~/install_mycat
# 使用 rz 或 sftp 将文件上传到服务上的 ~/install_mycat 目录
[root@ic-source install_mycat]$ unzip -q mycat2-install-template-1.21.zip -d /var/lib
[root@ic-source install_mycat]$ cd /var/lib/mycat
[root@ic-source mycat]$ ll *
bin:
总用量 2588
-rw-r--r--. 1 root root 15666 3月 5 2021 mycat
-rw-r--r--. 1 root root 3916 3月 5 2021 mycat.bat
-rw-r--r--. 1 root root 281540 3月 5 2021 wrapper-aix-ppc-32
-rw-r--r--. 1 root root 319397 3月 5 2021 wrapper-aix-ppc-64
-rw-r--r--. 1 root root 253808 3月 5 2021 wrapper-hpux-parisc-64
-rw-r--r--. 1 root root 140198 3月 5 2021 wrapper-linux-ppc-64
-rw-r--r--. 1 root root 99401 3月 5 2021 wrapper-linux-x86-32
-rw-r--r--. 1 root root 111027 3月 5 2021 wrapper-linux-x86-64
-rw-r--r--. 1 root root 114052 3月 5 2021 wrapper-macosx-ppc-32
-rw-r--r--. 1 root root 233604 3月 5 2021 wrapper-macosx-universal-32
-rw-r--r--. 1 root root 253432 3月 5 2021 wrapper-macosx-universal-64
-rw-r--r--. 1 root root 112536 3月 5 2021 wrapper-solaris-sparc-32
-rw-r--r--. 1 root root 148512 3月 5 2021 wrapper-solaris-sparc-64
-rw-r--r--. 1 root root 110992 3月 5 2021 wrapper-solaris-x86-32
-rw-r--r--. 1 root root 204800 3月 5 2021 wrapper-windows-x86-32.exe
-rw-r--r--. 1 root root 220672 3月 5 2021 wrapper-windows-x86-64.exe
conf:
总用量 32
drwxr-xr-x. 2 root root 36 6月 28 2021 clusters
drwxr-xr-x. 2 root root 41 6月 28 2021 datasources
-rw-r--r--. 1 root root 3338 3月 5 2021 dbseq.sql
-rw-r--r--. 1 root root 316 11月 2 2021 logback.xml
-rw-r--r--. 1 root root 0 3月 5 2021 mycat.lock
drwxr-xr-x. 2 root root 69 6月 28 2021 schemas
drwxr-xr-x. 2 root root 6 6月 28 2021 sequences
-rw-r--r--. 1 root root 776 12月 28 2021 server.json
-rw-r--r--. 1 root root 1643 3月 5 2021 simplelogger.properties
drwxr-xr-x. 2 root root 233 6月 28 2021 sql
drwxr-xr-x. 2 root root 6 6月 28 2021 sqlcaches
-rw-r--r--. 1 root root 49 3月 5 2021 state.json
drwxr-xr-x. 2 root root 28 6月 28 2021 users
-rw-r--r--. 1 root root 211 3月 5 2021 version.txt
-rw-r--r--. 1 root root 4165 1月 13 2022 wrapper.conf
lib:
总用量 560
-rw-r--r--. 1 root root 22948 3月 4 2021 libwrapper-aix-ppc-32.a
-rw-r--r--. 1 root root 24499 3月 4 2021 libwrapper-aix-ppc-64.a
-rw-r--r--. 1 root root 74520 3月 4 2021 libwrapper-hpux-parisc-64.sl
-rw-r--r--. 1 root root 23839 3月 4 2021 libwrapper-linux-ppc-64.so
-rw-r--r--. 1 root root 11887 3月 4 2021 libwrapper-linux-x86-32.so
-rw-r--r--. 1 root root 15248 3月 4 2021 libwrapper-linux-x86-64.so
-rw-r--r--. 1 root root 15400 3月 4 2021 libwrapper-macosx-ppc-32.jnilib
-rw-r--r--. 1 root root 35332 3月 4 2021 libwrapper-macosx-universal-32.jnilib
-rw-r--r--. 1 root root 34968 3月 4 2021 libwrapper-macosx-universal-64.jnilib
-rw-r--r--. 1 root root 13760 3月 4 2021 libwrapper-solaris-sparc-32.so
-rw-r--r--. 1 root root 21032 3月 4 2021 libwrapper-solaris-sparc-64.so
-rw-r--r--. 1 root root 12572 3月 4 2021 libwrapper-solaris-x86-32.so
-rw-r--r--. 1 root root 83820 3月 5 2021 wrapper.jar
-rw-r--r--. 1 root root 81920 3月 4 2021 wrapper-windows-x86-32.dll
-rw-r--r--. 1 root root 76800 3月 4 2021 wrapper-windows-x86-64.dll
logs:
总用量 0
可见,这个模板包属于跨平台的,封装了很多平台的文件,这里我们仅需要 Linux x86_64 的,所以删除多余的文件。
[root@ic-source mycat]$ cd bin/
[root@ic-source bin]$ rm -f mycat.bat wrapper-[^l]* wrapper-linux-{ppc-64,x86-32}
[root@ic-source bin]$ chmod 754 *
[root@ic-source bin]$ ll
总用量 128
-rwxr-xr--. 1 root root 15666 3月 5 2021 mycat
-rwxr-xr--. 1 root root 111027 3月 5 2021 wrapper-linux-x86-64
[root@ic-source bin]$ ./wrapper-linux-x86-64 -v
Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
[root@ic-source bin]$ mv wrapper-linux-x86-64 wrapper
Mycat 官网提供的模板包里封装的 Wrapper 版本为 3.2.3 ,如果你不想使用最新的 Wrapper 可以跳过 2.4 替换最新的 Wrapper 。
注意
Mycat 安装目录的bin
子目录中的wrapper
是必须的,即便你在系统中安装了wrapper
实用程序。[root@ic-source bin]$ which wrapper /usr/bin/wrapper [root@ic-source mycat]$ mycat Unable to locate any of the following operational binaries: /var/lib/mycat/bin/./wrapper-linux-x86-64 /var/lib/mycat/bin/./wrapper-linux-x86-32 /var/lib/mycat/bin/./wrapper ```
[root@ic-source bin]$ cd ../lib
[root@ic-source lib]$ rm -rf libwrapper-[^l]* libwrapper-linux-{ppc,x86-32}* wrapper-windows-x86-*
[root@ic-source lib]$ ll
总用量 100
-rw-r--r--. 1 root root 15248 3月 4 2021 libwrapper-linux-x86-64.so
-rw-r--r--. 1 root root 83820 3月 5 2021 wrapper.jar
如果要使用最新的 Wrapper ,则可以将 lib
目录下的所有文件都删除。
[root@ic-source lib]$ rm -rf ../lib/*
2.3 将 Mycat2.jar 放入安装目录
# 注意替换此处的目录为 mycat2.jar 所在的目录
[root@ic-source lib]$ cd
[root@ic-source lib]$ cp ~/install_mycat/mycat2-1.22-release-jar-with-dependencies-2022-10-13.jar /var/lib/mycat/lib/mycat2-1.22.jar
2.4 (可选)替换最新的 Wrapper
[root@ic-source install_mycat]$ tar -zxf wrapper-linux-x86-64-3.5.53.tar.gz -C /var/lib
[root@ic-source install_mycat]$ ln -s /var/lib/wrapper-linux-x86-64-3.5.53/ /var/lib/wrapper
[root@ic-source lib]$ cp /var/lib/wrapper/lib/libwrapper.so /var/lib/mycat/lib
[root@ic-source lib]$ ll /var/lib/mycat/lib
总用量 149424
-rwxr-xr-x. 1 root root 56984 4月 20 04:11 libwrapper.so
-rw-r--r--. 1 root root 152950673 4月 20 04:14 mycat2-1.22.jar
[root@ic-source bin]$ echo '/var/lib/wrapper/lib/libwrapper.so' > /etc/ld.so.conf.d/wrapper.conf
[root@ic-source bin]$ cat /etc/ld.so.conf.d/wrapper.conf
/var/lib/wrapper/lib/libwrapper.so
[root@ic-source bin]$ ldconfig
[root@ic-source mycat]$ ln -s /var/lib/wrapper/bin/wrapper /usr/bin/wrapper
[root@ic-source mycat]$ wrapper -v
Java Service Wrapper Community Edition 64-bit 3.5.53
Copyright (C) 1999-2023 Tanuki Software, Ltd. All Rights Reserved.
http://wrapper.tanukisoftware.com
[root@ic-source bin]$ rm -f /var/lib/mycat/bin/wrapper*
创建 bin/wrapper
、lib/wrapper.jar
时,Wrapper 官方教程建议直接把 wrapper
二进制文件直接复制过来。我这里分别创建了一个软链接。以下操作二选一:
- 创建软链接。
[root@ic-source bin]$ ln -s /usr/bin/wrapper /var/lib/mycat/bin/wrapper [root@ic-source bin]$ ln -s /var/lib/wrapper/lib/wrapper.jar /var/lib/mycat/lib/wrapper.jar
- 直接复制。
[root@ic-source mycat]$ cp /var/lib/wrapper/bin/wrapper /var/lib/mycat/bin/
笔者采用的是软链接的方式,下面验证一下。
[root@ic-source bin]$ ll /var/lib/mycat/bin
总用量 16
-rwxr-xr--. 1 root root 15666 3月 5 2021 mycat
lrwxrwxrwx. 1 root root 16 4月 20 04:51 wrapper -> /usr/bin/wrapper
[root@ic-source bin]$ /var/lib/mycat/bin/wrapper -v
Java Service Wrapper Community Edition 64-bit 3.5.53
Copyright (C) 1999-2023 Tanuki Software, Ltd. All Rights Reserved.
http://wrapper.tanukisoftware.com
[root@ic-source bin]$ mycat
Usage: /usr/bin/mycat { console | start | stop | restart | status | dump }
2.5 创建并加载 Mycat 库配置文件
[root@ic-source mycat]$ echo '/var/lib/mycat/lib' > /etc/ld.so.conf.d/mycat2.conf
[root@ic-source mycat]$ cat /etc/ld.so.conf.d/mycat2.conf
/var/lib/mycat/lib
[root@ic-source mycat]$ ldconfig
[root@ic-source bin]$ mycat
Usage: /usr/bin/mycat { console | start | stop | restart | status | dump }
三、部署与配置
有关安装(Install)、部署(Deploy)、设置(Setup/Set up)和配置(Configure)的区别,请参见 安装(Install)、部署(Deploy)、设置(Setup/Set up)和配置(Configure)的区别 。
3.1 部署 Mycat 服务器
3.1.1 server.json
[root@ic-source conf]$ pwd
/var/lib/mycat/conf
[root@ic-source conf]# cat server.json
{
"loadBalance":{ // 负载均衡策略
"defaultLoadBalance":"BalanceRandom",
"loadBalances":[]
},
"mode":"local",
"properties":{},
"server":{
"serverVersion": "MySQL 8.0.31 - Mycat 2.0", // MySQL 客户端(比如 mysql)及 Mycat 版本
"bufferPool":{
},
"idleTimer":{
"initialDelay":3,
"period":60000,
"timeUnit":"SECONDS"
},
"ip":"replica3", // 主机名或IP
"mycatId":1, // Mycat 节点 ID
"port":8066, // 端口号
"reactorNumber":8,
"tempDirectory":null,
"timeWorkerPool":{
"corePoolSize":0,
"keepAliveTime":1,
"maxPendingLimit":65535,
"maxPoolSize":2,
"taskTimeout":5,
"timeUnit":"MINUTES"
},
"workerPool":{
"corePoolSize":1,
"keepAliveTime":1,
"maxPendingLimit":65535,
"maxPoolSize":1024,
"taskTimeout":5,
"timeUnit":"MINUTES"
}
}
}
3.1.2 state.json
[root@ic-source conf]# cat state.json
{
"master":{
"cls02":["source"]
}
"replica":{
"cls02":["replica1"]
}
}
3.1.3 users/Mycat用户.user.json
笔者使用默认的 Mycat 的 root
用户及密码。注意,这是 Mycat 的 root
用户,本质上是一个MySQL 代理(Proxy)用户,而非真实的 MySQL 物理库的用户。
[root@ic-source conf]# cat users/root.user.json
{
"dialect":"mysql", // SQL 方言
"ip":null, // 限制可访问的 IP 地址,如果配置为某一 IP 或 IP 网段,则限制只有配置的 IP 或 IP 网段能访问
"username":"root", // Mycat 用户名
"password":"123456", // 上面的 Mycat 用户名的密码
"transactionType":"proxy",
}
注意
- 该文件的原始配置文件结尾的换行符有问题,请使用诸如
vi
的编辑器重新编辑,或者直接复制笔者的配置。
ip
属性不支持 DNS 名称,只支持 IP 地址或网段。
3.1.4 wrapper.conf
一定要注意看注释!
就比如 Mycat 开发人员就是最好的反例!明明 Wrapper 的注释里都写了 Mycat 开发人员也能配错的吗? 内存配置注释里写了默认单位是 M ,举的例子也是数字,他非得做无用功,添个 M ,虽然产生的仅是警告,进行了隐式转换、截取处理,但就不该发生这种低级错误。
在所有平台上,Wrapper 都会在启动时立即将其工作目录强制到其二进制文件所在的目录。这一点至关重要,因为进程是由其父操作系统启动的,其工作目录与其父进程相同。
以下仅列出需要修改的配置:
[root@ic-source conf]$ vi wrapper.conf
# Initial Java Heap Size (in MB)
#wrapper.java.initmemory=3
wrapper.java.initmemory=256
# Maximum Java Heap Size (in MB)
#wrapper.java.maxmemory=64
wrapper.java.maxmemory=2048
如果你是使用 ln -s
在 /var/lib/mycat/bin
目录创建的 wrapper 软链接,而不是直接复制过来的,则还需修改
wrapper.working.dir=/var/lib/mycat
3.2 配置 Mycat2 原型库(可选但建议)
先进入到 Mycat2 的配置目录。
[root@ic-source ~]$ cd /var/lib/mycat/conf
按我目前的理解(可能有误,如后续发现有误,会及时修正本文),建议将原型库独立放在一个单独的 MySQL 实例上,以使架构清晰,既便于初学者理解,又可避免大规模复杂分库分表拓扑导致元数据过多,占用存储节点空间。
同时,建议保留 Mycat2 模板里自带的 conf/datasources/prototypeDs.datasource.json
、 clusters/clusters/prototype.cluster.json
、conf/schemas/mysql.schema.json
、conf/schemas/information_schema.schema.json
。其中,仅需要配置前两者。 除非你充分理解原型库的概念,否则无需修改太多原型库的配置。
3.2.1 datasources/prototypeDs.datasource.json
笔者以主机 replica3 上的 prototype
实例作为原型库 prototype
实例,且以 root@'%\'
作为连接用户,以获得创建、删除数据库等全局权限。
[root@ic-source conf]$ cat datasources/prototypeDs.datasource.json
{
"dbType":"mysql",
"idleTimeout":60000,
"initSqls":[],
"initSqlsGetConnection":true,
"instanceType":"READ_WRITE",
"maxCon":1000,
"maxConnectTimeout":3000,
"maxRetryCount":5,
"minCon":1,
"name":"prototypeDs",
"password":"Root@123",
"type":"JDBC",
"url":"jdbc:mysql://replica3:3307/mysql?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
"user":"root",
"weight":0
}
测试用 root
用户是否可以连通 replica3 上的 prototype MySQL 实例。
3.3 配置用户自定义的 Mycat2 集群
仿照 prototype
的配置文件,创建、配置用户自定义集群、数据源。也可以学习一下 Mycat2 提供的注释语法来在 Mycat2 终端中创建、配置用户自定义集群,执行结果是解析注释自动创建相应的 JSON 配置文件。
3.3.1 clusters/集群名.cluster.json
[root@ic-source conf]$ pwd
/var/lib/mycat/conf
[root@ic-source conf]$ cat clusters/cls02.cluster.json
{
"clusterType":"MASTER_SLAVE", // 集群类型
"heartbeat":{
"heartbeatTimeout":1000,
"maxRetry":3,
"minSwitchTimeInterval":300,
"slaveThreshold":0
},
"masters":[ // 主成员
"source" // 成员节点1
],
"replicas":[ // 副本成员
"replica1" // 成员节点2
],
"maxCon":200,
"name":"cls02", // 集群名
"readBalanceType":"BALANCE_ALL", // 读负载均衡类型
"switchType":"SWITCH"
}
3.3.2 datasources/集群节点.datasource.json
笔者用 MySQL 建立了一个简单的使用 SSL 的两节点复制拓扑,source 为主节点,replica1 为从节点。详见 【MySQL 8.0】建立 MySQL 复制拓扑 。
注意
笔者并非使用root@'%'
作为 Mycat 连接数据源的用户,而是创建并使用了权限范围更小的、受限的mycat@'%'
用户,目的是出于安全考虑。权限分离、审计、安全都是生产环境应考虑的方面,而国内 IT 环境往往会忽略这点,仗着仅用于内网就肆无忌惮。
配置节点1 source :
[root@ic-source conf]$ cat datasources/source.datasource.json
{
"dbType":"mysql",
"idleTimeout":60000,
"initSqls":[],
"initSqlsGetConnection":true,
"instanceType":"READ_WRITE", // 实例类型,设置为读写
"maxCon":1000,
"maxConnectTimeout":3000,
"maxRetryCount":5,
"minCon":1,
"name":"source", // 为数据源命名,应与配置文件名保持一致
"password":"Mycat!123", // 修改该用户的密码
"type":"JDBC",
"url":"jdbc:mysql://source:3307/testdb?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8", // MySQL 连接串
"user":"mycat", // 修改为你所使用的物理库的用户
"weight":0 // 权重
}
配置节点2 replica1 :
[root@ic-source conf]$ cat datasources/replica1.datasource.json
{
"dbType":"mysql",
"idleTimeout":60000,
"initSqls":[],
"initSqlsGetConnection":true,
"instanceType":"READ", // 实例类型,设置为只读
"maxCon":1000,
"maxConnectTimeout":3000,
"maxRetryCount":5,
"minCon":1,
"name":"replica1", // 为数据源命名,应与配置文件名保持一致
"password":"Mycat!123", // 修改该用户的密码
"type":"JDBC",
"url":"jdbc:mysql://replica1:3307/testdb?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8", // MySQL 连接串
"user":"mycat", // 修改为你所使用的物理库的用户
"weight":0 // 权重
}
3.3.3 schemas/方案名.schema.json
3.3.3.1 系统视图方案
笔者使用的是默认的配置。
注意
如果你的拓扑需要修改系统视图方案的配置,请替换默认information_schema
和mysql
方案的 targetName (集群或数据源名)prototype
为你的集群或数据源名称
。例如:
[root@ic-source conf]$ sed -i '1,$ s/prototype/cls02/g' schemas/information_schema.schema.json
[root@ic-source conf]$ sed -i '1,$ s/prototype/cls02/g' schemas/mysql.schema.json
3.3.3.2 用户自定义的方案
[root@ic-source conf]$ cat schemas/mycat_db.schema.json
{
"customTables": {},
"globalTables": {},
"normalTables": {
"logical_t1": {
"createTableSQL":"CREATE TABLE `logical_t1` (\n `id` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", // 可选
"locality": {
"schemaName": "testdb", // 物理库,可选
"tableName": "t1", // 物理表,可选
"targetName": "cls02" // 指向集群,或者数据源
}
}
},
"schemaName": "testdb",
"shardingTables": {},
"targetName": "cls02"
}
3.4 启动
[root@ic-source conf]$ mycat start
Starting mycat2...
启动日志如下:
STATUS | wrapper | 2023/04/22 19:17:38 | --> Wrapper Started as Daemon
STATUS | wrapper | 2023/04/22 19:17:38 | Java Service Wrapper Community Edition 64-bit 3.5.53
STATUS | wrapper | 2023/04/22 19:17:38 | Copyright (C) 1999-2023 Tanuki Software, Ltd. All Rights Reserved.
STATUS | wrapper | 2023/04/22 19:17:38 | http://wrapper.tanukisoftware.com
STATUS | wrapper | 2023/04/22 19:17:38 |
STATUS | wrapper | 2023/04/22 19:17:38 | Launching a JVM...
INFO | jvm 1 | 2023/04/22 19:17:39 | WrapperManager: Initializing...
INFO | jvm 1 | 2023/04/22 19:17:39 | path:/var/lib/mycat/./conf
INFO | jvm 1 | 2023/04/22 19:17:41 | 2023-04-22 19:17:41,059[INFO]com.alibaba.druid.pool.DruidDataSource.init:998{dataSource-1} inited
INFO | jvm 1 | 2023/04/22 19:17:41 | 2023-04-22 19:17:41,731[INFO]com.alibaba.druid.pool.DruidDataSource.init:998{dataSource-2} inited
INFO | jvm 1 | 2023/04/22 19:17:44 | 2023-04-22 19:17:44,114[INFO]io.mycat.vertx.VertxMycatServer.lambda$start$1:168Mycat Vertx server 7edc873a-e793-4eed-ba5e-0c1dff0e196d started up.
INFO | jvm 1 | 2023/04/22 19:17:44 | 2023-04-22 19:17:44,114[INFO]io.mycat.vertx.VertxMycatServer.lambda$start$1:168Mycat Vertx server 7d83108a-f878-4a87-9f7c-31b907179b39 started up.
INFO | jvm 1 | 2023/04/22 19:17:44 | 2023-04-22 19:17:44,115[INFO]io.mycat.vertx.VertxMycatServer.lambda$start$1:168Mycat Vertx server 0d44b877-e581-4194-afe4-9b0611df9368 started up.
INFO | jvm 1 | 2023/04/22 19:17:44 | 2023-04-22 19:17:44,116[INFO]io.mycat.vertx.VertxMycatServer.lambda$start$1:168Mycat Vertx server 42add207-5166-4469-a052-f72ae903e74c started up.
INFO | jvm 1 | 2023/04/22 19:17:44 | 2023-04-22 19:17:44,117[INFO]io.mycat.vertx.VertxMycatServer.lambda$start$1:168Mycat Vertx server 0fb29a60-ef3b-47d1-9a1c-80e425987668 started up.
INFO | jvm 1 | 2023/04/22 19:17:44 | 2023-04-22 19:17:44,117[INFO]io.mycat.vertx.VertxMycatServer.lambda$start$1:168Mycat Vertx server d82e80da-8a50-4c6e-9477-60552810bf3c started up.
INFO | jvm 1 | 2023/04/22 19:17:44 | 2023-04-22 19:17:44,120[INFO]io.mycat.vertx.VertxMycatServer.lambda$start$1:168Mycat Vertx server 726a136d-f1fc-4763-b791-9c393e8bffba started up.
INFO | jvm 1 | 2023/04/22 19:17:44 | 2023-04-22 19:17:44,120[INFO]io.mycat.vertx.VertxMycatServer.lambda$start$1:168Mycat Vertx server 229c52de-0ad2-4cb1-b4f8-9e7958af0e5f started up.
3.5 创建 Mycat 元数据库
使用 Mycat 官方给出的方法创建 Mycat 元数据库。
创建 create_mycat_metaDB.sql
以复用,内容如下
CREATE DATABASE IF NOT EXISTS `mycat`;
USE `mycat`;
DROP TABLE IF EXISTS `analyze_table`;
CREATE TABLE `analyze_table` (
`table_rows` bigint(20) NOT NULL,
`name` varchar(64) NOT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
DROP TABLE IF EXISTS `config`;
CREATE TABLE `config` (
`key` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`value` longtext,
`version` bigint(20) DEFAULT NULL,
`secondKey` longtext,
`deleted` tinyint(1) DEFAULT '0',
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
DROP TABLE IF EXISTS `replica_log`;
CREATE TABLE `replica_log` (
`name` varchar(22) DEFAULT NULL,
`dsNames` text,
`time` datetime DEFAULT NULL,
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
DROP TABLE IF EXISTS `spm_baseline`;
CREATE TABLE `spm_baseline` (
`id` bigint(22) NOT NULL AUTO_INCREMENT,
`fix_plan_id` bigint(22) DEFAULT NULL,
`constraint` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`extra_constraint` longtext,
PRIMARY KEY (`id`),
UNIQUE KEY `constraint_index` (`constraint`(22)),
KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
DROP TABLE IF EXISTS `spm_plan`;
CREATE TABLE `spm_plan` (
`id` bigint(22) NOT NULL AUTO_INCREMENT,
`sql` longtext,
`rel` longtext,
`baseline_id` bigint(22) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
DROP TABLE IF EXISTS `sql_log`;
CREATE TABLE `sql_log` (
`instanceId` bigint(20) DEFAULT NULL,
`user` varchar(64) DEFAULT NULL,
`connectionId` bigint(20) DEFAULT NULL,
`ip` varchar(22) DEFAULT NULL,
`port` bigint(20) DEFAULT NULL,
`traceId` varchar(22) NOT NULL,
`hash` varchar(22) DEFAULT NULL,
`sqlType` varchar(22) DEFAULT NULL,
`sql` longtext,
`transactionId` varchar(22) DEFAULT NULL,
`sqlTime` bigint(20) DEFAULT NULL,
`responseTime` datetime DEFAULT NULL,
`affectRow` int(11) DEFAULT NULL,
`result` tinyint(1) DEFAULT NULL,
`externalMessage` tinytext,
PRIMARY KEY (`traceId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
DROP TABLE IF EXISTS `variable`;
CREATE TABLE `variable` (
`name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`value` varchar(22) DEFAULT NULL,
PRIMARY KEY (`name`)
) ENGINE = InnoDB CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;
DROP TABLE IF EXISTS `xa_log`;
CREATE TABLE `xa_log` (
`xid` bigint(20) NOT NULL,
PRIMARY KEY (`xid`)
) ENGINE = InnoDB CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;
3.5.1 配置了原型库
如果你保留了默认的配置文件 prototype 或自行配置了一个 prototype
类型的原型库,则 Mycat 会在原型库所配置的物理库中创建一个名为 mycat
的数据库作为 Mycat 的元数据库。
运行以上 SQL 建表语句并未报错。
查询 Mycat 逻辑库。
查询原型库。
3.5.2 未配置原型库
否则,如果你删除了默认的 prototype 相关的配置文件,仅保留了你自定义的配置文件,则 即便不执行以上 SQL 脚本也会自动创建 mycat
数据库,该库为空库,且不生成 JSON 配置文件(schemas/mycat.schema.json
)。
以我在 replica3 主机上创建的另一个 Mycat 实例为例。该 Mycat 实例,展现了上述只保留自定义配置的情况。
没有 schemas/mycat.schema.json
文件。
SHOW DATABASES;
也查看不到 mycat
库,却可以 USE
,但为空库。
如果执行以上 SQL 脚本时,会报错,库和表虽创建成功了,却只保存元数据(表结构)于 JSON 配置文件(schemas/mycat.schema.json
)中,而不存储在物理库中。
只要存在 JSON 配置文件,在 Mycat 终端中就可以查看到这些库和表。
而并没有像 Mycat 官方文档 所说的那样, 在第一个数据源类型为 mysql
的数据源作为 prototype
集群的主数据源,在其上创建 mycat
元数据库。
连接物理库可证实这点。
3.6 测试
3.6.1 场景1:使用原型库,用户自定义数据源用户没有建库权限
该场景中,已配置了一个独立于存储节点的原型库,配置的数据源使用的是 mycat
用户,该用户没有建库权限,仅拥有 testdb
库上的所有权限。
3.6.1.1 创建新库、新表
连接 Mycat 实例,在 Mycat 终端中执行以下 SQL,创建一个新库 db1
,在其中创建一个新表 a1
。
mysql> show databases;
+--------------------+
| `Database` |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| testdb |
+--------------------+
4 rows in set (0.01 sec)
mysql> create database db1;
Query OK, 0 rows affected (0.02 sec)
mysql> show databases;
+--------------------+
| `Database` |
+--------------------+
| db1 |
| information_schema |
| mysql |
| performance_schema |
| testdb |
+--------------------+
5 rows in set (0.10 sec)
mysql> use db1;
Database changed
mysql> insert into a1 values(1),(2),(3);
Query OK, 3 rows affected (0.01 sec)
# 不支持 MySQL 8 TABLE 语法
mysql> table a1;
ERROR:
com.alibaba.druid.sql.parser.ParserException: not supported.pos 5, line 1, column 1, token TABLE
mysql> select * from a1;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
3 rows in set (0.01 sec)
直连 MySQL 物理库,查看到底在哪个库创建的 db1
和 a1
。
[root@ic-source conf]$ mysql -uroot -p -e 'show databases;'
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
[root@ic-source conf]$ mysql -uroot -p -hreplica1 -e 'show databases;'
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
[root@ic-source conf]$ mysql -uroot -p -hreplica3 -e 'show databases;'
Enter password:
+--------------------+
| Database |
+--------------------+
| db1 |
| information_schema |
| mycat |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
[root@ic-source conf]$ mysql -uroot -p -hreplica3 -e 'table db1.a1;'
Enter password:
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
由上可知,Mycat 检查权限后在原型库创建了 db1
和 a1
。
3.6.1.2 在拥有全部权限的 testdb
上建表
Mycat 终端:
mysql> show databases;
+--------------------+
| `Database` |
+--------------------+
| db1 |
| information_schema |
| mysql |
| performance_schema |
| testdb |
+--------------------+
5 rows in set (0.18 sec)
mysql> use testdb;
Database changed
mysql> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| t1 |
| logical_t1 |
+------------------+
2 rows in set (0.25 sec)
mysql> create table t2(id int primary key,name varchar(30) not null);
Query OK, 0 rows affected (3.07 sec)
mysql> insert into t2 values (1,'Jack');
Query OK, 1 row affected (0.14 sec)
mysql> select * from t2;
+----+------+
| id | name |
+----+------+
| 1 | Jack |
+----+------+
1 row in set (0.14 sec)
直连MySQL 终端,查看 t2
实际建在哪个物理库内:
[root@ic-source conf]$ mysql -uroot -p -e 'table testdb.t2;'
Enter password:
+----+------+
| id | name |
+----+------+
| 1 | Jack |
+----+------+
[root@ic-source conf]$ mysql -uroot -p -e 'table testdb.t2;' -hreplica1
Enter password:
+----+------+
| id | name |
+----+------+
| 1 | Jack |
+----+------+
[root@ic-source conf]$ mysql -uroot -p -e 'table testdb.t2;' -hreplica3
Enter password:
ERROR 1146 (42S02) at line 1: Table 'testdb.t2' doesn't exist
[root@ic-source conf]$
由上可知,在 Mycat 终端中创建的 t2
表实际建立在 source 主机上的 MySQL 物理库,该库为此 Mycat 实例配置的第一个数据源,且角色为 主成员(Master
),然后 MySQL 复制到 replica1 副本上。
3.6.2 场景2:使用原型库,用户自定义数据源用户为类 root
的管理员
修改 Mycat 实例服务器的数据源配置(仅列出修改处)。注意,source
和 replica1
数据源都要修改。
"password":"Root@123", // 修改该用户的密码
"user":"root", // 修改为你所使用的物理库的用户
然后重启 Mycat 服务。
[root@ic-source conf]$ mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...
看日志启动成功了。
3.6.2.1 创建新库、新表
连接 Mycat 实例,在 Mycat 终端中执行以下 SQL,创建一个新库 db2
,在其中创建一个新表 a2
。
mysql> show databases;
+--------------------+
| `Database` |
+--------------------+
| db1 |
| information_schema |
| mysql |
| performance_schema |
| testdb |
+--------------------+
5 rows in set (1.58 sec)
mysql> create database db2;
Query OK, 0 rows affected (0.66 sec)
mysql> use db2;
Database changed
mysql> create table a2(id int primary key,ip_address varchar(15) not null);
Query OK, 0 rows affected (0.40 sec)
mysql> insert into a2 values (1,'192.168.52.3');
Query OK, 1 row affected (0.01 sec)
mysql> select * from a2;
+----+--------------+
| id | ip_address |
+----+--------------+
| 1 | 192.168.52.3 |
+----+--------------+
1 row in set (0.07 sec)
直连 MySQL 物理库,查看到底在哪个库创建的 db1
和 a1
。
[root@ic-source conf]$ mysql -uroot -p -P3307 -e 'show databases;'
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
[root@ic-source conf]$ mysql -uroot -p -P3307 -e 'show databases;' -hreplica1
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
[root@ic-source conf]$ mysql -uroot -p -P3307 -e 'show databases;' -hreplica3
Enter password:
+--------------------+
| Database |
+--------------------+
| db1 |
| db2 |
| information_schema |
| mycat |
| mysql |
| performance_schema |
| sys |
+--------------------+
由上可知,即便数据源中配置的连接用户有 CREATE DATABASE
的权限,却仍然和 3.6.1 节一样将库 db2
和表 a2
创建在原型库中。
笔者通过查看 Mycat2 文档以及自己的了解,知道很多像 Mycat 一样的 MySQL 分库分表中间件对 DDL 、INSET ... SELECT
、MySQL 8 新语法等语句的兼容性做得都不是很好。单就处理 CREATE DATABASE/TABLE
而言,考虑的情况确实有些复杂,Mycat2 目前的支持度很差,所以不建议使用。要想在物理库创建对象,还是得在物理库上直接创建,适合在 Mycat 上使用的 SQL 一般是 DML 和创建逻辑库、表的 SQL 。
3.6.3 场景3:不使用原型库
使用 replica3 上的 Mycat 实例测试。
mysql> show databases;
+--------------------+
| `Database` |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| testdb |
+--------------------+
4 rows in set (0.16 sec)
mysql> use testdb;
Database changed
mysql> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| mycat_t1 |
| t1 |
| t2 |
+------------------+
3 rows in set (0.34 sec)
mysql> create database db3;
Query OK, 0 rows affected (0.58 sec)
mysql> use db3;
Database changed
mysql> create table a3(id int primary key,phone int not null);
ERROR:
java.lang.IllegalArgumentException: can not found prototype
mysql>
创建库 db3
没报错,在其中创建表 a3
却报错 java.lang.IllegalArgumentException: can not found prototype
。
而且启动时同样报了原型库的错误:
还有,在创建 db3
库时虽然终端没有报错,但后台日志产生了一个告警:
以上三点证明:对于当前版本的 Mycat2 原型库时必须的。
3.6.4 场景4:使用第一个 MySQL 数据源作为原型库,用户自定义数据源用户没有建库权限
3.6.4.1 使用 prototype
的集群和数据源配置文件
恢复备份的模板包中 prototype
集群和数据源配置文件。
[root@ic-replica2 conf]# cp ~/install_mycat/mycat/conf/datasources/prototypeDs.datasource.json datasources/
[root@ic-replica2 conf]# cp ~/install_mycat/mycat/conf/clusters/prototype.cluster.json clusters/
修改 datasources/source.datasource.json
中以下部分内容:
"password":"Mycat!123",
"url":"jdbc:mysql://source:3307/testdb?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
"user":"mycat",
重启 Mycat 服务前的 schemas/mycat.schema.json
截图。
重启 Mycat 服务,会覆盖之前的 schemas/mycat.schema.json
。
[root@ic-replica2 conf]# mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...
[root@ic-replica2 conf]# cat schemas/mycat.schema.json
{
"customTables":{},
"globalTables":{},
"normalProcedures":{},
"normalTables":{},
"schemaName":"mycat",
"shardingTables":{},
"views":{}
}[root@ic-replica2 conf]#
使用 Mycat 终端连接到 Mycat 实例服务器,创建 db4
库,并在其中创建 a4
表。
mysql> show databases;
+--------------------+
| `Database` |
+--------------------+
| db3 |
| information_schema |
| mysql |
| performance_schema |
| testdb |
+--------------------+
5 rows in set (0.04 sec)
mysql> create database db4;
Query OK, 0 rows affected (0.60 sec)
mysql> use db4;
Database changed
mysql> create table a4(id int);
Query OK, 0 rows affected (0.26 sec)
mysql> insert into a4 values(11);
ERROR 1142 (HY000): INSERT command denied to user 'mycat'@'replica2' for table 'a4'
mysql> show tables;
+---------------+
| Tables_in_db4 |
+---------------+
| a4 |
+---------------+
1 row in set (0.21 sec)
查看 source 上的物理库,同时也是原型库。
[root@ic-source conf]$ mysql -uroot -p -P3307 -e 'show databases;'
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
创建 db4
库会报警告。
创建表 a4
会报错。
向表中插入数据也会报错。
由上可知,虽然配置了原型库,避免了之前的报错,但因没有全局 CREATE
权限,无法在原型库中创建数据库和表。
创建 mycat
库及表。
mysql> \. create_mycat_metaDB.sql
Query OK, 0 rows affected (0.01 sec)
Database changed
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.22 sec)
Query OK, 0 rows affected (0.22 sec)
Query OK, 0 rows affected (0.15 sec)
Query OK, 0 rows affected (0.15 sec)
Query OK, 0 rows affected (0.16 sec)
Query OK, 0 rows affected (0.16 sec)
Query OK, 0 rows affected (0.13 sec)
Query OK, 0 rows affected (0.13 sec)
Query OK, 0 rows affected (0.12 sec)
Query OK, 0 rows affected (0.12 sec)
Query OK, 0 rows affected (0.16 sec)
Query OK, 0 rows affected (0.16 sec)
Query OK, 0 rows affected (0.13 sec)
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.10 sec)
mysql> show tables;
+-----------------+
| Tables_in_mycat |
+-----------------+
| spm_baseline |
| xa_log |
| spm_plan |
| variable |
| analyze_table |
| config |
| sql_log |
| replica_log |
+-----------------+
8 rows in set (0.07 sec)
mysql> select database();
+------------+
| DATABASE() |
+------------+
| mycat |
+------------+
1 row in set (0.03 sec)
mysql> show databases;
+--------------------+
| `Database` |
+--------------------+
| db3 |
| db4 |
| information_schema |
| mysql |
| performance_schema |
| testdb |
+--------------------+
6 rows in set (0.02 sec)
mysql>
这仍是在 JSON 中“建表”。
3.6.5 场景5:使用第一个 MySQL 数据源作为原型库,用户自定义数据源用户为类 root
的管理员
3.6.5.1 使用 prototype
的集群和数据源配置文件
修改 datasources/source.datasource.json
中以下部分内容:
"password":"Root@123",
"url":"jdbc:mysql://source:3307/testdb?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
"user":"root",
在物理库上查询:
[root@ic-source conf]$ mysql -uroot -p -P3307 -e 'show databases;use mycat;show tables;table spm_baseline;table spm_plan;'
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mycat |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
+-----------------+
| Tables_in_mycat |
+-----------------+
| spm_baseline |
| spm_plan |
+-----------------+
[root@ic-source conf]$ mysql -uroot -p -P3307 -e 'show databases;use db5;show tables;table db5.a5;'
Enter password:
+--------------------+
| Database |
+--------------------+
| db5 |
| information_schema |
| mycat |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
+---------------+
| Tables_in_db5 |
+---------------+
| a5 |
+---------------+
+------+
| id |
+------+
| 5 |
+------+
其他操作与上面类似,只说结果:
- 启动时会自动创建
mycat
库及spm_baseline
、spm_plan
两张空表。 - 可以成功在原型库中建库建表。
- 重新创建
mycat
库,才会在原型库中建立所有表。
3.6.5.2 仅使用 prototype
的数据源配置文件
[root@ic-replica2 conf]# rm -f clusters/prototype.cluster.json
测试结果:
-
没有自动创建
prototype
集群配置文件。 -
Mycat 启动时报错。
-
能建库,不能建表。与官方文档所述不符。
-
原型库中的
mycat
库还存在。 -
重新创建
mycat
库报错。
四、Bugs
因安装、部署、测试过程中发现很多 Bug ,故决定另起一篇文章详述,参见 【Mycat】Mycat2 Bugs (V1.22_2022-10-13) 。
此处仅列出一个重要的 Bug 。
4.1 wrapper.conf
数字类型参数配置有误,多了末尾的单位 M
点击以下链接查看 Wrapper 官网有关该参数的配置信息。如下图所示。
https://wrapper.tanukisoftware.com/doc/english/prop-java-initmemory.html
这是一个低级 Bug 。
wrapper.log
产生警告:
WARN | wrapper | 2023/04/20 22:42:00 | Encountered an invalid numerical value for configuration property wrapper.java.initmemory=256M. Resolving to 256.
WARN | wrapper | 2023/04/20 22:42:00 | Encountered an invalid numerical value for configuration property wrapper.java.maxmemory=2048M. Resolving to 2048.