mycat的schema.xml 配置文件详情

夙愿已清 提交于 2020-01-06 20:17:19

一、概念与图示

schema.xml 是 Mycat对应的物理数据库和数据库表的配置。

schema.xml 配置的几个术语与其关系图示:

在这里插入图片描述

二、schema 标签:逻辑数据库

schema 标签用于定义 MyCat 实例中的逻辑库。

MyCat 可以有多个逻辑库,每个逻辑库都有自己的相关配置,可以使用 schema 标签来划分这些不同的逻辑库。

ps:如果不配置 schema 标签,所有的表配置,会属于同一个默认的逻辑库。

<schema  name="USERDB" checkSQLschema="false"  sqlMaxLimit="100" dataNode="dn1" >
</schema>
    
<schema name="USERDB"  checkSQLschema="false"  sqlMaxLimit="100"  dataNode="dn3,dn4">
       <table name="eg_user" dataNode="dn5,dn6" rule="auto-sharing-long"></table>
</schema>

2.1、属性列表

属性 说明 备注
name 配置逻辑库的名字。通过mycat访问看到的数据库名。
逻辑库名和后端物理库名可能不同,也可能对应后端多个物理库。同一个实例下的物理数据库名称不能重复。同一个schema 的逻辑库名也不能重复
dataNode 配置该逻辑库默认的分片。

没有通过 table 标签配置的表,就会走到此处配置的默认的分片上。这里注意没有配置在 table 标签的表,用工具查看是无法显示的,但是可以正常使用。
如果该表有配置 table 标签,当满足条件时,则表会在 table 标签指定的 dataNode上建表。
如果没有配置 dataNode 属性,也没有配置在table标签的表,是无法使用的。
注意,dual 表在mycat中,也被视为一个表。
dataNode 值与dataNode 标签的name属性值一致。
checkSQLschema 检查发给Mycat的SQL中是否含有库名。boolean类型。
mysql中可以通过dbName.tableName的方式来访问指定库下的指定表。而mycat中却不推荐这样使用,因为mycat对应的逻辑库可能是在不同物理服务器上的。mycat中dbName.tableName访问的方式可能会出错,
当checkSQLschema=ture时,Mycat来检查SQL中是否有dbName.tableName,如果有,则会删除dbName,
默认false,即不检查。
sqlMaxLimit 限制每次查询数据所返回的最大行数。
(server.xml中的limit是整个mycat系统的默认值,这里则是当前逻辑库的默认值,默认先看schema.xml的限制数)
如果table标签的表,needAddLimit 属性为false,则该表的sql禁止自动加上limit 。

2.2、其他注意事项:

2.2.1、dataNode属性

注意,dual表在mycat中,也被视为一个表。

查询:select sysdate() from dual LIMIT 0, 1000 

错误代码: 1064

can't find table define in schema DUAL schema:USERDB

另外,通过mycat建表,而该表并没有提前配置table标签,则mycat会找到默认的dataNode,并把表建在默认的dataNode上。如果没有配置默认dataNode,则mycat会报错。

查询:create table test(id varchar(10))

错误代码: 1064

op table not in schema----TEST

而如果该表有配置table标签,则表会分别在table标签指定的dataNode上建表。

2.2.2、checkSQLschema 属性

数据库前缀相关设置。boolean类型。

当前端执行 select *from USERDB.tf_user; 时(表名前指定了mycat 逻辑数据库名 ),两种取值:

  • true:mycat会把语句转换为 select * from tf_user;

  • false:会报错,如下:

    查询:SELECT * FROM USERDB.tf_user LIMIT 0, 1000
    
    错误代码: 1064
    
    find no Route:SELECT * FROM USERDB.tf_user LIMIT 0, 1000
    

2.2.3、sqlMaxLimit 属性

相当于sql的结果集中,加上【 limit N 】。如果sql本身已经指定limit,则以sql指定的为准。

mysql> explain select * from tf_user;
+-----------+---------------------------------+
| DATA_NODE | SQL |
+-----------+---------------------------------+
| dn1 | SELECT * FROM tf_user LIMIT 100 |
| dn2 | SELECT * FROM tf_user LIMIT 100 |
+-----------+---------------------------------+

2 rows in set (0.00 sec) 

mysql> explain select * from tf_user limit 50;
+-----------+--------------------------------+
| DATA_NODE | SQL |
+-----------+--------------------------------+
| dn1 | SELECT * FROM tf_user LIMIT 50 |
| dn2 | SELECT * FROM tf_user LIMIT 50 |
+-----------+--------------------------------+
2 rows in set (0.00 sec)

注意: 如果table标签的表,needAddLimit 属性配置为 false ,则该表的 sql 禁止自动加上 limit 。

2.3、table 标签——逻辑表

table标签为schema标签的子标签。

<schema><table> 的关系?

Mycat请求过来的表,首先会匹配</table> 标签中的表名,如果匹配成功,而按成 </table> 的分片规则进行,否则,按则</schema> 标签的默认分片配置进行。

table 标签用于定义Mycat的逻辑表,以及逻辑表的分片规则。如:

<schema name="USERDB"  checkSQLschema="false"  sqlMaxLimit="100"  dataNode="dn1">
       <table name="eg_user" dataNode="dn2" rule="auto-sharing-long"></table>
</schema>

<dataNode name="dn1" dataHost="host1" database="mysqlDB" />
<dataNode name="dn2" dataHost="host2" database="mysqlDB" />
属性 说明 备注
name 物理数据库中的表名。
逻辑表名 和 相应的物理表名 要一致
在同一个 schema 库中,表名必须唯一,不能重复。
dataNode 定义了表数据存储的实际物理节点名称。
该值要与dataNode 标签的name属性值一致。
多个用英文逗号间隔,如:dataNode=“dn1,dn2”。顺序一旦定义就不能修改,否则会出现混乱。
rule 指定逻辑表要使用的规则名字,
规则名字在 rule.xml 中定义,必须与 tableRule 标签中 name 属性值一一对应。
ruleRequired 指定表是否绑定分片规则。
如果配置为 true,但没有配置具体 rule 的话 ,程序会报错
primaryKey 物理表的真实主键。
MyCat会缓存主键(通过primaryKey属性配置)与具体 dataNode 的信息。当分片规则使用非主键进行分片时,那么在使用主键进行查询时,MyCat就会通过缓存先确定记录在哪个 dataNode上,然后再在该 dataNode 上执行查询。
type 定义了逻辑表的类型,
目前逻辑表只有 “全局表” 和 ”普通表” 两种类型。对应的配置:
全局表:global。在所有的数据节点中,均有相同的数据。数据冗余到每个数据节点中。
普通表:不指定该值为 global,则为普通表。
常见,如字典表
autoIncrement 是否自增。
subTables 分表配置,
mycat1.6之后开始支持,但dataNode 在分表条件下只能配置一个 Join。
needAddLimit 指定表是否需要自动的在每个语句后面加上limit限制。默认为true。
由于使用了分库分表,数据量有时候会特别庞大,这时候执行查询语句,所以mycat自动为我们加上了limit 100。
与schema标签的 sqlMaxLimit 配合使用。

2、dataNode属性

定义这个逻辑表所属的 dataNode,多个时用英文逗号间隔,如:dataNode=“dn1,dn2”

如果dataNode过多,可以使用如下的方法减少配置:

<schema name="USERDB" dataNode="dn1" checkSQLschema="false" sqlMaxLimit="100">
    
	<table name="travelrecord" dataNode="multipleDn$0-99,multipleDn2$100-199" rule="auto-shardinglong" ></table>
    
</schema>

<dataNode name="multipleDn"  dataHost="localhost1" database="db$0-99" ></dataNode>

<dataNode name="multipleDn2" dataHost="localhost2" database="db$0-99" ></dataNode>

db$0-99 为 mysql 的数据库,即从 db0 至 db99 的数据库(100个)。

3、primaryKey 属性

如果缓存并没有命中的话,还是会发送语句给所有的dataNode。

mysql> explain select * from employee where id=101;
+-----------+-------------------------------------+
| DATA_NODE | SQL |
+-----------+-------------------------------------+
| dn1 | select * from employee where id=101 |
| dn2 | select * from employee where id=101 |
+-----------+-------------------------------------+
2 rows in set (0.00 sec) 

mysql> select * from employee where id=101;
+-----+------+-------------+
| id | name | sharding_id |
+-----+------+-------------+
| 101 | A | 10000 |
+-----+------+-------------+
1 row in set (0.01 sec) 

mysql> explain select * from employee where id=101;
+-----------+-------------------------------------+
| DATA_NODE | SQL |
+-----------+-------------------------------------+
| dn1 | select * from employee where id=101 |
+-----------+-------------------------------------+
1 row in set (0.00 sec)

关于Mycat的主键缓存,其机制是:

当根据主键查询的SQL语句第一次执行时,Mycat会对其结果进行分析,确定该主键在哪个分片上,并进行该主键到分片ID的缓存。通过连接MyCAT的9066管理端口,执行 show @@cache,可以显示当前缓存的使用情况。可在sql执行前后的2个时间点执行show @@cache ,通过结果信息中的 LAST_PUT 和 LAST_ACCESS 列,判断相应表的缓存是否有被更新过。

2.3.2、childTable 标签

childTable 标签用于定义 E-R 分片的子表。通过标签上的属性与父表进行关联。

<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>
属性 说明 备注
name 子表的表名
joinKey 子表的那个字段,和主表关联
parentKey 主表的关联主键
primaryKey 主表自身的主键
needAddLimit 是否加 limit 限制

三、dataNode 标签:分片信息,也就是分库相关配置

<schema name="USERDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1" >    
	<table name="tf_user" primaryKey="USER_ID" autoIncrement="true" dataNode="dn1,dn2" rule="hash-int" />    
</schema>

