分库分表-mycat基础

目标:

1、通过实际案例掌握 Mycat 特性与详细配置含义

2、了解 Mycat 监控与日志查看

1. Mycat 概念与配置

1.1 Mycat介绍与核心概念

1.1.1 基本介绍

历史:从阿里 cobar 升级而来,由开源组织维护(兼职)。

定位:运行在应用和数据库之间,可以当做一个 MySQL 服务器使用(不论是在工具 还是在代码或者命令行中都可以直接连接)。实现对 MySQL 数据库的分库分表,也可以通过 JDBC 支持其他的数据库。

Mycat 的关键特性(官网首页)

  1. 可以当做一个 MySQL 数据库来使用
  2. 支持 MySQL 之外的数据库,通过 JDBC 实现
  3. 解决了我们提到的所有问题,多表 join、分布式事务、全局序列号、翻页排序
  4. 支持 ZK 配置,带监控 mycat-web(已经停止维护)
  5. 2.0 已经发布;文档许久没有更新

关键特性:

  • 只是SQL92标准
  • 支持MySQL、Oracle、DB2、SQL Server、PostgreSQL
  • 遵守MySQL原生协议,跨语言,跨平台,跨数据库的通用中间件代理
  • 基于心跳的自动故障切换,支持读写分离,支持MySQL主从模式,以及galera cluster集群
  • 支持Galera for MySQL集群,Percona Cluster或者MariaDB Cluster
  • 基于Nio实现,有效管理线程,解决高并发问题。
  • 支持数据库的多片自动路由与聚合,支持sum/count/max等常用的聚合函数,支持跨库分页。
  • 支持单库内部任意join,支持跨库2表join,甚至基于caltlet的夺标join
  • 支持通过全局表,ER关系的分片策略,实现了搞笑的夺标join查询。
  • 支持多租户方案。
  • 支持分布式事务(弱xa)
  • 支持XA分布式事务(1.6.5)
  • 支持全局id,解决分布式下的主键生成问题
  • 分片规则丰富,插件化开发,易于扩展。
1.1.2 核心概念
概念 含义
主机 物理主机,一台服务器,一个数据库服务,一个 3306 端口
物理数据库 真实的数据库,例如 146、150、151 的 gpcat 数据库
物理表 真实的表,例如 146、150、151 的 gpcat 数据库的 order_info 表
分片 将原来单个数据库的数据切分后分散存储在不同的数据库节点
分片节点 分片以后数据存储的节点
分片键 分片依据的字段,例如 order_info 表以 id 为依据分片,id 就是分片键,通常是主键
分片算法 分片的规则,例如随机、取模、范围、哈希、枚举以及各种组合算法
逻辑表 相对于物理表,是分片表聚合后的结果,对于客户端来说跟真实的表没有区别
逻辑数据库 相对于物理数据库,是数据节点聚合后的结果

一个逻辑表可以映射到多个节点的一张表(分片表),也可以映射到一个节点的表 (非分片表),也可以映射到一个节点的多张表(单库分表)。

下载、解压 Mycat(有 Windows 版本,可以在本地数据库测试)

1
wget http://dl.mycat.org.cn/1.6.7.3/20190927161129/Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz tar -xzvf Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz

Mycat 解压以后有 5 个目录

目录 作用
bin 启动目录
catlet 空目录
conf 配置目录
lib jar 包依赖
logs 日志目录

1.2 Mycat配置详解

主要的配置文件 server.xml、schema.xml、rule.xml 和具体的分片配置文件。

坑非常多,配置错误会导致无法启动,这个时候要看 wrapper 日志!

文件一定要注意备份,不知道什么时候就跑不起来了……

1.2.1 server.xml

包含系统配置信息。

标签:例如字符集、线程数、心跳、分布式事务开关等等。

标签:配置登录用户和权限。

1
2
3
4
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">imall</property>
</user>

mycat 对密码加密:

1
java -cp Mycat-server-1.6.7.3-release.jar io.mycat.util.DecryptUtil 0:root:123456
1.2.2 schema.xml

schema 在 MySQL 里面跟数据库是等价的。

schema.xml 包括逻辑库、表、分片规则、分片节点和数据源,可以定义多个 schema。

这里面有三个主要的标签(table、dataNode、dataHost)

