Mycat的序列管理有3种模式,server.xml文件中system标签的sequnceHandlerType属性为0,1,2分别表示本地管理、数据库管理和本地时间戳管理
<system>
......
<property name="sequnceHandlerType">0|1|2</property>
......
</system>
1.本地管理序列
序列是基于sequence_conf.properties文件来管理,内容如下:
GLOBAL.CURID=10001
GLOBAL.MINID=10001
GLOBAL.HISIDS=
GLOBAL.MAXID=10010
表示名为GLOBAL的序列的当前值为10001,最小值为10001,最大值为10010。select next value for MYCATSEQ_GLOBAL或在insert语句中将next value for MYCATSEQ_GLOBAL作为某一列的值可查看或使用下一个序列,即为GLOBAL.CURID的值+1,同时sequence_conf.properties中GLOBAL.CURID自增1.在上面给出的示例中,GLOBAL.MAXID=10010,那么当GLOBAL.CURID已经自增到10010时,下一次再次使用next value for MYCATSEQ_GLOBAL,GLOBAL.CURID会继续增长,变为10011,而非回到10001,此时,文件里的内容会变成
GLOBAL.CURID=10011
GLOBAL.MINID=10011
GLOBAL.HISIDS=10001-10010
GLOBAL.MAXID=10020
这里我们看到,GLOBAL.HISIDS=10001-10010,10001和10010分别是CURID超过MAXID之前的MINID和MAXID。实际上HISIDS是用于记录上一次超过MAXID之前的MINID和MAXID。那么这一次,CURID变成了上一次的MAXID+1,变成了10011,而MAXID变成了上一次MAXID+9,为什么+9呢?因为上一次MAXID-MINID=9,也就是说,MAXID-MINID的值是固定的,除非对文件进行手工修改,这个差值会保持不变。另外,GLOBAL.HISIDS=10001-10010,可以说明这是10001和10010分别是第一次MINID和MAXID,为什么是你一次呢,接下来我们让CURID再次达到当前的MAXID,然后再自增一次,即CURID=10021,会发现文件内容如下:
GLOBAL.CURID=10021
GLOBAL.MINID=10021
GLOBAL.MAXID=10030
GLOBAL.HISIDS=,10011-10020
10011-10020前面多了一个逗号‘,’,因为这已经是第二次达到MAXID了,MAXID已经第二次发生变化了。
2.数据库管理序列
数据库序列表和序列函数创建脚本
--创建序列表
CREATE TABLE MYCAT_SEQUENCE(name VARCHAR(50) NOT NULL,current_value INT NOT NULL,increment INT NOT NULL DEFAULT 100,PRIMARY KEY(name)) ENGINE=InnoDB;
--创建获取当前序列值的函数
DROP FUNCTION IF EXISTS mycat_seq_currval;
DELIMITER //
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
SET retval="-999999999,null";
SELECT concat(CAST(current_value AS CHAR),",",CAST(increment AS CHAR)) INTO retval FROM MYCAT_SEQUENCE WHERE name = seq_name;
RETURN retval;
END //
DELIMITER ;
--创建初始化序列值的函数
DROP FUNCTION IF EXISTS mycat_seq_setval;
DELIMITER //
CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),value INTEGER) RETURNS varchar(64) CHARSET utf8
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = value
WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END //
DELIMITER ;
--创建获取下一个序列值的函数
DROP FUNCTION IF EXISTS mycat_seq_nextval;
DELIMITER //
CREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = current_value + increment WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END //
DELIMITER ;
MYCAT_SEQUENCE表三个字段的含义:
name:序列名字,如果想要使用名字为'ABC'的序列 这张表中必须含有name='ABC'的记录,并且sequence_db_conf.properties文件中需要加上ABC=dn1,dn1表示MYCAT_SEQUENCE表所在的数据节点。建议name的值和表名对应,表示该序列被该表所专用,以方便管理维护,使用方法为:
select next value for MYCATSEQ_ABC;
insert into ABC(id,name) values (next value for MYCATSEQ_ABC);
increment:mycat每次从数据库中取用的序列数,而非序列每次使用增加的数量,Mycat在使用时每次始终自增1。increment可以理解为每次缓存到Mycat中的序列个数,Mycat在重启后会丢失缓存的序列,重新从数据库中MYCAT_SEQUENCE表中获取。
current_val:mycat上次取走的最小序列数。每当Mycat用完上次取走的序列,下一次使用时,这个列会自增一个increment的值,并意味着mycat又取走了一个increment那么多的序列
3.本地时间戳管理
ID= 64位二进制 (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)
按照上面的规则生成唯一ID,若存在多个mycat节点,sequence_time_conf.properties文件中
WORKID=01 #01-32任选
DATAACENTERID=01 #01-32任选
可任意组合用于避免不同节点出现重复的可能性
select next value for MYCATSEQ_XXX;--XXX可以是任意字符
网友评论