作者:窗外流星

Mycat2安装配置

一、资源列表

1.官网:http://www.mycat.org.cn/
2.资源地址:http://dl.mycat.org.cn/2.0/
3.安装程序包:http://dl.mycat.org.cn/2.0/install-template/mycat2-install-template-1.21.zip
4.Jar包:http://dl.mycat.org.cn/2.0/1.21-release/mycat2-1.21-release-jar-with-dependencies.jar
5.mycat2注释命令文档
https://www.yuque.com/go/doc/45478923
https://www.yuque.com/go/doc/30128408
https://www.yuque.com/go/doc/43941475
https://www.yuque.com/go/doc/44606465
https://www.yuque.com/go/doc/31952506
https://www.yuque.com/go/doc/30128409
https://www.yuque.com/go/doc/44549434
https://www.yuque.com/go/doc/30128424
https://www.yuque.com/go/doc/47352479

二、概述

项目使用微服务架构搭建的SAAS平台,每个租户一个单独的数据库,需要使用Mycat把不同租户的数据存储到自己的数据库中。
本文档只记录安装过程,详细说明请到官网查看。
本次测试用mycat搭建分发到两个mycat中,端口分别是3306和3307.
安装前要在服务器上安装jdk1.8
如果是mysql 8, 需要用root用户连接并执行下面语句开启XA事务
GRANT XA_RECOVER_ADMIN ON . TO ‘root’@’%’;

三、文件下载

把所有文件都下载到/data/tools目录
cd /data/tools
wget http://dl.mycat.org.cn/2.0/install-template/mycat2-install-template-1.21.zipwget http://dl.mycat.org.cn/2.0/1.21-release/mycat2-1.21-release-jar-with-dependencies.jar

四、安装Mycat

程序安装目录为/data,解压并移到到/data目录
cd /data/tools
unzip mycat2-install-template-1.21.zip
mv mycat ../
把bin目录的文件加执行权限
cd /data/mycat/bin
chmod +x *
把所需的jar复制到mycat/lib目录
cd /data/mycat/lib/
cp /data/tools/mycat2-1.21-release-jar-with-dependencies.jar ./

五、修改数据源

注意只修改红色字体内容
cd /data/mycat/conf/datasources
把mycat带的数据源配置正确
vim prototypeDs.datasource.json

{
“dbType”:”mysql”,
“idleTimeout”:60000,
“initSqls”:[],
“initSqlsGetConnection”:true,
“instanceType”:”READ_WRITE”,
“maxCon”:1000,
“maxConnectTimeout”:3000,
“maxRetryCount”:5,
“minCon”:1,
“name”:”prototypeDs”,
“password”:”123456”,
“type”:”JDBC”,
“url”:”jdbc:mysql://localhost:3306/test?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8”,
“user”:”root”,
“weight”:0
}

:wq

新增第一个数据源,名称为:113-3306
vim 113-3306.datasource.json

{
“dbType”:”mysql”,
“idleTimeout”:60000,
“initSqls”:[],
“initSqlsGetConnection”:true,
“instanceType”:”READ_WRITE”,
“maxCon”:1000,
“maxConnectTimeout”:3000,
“maxRetryCount”:5,
“minCon”:1,
“name”:”113-3306”,
“password”:”123456”,
“type”:”JDBC”,
“url”:”jdbc:mysql://localhost:3306/test?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8”,
“user”:”root”,
“weight”:0
}

:wq

新增第二个数据源,名称为:113-3307
vim 113-3307.datasource.json

{
“dbType”:”mysql”,
“idleTimeout”:60000,
“initSqls”:[],
“initSqlsGetConnection”:true,
“instanceType”:”READ_WRITE”,
“maxCon”:1000,
“maxConnectTimeout”:3000,
“maxRetryCount”:5,
“minCon”:1,
“name”:”113-3306”,
“password”:”123456”,
“type”:”JDBC”,
“url”:”jdbc:mysql://localhost:3307/test?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8”,
“user”:”root”,
“weight”:0
}

:wq

六、修改mycat登录密码为:zxcvbn

注意只修改红色字体内容
cd /data/mycat/conf/users

{
“dialect”:”mysql”,
“ip”:null,
“password”:”zxcvbn”,
“transactionType”:”xa”,
“username”:”root”
}

七、修改服务器server配置

注意只修改红色字体内容
cd /data/mycat/conf/
vim server.json

{
“loadBalance”:{
“defaultLoadBalance”:”BalanceRandom”,
“loadBalances”:[]
},
“mode”:”local”,
“properties”:{},
“server”:{
“bufferPool”:{

},
“idleTimer”:{
“initialDelay”:3,
“period”:60000,
“timeUnit”:”SECONDS”
},
“ip”:”0.0.0.0”,
“mycatId”:1,
“port”:8066,
“serverVersion”:”8.0.27-mycat-2.0”,
“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”
}
}
}