schema 在 MySQL 里面跟数据库是等价的。

表名和库名最好都用小写 定义了逻辑表,以及逻辑表分布的节点和分片规则

1
2
3
4
5
6
7
8
9
<schema name="imall" checkSQLschema="false" sqlMaxLimit="100">
<table name="customer" primaryKey="id" dataNode="122-imall,123-imall,124-imall" rule="auto-sharding-long" />
<table name="order_info" dataNode="122-imall,123-imall,124-imall" rule="mod-long-order" >
<childTable name="order_detail" primaryKey="id" joinKey="order_id" parentKey="order_id"/> </table>
</schema>

<schema name="gupao" checkSQLschema="false" sqlMaxLimit="100">
<table name="student" primaryKey="sid" dataNode="122-gupao,123-gupao,124-gupao" rule="mod-long" />
</schema>

属性:

checkSQLschema:在查询 SQL 中去掉逻辑库名

sqlMaxLimit:自动加上 limit 控制数据的返回

primaryKey:指定该逻辑表对应真实表的主键。MyCat 会缓存主键(通过 primaryKey 属性配置)与 具体 dataNode 的信息。当分片规则(rule)使用非主键进行分片时,那么在使用主键进行查询时,MyCat 就会通过缓存先确定记录在哪个 dataNode 上,然后再在该 dataNode 上执行查询。 如果没有缓存/缓存并没有命中的话,还是会发送语句给所有的 dataNode。

dataNode:数据分片的节点

autoIncrement:自增长(全局序列),true 代表主键使用自增长策略

type:全局表:global。其他表:不配置

:数据节点与物理数据库的对应关系。

1
2
3
4
5
6
7
<dataNode name="122-imall" dataHost="host122" database="imall" /> 
<dataNode name="123-imall" dataHost="host123" database="imall" />
<dataNode name="124-imall" dataHost="host124" database="imall" />

<dataNode name="122-gupao" dataHost="host122" database="gupao" />
<dataNode name="123-gupao" dataHost="host123" database="gupao" />
<dataNode name="124-gupao" dataHost="host124" database="gupao" />

:配置物理主机的信息,readhost 是从属于 writehost 的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dataHost name="host122" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.44.122:3306" user="root" password="123456"></writeHost> </dataHost>

<dataHost name="host123" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.44.123:3306" user="root" password="123456">
<!-- <readHost host="hostS1"></readHost> -->
</writeHost>
</dataHost>

<dataHost name="host124" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.44.124:3306" user="root" password="123456"></writeHost>
</dataHost>

balance:负载的配置,决定 select 语句的负载

  • 0:不开启读写分离机制,所有操作都会发送到当前可用的writeHost上。
  • 1:所有读操作都随机发送到当前的writeHost对用的readHost和备用的writeHost上
  • 2:所有读操作都随机发送到所有的writeHost,readHost上
  • 3:所有读操作都只发送到writeHost的readHost上

writeType:读写分离的配置,决定 update、delete、insert 语句的负载

  • 0:所有写操作都发送到可用的writeHost上(默认第一个,第一个挂了以后发到第二个)
  • 1:所有写操作都随机发送到writeHost上

switchType:主从切换配置

  • -1: 表示不自动切换
  • 1: 默认值,表示自动切换
  • 2:基于MySQL主从同步的状态决定了是否切换,心跳语句为show slave status
  • 3:基于MySQL galera cluster的切换机制(适合集群),心跳语句为show statu like ‘wsrep%’
1.2.3 rule.xml

定义了分片规则和算法
分片规则:

1
2
3
4
5
6
<tableRule name="rang-long-cust"> 
<rule>
<columns>id</columns>
<algorithm>func-rang-long-cust</algorithm>
</rule>
</tableRule>

分片算法:

1
2
<function name="func-rang-long-cust" class="io.mycat.route.function.AutoPartitionByLong"> 				<property name="mapFile">rang-long-cust.txt</property>
</function>

分片配置:rang-long-cust.txt

1
2
3
10001-20000=1 
0-10000=0
20001-100000=2

以上是最重要的三个配置文件。

1.2.4 ZK 配置

除了本地文件之外,Mycat 也支持 ZK 配置(管理配置和全局 ID),用于实现集群扩展。

