一.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表中了,即实现了分表操作。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。