:wq

八、启动mycat

cd /data/mycat/bin/
./mycat start

九、查看mycat日志

cd /data/mycat/logs
tail -f wrapper.log

十、创建schema

用Navicat或者SQLyog连接mycat
注意mycat端口是8066,其他的连接和mysql类似。
官方推荐SQLyong, navicat不能查看mycat数据库。
做下面操作前请先用Navicat、SQLyog连接mycat

1. 创建数据库

在Navicat执行此SQL
CREATE DATABASE 1cloud DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ;

2. 创建表

这里采用枚举分片,targetNames 可以是数据源或者mysql集群,这里使用数据源
把tenant_code=”KDY”插入113-3306数据源
把tenant_code=”CY”插入113-3307数据源
如果tenant_code不等于”KDY”和”CY”,则插入第1个数据源,具体由defaultNode决定。
这里把枚举值都写到createTable中,实际生产推荐用 mapFile的方式,不需要每个表都修改。只要改partition-hash-int.txt。参考文档:
https://www.yuque.com/books/share/6606b3b6-3365-4187-94c4-e51116894695/518d1c41faf01cca8f4544f0c6ee5d6e
在SQLyog执行此SQL

/+ mycat:createTable{
“schemaName”:”1cloud”,
“shardingTable”:{
“createTableSQL”:”CREATE TABLE t_student (
id bigint NOT NULL AUTO_INCREMENT COMMENT ‘id’,
name varchar(150) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ‘姓名’,
age int DEFAULT NULL COMMENT ‘年级’,
tenant_code varchar(20) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ‘租户’,
PRIMARY KEY (id),
KEY student_01 (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT=’学生表’; “,
“function”:{
“clazz”:”io.mycat.router.mycat1xfunction.PartitionByFileMap”,
“properties”:{
“defaultNode”:”0”,
“type”:”String”,
“columnName”:”tenant_code”
},
“ranges”:{
“KDY”:”0”,
“CY”:”1”
}
},
“partition”:{
“schemaNames”:”1cloud”,
“tableNames”:”t_student”,
“targetNames”:”113-3306,113-3307”
}
},
“tableName”:”t_student”
}
/;

3. 把mycat创建的表同步到mysql

在SQLyog执行下面语句,
注意一这个只能是新创建的表才会同步,如果修改表需要手工到mysql修改,然后再来修改mycat表。建议不要用这个命令创建mysql的表和数据库
注意二在mycat通过CREATE DATABASE 创建的数据库到mysql中字符集有可能变乱,需要人工在mysql中修改。
/+ mycat:repairPhysicalTable{} /;

4. 查看mycat的表会保存到哪些mysql中

在SQLyog执行下面语句,注意正常来说每个数据源都会有一条数据
/+ mycat:showTopology{
“schemaName”:”1cloud”,
“tableName”:”t_student”
}
/;

执行结果

5. 插入数据,查看结果

在SQLyog执行下面语句
insert into t_student ( name, age, tenant_code)
values ( ‘测试3’, 22, ‘CY’);
insert into t_student ( name, age, tenant_code)
values ( ‘测试4’, 22, ‘KDY’);

select * from t_student ;

查看结果,在mycat能查看到所有数据,到每个3306和3307查看分片后否只能看到自己的数据。
注意 发现ID是随机生成,不是递增,需要配置序列号sequence 或者把第二步的AUTO_INCREMENT 去掉使用mysql的id自动递增规则

十一、创建序列号sequence

这里使用113-3306记录数据库序列号

1.在mysql执行dbseq.sql
在/data/mycat/conf目录找到dbseq.sql, 用navicat连接3306mysql执行dbseq.sql

DROP TABLE IF EXISTS MYCAT_SEQUENCE;
CREATE TABLE MYCAT_SEQUENCE ( name VARCHAR(64) NOT NULL, current_value BIGINT(20) NOT NULL, increment INT NOT NULL DEFAULT 1, PRIMARY KEY (name) ) ENGINE=InnoDB;

— ——————————————
— Function structure for mycat_seq_currval
— ——————————————
DROP FUNCTION IF EXISTS mycat_seq_currval;
DELIMITER ;;
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(64)) RETURNS varchar(64) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
SET retval=”-1,0”;
SELECT concat(CAST(current_value AS CHAR),”,”,CAST(increment AS CHAR) ) INTO retval FROM MYCAT_SEQUENCE WHERE name = seq_name;
RETURN retval ;
END
;;
DELIMITER ;

— ——————————————
— Function structure for mycat_seq_nextval
— ——————————————
DROP FUNCTION IF EXISTS mycat_seq_nextval;
DELIMITER ;;
CREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(64)) RETURNS varchar(64) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
DECLARE val BIGINT;
DECLARE inc INT;
DECLARE seq_lock INT;
set val = -1;
set inc = 0;
SET seq_lock = -1;
SELECT GET_LOCK(seq_name, 15) into seq_lock;
if seq_lock = 1 then
SELECT current_value + increment, increment INTO val, inc FROM MYCAT_SEQUENCE WHERE name = seq_name for update;
if val != -1 then
UPDATE MYCAT_SEQUENCE SET current_value = val WHERE name = seq_name;
end if;
SELECT RELEASE_LOCK(seq_name) into seq_lock;
end if;
SELECT concat(CAST((val - inc + 1) as CHAR),”,”,CAST(inc as CHAR)) INTO retval;
RETURN retval;
END
;;
DELIMITER ;

