Mysql_Mycat全局序列

产生背景

使用了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);
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 $$

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 $$

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 ;

select * from MYCAT_SEQUENCE;
TRUNCATE TABLE MYCAT_SEQUENCE;

-- 增加要用的序列
insert into MYCAT_SEQUENCE(name,current_value,increment) values('ORDERS',400000,100);

mysql> select * from MYCAT_SEQUENCE;
+--------+---------------+-----------+
| name   | current_value | increment |
+--------+---------------+-----------+
| ORDERS |        400000 |       100 |
+--------+---------------+-----------+
1 row in set (0.00 sec)

mysql> 


修改mycat配置
配置sequence_db_conf.properties,指定sequence相关配置在哪个节点上:
vim sequence_db_conf.properties

ORDERS=dn1

在这里插入图片描述
指定sequenceHandlerType=1,为数据库方式。(0=本地文件、1=数据库、2=时间戳)
vim server.xml

 <property name="sequnceHandlerType">1</property>

在这里插入图片描述
重启mycat,连接mycat,进行测试

mysql -umycat -p'123456' -P 8066 -h 192.168.78.120
use TESTDB

insert into orders(id,amount,customer_id,order_type) values(next value for MYCATSEQ_ORDERS,1000,101,102);
insert into orders(id,amount,customer_id,order_type) values(next value for MYCATSEQ_ORDERS,1000,101,102);
insert into orders(id,amount,customer_id,order_type) values(next value for MYCATSEQ_ORDERS,1000,101,102);

mysql> select * from orders;
+--------+------------+-------------+-----------+
| id     | order_type | customer_id | amount    |
+--------+------------+-------------+-----------+
|      1 |        101 |         100 | 100100.00 |
|      2 |        101 |         100 | 100300.00 |
|      6 |        102 |         100 | 100020.00 |
|      3 |        101 |         101 | 120000.00 |
|      4 |        101 |         101 | 103000.00 |
|      5 |        102 |         101 | 100400.00 |
| 400100 |        102 |         101 |   1000.00 |
| 400101 |        102 |         101 |   1000.00 |
| 400102 |        102 |         101 |   1000.00 |
| 400103 |        102 |         101 |   1000.00 |
+--------+------------+-------------+-----------+
10 rows in set (0.08 sec)

mysql> 

验证成功,如果mycat故障了,修复后,再次插入数据,orders表的id会从 400200 开始递增。

更详细参考:https://blog.csdn.net/cold___play/article/details/107520844
视频教程:https://www.bilibili.com/video/BV12b411K7Zu?p=350&spm_id_from=pageDriver

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值