目录
第一章:mysql的主从复制之一主一从
第二章:mysql的主从复制之双主双从
第三章:mycat实现数据库的读写分离
第四章:mycat实现mysql分库(垂直切分)
第五章:mycat实现mysql分库(水平切分)
第六章:mycat ER表与全局表
第七章:mycat全局序列号
全局序列号
在实现分库分表的情况下,数据库自增主键已经无法保证自增主键的全局唯一,为此,mycat提供了全局sequence,并且提供了包含本地配置、数据库配置和时间戳等多种实现方式。如果需要切换其获取方式可以修改sequnceHandlerType 的值来实现:
| 字段 | 值 | 含义 |
|---|---|---|
| sequnceHandlerType | 0 | 本地配置 |
| sequnceHandlerType | 1 | 数据库配置 |
| sequnceHandlerType | 2 | 时间戳配置 |
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太长,需要耗费多余的存储空间。
mycat在分库分表场景下,通过全局序列号确保主键全局唯一。提供了本地文件、数据库和时间戳三种实现方式。本地文件方式快速但重启后需重置;数据库方式通过维护序列表实现,适合多实例;时间戳方式简单但ID较长。配置涉及server.xml、schema.xml和相关配置文件。

3万+

被折叠的 条评论
为什么被折叠?



