全局序列号介绍
在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一。为此,mycat 提供了全局sequence,并且提供了包含本地配置和数据库配置等多种实现方式。
本地文件方式
原理:此方式mycat将sequence配置到文件中,当使用到sequence中的配置后,mycat会更下classpath中的sequence_conf.properties文件中sequence当前的值。
配置方式:
在sequence_conf.properties文件中做如下配置:
global_seq.hisids=
global_seq.minid=1001
global_seq.maxid=1000000000
global_seq.curid=1000
其中hisids表示使用过的历史分段(一般无特殊需要可不配置),minid表示最小id值,maxid表示最大id值,curid表示当前id值。
server.xml中配置:
1
<code><</code><code>property</code> <code>name</code><code>=</code><code>"sequncehandlertype"</code><code>>0</</code><code>property</code><code>></code>
注:sequncehandlertype需要配置为0,表示使用本地文件方式。 1表示数据库方式
使用示例:
<code>insert</code> <code>into</code> <code>table1(id,</code><code>name</code><code>) </code><code>values</code><code>(</code><code>next</code> <code>value </code><code>for</code> <code>mycatseq_global,‘test’);</code>
缺点:当mycat重新发布后,配置文件中的sequence会恢复到初始值。
优点:本地加载,读取速度较快。
数据库方式
原理:在数据库中建立一张表,存放sequence名称(name),sequence当前值(current_value),步长(increment int类型每次读取多少个sequence,假设为k)等信息;
sequence获取步骤:
1).当初次使用该sequence时,根据传入的sequence名称,从数据库这张表中读取current_value,和increment到mycat中,并将数据库中的current_value设置为原current_value值+increment值;
2).mycat将读取到current_value+increment作为本次要使用的sequence值,下次使用时,自动加1,当使用increment次后,执行步骤1)相同的操作.
mycat负责维护这张表,用到哪些sequence,只需要在这张表中插入一条记录即可。若某次读取的sequence没有用完,系统就停掉了,则这次读取的sequence剩余值不会再使用。
server.xml配置:
<code><</code><code>property</code> <code>name</code><code>=</code><code>"sequncehandlertype"</code><code>>1</</code><code>property</code><code>></code>
注:sequncehandlertype 需要配置为1,表示使用数据库方式生成sequence.
数据库配置:
1) 创建mycat_sequence表
– 创建存放sequence的表
drop table if exists mycat_sequence;
– name sequence名称
– current_value 当前value
– increment 增长步长! 可理解为mycat在数据库中一次读取多少个sequence. 当这些用完后, 下次再从数据库中读取.
2
3
4
5
6
<code>create</code> <code>table</code> <code>mycat_sequence (</code>
<code>name</code> <code>varchar</code> <code>(50) </code><code>not</code> <code>null</code><code>,</code>
<code>current_value </code><code>int</code> <code>not</code> <code>null</code><code>,</code>
<code>increment </code><code>int</code> <code>not</code> <code>null</code> <code>default</code> <code>100,</code>
<code>primary</code> <code>key</code> <code>(</code><code>name</code><code>)</code>
<code>) engine = innodb;</code>
– 插入一条sequence
<code>insert</code> <code>into</code> <code>mycat_sequence(</code><code>name</code><code>,current_value,increment) </code><code>values</code> <code>(‘</code><code>global</code><code>’, 100000, 100);</code>
2) 创建相关function
– 获取当前sequence的值 (返回当前值,增量)
7
8
9
10
11
12
13
14
<code>drop</code> <code>function</code> <code>if exists `mycat_seq_currval`;</code>
<code>delimiter ;;</code>
<code>create</code> <code>definer=`root`@`%` </code><code>function</code> <code>`mycat_seq_currval`(seq_name </code><code>varchar</code><code>(50)) </code>
<code>returns</code> <code>varchar</code><code>(64) charset latin1</code>
<code> </code><code>deterministic</code>
<code>begin</code>
<code> </code><code>declare</code> <code>retval </code><code>varchar</code><code>(64);</code>
<code> </code><code>set</code> <code>retval=</code><code>"-999999999,null"</code><code>; </code>
<code> </code><code>select</code> <code>concat(</code><code>cast</code><code>(current_value </code><code>as</code> <code>char</code><code>),</code><code>","</code><code>,</code><code>cast</code><code>(increment </code><code>as</code> <code>char</code><code>) ) </code><code>into</code> <code>retval </code>
<code> </code><code>from</code> <code>mycat_sequence </code><code>where</code> <code>name</code> <code>= seq_name; </code>
<code> </code><code>return</code> <code>retval ; </code>
<code>end</code>
<code>;;</code>
<code>delimiter ;</code>
– 设置sequence值
<code>drop</code> <code>function</code> <code>if exists `mycat_seq_nextval`;</code>
<code>create</code> <code>definer=`root`@`%` </code><code>function</code> <code>`mycat_seq_nextval`(seq_name </code><code>varchar</code><code>(50)) </code><code>returns</code> <code>varchar</code><code>(64)</code>
<code> </code><code>charset latin1</code>
<code> </code><code>update</code> <code>mycat_sequence </code>
<code> </code><code>set</code> <code>current_value = current_value + increment </code>
<code> </code><code>where</code> <code>name</code> <code>= seq_name; </code>
<code> </code><code>return</code> <code>mycat_seq_currval(seq_name); </code>
– 获取下一个sequence值
<code>drop</code> <code>function</code> <code>if exists `mycat_seq_setval`;</code>
<code>create</code> <code>definer=`root`@`%` </code><code>function</code> <code>`mycat_seq_setval`(seq_name </code><code>varchar</code><code>(50), value </code><code>integer</code><code>) </code>
<code> </code><code>set</code> <code>current_value = value </code>
<code> </code><code>where</code> <code>name</code> <code>= seq_name; </code>
3) sequence_db_conf.properties相关配置,指定sequence相关配置在哪个节点上:
例如:
user_seq=test_dn1
注意:mycat_sequence表和以上的3个function,需要放在同一个节点上。function请直接在具体节点的数据库上执行,如果执行的时候报:
you might want to use the less safe log_bin_trust_function_creators variable
需要对数据库做如下设置:
windows下my.ini[mysqld]加上log_bin_trust_function_creators=1
linux下/etc/my.cnf下my.ini[mysqld]加上log_bin_trust_function_creators=1
修改完后,即可在mysql数据库中执行上面的函数.
本文摘自:《mycat权威指南》
特别说明:尊重作者的劳动成果,转载请注明出处哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt332