mycat全局序列号

mycat在分库分表场景下,通过全局序列号确保主键全局唯一。提供了本地文件、数据库和时间戳三种实现方式。本地文件方式快速但重启后需重置;数据库方式通过维护序列表实现,适合多实例;时间戳方式简单但ID较长。配置涉及server.xml、schema.xml和相关配置文件。

目录

第一章:mysql的主从复制之一主一从
第二章:mysql的主从复制之双主双从
第三章:mycat实现数据库的读写分离
第四章:mycat实现mysql分库(垂直切分)
第五章:mycat实现mysql分库(水平切分)
第六章:mycat ER表与全局表
第七章:mycat全局序列号

全局序列号

在实现分库分表的情况下,数据库自增主键已经无法保证自增主键的全局唯一,为此,mycat提供了全局sequence,并且提供了包含本地配置、数据库配置和时间戳等多种实现方式。如果需要切换其获取方式可以修改sequnceHandlerType 的值来实现:

字段含义
sequnceHandlerType0本地配置
sequnceHandlerType1数据库配置
sequnceHandlerType2时间戳配置
1、本地文件方式

​ 使用此方式的时候,mycat讲sequence配置到文件中,当使用到sequence中的配置,mycat会更新sequence_conf.properties文件中sequence当前的值。

配置方式:

​ 在 sequence_conf.properties 文件中做如下配置:

GLOBAL_SEQ.HISIDS=
GLOBAL_SEQ.MINID=10001
GLOBAL_SEQ.MAXID=20000
GLOBAL_SEQ.CURID=10000

​ 其中 HISIDS 表示使用过的历史分段(一般无特殊需要可不配置), MINID 表示最小 ID 值, MAXID 表示最大
ID 值, CURID 表示当前 ID 值。
​ server.xml 中配置:

<system><property name="sequnceHandlerType">0</property></system>

​ 注: sequnceHandlerType 需要配置为 0,表示使用本地文件方式。

​ 案例使用:

create table tab1(id int primary key,name varchar(10));
insert into tab1(id,name) values(next value for mycatseq_global,'test1');
insert into tab1(id,name) values(next value for mycatseq_global,'test2');
insert into tab1(id,name) values(next value for mycatseq_global,'test3');

​ 缺点:当mycat重新发布后,配置文件中的sequence会恢复到初始值

​ 优点:本地加载,读取速度较快

2、数据库方式

​ 在数据库中建立一张表,存放sequence名称(name),sequence当前值(current_value),步长(increment int类型,每次读取多少个sequence,假设为K)等信息;

获取数据步骤

​ 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剩余值不会再使用

配置方式:

​ 1、修改server.xml文件

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

​ 2、修改schema.xml文件

<table name="test" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2" rule="mod-long"/>
<table name="mycat_sequence" primaryKey="name" dataNode="dn2"/>

​ 3、修改mycat配置文件sequence_db_conf.properties,添加属性值

#sequence stored in datanode
GLOBAL=dn1
COMPANY=dn1
CUSTOMER=dn1
ORDERS=dn1
MYCAT=dn2

​ 4、在dn2上添加mycat_sequence表

DROP TABLE IF EXISTS mycat_sequence;
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;

​ 5、在dn2上的mycat_sequence表中插入初始记录

INSERT INTO mycat_sequence(name,current_value,increment) VALUES ('mycat', -99, 100);

​ 6、在dn2上创建函数

--创建函数
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 ;
--设置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
DETERMINISTIC
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
DETERMINISTIC
BEGIN
UPDATE mycat_sequence
SET current_value = current_value + increment WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END $
DELIMITER ;

数据测试:

​ 1、插入数据表

create table test(id int,name varchar(10));

​ 2、查询对应的序列数据表

SELECT * FROM mycat_sequence;

​ 3、向表中插入数据,可以多执行几次

insert into test(id,name) values(next value for MYCATSEQ_MYCAT,(select database()));

​ 4、查询添加的数据

SELECT * FROM test order by id asc;

​ 5、重新启动mycat,重新添加数据,查看结果,重启之后从101开始

SELECT * FROM mycat_sequence;

​ 6、重新查询数据表test

SELECT * FROM test order by id asc;

​ 大家在使用的时候会发现报错的情况,这个错误的原因不是因为我们的配置,是因为我们的版本问题,简单替换下版本即可。

mysql> insert into test(id,name) values(next value for MYCATSEQ_MYCAT,(select database()));
ERROR 1003 (HY000): mycat sequnce err.java.lang.NumberFormatException: null
3、本地时间戳方式

​ ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)。

​ 换算成十进制为 18 位数的 long 类型,每毫秒可以并发 12 位二进制的累加。

使用方式:

​ 1、配置server.xml文件

<system><property name="sequnceHandlerType">2</property></system>

​ 2、修改sequence_time_conf.properties,可以不改

WORKID=06 #任意整数
DATAACENTERID=06  #任意整数

​ 3、修改schema.xml文件

<table name="test2" dataNode="dn1,dn2" primaryKey="id" autoIncrement="true" rule="mod-long" />

​ 4、启动mycat,并且创建表进行测试

create table test2(id bigint auto_increment primary key,xm varchar(32));
insert into test2(id,xm) values(next value for MYCATSEQ_GLOBAL,'lisi') ; 

​ 此方式的优点是配置简单,但是缺点也很明显就是18位的id太长,需要耗费多余的存储空间。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值