• 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必须大写。

  • 相关阅读:
    SQL基础-子查询&EXISTS&UNION
    SQL基础-汇总统计及GROUP BY
    SQL基础-创建新的输出字段
    SQL基础-过滤数据
    获取图片为二进制流,并且显示图片到网页
    计算两个日期相差的工作小时数,过滤了周末双休小时数
    计算两个日期相差的工作天数,过滤了周末双休天数
    WEB性能测试工具
    C#整合VS2010和NUnit
    如何打开Windows Server 2008 R2的域安全策略
  • 原文地址:https://www.cnblogs.com/ivictor/p/5235147.html
Copyright © 2020-2023  润新知