来自 新葡亰数据库 2019-11-20 12:39 的文章
当前位置: 澳门新葡亰app > 新葡亰数据库 > 正文

从数据库那张表中读取,此情势MyCAT将sequence配置

1.MyCat中的全局序列号介绍

在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一。为此,MyCat 提供了全局 sequence,并且提供了包含本地配置和数据库配置等多种实现方式。

MyCAT全局序列号,mycat全局

在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一。为此,MyCat 提供了全局sequence,并且提供了包含本地配置和数据库配置等多种实现方式。

本地文件方式

原理:此方式MyCAT将sequence配置到文件中,当使用到sequence中的配置后,MyCAT会更下conf中的sequence_conf.properties文件中sequence当前的值。

譬如:

#default global sequence
GLOBAL.HISIDS=
GLOBAL.MINID=10001
GLOBAL.MAXID=20000
GLOBAL.CURID=10000

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

使用方式:

在server.xml中配置如下:

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

其中0,表示使用本地文件方式。

测试如下:

mysql> create table test(id int,name varchar(20));
Query OK, 0 rows affected (0.13 sec)

mysql> insert into test(id,name) values(next value for MYCATSEQ_GLOBAL,@@hostname);
Query OK, 1 row affected, 1 warning (0.03 sec)

mysql> select * from test;
+-------+--------------+
| id    | name         |
+-------+--------------+
| 10001 | mysql-slave2 |
+-------+--------------+
1 row in set (0.02 sec)

此时,sequence_conf.properties中GLOBAL.CURID值为10001。当然,可以使用sequence_conf.properties中定义的任何规则,譬如:

# self define sequence
COMPANY.HISIDS=
COMPANY.MINID=1001
COMPANY.MAXID=2000
COMPANY.CURID=1000

mysql> insert into test(id,name) values(next value for MYCATSEQ_COMPANY,@@hostname);
Query OK, 1 row affected, 1 warning (0.02 sec)

mysql> select * from test;
+-------+--------------+
| id    | name         |
+-------+--------------+
| 10001 | mysql-slave1 |
|  1001 | mysql-slave1 |
+-------+--------------+
2 rows in set (0.10 sec)

这个可自定义。

 

数据库方式

原理

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

Sequence获取步骤:

1).第一次使用该sequence时,根据传入的sequence名称,从数据库这张表中读取current_value,和increment到MyCat中,并将数据库中的current_value设置为原current_value值+increment值(实现方式是基于后续的存储函数)

2).MyCat将读取到current_value+increment作为本次要使用的sequence值,下次使用时,自动加1,当使用increment次后,执行步骤1)相同的操作.
MyCat负责维护这张表,用到哪些sequence,只需要在这张表中插入一条记录即可。若某次读取的sequence没有用完,系统就停掉了,则这次读取的sequence剩余值不会再使用。

使用方式:

  1. 配置server.xml文件

    1

1代表使用数据库方式生成sequence

  1. 配置数据库

在其中一个分片点对应的数据库中创建表和存储过程

因我在schem.xml中datanode的配置信息如下:

<dataNode name="dn$1-3" dataHost="localhost1" database="db$1-3" />

譬如我在dn2中创建,对应的数据库名为db2(为什么这里会涉及到datanode,因为后续的sequence_db_conf.properties文件会使用到),注意,是登录到数据库中创建,而不是在mycat中创建

1> 创建MYCAT_SEQUENCE表

mysql> DROP TABLE IF EXISTS MYCAT_SEQUENCE;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> 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;
Query OK, 0 rows affected (0.07 sec)

其中: – name sequence名称
         – current_value 当前value
         – increment 增长步长! 可理解为mycat在数据库中一次读取多少个sequence. 当这些用完后, 下次再从数据库中读取.

注意:MYCAT_SEQUENCE必须大写。

2> 插入sequence记录

mysql> INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('mycat', 1, 100);
Query OK, 1 row affected (0.01 sec)

代表插入了一个名为mycat的sequence,当前值为1,步长为100。

3> 创建存储函数。

注意:必须在同一个数据库中创建,在本例中,是db2。一共要创建三个。

– 获取当前sequence的值(返回当前值,增量)

    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. 在mycat conf目录下的sequence_db_conf.properties文件中添加如下内容:

    MYCAT=dn2

