基于MyCat实现的Mysql数据库的分库分表、全局表、父子表等

1、前言

  在上一篇《基于MyCat实现的Mysql数据库的读写分离》中,我们学习了数据切分的知识、mycat的基本概念,最后又尝试了基于mycat实现的Mysql数据库的读写分离。这一节,我们详细学习mycat的用法,并实现数据库的分库分表。

2、Mycat的基本用法

2.1、MyCat的安装

  MyCat的安装很简单,就是下载、解压、配置即可,上一篇已经详细记录了下载地址、解压命令,这里不再重复。

2.2、mycat目录

  安装目录如下:
在这里插入图片描述

  • bin 目录存放了脚本命令,包括 window 版本和 linux 版本
  • conf 目录下存放配置文件,server.xml 是 Mycat 服务器参数调整和用户授权的配置文件,schema.xml 是逻辑库定义和表以及分片定义的配置文件,rule.xml 是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在这个目录下,配置文件修改,需要重启 Mycat 或者通过 9066 端口 reload。
  • lib 目录下主要存放 mycat 依赖的一些 jar 文件。
  • logs目录存放日志,其中warapper.log记录启动日志,mycat.log记录操作日志。
2.3、mycat的常用命令
  1. 启动命令start
    在bin目录下,执行./mycat start 命令,可以进行后台启动

  2. 启动命令console
    在bin目录下,执行./mycat console 命令,可以进行启动,会占用命令行窗口,可以直接打印启动日志

  3. 停止、重启命令

./mycat stop 
#或
./mycat restart 
  1. 查看状态
./mycat status

在这里插入图片描述

  1. 导入导出 dump命令
    类似mysql的dump命令。
2.4、命令行管理Mycat

  我们可以通过mysql命令登录Mycat的管理端口(默认9066),Mycat的管理端口是在server.xml文件中进行配置的。

  首先,通过Navicat连接(端口9066)。
在这里插入图片描述
  然后,通过命令列介面,执行show @@help;命令,查看支持的全部命令,如下:

mysql> show @@help;
+---------------------------------+----------------------------+
| STATEMENT                         | DESCRIPTION                                |
+---------------------------+--------------------------------+
| show @@time.current                                          | Report current timestamp                   |
| show @@time.startup                                          | Report startup timestamp                   |
| show @@version                                               | Report Mycat Server version                |
| show @@server                                                | Report server status                       |
| show @@threadpool                                            | Report threadPool status                   |
| show @@database                                              | Report databases                           |
| show @@datanode                                              | Report dataNodes                           |
| show @@datanode where schema = ?                             | Report dataNodes                           |
| show @@datasource                                            | Report dataSources                         |
| show @@datasource where dataNode = ?                         | Report dataSources                         |
| show @@datasource.synstatus                                  | Report datasource data synchronous         |
| show @@datasource.syndetail where name=?                     | Report datasource data synchronous detail  |
| show @@datasource.cluster                                    | Report datasource galary cluster variables |
| show @@processor                                             | Report processor status                    |
| show @@command                                               | Report commands status                     |
| show @@connection                                            | Report connection status                   |
| show @@cache                                                 | Report system cache usage                  |
| show @@backend                                               | Report backend connection status           |
| show @@session                                               | Report front session details               |
| show @@connection.sql                                        | Report connection sql                      |
| show @@sql.execute                                           | Report execute status                      |
| show @@sql.detail where id = ?                               | Report execute detail status               |
| show @@sql                                                   | Report SQL list                            |
| show @@sql.high                                              | Report Hight Frequency SQL                 |
| show @@sql.slow                                              | Report slow SQL                            |
| show @@sql.resultset                                         | Report BIG RESULTSET SQL                   |
| show @@sql.sum                                               | Report  User RW Stat                       |
| show @@sql.sum.user                                          | Report  User RW Stat                       |
| show @@sql.sum.table                                         | Report  Table RW Stat                      |
| show @@parser                                                | Report parser status                       |
| show @@router                                                | Report router status                       |
| show @@heartbeat                                             | Report heartbeat status                    |
| show @@heartbeat.detail where name=?                         | Report heartbeat current detail            |
| show @@slow where schema = ?                                 | Report schema slow sql                     |
| show @@slow where datanode = ?                               | Report datanode slow sql                   |
| show @@sysparam                                              | Report system param                        |
| show @@syslog limit=?                                        | Report system mycat.log                    |
| show @@white                                                 | show mycat white host                      |
| show @@white.set=?,?                                         | set mycat white host,[ip,user]             |
| show @@directmemory=1 or 2                                   | show mycat direct memory usage             |
| show @@check_global -SCHEMA= ? -TABLE=? -retry=? -interval=? | check mycat global table consistency       |
| switch @@datasource name:index                               | Switch dataSource                          |
| kill @@connection id1,id2,...                                | Kill the specified connections             |
| stop @@heartbeat name:time                                   | Pause dataNode heartbeat                   |
| reload @@config                                              | Reload basic config from file              |
| reload @@config_all                                          | Reload all config from file                |
| reload @@route                                               | Reload route config from file              |
| reload @@user                                                | Reload user config from file               |
| reload @@sqlslow=                                            | Set Slow SQL Time(ms)                      |
| reload @@user_stat                                           | Reset show @@sql  @@sql.sum @@sql.slow     |
| rollback @@config                                            | Rollback all config from memory            |
| rollback @@route                                             | Rollback route config from memory          |
| rollback @@user                                              | Rollback user config from memory           |
| reload @@sqlstat=open                                        | Open real-time sql stat analyzer           |
| reload @@sqlstat=close                                       | Close real-time sql stat analyzer          |
| offline                                                      | Change MyCat status to OFF                 |
| online                                                       | Change MyCat status to ON                  |
| clear @@slow where schema = ?                                | Clear slow sql by schema                   |
| clear @@slow where datanode = ?                              | Clear slow sql by datanode                 |
+--------------------------------------------------------------+--------------------------------------------+
59 rows in set

  上面有59个命令,我们下面选几个常用的命令介绍一下:

1、重新加载配置文件

  修改mycat配置文件后,除了重启服务让配置文件生效外,在生成环境更多的使用reload命令重新加载命令。

#主要加载基本的配置文件,需要注意执行该命令时,Mycat是不可使用的。
mysql> reload @@config;
Query OK, 1 row affected (2.33 sec)
Reload config success
#该命令可以重新加载全部的配置文件
mysql> reload @@config_all

2、查看逻辑库

  可以使用如下命令查看Mycat的逻辑库。

mysql> show @@database;
+----------+
| DATABASE |
+----------+
| db_test  |
+----------+
1 row in set

3、查看数据节点

  查看逻辑库对应的物理数据库所在的数据节点,则可以使用如下命令进行查看。

mysql> show @@datanode;
+------+--------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| NAME | DATHOST      | INDEX | TYPE  | ACTIVE | IDLE | SIZE | EXECUTE | TOTAL_TIME | MAX_TIME | MAX_SQL | RECOVERY_TIME |
+------+--------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
| dn1  | db_host/test |     0 | mysql |      0 |   10 | 1000 |   10206 |          0 |        0 |       0 |            -1 |
+------+--------------+-------+-------+--------+------+------+---------+------------+----------+---------+---------------+
1 row in set

4、查看心跳信息

mysql> show @@heartbeat;
+--------+-------+-------------+------+---------+-------+--------+---------+--------------+---------------------+-------+
| NAME   | TYPE  | HOST        | PORT | RS_CODE | RETRY | STATUS | TIMEOUT | EXECUTE_TIME | LAST_ACTIVE_TIME    | STOP  |
+--------+-------+-------------+------+---------+-------+--------+---------+--------------+---------------------+-------+
| hostM1 | mysql | 192.168.1.8 | 3306 |       1 |     0 | idle   |   30000 | 0,1,1        | 2021-01-23 22:12:36 | false |
| hostS2 | mysql | 192.168.1.9 | 3306 |       1 |     0 | idle   |   30000 | 5,3,2        | 2021-01-23 22:12:36 | false |
+--------+-------+-------------+------+---------+-------+--------+---------+--------------+---------------------+-------+
2 rows in set

5、查看连接信息