启用 ZK 配置: mycat/conf/myid.properties

1
2
3
4
5
6
7
8
loadZk=true
zkURL=127.0.0.1:2181
clusterId=010
myid=01001
clusterSize=1
clusterNodes=mycat_gp_01
\#server booster ; booster install on db same server,will reset all minCon to 2 type=server
boosterDataHosts=dataHost1

执行 bin 目录下 init_zk_data.sh,会自动将 zkconf 下的所有配置文件上传到 zk(先 拷贝过去)。

1
2
3
cd /usr/local/soft/mycat/conf
cp *.txt *.xml *.properties zkconf/
cd /usr/local/soft/mycat/bin ./init_zk_data.sh

注意:如果执行 init_zk_data.sh 脚本报错的话,代表未写入成功,此时不要启用 ZK 配置并重启,否则本地文件会被覆盖。

启动时如果 loadzk=true 启动时,会自动从 zk 下载配置文件覆盖本地配置。

在这种情况下如果修改配置,需要先修改 conf 目录的配置,copy 到 zkconf,再执 行上传。

1.2.5 启动停止

检查环境变量配置:

1
2
conf/wrapper.conf 
wrapper.java.command=/usr/local/soft/java/jdk1.8.0_40/bin/java

进入 mycat/bin 目录(注意要先启动物理数据库):

如果直接用解压包,需要对 bin 目录下所有执行文件 chmod777。

  • 启动命令:./mycat start
  • 停止命令:./mycat stop
  • 重启命令:./mycat restart
  • 查看状态:./mycat status
  • 前台运行:./mycat console

应用连接:

mysql -uroot -p123456 -h 192.168.44.122 -P8066 imall

1.3 Mycat分片验证

准备三个数据库

customer:范围分片

student 表:取模分片

order_info order_detail ER 表。

dict 表:全局表。

noshard 表:不分片表。

feedetail 表:库内分表