— ——————————————
— Function structure for mycat_seq_setvals
— ——————————————
DROP FUNCTION IF EXISTS mycat_seq_nextvals;
DELIMITER ;;
CREATE FUNCTION mycat_seq_nextvals(seq_name VARCHAR(64), count INT) RETURNS VARCHAR(64) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
DECLARE val BIGINT;
DECLARE seq_lock INT;
SET val = -1;
SET seq_lock = -1;
SELECT GET_LOCK(seq_name, 15) into seq_lock;
if seq_lock = 1 then
SELECT current_value + count INTO val FROM MYCAT_SEQUENCE WHERE name = seq_name for update;
IF val != -1 THEN
UPDATE MYCAT_SEQUENCE SET current_value = val WHERE name = seq_name;
END IF;
SELECT RELEASE_LOCK(seq_name) into seq_lock;
end if;
SELECT CONCAT(CAST((val - count + 1) as CHAR), “,”, CAST(val as CHAR)) INTO retval;
RETURN retval;
END
;;
DELIMITER ;

— ——————————————
— Function structure for mycat_seq_setval
— ——————————————
DROP FUNCTION IF EXISTS mycat_seq_setval;
DELIMITER ;;
CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(64), value BIGINT) RETURNS varchar(64) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
DECLARE inc INT;
SET inc = 0;
SELECT increment INTO inc FROM MYCAT_SEQUENCE WHERE name = seq_name;
UPDATE MYCAT_SEQUENCE SET current_value = value WHERE name = seq_name;
SELECT concat(CAST(value as CHAR),”,”,CAST(inc as CHAR)) INTO retval;
RETURN retval;
END
;;
DELIMITER ;

INSERT INTO MYCAT_SEQUENCE VALUES (‘GLOBAL’, 1, 1);

2. 在mycat创建序号

注意命名规则{数据库名}_{表名}

A.用navicat连接mycat执行,如果执行完成后在/data/mycat/conf/sequences/没有创建文件则,需要手工创建。
/+ mycat:setSequence
{“name”:”1cloud_t_student”,”clazz”:”io.mycat.plug.sequence.SequenceMySQLGenerator”,”targetName”:”113-3306”,”schemaName”:”1cloud”}
/;

B. 手工创建序列号
cd /data/mycat/conf/sequences/
vim 1cloud_t_student.sequence.json

{
“clazz”:”io.mycat.plug.sequence.SequenceMySQLGenerator”,
“name”:”1cloud_t_student”,
“targetName”: “113-3306”,
“schemaName”:”1cloud”
}

:wq

3. 在113-3306mysql数据库插入序列号名称

用工具连接3306数据库,执行语句
INSERT INTO 1cloud.MYCAT_SEQUENCE(name, current_value, increment) VALUES (‘1cloud_t_student’, 1, 1);

4. 加载配置文件,可以不重启mycat

用工具连接mycat执行命令
/+mycat:loadConfigFromFile{} /

5. 加载配置文件,可以不重启mycat

清空3306和3307端口的数据,在navicat执行下面语句
insert into t_student ( name, age, tenant_code)
values ( ‘测试3’, 22, ‘CY’);
insert into t_student ( name, age, tenant_code)
values ( ‘测试4’, 22, ‘KDY’);

select * from t_student ;
查看结果

到此配置完成

十二、其他

/+mycat:syncConfigFromDbToFile{} / 把原型的配置写入该mycat的本地配置,但不加载到运行时
/+mycat:syncConfigFromFileToDb{} /把本地配置写入该mycat指向的原型库,但不加载到运行时
/+mycat:loadConfigFromFile{} /把本地配置加载到运行时
/+mycat:checkConfigConsistency{} /检查原型库配置与本地配置是否一致
可以连接mycat用 explain 查看 sql执行计划