mysql> show @@connection;
+------------+----+--------------+------+------------+------+--------+---------+--------+---------+---------------+-------------+------------+---------+------------+
| PROCESSOR  | ID | HOST         | PORT | LOCAL_PORT | USER | SCHEMA | CHARSET | NET_IN | NET_OUT | ALIVE_TIME(S) | RECV_BUFFER | SEND_QUEUE | txlevel | autocommit |
+------------+----+--------------+------+------------+------+--------+---------+--------+---------+---------------+-------------+------------+---------+------------+
| Processor1 |  6 | 192.168.1.87 | 9066 |      49961 | root | NULL   | utf8:33 |    175 |    1334 |          1018 |        4096 |          0 |         |            |
| Processor2 |  7 | 192.168.1.87 | 9066 |      49972 | root | NULL   | utf8:33 |    185 |    4354 |          1011 |        4096 |          0 |         |            |
+------------+----+--------------+------+------------+------+--------+---------+--------+---------+---------------+-------------+------------+---------+------------+
2 rows in set

6、SQL统计命令

show @@sql:显示在mycat中执行过的sql语句。
show @@sql.slow:显示慢SQL语句。
show @@sql.sum: 显示sql语句的整体执行情况,读写比例等。

更多命令,请参考 《管理mycat命令详解》

2.5、Mycat的常用配置

  Mycat的配置文件,主要是./conf目录下,如下所示:
在这里插入图片描述
  mycat的配置文件主要分为以下几类,我们分别进行学习。

2.5.1、server.xml配置文件

  server.xml 几乎保存了所有 mycat 需要的系统配置信息。其在代码内直接的映射类为 SystemConfig 类。上一篇博客中,我们已经使用到了该配置文件,我们下面详细介绍其中涉及到的标签。

1、user标签

这个标签主要用于定义登录 mycat 的用户和权限。

其中,user 标签的name 属性来指定用户名;修改 password 内的文本来修改密码;修改 readOnly 为 true 或 false 来限制用户是否只是可读的;修改 schemas 内的文本来控制用户可放问的 schema;修改 schemas 内的文本来控制用户可访问的 schema,同时访问多个 schema 的话使用 , 隔开。

privileges 子节点。对用户的 schema 及 下级的 table 进行精细化的 DML 权限控制,privileges 节点中的 check 属性是用于标识是否开启 DML 权限检查, 默认 false 标识不检查,当然 privileges 节点不配置,等同 check=false,由于 Mycat 一个用户的 schemas 属性可配置多个 schema ,所以 privileges 的下级节点 schema 节点同样可配置多个,对多库多表进行细粒度的 DML 权限控制。
在这里插入图片描述
2、system 标签

这个标签内嵌套的所有 property 标签都与系统配置有关。具体的每个属性的定义,请参考《官方文档》

3、firewall 防火墙配置。

上篇中使用的配置,如下所示。可以配置允许登录的IP白名单或者配置黑名单SQL拦截。

详细配置请参考《官方文档- Mycat 防火墙配置》

<firewall>
  <whitehost>
      <host host="1*7.0.0.*" user="root"/>
	  <host host="*" user="root" />
   </whitehost>
      <blacklist check="false">
      </blacklist>
</firewall>
2.5.2、schema.xml配置文件

  schema.xml 是 MyCat 中重要的配置文件之一,管理着 MyCat 的逻辑库、表、分片规则、DataNode 以 及 DataSource等信息。在前面我们做读写分离配置的时候,也使用了该文件。

1、schema 标签

schema 标签用于定义 MyCat 实例中的逻辑库,MyCat 可以有多个逻辑库,每个逻辑库都有自己的相关配置。如果不配置 schema 标签,所有的表配置,会属于同一个默认的逻辑库。

2、dataNode 标签

该属性用于绑定逻辑库到某个具体的 database 上,1.3 版本如果配置了 dataNode,则不可以配置分片表,1.4 可以配置默认分片,只需要配置需要分片的表即可。

3、table 标签

Table 标签定义了 MyCat 中的逻辑表,所有需要拆分的表都需要在这个标签中定义。

4、childTable 标签

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

5、dataNode 标签

dataNode 标签定义了 MyCat 中的数据节点,也就是我们通常说所的数据分片。一个 dataNode 标签就是一个独立的数据分片。

6、dataHost 标签

作为 Schema.xml 中最后的一个标签,该标签在 mycat 逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。

7、heartbeat 标签

这个标签内指明用于和后端数据库进行心跳检查的语句。例如,MYSQL 可以使用 select user()。