其中,dn2对应的是数据库db2的datanode

注意:MYCAT必须为大写,这个与表的数据是否大写无关,事实上,MYCAT_SEQUENCE中name是否大小写对结果没有影响。

开始测试:

登录mycat客户端

# mysql -h127.0.0.1 -utest -ptest -P8066 -DTESTDB

创建测试表

mysql> create table test(id int,name varchar(10));
Query OK, 0 rows affected (0.22 sec)

插入数据

插入的格式如下:

insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,'test');

mysql> mysql> insert into test(id,name) values(next value for MYCATSEQ_MYCAT,'test1');
ERROR 1003 (HY000): mycat sequnce err.org.opencloudb.config.util.ConfigException: can't find definition for sequence :MYCAT
mysql> insert into test(id,name) values(next value for MYCATSEQ_MYCAT,'test1');
Query OK, 1 row affected (0.11 sec)

mysql> select * from test;
+------+-------+
| id   | name  |
+------+-------+
|  101 | test1 |
+------+-------+
1 row in set (0.09 sec)

第一次会报如下错误:

ERROR 1003 (HY000): mycat sequnce err.org.opencloudb.config.util.ConfigException: can't find definition for sequence :MYCAT

因为对于sequence_db_conf.properties的修改当前的mycat并不知晓,这时候,可重启mycat或者登录9066管理端口进行 reload @@config;

至此,测试完毕,关键还是两点:MYCAT_SEQUENCE必须大写,sequence_db_conf.properties文件中MYCAT=dn2必须大写。

 

 

宋德福

在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一。为此,MyCat 提供了全局sequence,并且...

2.数据库方式

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

获取步骤:

当初次使用该 sequence 时,根据传入的 sequence 名称,从数据库这张表中读取 current_value,和 increment 到 MyCat 中,并将数据库中的 current_value 设置为原 current_value 值+increment 值; .

MyCat 将读取到 current_value+increment 作为本次要使用的 sequence 值,下次使用时,自动加 1,当 使用 increment 次后,执行步骤 1)相同的操作. MyCat 负责维护这张表,用到哪些 sequence,只需要在这张表中插入一条记录即可。若某次读取的 sequence 没有用完,系统就停掉了,则这次读取的 sequence 剩余值不会再使用。

3.配置数据库方式

<3.1> 修改Mycat配置文件server.xml

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

1代表使用数据库方式生成sequence

<3.2> 修改Mycat配置文件schema.xml

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

<3.3> 修改Mycat 配置文件 sequence_db_conf.properties,添加MYCAT=dn2

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

<3.4> 在dn2节点的 db2 数据库中添加 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;

<3.5> 在dn2节点的 db2 数据库中的 MYCAT_SEQUENCE 表插入sequence初始记录

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

代表插入了一个名为mycat的sequence,当前值为-99,步长为100。

<3.6> 在dn2节点的 db2 数据库中创建存储过程

(3.6.1) 获取当前sequence的值:

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 ;

  (3.6.2) 设置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 ;

  (3.6.3) 获取下一个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 ;

获取全局id的配置已经准备完毕。

4.测试获取全局自增ID

(4.1) 向dn1,dn2,dn3 中的db1,db2,db3 分别添加测试表 test

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

(4.2) 重启mycat ,使用WorkBench链接mycat

SELECT * FROM db2.mycat_sequence;

图片 1

这是Mycat重启之前的的 mycat_sequence初始化数据

图片 2

这室mycat 重启之后的  mycat_sequence 数据

(4.3) 向test表中添加测试数据,多次执行以下语句,这里我执行了9次添加数据

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

(4.4) 查询添加的数据

SELECT * FROM test order by id asc;

图片 3

全局自增id生成成功,同时数据被水平切分到 3个分片上

(4.5) 再次重启mycat,执行(4.3)步骤,添加多次数据,之后查看 mycat_sequence 数据

图片 4

发现在上次的基础上增加了100

重启后的id重101开始计数

图片 5

 

本文由澳门新葡亰app发布于新葡亰数据库,转载请注明出处:从数据库那张表中读取,此情势MyCAT将sequence配置

关键词: