一.Mycat 分表
配置
导入 mycat 源码: 如下
mycat 有三个重要的配置文件
1.server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="charset">utf8</property>
<property name="nonePasswordLogin">0</property> <!-- 0 是须要明码登陆、1 则不须要明码登陆 . 默认 0,设置 1 则须要指定默认账户 -->
<property name="ignoreUnknownCommand">0</property><property name="useHandshakeV10">1</property>
<property name="removeGraveAccent">1</property>
<property name="useSqlStat">0</property> <!-- 1 为开启实时统计、0 为敞开 -->
<property name="useGlobleTableCheck">0</property> <!-- 1 为开启全局表一致性检测、0 为敞开 -->
<property name="sqlExecuteTimeout">300</property> <!-- SQL 执行超时 单位: 秒 -->
<!-- 0: 文件形式 1:数据库形式 2:工夫戳形式 3:zk --> <property name="sequenceHandlerType">0</property>
<!--<property name="sequnceHandlerPattern">(?:(s*nexts+values+fors*MYCATSEQ_(w+))(,|)|s)*)+</property>
INSERT INTO `travelrecord` (`id`,user_id) VALUES ('next value for MYCATSEQ_GLOBAL',"xxx"); --> <!-- 必须带有 MYCATSEQ_或者 mycatseq_进入序列匹配流程 留神 MYCATSEQ_有空格的状况 --> <property name="sequnceHandlerPattern">(?:(s*nexts+values+fors*MYCATSEQ_(w+))(,|)|s)*)+</property>
<property name="subqueryRelationshipCheck">false</property> <!-- 子查问中存在关联查问的状况下, 查看关联字段中是否有分片字段 . 默认 false -->
<property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandler</property>
<!-- <property name="useCompression">1</property>--> <!-- 1 为开启 mysql 压缩协定 -->
<!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!-- 设置模仿的 MySQL 版本号 --> <!-- <property name="processorBufferChunk">40960</property> --> <!-- <property name="processors">1</property> <property name="processorExecutor">32</property> --> <!-- 默认为 type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool --> <property name="processorBufferPoolType">0</property>
<!-- 分布式事务开关,0 为不过滤分布式事务,1 为过滤分布式事务(如果分布式事务内只波及全局表,则不过滤),2 为不过滤分布式事务, 然而记录分布式事务日志 --> <property name="handleDistributedTransactions">0</property>
<!--off heap for merge/order/group/limit 1 开启 0 敞开 -->
<property name="useOffHeapForMerge">0</property>
<!-- 单位为 m -->
<property name="memoryPageSize">64k</property>
<!-- 单位为 k -->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!-- 单位为 m -->
<property name="systemReserveMemorySize">384m</property>
<!-- 是否采纳 zookeeper 协调切换 -->
<property name="useZKSwitch">false</property>
<property name="strictTxIsolation">false</property>
<!-- 如果为 0 的话, 波及多个 DataNode 的 catlet 工作不会跨线程执行 -->
<property name="parallExecute">0</property>
</system>
<user name="user">
<property name="password">user</property> <property name="schemas">TESTDB</property> <property name="readOnly">true</property> <property name="defaultSchema">TESTDB</property> </user>-->
<!-- 增加 root 用户,拜访 enjoyDB 逻辑库 -->
<user name="root">
<property name="password">123456</property>
<property name="schemas">enjoyDB</property>
</user>
</mycat:server>
2.schema.xml(逻辑库配置)
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 逻辑库,跟数据库的 database 的概念雷同 -->
<schema name="enjoyDB" checkSQLschema="true" dataNode="localdn">
<table name="t_order" dataNode="localdn" autoIncrement="true" subTables="t_order$1-3" primaryKey="order_id" rule="mod-long">
</table>
</schema>
<dataNode name="localdn" dataHost="localhost1" database="consult" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<!--heartbeat 标签 :MYSQL 能够应用 select user() Oracle 能够应用 select 1 from dual -->
<heartbeat>select user()</heartbeat>
<connectionInitSql></connectionInitSql>
<!-- 如果 writeHost 指定的后端数据库宕机,那么这个 writeHost 绑定的所有 readHost 都将不可用。另一方面,因为这个 writeHost 宕机零碎会主动的检测到,并切换到备用的 writeHost 下来 -->
<writeHost
host="hostM1" url="jdbc:mysql://192.168.64.131:3307"
user="root" password="123456">
</writeHost>
</dataHost>
</mycat:schema>
schemal 标签下的 table 标签解读(mycat 中的逻辑表):
- name: 逻辑表的名称,名称必须惟一
- dataNode: 值必须跟 dataNode 标签中的 name 对应,如果值过多能够用 dataNode=”dn$0-99,cn$100-199″
- rule: 分片规定配置,定义在 rule.xml 中,必须与 tableRule 中的 name 对应
- ruleRequired: 该属性用于指定表是否绑定分片规定,如果配置为 true,但没有配置具体 rule 的话,程序会报错
- primaryKey:该逻辑表对应实在表的主键,例如:分片的规定是应用非主键进行分片的,那么在应用主键查问的时候,就会发送查问语句到所有配置的 DN 上,如果应用该属性配置实在表的主键。难么 MyCat 会缓存主键与具体 DN 的信息,那么再次应用非主键进行查问的时候就不会进行广播式的查问,就会间接发送语句给具体的 DN,然而只管配置该属性,如果缓存并没有命中的话,还是会发送语句给具体的 DN,来取得数据
- type:全局表:global 每一个 dn 都会保留一份全局表,一般表:不指定该值为 globla 的所有表 autoIncrement:autoIncrement=“true”, 默认是禁用的。
- needAddLimit:默认是 true
数据节点 dataNode 下 dataHost 配置解读:
balance:
- balance=”0″, 不开启读写拆散机制,所有读操作都发送到以后可用的 writeHost 上。
- balance=”1″,全副的 readHost 与 stand by writeHost 参加 select 语句的负载平衡,简略的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),失常状况下,M2,S1,S2 都参加 select 语句的负载平衡。
- balance=”2″,所有读操作都随机的在 writeHost、readhost 上散发。
- balance=”3″,所有读申请随机的散发到 writeHost 对应的 readhost 执行,writerHost 不累赘读压力,留神 balance= 3 只在 1.4 及其当前版本有,1.3 没有。
writeType: 负载平衡类型,目前的取值有 3 种:
- writeType=”0″, 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个 writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties .
- writeType=”1″,所有写操作都随机的发送到配置的 writeHost。
- writeType=”2″,没实现
switchType: -1 示意不主动切换 1 默认值,主动切换 2 基于 MySQL 主从同步的状态决定是否切换 心跳语句为 show slave status 3 基于 MySQL galary cluster 的切换机制(适宜集群)(1.4.1)心跳语句为 show status like‘wsrep%’。
dataHost 下配置的 url 为物理机的地址。
3.rule.xml(分片规定的配置文件)
下面配置了简略的 mod-long 规定,是 mycat 自带的, 即依据 schemal.xml 外面配置的主键来进行取模操作, 落到对应切分的表里,配置里的 count3 示意分三个表。
<tableRule name="mod-long">
<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>
应用
启动 MycatStartup 类:mycat 数据库中间件即启动胜利。
用 navicat 连贯 mycat,应用 server.xml 外面配置的用户
root,123456 默认端口 8066,插入数据:
查看控制台可看曾经路由到 order1 表中了,即实现了分表操作。