8、writeHost 标签、readHost 标签

这两个标签都指定后端数据库的相关配置给 mycat,用于实例化后端连接池。唯一不同的是,writeHost 指定写实例、readHost 指定读实例,组着这些读写实例来满足系统的要求。在一个 dataHost 内可以定义多个 writeHost 和 readHost。但是,如果 writeHost 指定的后端数据库宕机,那么这个 writeHost 绑定的所有 readHost 都将不可用。另一方面,由于这个 writeHost 宕机系统会自动的检测到,并切换到备用的 writeHost 上去。

2.5.3、rule.xml配置文件

  rule.xml 里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法,或者对表使用相同的算法但具体的参数不同。这个文件里面主要有 tableRule 和 function 这两个标签。

1、tableRule 标签

这个标签定义表规则。定义的表规则,在 schema.xml中。后面我们演示分库分表时,会用到数据拆分的规则。

2、function 标签

路由算法的配置。

以上关于mycat配置文件的标签内容,基本上都是来至于官方文档,每个标签都还有很多的属性可以使用,具体的可以查看《官方文档》

3、基于mycat实现分库分表

3.1、实现目标

  准备192.168.1.8/9两个数据库服务(两个服务不存在主从关系)。然后通过mycat实现以下目标:

1、分库分表,创建三个表user、role和order。其中,user只在192.168.1.8上,role只在192.168.1.9上,order在192.168.1.8/9上。

2、全局表,创建一个sys_dictionary表。在192.168.1.8/9两个服务上都是全量存储。

3、子表,创建order_item表。让它的拆分规则和order一样。

3.2、分库分表

首先,准备数据库表,如下所示,其中order按照取模的分片规则进行。

192.168.1.8上创建的数据库表:
在这里插入图片描述
192.168.1.9上创建的数据库表:
在这里插入图片描述
然后,修改server.xml配置文件,这里还是沿用读写分离的配置如下:

<firewall>
  <whitehost>
      <host host="1*7.0.0.*" user="root"/>
	  <host host="*" user="root" />
   </whitehost>
      <blacklist check="false">
      </blacklist>
</firewall>
<!--配置了写操作用户,其中name为用户名,password为用户密码,schemas为逻辑库名称-->
<user name="root" defaultAccount="true">
	<property name="password">123456</property>
	<property name="schemas">db_test</property>
	<property name="defaultSchema">db_test</property>
</user>

再,修改schema.xml配置文件。其中,配置了两个dataHost 节点,分别对应192.168.1.8/9两个数据库服务器,然后,配置了两个dataNode 节点,对应两个数据库服务器中的db_8、db_9两个数据库,最后定义了schema 节点,其中有三个table 子节点:user节点对应192.168.1.8数据库中的user表,role节点对应192.168.1.9数据库中的role表,而order节点对应192.168.1.8/9两个数据库中的order表,然后通过mod-long进行数据切分。具体配置如下:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

	<schema name="db_test" checkSQLschema="true" sqlMaxLimit="100">
		<table name="user" primaryKey="id"  dataNode="dn8" />
		<table name="role" primaryKey="id"  dataNode="dn9" />
		<table name="order" primaryKey="id" dataNode="dn8,dn9" rule="mod-long" />
	</schema>

	<dataNode name="dn8" dataHost="db_8" database="db_8" />
	<dataNode name="dn9" dataHost="db_9" database="db_9" />

	<dataHost name="db_8" maxCon="1000" minCon="10" balance="0"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<!-- can have multi write hosts -->
		<writeHost host="hostM1" url="192.168.1.8:3306" user="root"
				   password="123456">
		</writeHost>
	</dataHost>

 <dataHost name="db_9" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM1" url="192.168.1.9:3306" user="root"
                                   password="123456">
                </writeHost>
        </dataHost>
</mycat:schema>

  然后再,修改rule.xml配置,我们这里选择了取模的数据拆分方法,需要在rule.xml文件修改mod-long的数据拆分配置信息:这里主要修改了count的值,因为我们只有两个数据库服务,所以这里修改成了2(默认是3)