<dataNode name="dn1" dataHost="host1" database="mysqlDB" />
<dataNode name="dn2" dataHost="host2" database="mysqlDB2" />
属性 说明
name 数据节点的名字,自定义,必须唯一。 与table标签的dataNode属性值对应。
dataHost 定义该分片所在物理主机的名字。
与 dataHost 标签中的name属性值对应上 。
database 定义该分片属于哪个具体数据库实例上的具体库。(即对应mysql中实际的数据库)

四、dataHost 标签:物理数据库,真正存储数据的数据库

定义后端的数据库主机

<schema name="USERDB" checkSQLschema="false" sqlMaxLimit="100"  dataNode="dn1" >    
	<table name="tf_user" primaryKey="USER_ID" autoIncrement="true" dataNode="dn1,dn2" rule="hash-int" />    
</schema>

<dataNode name="dn1" dataHost="host1" database="mysqlDB" />
<dataNode name="dn2" dataHost="host2" database="mysqlDB2" />

<dataHost name="host1" maxCon="1000" minCon="10" balance="0" writeType="0"
          dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    
</dataHost>  
属性 说明 备注
name dataHost的名字。 与dataNode标签的dataHost属性值保持一致。
maxCon 指定每个读写实例连接池的最大连接。
标签内嵌套的writeHost、 readHost 标签都会使用这个属性的值来实例化出连接池的最大连接数。
minCon 指定每个读写实例连接池的最小连接,初始化连接池的大小。
balance 读请求的负载均衡。

(1)balance=“0”,不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。(默认
(2)balance=“1”,全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与 select 语句的负载均衡。(双主双从
(3)balance=“2”,所有读操作都随机的在 writeHost、 readhost 上分发。(学习,测试时使用
(4)balance=“3”,所有读请求随机的分发到 wiriterHost 对应的 readhost 执行,writerHost 不负担读压力。(单主单从,单读单写
注意:
balance=3 只在 V1.4 及其以后版本有,V1.3 没有。
writeType 写请求的负载均衡。

(1)writeType=“0”,所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties 。
(2)writeType=“1”,所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。
(3)writeType=“2”,不执行写操作。
dbType 指定后端连接的数据库类型。
目前支持二进制的 mysql 协议,还有其他使用 JDBC 连接的数据库。例如:mongodb、 oracle、 spark 等。
dbDriver 指定连接后端数据库使用的 Driver,目前可选的值有 native 和 JDBC。
使用native 的话,因为这个值执行的是二进制的 mysql 协议,所以可以使用 mysql 和 maridb。
其他类型的数据库则需要使用 JDBC 驱动来支持。
switchType 写数据库如何进行高可用切换。
-1 :表示不自动切换 。
1 :默认值,自动切换 。
2 :基于 MySQL 主从同步的状态决定是否切换。心跳语句为 show slave status
3 :基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1)。心跳语句为 show status like 'wsrep%'
tempReadHostAvailable 如果配置了这个属性 writeHost 下面的 readHost 仍旧可用,默认 0 可配置(0、 1)。

4.1、heartbeat标签

这个标签内指明用于和后端数据库进行心跳检查的语句。

例如:MYSQL 可以使用 select user() ,Oracle 可以使用 select 1 from dual 等。

4.2、writeHost 标签、 readHost 标签

writeHost、readHost 标签都指定后端数据库的相关配置,用于实例化后端连接池。唯一不同的是,writeHost 指定写实例、readHost 指定读实例。

readHost必须镶嵌在writeHost内的 (一个writeHost里可以定义多个readHost标签)。

在一个 dataHost 内可以定义多个 writeHost 和 readHost。但是,如果 writeHost 指定的后端数据库宕机,那么这个 writeHost 绑定的所有 readHost 都将不可用。
另一方面,由于这个 writeHost 宕机,系统会自动的检测到,并切换到 备用的 writeHost 上去。这两个标签的属性相同,这里就一起介绍。

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"  writeType="0"   dbType="mysql"
          dbDriver="native" switchType="1"  slaveThreshold="100">
   
    <heartbeat>select user()</heartbeat>

    <writeHost host="hostM1" url="localhost:3306" user="AAAA"   password="AAAA">		
        <readHost host="hostS2" url="localhost:3307" user="BBBB" password="BBBB" />
    </writeHost>
    
    <writeHost host="hostM2" url="localhost:3316" user="CCCC" password="CCCC"/>
    <writeHost host="hostS1" url="localhost:3317" user="DDDD" password="DDDD" />    
    
</dataHost>
属性 说明 备注
host mysql实例的名称。
一般习惯于 writeHost 我们使用 *Mn( 如:hostM1、myM2…),readHost 我们用 *Sn(如:hostS1、myS2…)。
url 物理数据库的连接地址。 如果是使用 native 的 dbDriver,则一般为 ip:port ,也可以是域名。
如果使用 JDBC 或其他的 dbDriver,则需要特殊指定。当使用 JDBC 时则可以这么写:jdbc:mysql://localhost:3306/
user 数据库的用户名
password 数据库的密码
weight 权重。配置在 readhost 中作为读节点的权重(1.4 以后)
usingDecrypt 是否对密码加密 。
默认是 0,否 ,不加密 。
配置-1,同时使用加密程序对密码加密。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!