在三个数据库中建表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
CREATE TABLE `customer` (
`id` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `order_info` (
`order_id` int(11) NOT NULL COMMENT '订单 ID',
`uid` int(11) DEFAULT NULL COMMENT '用户 ID',
`nums` int(11) DEFAULT NULL COMMENT '商品数量',
`state` int(2) DEFAULT NULL COMMENT '订单状态',
`create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `order_detail` (
`order_id` int(11) NOT NULL COMMENT '订单号',
`id` int(11) NOT NULL COMMENT '订单详情',
`goods_id` int(11) DEFAULT NULL COMMENT '货品 ID',
`price` decimal(10,2) DEFAULT NULL COMMENT '价格',
`is_pay` int(2) DEFAULT NULL COMMENT '支付状态',
`is_ship` int(2) DEFAULT NULL COMMENT '是否发货',
`status` int(2) DEFAULT NULL COMMENT '订单详情状态',
PRIMARY KEY (`order_id`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `student` (
`sid` int(8) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`qq` varchar(255) DEFAULT NULL,
PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

非分片表,在第一个节点上创建:

1
2
3
4
CREATE TABLE `noshard` (
`id` int(11) DEFAULT NULL,
`name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
1.3.1 范围分片

imall 库 customer 表:范围分片

1
<table name="customer" primaryKey="id" dataNode="72-imall,74-imall,76-imall" rule="auto-sharding-long" />

在rule.xml中可以查看到,名为auto-sharding-long 的分片规则使用的是rang-long算法,而该算法需要接收一个名为autopartition-long.txt的文件作为参数;

1
2
3
4
5
6
7
8
9
10
<!-- 来源 rule.xml -->
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>

在conf目录创建autopartition-long.txt文件:

1
2
3
4
5
6
# range start-end ,data node index
# K=1000,M=10000.
# 未使用
0-10000=0
10001-20000=1
20001-30000=2

那么当在customer表中插入如下数据。

1
2
3
4
5
6
INSERT INTO `customer` (`id`, `name`) VALUES (6666, '赵先生');  --72-mall
INSERT INTO `customer` (`id`, `name`) VALUES (7777, '钱先生'); --72-mall
INSERT INTO `customer` (`id`, `name`) VALUES (16666, '孙先生'); --74-mall
INSERT INTO `customer` (`id`, `name`) VALUES (17777, '李先生'); --74-mall
INSERT INTO `customer` (`id`, `name`) VALUES (26666, '周先生'); --76-mall
INSERT INTO `customer` (`id`, `name`) VALUES (27777, '吴先生'); --76-mall

问题:超过范围会怎么样?找不到节点。

1.3.2 取模分片表

panda 数据库,student 表:取模分片

1
<table name="student" dataNode="72-panda,74-panda,76-panda" rule="mod-long" />
1
2
3
4
5
6
7
8
9
10
<tableRule name="mod-long">
<rule>
<columns>sid</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes ,这里要根据实际需要进行配置 -->
<property name="count">3</property>
</function>
1
2
3
4
5
6
INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (1, '李大彪', '166669999'); 
INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (4, '菜狗子', '655556666');
INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (2, '等候那場雪', '466669999');
INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (5, '猫老公', '265286999');
INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (3, 'tj-大白', '368828888');
INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (6, '大郎', '516895555');
1.3.3 取模分片(ER表)

我们有些表的数据是存在逻辑的主外键关系的,比如订单表 order_info,存的是汇 总的商品数,商品金额;订单明细表 order_detail,是每个商品的价格,个数等等。或者 叫做从属关系,父表和子表的关系。

他们之间会经常有关联查询的操作,如果父表的数据和子表的数据分别存储在不同的数据库,跨库关联查询也比较麻烦。所以我们能不能把父表和数据和从属于父表的数 据落到一个节点上呢?

比如 order_id=1001 的数据在 node1,它所有的明细数据也放到 node1; order_id=1002 的数据在 node2,它所有的明细数据都放到 node2,这样在关联查询的 时候依然是在一个数据库。

注意,这个也是一种避免跨库关联的重要手段。

1
2
3
<table name="order_info" dataNode="72-imall,74-imall,76-imall" rule="mod-long-order" >
<childTable name="order_detail" primaryKey="id" joinKey="order_id" parentKey="order_id"/>
</table>

去rule.xml

1
2
3
4
5
6
7
8
9
10
<tableRule name="mod-long-order">
<rule>
<columns>order_id</columns> <!--此处需配置-->
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes ,这里要根据实际需要进行配置 -->
<property name="count">3</property>
</function>

imall 库,order_info

1
2
3
INSERT INTO `order_info` (`order_id`, `uid`, `nums`, `state`, `create_time`, `update_time`) VALUES (1, 1000001, 1, 2, '2025-9-23 14:35:37', '2025-9-23 14:35:37');
INSERT INTO `order_info` (`order_id`, `uid`, `nums`, `state`, `create_time`, `update_time`) VALUES (2, 1000002, 1, 2, '2025-9-24 14:35:37', '2025-9-24 14:35:37');
INSERT INTO `order_info` (`order_id`, `uid`, `nums`, `state`, `create_time`, `update_time`) VALUES (3, 1000003, 3, 1, '2025-9-25 11:35:49', '2025-9-25 11:35:49');

imall库,order_detail

1
2
3
4
5
6
INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (3, 20180001, 85114752, 19.99, 1, 1, 1);
INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (1, 20180002, 25411251, 1280.00, 1, 1, 0);
INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (1, 20180003, 62145412, 288.00, 1, 1, 2);
INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (2, 20180004, 21456985, 399.00, 1, 1, 2);
INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (2, 20180005, 21457452, 1680.00, 1, 1, 2);
INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (2, 20180006, 65214789, 9999.00, 1, 1, 3);
1.3.4 全局表

panda 数据库,dict 表:全局表

1
<table name="dict" primaryKey="id" type="global" dataNode="72-panda,74-panda,76-panda" />

注意没有配置rule属性,默认就是写到每个配置了的节点

1
INSERT INTO `dict` (`id`, `param_code`, `param_name`) VALUES (1, '0731', '长沙市');
1.3.5 非分片表

panda数据库,noshard 表

1
<table name="noshard" primaryKey="id" autoIncrement="true" dataNode="72-panda" />

没有配置rule属性,并且只配置一个节点

1
INSERT INTO `noshard` (`id`, `name`) VALUES (1, '这是一条没有分片的数据');
1.3.6 库内分表
1
<table name="fee" primaryKey="id" subTables="fee2025$1-3" dataNode="72-panda" rule="sharding-by-month" />

根据时间路由到不同的表中

注意,逻辑表也要创建,即使没有数据,否则会报错。
需要在 122-gupao 清空所有数据(bug,mycat 无法 truncate)

1
2
3
INSERT INTO `fee` (`id`, `create_time`) VALUES (1, '2025-1-1 14:46:19'); 
INSERT INTO `fee` (`id`, `create_time`) VALUES (2, '2025-2-1 14:46:19');
INSERT INTO `fee` (`id`, `create_time`) VALUES (3, '2025-3-1 14:46:19');

1.4 Mycat全局ID

Mycat 全局序列实现方式主要有 4 种:

  • 本地文件方式
  • 数据库方式
  • 本地时间戳算 法
  • ZK

也可以自定义业务序列。

注意获取的前缀都是:MYCATSEQ_

参考资料

首先全局id实现方式的选择在server.xml中配置

配置sequnceHandlerType 值:
0-文件

1-数据库

2-本地时间戳

3-ZK

1.4.1 文件方式

配置 conf/sequence_conf.properties

1
2
3
4
CUSTOMER.HISIDS= 
CUSTOMER.MINID=10000001
CUSTOMER.MAXID=20000000
CUSTOMER.CURID=10000001

语法:select next value for MYCATSEQ_CUSTOMER;

在插入时使用

1
INSERT INTO `noshard` (`id`, `name`) VALUES (8, next value for MYCATSEQ_CUSTOMER);

优点:本地加载,读取速度较快。

缺点:当 Mycat 重新发布后,配置文件中的 sequence 需要替换(还原)。Mycat 不能做集群部署。

1.4.2 数据库方式

这种方式需要一个表和 3 个存储过程。

配置: sequence_db_conf.properties

1
2
3
4
GLOBAL=72-imall 
COMPANY=72-imall
CUSTOMER=72-imall
ORDERS=72-imall

把这张表创建在第一个节点(72)上,所以是 72-imall

在第一个数据库节点(72)imall 数据库上创建 MYCAT_SEQUENCE 表:

1
2
3
4
5
DROP TABLE IF EXISTS MYCAT_SEQUENCE; CREATE TABLE MYCAT_SEQUENCE (
name VARCHAR(50) NOT NULL,
current_value INT NOT NULL,
increment INT NOT NULL DEFAULT 1, remark varchar(100),
PRIMARY KEY(name)) ENGINE=InnoDB;

注:可以在 schema.xml 配置文件中配置这张表,供外部访问。

1
<table name="mycat_sequence" dataNode="122-imall" autoIncrement="true" primaryKey="id"></table>

72-imall 数据库创建存储过程:获取当前 sequence 的值

1
2
3
4
5
6
7
8
9
10
11
12
DROP FUNCTION IF EXISTS `mycat_seq_currval`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
SET retval="-999999999,null";
SELECT concat(CAST(current_value AS CHAR),",",CAST(increment AS CHAR) ) INTO retval FROM MYCAT_SEQUENCE WHERE name = seq_name;
RETURN retval ;
END
;;
DELIMITER ;

72-imall 数据库创建存储过程:获取下一个 sequence

1
2
3
4
5
6
7
8
9
10
11
DROP FUNCTION IF EXISTS `mycat_seq_nextval`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET latin1
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = current_value + increment WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END
;;
DELIMITER ;

72-mall数据库创建存储过程:设置 sequence

1
2
3
4
5
6
7
8
9
10
11
DROP FUNCTION IF EXISTS `mycat_seq_setval`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50), value INTEGER) RETURNS varchar(64) CHARSET latin1
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = value
WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name); END
;;
DELIMITER ;