<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
	<tableRule name="mod-long">
		<rule>
			<columns>id</columns>
			<algorithm>mod-long</algorithm>
		</rule>
	</tableRule>
	<!--省略了其他的规则-->
	<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
		<!-- 这里主要修改了count的值,因为我们只有两个数据库服务,所以这里修改成了2(默认是3) -->
		<property name="count">2</property>
	</function>
</mycat:rule>

最后,完成上述配置后,重新mycat或者通过管理命令介面执行reload命令,刷新配置信息。然后,使用Navicat通过8066端口连接mycat。
在这里插入图片描述
在order中添加数据,数据会根据id的奇偶分别放到192.168.1.8/9两个数据库中,而role插入数据会进到192.168.1.9,user插入数据会到192.168.1.8。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3、全局表

  一个真实的业务系统中,往往存在大量的类似字典表的表格,它们与业务表之间可能有关系,这种关系,可以理解为“标签”,这些表具有:1、变动少,2、数据量少,3、关联业务表多等。

  在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,鉴于此,MyCAT 定义了一种特殊的表,称之为“全局表”。具有如下特性:

  • 全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性
  • 全局表的查询操作,只从一个节点获取
  • 全局表可以跟任何一个表进行 JOIN 操作

  全局表配置比较简单,不用写 Rule 规则,在配置table标签的时候,设置type=global即可,如下所示:

<table name="sys_dictionary" primaryKey="id" type="global" dataNode="dn8,dn9" />

  我们分别在192.168.1.8/9上创建sys_dictionary表,然后在schema.xml配置文件中添加上面的配置,重启mycat。我们通过mycat添加一条记录,该记录会分别添加到192.168.1.8/9两个数据库的sys_dictionary表。这里不再贴出测试结果了。

3.4、父子表

  父子表主要是为了避免不必要的跨表查询。比如在商城系统中,订单表包括订单的主题信息,订单编号,订单收货地址等,而订单明细表包括了购买商品的Id,商品名称,金额等,这里订单明细表就是子表,而订单表就是父表,这两个表的数据根据订单ID进行关联,需要避免同一个订单的订单表记录和订单明细表记录存在跨表情况。

  mycat提供了childTable标签解决该问题。我们基于前面的配置,修改order对应的节点,并添加childTable 子节点,如下所示:

<table name="order" primaryKey="id" dataNode="dn8,dn9" rule="mod-long">
   <childTable name="order_item" joinKey="order_id" parentKey="id"/>
</table>

  其中,

  • name 子表的表名
  • joinKey 插入子表的时候会使用这个列的值查找父表存储的数据节点
  • parentKey 属性指定的值一般为与父表建立关联关系的列名。程序首先获取 joinkey 的值,再通过 parentKey 属性指定的列名产生查询语句,通过执行该语句得到父表存储在哪个分片上。从而确定子表存储的位置。
  • primaryKey 该逻辑表对应真实表的主键,例如:分片的规则是使用非主键进行分片的,那么在使用主键查询的时候,就会发送查询语句到所有配置的 DN 上,如果使用该属性配置真实表的主键。难么 MyCat 会缓存主键与具体 DN 的信息,那么再次使用非主键进行查询的时候就不会进行广播式的查询,就会直接发送语句给具体的 DN,但是尽管
    配置该属性,如果缓存并没有命中的话,还是会发送语句给具体的 DN,来获得数据。
  • needAddLimit 指定表是否需要自动的在每个语句后面加上 limit 限制。由于使用了分库分表,数据量有时会特别巨大。这时候执行查询语句,如果恰巧又忘记了加上数量限制的话。那么查询所有的数据出来,也够等上一小会儿的。所以,mycat 就自动的为我们加上 LIMIT 100。当然,如果语句中有 limit,就不会在次添加了。这个属性默认为 true,你也可以设置成 false`禁用掉默认行为。

  完成上述配置后,重新启动mycat,然后根据前面已经添加的order记录,分别添加对应的order_item数据,这个时候数据会根据order的数据拆分进行拆分order_item的数据。

4、总结

  这里我们学习了mycat的一些操作命令、分库分表、全局表、父子表等内容,但是这些都是我们在单节点上进行的尝试,在生产环境,为了保证数据库的高可用性,我们一般都会进行集群部署,如果实现呢?我们下一篇将学习mycat的高可用环境搭建。

猜你喜欢

转载自blog.csdn.net/hou_ge/article/details/113005597