Mycat【数据库方式】实现全局序列号

说明:本文参考mycat官方提供的文档,结合自己的实践以及理解,做出如下整理,并附带一个分库分表的插入数据例子。
原理
在数据库中建立一张表,存放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)相同的操作.
3)MyCat负责维护这张表,用到哪些sequence,只需要在这张表中插入一条记录即可。若某次读取的sequence没有用完,系统就停掉了,则这次读取的sequence剩余值不会再使用。
配置方式
server.xml配置:

<system><property name=”sequnceHandlerType”>1</property></system>
1
注:sequnceHandlerType 需要配置为1,表示使用数据库方式生成sequence.
数据库配置:
1)创建sequence表

CREATE TABLE MYCAT_SEQUENCE (
name VARCHAR (50) NOT NULL comment “名称”,
current_value INT NOT NULL comment “当前值”,
increment INT NOT NULL DEFAULT 100 comment “步长”,
PRIMARY KEY (name)
) ENGINE = INNODB;
1
2
3
4
5
6
2)创建相关function

#取当前squence的值
DROP FUNCTION IF EXISTS mycat_seq_currval;
DELIMITER $$
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50))RETURNS VARCHAR(64) CHARSET ‘utf8′
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 ;

#设置 sequence 值
DROP FUNCTION IF EXISTS mycat_seq_setval;
DELIMITER $$
CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),VALUE INTEGER) RETURNS VARCHAR(64) CHARSET ‘utf8’
BEGIN
UPDATE MYCAT_SEQUENCE SET current_value = VALUE WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END$$
DELIMITER ;

#取下一个sequence的值
DROP FUNCTION IF EXISTS mycat_seq_nextval;
DELIMITER $$
CREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) RETURNS VARCHAR(64) CHARSET ‘utf8′
BEGIN
UPDATE MYCAT_SEQUENCE SET current_value = current_value + increment
WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END$$
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
3)sequence_db_conf.properties相关配置,指定sequence相关配置在哪个节点上:
例如:

COMPANY=dn3
1
注:COMPANY为表名,必须大写,dn3为schema.xml配置的dataNode节点。建议专门独立一个数据库,存放sequence表和相关的function,方便维护管理和隔离。

注意: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数据库中执行上面的函数.
使用示例:

SELECT next value for MYCATSEQ_SAM_TEST
insert into sam_test(id_,name_) values(next value for MYCATSEQ_SAM_TEST,’test’);
# 数据库表定义了自增,在mycat也定义了主键和自增,可以用如下方式
insert into sam_test(name_) values(‘test’);
1
2
3
4
测试
1.配置schema.xml

<schema name=”TESTDB” checkSQLschema=”false” sqlMaxLimit=”100″>
<table name=”company” dataNode=”dn1,dn2″ rule=”companyRule” primaryKey=”id” autoIncrement=”true” />
</schema>

<dataNode name=”dn1″ dataHost=”localhost1″ database=”mycat_test” />
<dataNode name=”dn2″ dataHost=”localhost1″ database=”mycat_test2″ />
<dataNode name=”dn3″ dataHost=”localhost2″ database=”testmycat” />

<dataHost name=”localhost1″ maxCon=”1000″ minCon=”10″ balance=”0″
writeType=”0″ dbType=”mysql” dbDriver=”native” switchType=”1″ slaveThreshold=”100″>
<heartbeat>select user()</heartbeat>
<writeHost host=”hostM1″ url=”192.168.1.95:3306″ user=”admin” password=”admin”/>
<writeHost host=”hostM2″ url=”192.138.1.112:3306″ user=”root” password=”root”/>
</dataHost>
<!– 存放sequence数据库 –>
<dataHost name=”localhost2″ maxCon=”1000″ minCon=”10″ balance=”0″
writeType=”0″ dbType=”mysql” dbDriver=”native” switchType=”1″ slaveThreshold=”100″>
<heartbeat>select user()</heartbeat>
<writeHost host=”localhost2M2″ url=”192.138.1.112:3306″ user=”root” password=”root”/>
</dataHost>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2.配置server.xml

<property name=”sequnceHandlerType”>1</property><!– 1:使用数据库方式生成sequence –>
1
3.配置rule.xml

<tableRule name=”companyRule”>
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name=”mod-long” class=”org.opencloudb.route.function.PartitionByMod”>
<!– how many data nodes –>
<property name=”count”>2</property>
</function>
1
2
3
4
5
6
7
8
9
10
4.配置sequence_db_conf.properties

COMPANY=dn3
1
5.数据库配置文件修改my.ini

log_bin_trust_function_creators=1
# 忽略大小写
lower_case_table_names=1
1
2
3
6.数据库表
1)分别到192.168.1.95的mycat_test数据库和mycat_test2数据库新建如下的表,由于是分库分表,所以两边都要创建。

DROP TABLE IF EXISTS `company`;
CREATE TABLE `company` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1
2
3
4
5
6
注:只有数据库和mycat都设置AUTO_INCREMENT才能通过mycat命令LAST_INSERT_ID()获取插入的id
2)到192.168.1.112的testmycat数据库中执行上面的创建sequence和function过程。
3)插入数据到MYCAT_SEQUENCE表

insert into MYCAT_SEQUENCE(name,current_value,increment) values(‘COMPANY’,19,5);
1
7.mycat测试
配置完之后,重启mycat
执行

insert into company(id,name) values (next value for MYCATSEQ_COMPANY,”test”)

insert into company(name) values (“test”)
1
2
3
插入数据成功后
执行

select LAST_INSERT_ID()
1
可以看到本次插入的id

小结
如果要获取插入数据后的id,必须同时在mysql和mycat设置表的自增。
sequence_db_conf.properties配置的表名必须大写。
存放sequence表和function在同一个数据库中,且只有一个。
以上【Sequence获取步骤】是mycat原理,注意理解。
———————
作者:黄晓杰Aries
来源:CSDN
原文:https://blog.csdn.net/u010956470/article/details/70837876
版权声明:本文为博主原创文章,转载请附上博文链接!

发表评论

电子邮件地址不会被公开。 必填项已用*标注


*