> 文章列表 > 【Mycat2】介绍、安装、部署、配置、测试与 Bugs

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

文章目录

  • 一、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 开源协议的开源数据库中间件

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

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 先决条件

  1. JDK 8
  2. unzip 实用程序
    yum install -y unzip

1.5.2 Mycat2 安装包(以下二选一)

建议从 http://dl.mycat.org.cn/2.0/ 处下载,因为 github 的连接因 DNS 污染导致不稳定而无法访问。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

Mycat2Wrapper 为壳,因而目录结构与其保持一致,仅提供核心 jar 包,不提供安装包。

  • 笔者制作一个安装包。里面包含最新版的 Wrapper 与上文中的 Mycat-1.22.jar 一起,只保留了 Linux x64 平台的 lib 库,删除了其他平台的 lib.dll 库。
  • 使用 Mycat2 官网下载的安装包
    1. 首先是 Mycat2 最重要的核心文件 .jar 包。

      【Mycat2】介绍、安装、部署、配置、测试与 Bugs

    2. 其次是配置文件的样例模板文件。

      【Mycat2】介绍、安装、部署、配置、测试与 Bugs

    3. (可选)最新的 Wrapper (点击即可跳转)。

      笔者选用的是 Linux x86 64bit 版本的 .tar.gz 包。
      【Mycat2】介绍、安装、部署、配置、测试与 Bugs

1.6 Mycat2权威指南

  • Mycat2权威指南(语雀文档) (官方文档,写得很烂,文档编撰人员语言能力不行,初学者会看得云里雾里)
  • https://www.w3cschool.cn/mycat2/mycat2-vgis3kri.html (推荐,比官方文档写的好)

1.7 原型库

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

上图右侧的 MySQL 在 Mycat2 的配置里面叫做 原型库(Prototype) ,专门用来响应兼容性 SQL 和系统表 SQL 。

什么是兼容性 SQL?

兼容性 SQL 是指客户端或者所在应用框架运行所需必须的 SQL ,但是用户一般接触不到,它们会影响客户端的启动和运行。而 Mycat2 处理这种 SQL 时尽可能不影响用户使用。

什么是 Prototype 服务器?

Prototype 服务器 是指分库分表中间件中用于处理 MySQL 的兼容性 SQL 和系统表 SQL 的服务器。这个配置项可以指向一个服务器,也可以是一个集群,Mycat 依靠它处理非 SELECTINSERTUPDATEDELETE 语句。当这个服务器是与第一个存储节点是同一个服务器/集群的时候,我们一般把它称之为 0 号节点

原型库实现程度(V1.21)

  1. 如果集群中配置了名为 prototype 的集群,则使用它作为 prototype
  2. 如果数据源中存在 prototypeDs 的数据源,但是没有名为 prototype 的集群,则自动创建主数据源为 prototypeDsprototype 集群。
  3. 如果集群和数据源中没有 prototype 也没有 prototypeDs ,则选择数据源中第一个数据源类型为 mysql 类型的数据源作为 prototype 集群的主数据源。
  4. 上述都不适用的情况下,使用第一个数据源作为 prototype 的集群的主数据源。
  5. 如果没有数据源,则不处理。

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】介绍、安装、部署、配置、测试与 Bugs

在 Mycat2 的结果:

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