72-imall 数据库插入记录

1
INSERT INTO MYCAT_SEQUENCE(name,current_value,increment,remark) VALUES ('GLOBAL', 1, 100,''); INSERT INTO MYCAT_SEQUENCE(name,current_value,increment,remark) VALUES ('ORDERS', 1, 100,' 订单表使用');

测试:

1
select next value for MYCATSEQ_ORDERS
1.4.3 本地时间戳方式

ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加) ,长度为 18 位

配置文件 sequence_time_conf.properties

1
2
3
#sequence depend on TIME
WORKID=01
DATAACENTERID=01

验证:

1
select next value for MYCATSEQ_GLOBAL
1.4.4 ZK 方式

修改 conf/myid.properties

设置 loadZk=true(启动时会从 ZK 加载配置,一定要注意备份配置文件,并且先用 bin/init_zk_data.sh,把配置文件写入到 ZK)

配置文件:sequence_distributed_conf.properties

1
2
3
# 代表使用 zk
INSTANCEID=ZK
# 与 myid.properties 中的 CLUSTERID 设置的值相同 CLUSTERID=010

复制配置文件

1
2
3
4
5
6
cd /usr/local/soft/mycat/conf
cp *.txt *.xml *.properties zkconf/
chown -R zkconf/

cd /usr/local/soft/mycat/bin
./init_zk_data.sh

