Mycat配置文件解析与分表存储测试

前文已经部署了mycat并且启动,此时登陆到mycat的8066端口,可以看到有一个database,这个database里有几个tables,如图:
akb48

这些库和表根本不是我数据库里的啊,那它是从哪里来的呢?前文说了,mycat有一个虚拟库(逻辑库),它会把逻辑库上的操作映射到真实库里,现在8066这个端口就是虚拟库,里面有几个逻辑表,但是这些表其实不是真正存在的。而mycat主要有三个配置文件,分别是schema.xmlrule.xmlserver.xmlserver.xml就是配置虚拟数据库的账号密码的地方,很简单没什么好说的,rule.xml是分片规则的配置文件,没事别动它。而schema.xml里是主要配置逻辑库和逻辑表的配置文件。

配置文件解析

去除掉注释的schema.xml文件是这样的:
akb48

可以看到整个配置文件分为三大块,第一块是schema,第二块是dataNode,第三块是dataHost,其中第三块是跟读写分离相关的,所以这里就说前两个部分,先说第二块dataNode

1
2
3
<dataNode name="dn1" dataHost="mycatTEST" database="db1" />
<dataNode name="dn2" dataHost="mycatTEST" database="db2" />
<dataNode name="dn3" dataHost="mycatTEST" database="db3" />

这一段表示该数据库有哪些数据节点,以及这些数据节点实际对应的数据服务器(这个节点跟dataHost的块有关)和数据库名,这里配置了3个节点dn1,dn2,dn3,都是在mycatTEST服务器上,也就是说我们需要在mycatTEST那个服务器,也就是下面writeHost的机器里先创建三个database,分别叫db1,db2,db3。我们在逻辑库上的操作都会分别下发到这三个db里,具体的下发算法在上面schema里有写。

再看第一块schema的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<table name="hotnews" primaryKey="ID" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="mod-long" />
<table name="employee" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" />
<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile">
<childTable name="orders" primaryKey="ID" joinKey="customer_id" parentKey="id">
<childTable name="order_items" joinKey="order_id" parentKey="id" />
</childTable>
<childTable name="customer_addr" primaryKey="ID" joinKey="customer_id" parentKey="id" />
</table>
</schema>

这一段主要描述了虚拟数据库的schema即TESTDB中有哪些表,以及每个表分布在哪些数据节点上、分布的方法采用哪种算法。其他的选项含义如下:

  1. checkSQLschema:当该值设置为true时,如果我们执行语句select * from TESTDB.travelrecord;则MyCat会把语句修改为select * from travelrecord;。即把表示schema的字符去掉,避免发送到后端数据库执行时报(ERROR 1146 (42S02): Table ‘testdb.travelrecord’ doesn’t exist)。这里最好是采用默认的false;
  2. sqlMaxLimit:当该值设置为某个数值时。每条执行的SQL语句,如果没有加上limit语句,MyCat也会自动的加上所对应的值。例如设置值为100,执行select fromTESTDB.travelrecord;的效果为和执行select from TESTDB.travelrecord limit 100;相同。需要注意的是,如果运行的schema为非拆分库的,那么该属性不会生效。需要手动添加limit语句;
  3. primaryKey:该逻辑表对应真实表的主键,例如:分片的规则是使用非主键进行分片的,那么在使用主键查询的时候,就会发送查询语句到所有配置的DN上,如果使用该属性配置真实表的主键;
  4. type:该属性定义了逻辑表的类型,目前逻辑表只有“全局表(global)”和”普通表”两种类型;
  5. autoIncrement:mysql对非自增长主键,使用last_insert_id()是不会返回结果的,只会返回0。所以,只有定义了自增长主键的表才可以用last_insert_id()返回主键值。使用autoIncrement=“true”指定这个表有使用自增长主键,这样mycat才会不抛出分片键找不到的异常。这里最好是采用默认的false;
  6. rule:该属性用于指定逻辑表要使用的规则名字,规则名字在rule.xml中定义,必须与tableRule标签中name属性属性值一一对应;
  7. joinKey:插入子表的时候会使用这个列的值查找父表存储的数据节点;
  8. parentKey: 属性指定的值一般为与父表建立关联关系的列名。程序首先获取joinkey的值,再通过parentKey属性指定的列名产生查询语句,通过执行该语句得到父表存储在哪个分片上。从而确定子表存储的位置;

举个例子方便理解,<table name="employee" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" />,意思就是“这个employee的表,主键是ID,只在dn1和dn2以sharding-by-intfile的规则存储”。

举个例子

按照上面修改了配置文件之后,重启一波mycat,登陆mycat的9066管理端口,使用show @@datanode;show @@datasource;可以查看到数据库源和datanode已经成功建立了,如图:
akb48

手动在阿里云的RDS的读库上创建db1、db2、db3这三个databases,如图:
akb48

由于阿里云读写同步,所以只读实例上也有了db1、db2、db3这三个databases。

此时再开一个窗口,登陆mycat的8066端口,看到里面有了TESTDB这个逻辑库以及里面的逻辑表,但是这些逻辑表实际是不存在的,如图:
akb48

这时创建employee表,插入数据:

1
2
3
4
5
create table employee (id int not null primary key,name varchar(100),sharding_id int not null);
insert into employee(id,name,sharding_id) values(1,'leader us',10000);
insert into employee(id,name,sharding_id) values(2, 'me',10010);
insert into employee(id,name,sharding_id) values(3, 'mycat',10000);
insert into employee(id,name,sharding_id) values(4, 'mydog',10010);

检查一下数据已经被成功插入,并且如果使用select * from查看的话,会从两个datanode上去查,而且都自动加上了limit 100的字样,这一点符合我们在schema.xml里配置的<table name="employee" primaryKey="ID" dataNode="dn1,dn2"/>sqlMaxLimit="100",如图:
akb48

再来到阿里云只读RDS数据库里,检查一下刚刚在虚拟数据库里操作的动作是否被正确映射过来。如图:
akb48
akb48

可见writeType=“0”已经成功,这就是分表存储。

参考资料

https://blog.csdn.net/wangshuang1631/article/details/62898469
https://sylvanassun.github.io/2016/07/09/2016-07-09-MyCat/
http://codingo.xyz/index.php/2018/02/27/mycat1/

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------