在 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 包安装的,一直没更新。
【Mycat2】介绍、安装、部署、配置、测试与 Bugs

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 35 2021 mycat
-rw-r--r--. 1 root root   3916 35 2021 mycat.bat
-rw-r--r--. 1 root root 281540 35 2021 wrapper-aix-ppc-32
-rw-r--r--. 1 root root 319397 35 2021 wrapper-aix-ppc-64
-rw-r--r--. 1 root root 253808 35 2021 wrapper-hpux-parisc-64
-rw-r--r--. 1 root root 140198 35 2021 wrapper-linux-ppc-64
-rw-r--r--. 1 root root  99401 35 2021 wrapper-linux-x86-32
-rw-r--r--. 1 root root 111027 35 2021 wrapper-linux-x86-64
-rw-r--r--. 1 root root 114052 35 2021 wrapper-macosx-ppc-32
-rw-r--r--. 1 root root 233604 35 2021 wrapper-macosx-universal-32
-rw-r--r--. 1 root root 253432 35 2021 wrapper-macosx-universal-64
-rw-r--r--. 1 root root 112536 35 2021 wrapper-solaris-sparc-32
-rw-r--r--. 1 root root 148512 35 2021 wrapper-solaris-sparc-64
-rw-r--r--. 1 root root 110992 35 2021 wrapper-solaris-x86-32
-rw-r--r--. 1 root root 204800 35 2021 wrapper-windows-x86-32.exe
-rw-r--r--. 1 root root 220672 35 2021 wrapper-windows-x86-64.execonf:
总用量 32
drwxr-xr-x. 2 root root   36 628 2021 clusters
drwxr-xr-x. 2 root root   41 628 2021 datasources
-rw-r--r--. 1 root root 3338 35 2021 dbseq.sql
-rw-r--r--. 1 root root  316 112 2021 logback.xml
-rw-r--r--. 1 root root    0 35 2021 mycat.lock
drwxr-xr-x. 2 root root   69 628 2021 schemas
drwxr-xr-x. 2 root root    6 628 2021 sequences
-rw-r--r--. 1 root root  776 1228 2021 server.json
-rw-r--r--. 1 root root 1643 35 2021 simplelogger.properties
drwxr-xr-x. 2 root root  233 628 2021 sql
drwxr-xr-x. 2 root root    6 628 2021 sqlcaches
-rw-r--r--. 1 root root   49 35 2021 state.json
drwxr-xr-x. 2 root root   28 628 2021 users
-rw-r--r--. 1 root root  211 35 2021 version.txt
-rw-r--r--. 1 root root 4165 113 2022 wrapper.conflib:
总用量 560
-rw-r--r--. 1 root root 22948 34 2021 libwrapper-aix-ppc-32.a
-rw-r--r--. 1 root root 24499 34 2021 libwrapper-aix-ppc-64.a
-rw-r--r--. 1 root root 74520 34 2021 libwrapper-hpux-parisc-64.sl
-rw-r--r--. 1 root root 23839 34 2021 libwrapper-linux-ppc-64.so
-rw-r--r--. 1 root root 11887 34 2021 libwrapper-linux-x86-32.so
-rw-r--r--. 1 root root 15248 34 2021 libwrapper-linux-x86-64.so
-rw-r--r--. 1 root root 15400 34 2021 libwrapper-macosx-ppc-32.jnilib
-rw-r--r--. 1 root root 35332 34 2021 libwrapper-macosx-universal-32.jnilib
-rw-r--r--. 1 root root 34968 34 2021 libwrapper-macosx-universal-64.jnilib
-rw-r--r--. 1 root root 13760 34 2021 libwrapper-solaris-sparc-32.so
-rw-r--r--. 1 root root 21032 34 2021 libwrapper-solaris-sparc-64.so
-rw-r--r--. 1 root root 12572 34 2021 libwrapper-solaris-x86-32.so
-rw-r--r--. 1 root root 83820 35 2021 wrapper.jar
-rw-r--r--. 1 root root 81920 34 2021 wrapper-windows-x86-32.dll
-rw-r--r--. 1 root root 76800 34 2021 wrapper-windows-x86-64.dlllogs:
总用量 0

可见,这个模板包属于跨平台的,封装了很多平台的文件,这里我们仅需要 Linux x86_64 的,所以删除多余的文件。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