验证:

1
select next value for MYCATSEQ_GLOBAL
1.4.5 使用

每次获取都要 next value 吗?可以自动自增吗?

在 schema.xml 的 table 标签上配置 autoIncrement=”true”,不需要获取和指定序 列的情况下,就可以使用全局 ID 了。

例如非分片表:

1
INSERT INTO `noshard` (`name`) VALUES ( '自动获取自增值');

2. Mycat 监控与日志查看

2.1 监控

2.1.1 命令行监控

连接到管理端口 9066(注意不是 8066),注意必须要带 IP

1
mysql -uroot -h127.0.0.1 -p123456 -P9066

全部命令:

1
mysql>show @@help;
命令 作用
show @@server; 查看服务器状态,包括占用内存等
show @@database; 查看数据库
show @@datanode; 查看数据节点
show @@datasource; 查看数据源
show @@connection; 该命令用于获取 Mycat 的前端连接状态,即应用与 mycat 的连接
show @@backend; 查看后端连接状态
show @@cache; 查看缓存使用情况
SQLRouteCache:sql 路由缓存。
TableID2DataNodeCache : 缓存表主键与分片对应关系。 ER_SQL2PARENTID : 缓存 ER 分片中子表与父表关系
reload @@config; 重新加载基本配置(热加载),使用这个命令时 mycat 服务不可用
show @@sysparam; 查询 mycat 服务的系统参数
show @@sql.high; 执行频率高的 SQL
show @@sql.slow; 慢 SQL
设置慢 SQL 的命令:reload @@sqlslow=5 ;
show @@syslog limit=50; 查看最近 50 条系统日志

#####

2.1.2 命令行监控 mycatweb 监控

https://github.com/MyCATApache/Mycat-download/tree/master/mycat-web-1.0

Mycat-eye 是 mycat 提供的一个监控工具,它依赖于 ZK。 本地必须要运行一个 ZK,必须先启动 ZK。

参考:https://gper.club/articles/7e7e7f7ff7g59gc3g64

下载 mycat-web

1
2
cd /usr/local/soft
wget http://dl.mycat.io/mycat-web-1.0/Mycat-web-1.0-SNAPSHOT-20170102153329-linux.tar.gz tar -xzvf Mycat-web-1.0-SNAPSHOT-20170102153329-linux.tar.gz

启动 mycat-web

1
2
cd mycat-web nohup 
./start.sh &

停止:kill start.jar 相关的进程

访问端口 8082

http://10.0.12.72:8082/mycat/

mycat server.xml 配置

1
2
<!-- 1 为开启实时统计、0 为关闭 --> 
<property name="useSqlStat">1</property>

重启 mycat 服务生效

2.2 日志

log4j 的 level 配置要改成 debug

2.2.1 wrapper.log 日志

wrapper 日志:mycat 启动,停止,添加为服务等都会记录到此日志文件,如果系 统环境配置错误或缺少配置时,导致 Mycat 无法启动,可以通过查看 wrapper.log 定位 具体错误原因。

2.2.2 mycat.log 日志

mycat.log 为 mycat 主要日志文件,记录了启动时分配的相关 buffer 信息,数据源 连接信息,连接池,动态类加载信息等等。

在 conf/log4j2.xml 文件中进行相关配置,如保留个数,大小,字符集,日志文件大 小等。