mycat - 全局序列
解决主键冲突问题:例如id自增的order表,如果分布式情况下不处理的话,当每个表的第一条数据id都是1。
怎么确保id唯一呢?
解决办法:
1、本地文件(不推荐)
2、数据库方式(推荐)
3、时间戳(位数较多,占空间多,并且不安全)
数据库方式详解:
原理:利用数据库的一个表来进行计数累加。但是并不是每次生成序列都需要读写该数据库,这样效率不好。mycat会预加载一部分号段到mycat内存中,这样下次使用先使用内存中的号段,直到使用完毕,才去数据获取下一批号段。如果mycat获取的号段没用完,中途挂掉了,待到mycat在上线时,会重新从下一号段开始获取,例如第一次获取1-100,然而没用完挂了,下次mycat上线就从200开始获取。
配置步骤:
找一数据库维护MYCAT_SEQUENCE ,我是在order_win数据库中维护。
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;
创建相关函数,mycat官方提供。
DELIMITER $$
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS VARCHAR(64)
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;
DELIMITER $$
CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),VALUE INTEGER) RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = VALUE
WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END $$
DELIMITER ;
DELIMITER $$
CREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = current_value + increment WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END $$
DELIMITER;
增加要使用的序列
INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ('ORDERS', 400000,100);
执行完后,确认下已经创建。并修改mycat的配置。
vim /usr/local/mycat/conf/sequence_db_conf.properties 配置ORDERS这个序列在哪个节点上,参考schema.xml
vim /usr/local/mycat/conf/server.xml 0文件方式1数据库方式2时间戳方式
然后重启mycat,测试。