zoukankan      html  css  js  c++  java
  • 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文件

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

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

    2. 配置数据库

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

    因我在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 ;

    至此,数据库方面的准备工作已结束完毕。

    3. 在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必须大写。

  • 相关阅读:
    第二十一章流 1流的操作 简单
    第二十章友元类与嵌套类 1友元类 简单
    第十九章 19 利用私有继承来实现代码重用 简单
    第二十章友元类与嵌套类 2嵌套类 简单
    第十九章 8链表类Node 简单
    第二十一章流 3用cin输入 简单
    第十九章 10 图书 药品管理系统 简单
    第十九章 11图书 药品管理系统 简单
    第二十一章流 4文件的输入和输出 简单
    第十九章 12 什么时候使用私有继承,什么时候使用包含 简单
  • 原文地址:https://www.cnblogs.com/ivictor/p/5235147.html
Copyright © 2011-2022 走看看