[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 35 2021 mycat
-rwxr-xr--. 1 root root 111027 35 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 34 2021 libwrapper-linux-x86-64.so
-rw-r--r--. 1 root root 83820 35 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 420 04:11 libwrapper.so
-rw-r--r--. 1 root root 152950673 420 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.53Copyright (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/wrapperlib/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 35 2021 mycat
lrwxrwxrwx. 1 root root    16 420 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.53Copyright (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",
}

注意

  1. 该文件的原始配置文件结尾的换行符有问题,请使用诸如 vi 的编辑器重新编辑,或者直接复制笔者的配置。
    【Mycat2】介绍、安装、部署、配置、测试与 Bugs
  2. ip 属性不支持 DNS 名称,只支持 IP 地址或网段。
    【Mycat2】介绍、安装、部署、配置、测试与 Bugs
    【Mycat2】介绍、安装、部署、配置、测试与 Bugs
    【Mycat2】介绍、安装、部署、配置、测试与 Bugs

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.jsonclusters/clusters/prototype.cluster.jsonconf/schemas/mysql.schema.jsonconf/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 实例。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

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_schemamysql 方案的 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 建表语句并未报错。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

查询 Mycat 逻辑库。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

查询原型库。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

3.5.2 未配置原型库

否则,如果你删除了默认的 prototype 相关的配置文件,仅保留了你自定义的配置文件,则 即便不执行以上 SQL 脚本也会自动创建 mycat 数据库,该库为空库,且不生成 JSON 配置文件(schemas/mycat.schema.json

以我在 replica3 主机上创建的另一个 Mycat 实例为例。该 Mycat 实例,展现了上述只保留自定义配置的情况。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

没有 schemas/mycat.schema.json 文件。
【Mycat2】介绍、安装、部署、配置、测试与 Bugs

SHOW DATABASES; 也查看不到 mycat 库,却可以 USE ,但为空库。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

如果执行以上 SQL 脚本时,会报错,库和表虽创建成功了,却只保存元数据(表结构)于 JSON 配置文件(schemas/mycat.schema.json)中,而不存储在物理库中。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

只要存在 JSON 配置文件,在 Mycat 终端中就可以查看到这些库和表。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs
【Mycat2】介绍、安装、部署、配置、测试与 Bugs

而并没有像 Mycat 官方文档 所说的那样, 在第一个数据源类型为 mysql 的数据源作为 prototype 集群的主数据源,在其上创建 mycat 元数据库。

连接物理库可证实这点。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

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 changedmysql> 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 物理库,查看到底在哪个库创建的 db1a1

[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 检查权限后在原型库创建了 db1a1

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 实例服务器的数据源配置(仅列出修改处)。注意,sourcereplica1 数据源都要修改

        "password":"Root@123",  // 修改该用户的密码"user":"root",  // 修改为你所使用的物理库的用户

然后重启 Mycat 服务。

[root@ic-source conf]$ mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...

看日志启动成功了。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

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 物理库,查看到底在哪个库创建的 db1a1

[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

而且启动时同样报了原型库的错误:
【Mycat2】介绍、安装、部署、配置、测试与 Bugs

还有,在创建 db3 库时虽然终端没有报错,但后台日志产生了一个告警:
【Mycat2】介绍、安装、部署、配置、测试与 Bugs

以上三点证明:对于当前版本的 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 截图。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

重启 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 库会报警告。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

创建表 a4 会报错。
【Mycat2】介绍、安装、部署、配置、测试与 Bugs

向表中插入数据也会报错。

【Mycat2】介绍、安装、部署、配置、测试与 Bugs

由上可知,虽然配置了原型库,避免了之前的报错,但因没有全局 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_baselinespm_plan 两张空表。
  • 可以成功在原型库中建库建表。
  • 重新创建 mycat 库,才会在原型库中建立所有表。

3.6.5.2 仅使用 prototype 的数据源配置文件

[root@ic-replica2 conf]# rm -f clusters/prototype.cluster.json

测试结果:

  • 没有自动创建 prototype 集群配置文件。

  • Mycat 启动时报错。
    【Mycat2】介绍、安装、部署、配置、测试与 Bugs

  • 能建库,不能建表。与官方文档所述不符
    【Mycat2】介绍、安装、部署、配置、测试与 Bugs

  • 原型库中的 mycat 库还存在。

  • 重新创建 mycat 库报错。
    【Mycat2】介绍、安装、部署、配置、测试与 Bugs

四、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
【Mycat2】介绍、安装、部署、配置、测试与 Bugs

这是一个低级 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.