产生背景
使用了mycat进行了分表后,如果还使用原来的mysql数据库自增序列(auto increment)将会造成id重复,所以,在使用了mycat进行了表数据水平切分后,数据按照一定的规则进行分布,id自增序列需要使用mycat的全局序列。
全局序列的三种方式
- 本地文件【0】
在mycat上生成一个文件,里面存放id,抗风险能力差,但凡mycat故障,备机mycat不知道文件记录的id到哪个值了。 - 数据库方式【1】
让某个主机的数据库产生id,每次提供一个范围(比如:1 ~ 100)的序列给mycat用,使用完了,再提供新的范围(如:101 ~ 200),如果mycat故障了,备机从数据库获取新的范围段的序列继续分配,那些因为mycat故障而未使用完的那部分id被丢弃,该方式使用普遍,相对合理。原理:
利用数据库一个表 来进行计数累加。但是并不是每次生成序列都读写数据库,这样效率太低;mycat会预加载一部分号段到mycat内存中,这样大部分读写序列都是在内存中完成的。如果内存中号段用完了,mycat会再向数据库要一次。
问:如果mycat崩溃了,内存中的序列岂不是都没了?
是的,如果是这样,那么mycat启动后会向数据库申请新的号段,原有号段会被弃用。
也就是说,如果mycat重启,那么损失是当前号段没用完的号码,虽然有些损失,但是不会因此产生主键重复。 - 时间戳方式【2】
实现方式很优秀,但是值太长了(18位),浪费存储空间。 - 自主生成
插入数据的时候,使用者自己根据算法或规则生成不重复的值。
数据库方式【1】
在dn1数据结点执行如下sql创建相关 table 和 function
mysql -uroot -p'root' -P 3306 -h 192.168.78.120
use order190401
CREATE TABLE MYCAT_SEQUENCE (
name VARCHAR(50) NOT NULL, #名称
current_value INT NOT NULL, #当前value
increment INT NOT NULL DEFAULT 100, #mycat在数据库中一次读取多少个sequence
PRIMARY KEY(name)
) ENGINE=InnoDB;
DELIMITER $$
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS varchar(64)
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);