• TDSQL FOR MYSQL 内部的序例介绍


    TDSQL序列:

    Oracle提供了sequence对象,由系统提供自增长的序列号,用于生成数据库数据记录的自增长主键或序号的地方。如果当前的序列不存在,它会创建一个序列,如果存在,它首先要得到当前序列的最大值,然后再加一,实现自增长的功能。

    在TDSQL使用过程用,也有不少金融用户要求能支持ORACLE sequence 一样功能的全局序例。而TDSQL也正是在percona数据库内核中实现了Oracle sequence功能,该功能与oracle原版sequence功能完全相同,没有任何省略和遗漏。

    TDSQL sequence 完全解决了mysql 自增列的缺陷;

    • sequence完全独立与表而存在,不需要作为表的索引第一列;
    • 一个表的不同字段可以使用多个sequence产生序列值;
    • 一个sequence可以给任意多个表使用产生自增序列值,也可以脱离表的insert/update语句而单独使用。

    所有存储引擎上面的表都可以使用sequence功能。当然,对于SBR复制模式来说,与mysql自增列一样,使用sequence仍然会导致主备数据不一致。TDSQL使用RBR复制,所以不存在这个问题。

    Tdsql Sequence 语法:

    创建语法:
    
    CREATE TDSQL_SEQUENCE [dbname.]sequence_name
    [start with n]
    [tdsql_minvalue n | nominvalue]
    [maxvalue n | nomaxvalue]
    [tdsql_increment by n]
    [TDSQL_NOCYCLE | TDSQL_CYCLE] 
          
    说明:
    START WITH:指定生成的第一个序列号。在升序时,序列可从比最小值大的值开始,缺省值为序列的最小值。对于降序,序列可由比最大值小的值开始,缺省值为序列的最大值。
    TDSQL_INCREMENT BY: 指定序列号之间的间隔,该值可为正的或负的整数,但不可为0。序列为升序。忽略该子句时,缺省值为1。
    TDSQL_MINVALUE:指定序列的最小值。
    MAXVALUE:指定序列可生成的最大值。
    TDSQL_NOCYCLE:一直累加,不循环。

    下面我们来测试一下 TDSQL 的 SEQUENCE :

    #更能proxy 参数,并重启proxy 
    [root@huyidb01 conf]# pwd
    /data/tdsql_run/15002/gateway/conf
    [root@huyidb01 conf]# cat instance_15002.cnf |  grep sequence
     <sequence mode="1"/> 
     <save_in_db open="1"/>
    
    
    [root@huyidb03 bin]# ./restart_cgroup.sh instance_15002
    stop router_update
    OK: router_update of instance_15002 is stopped
    stop proxy
    OK: MySQL-Proxy of instance_15002 is stopped
    rm ../data/instance_15002_embedded_mysql* -rf
    port:15002
    sh: ./initcgrouphierarchy.sh: No such file or directory
    popen file:netstat -apn 2>/dev/null | grep 36000| grep -i LISTEN | awk '{print $4}' | awk -F':' '{print $1}' get buff is empty
    hierarchy is empty,after guess is:/sys/fs/cgroup
    use ../data as embedded database dir
    start router_update
    rm /dev/shm/0.0.0.0_15002
    zookeeper timeout:10000 msec,msg timeout 30000 msec
    kp init success
    
    start proxy
    [2020-12-20 16:43:36] pid:65639,we are the init master
    OK: MySQL-Proxy of instance_15002 is started  
    
    
    
    
    #创建序例
    [root@huyidb01 bin]# mysql -uhuyi -phuyi -h10.85.10.51 -P15002 -c
    
    MySQL [(none)]> use huyidb ;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    
    MySQL [huyidb]>  select * from mysql.tdsql_sequences ;
    Empty set (0.01 sec)
    
    
    #创建一个默认参数的sequence 
    MySQL [huyidb]> create tdsql_sequence huyidb.s1   ;
    Query OK, 0 rows affected (0.01 sec)
    
    MySQL [huyidb]> show create tdsql_sequence huyidb.s1 ;
    +---------+------------------------------------------------------------------------------------------------------------------------------+
    |  Table  | Create Table                                                                                                                 |
    +---------+------------------------------------------------------------------------------------------------------------------------------+
    | huyidb.s1 | create tdsql_sequence huyidb.s1 start with 1 tdsql_minvalue 1 maxvalue 9223372036854775806 tdsql_increment by 1 tdsql_nocycle  |
    +---------+------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    
    
    #创建一个指定参数的sequence 
    
    MySQL [huyidb]> create tdsql_sequence huyidb.s2 start with 1 tdsql_minvalue 1 maxvalue 5  tdsql_increment by 1  tdsql_nocycle ;  
    Query OK, 0 rows affected (0.01 sec)
    
    #创建一个带缓存的sequence 
    
    
    MySQL [huyidb]> create tdsql_sequence huyidb.s3 start with 1 tdsql_minvalue 1 maxvalue 50  tdsql_increment by 1   cache 10 tdsql_nocycle ;  
    Query OK, 0 rows affected (0.00 sec)
    
    #虽然创建成功了,但是从生成的语句来看,并没有cache 10 关键字。
    MySQL [(none)]> show create tdsql_sequence huyidb.s3;
    +-----------+---------------------------------------------------------------------------------------------------------------+
    |  Table    | Create Table                                                                                                  |
    +-----------+---------------------------------------------------------------------------------------------------------------+
    | huyidb.s4 | create tdsql_sequence huyidb.s3 start with 1 tdsql_minvalue 1 maxvalue 50 tdsql_increment by 1 tdsql_nocycle  |
    +-----------+---------------------------------------------------------------------------------------------------------------+
    
    
    #创建一张测试表
     
    MySQL [(none)]> create table huyidb.test1 ( a int , b int , c int,primary key (a) ) shardkey=a;
    Query OK, 0 rows affected (0.14 sec)
    
    
    #一个表同时使用多个sequence 
    MySQL [(none)]> insert into huyidb.test1 (a,b,c) values (tdsql_nextval(huyidb.s1), tdsql_nextval(huyidb.s2), tdsql_nextval(huyidb.s3)) ;
    Query OK, 1 row affected (0.03 sec)
    
    MySQL [(none)]> select * from huyidb.test1 ;
    +---+------+------+
    | a | b    | c    |
    +---+------+------+
    | 1 |    1 |    1 |
    +---+------+------+
    1 row in set (0.00 sec)
    
    
    #多个例使用同一个sequence 
    insert into huyidb.test1 (a,b,c) values (tdsql_nextval(huyidb.s1), tdsql_nextval(huyidb.s1), tdsql_nextval(huyidb.s1)) ;
    
    MySQL [(none)]> select * from huyidb.test1 ;
    +---+------+------+
    | a | b    | c    |
    +---+------+------+
    | 1 |    1 |    1 |
    | 2 |    3 |    4 |
    +---+------+------+
    2 rows in set (0.00 sec)
    
    
    # nocycle 达到最大值时会报错。
    MySQL [(none)]> truncate table  huyidb.test1 ;
    
    MySQL [(none)]> insert into huyidb.test1 (a,b,c) values (tdsql_nextval(huyidb.s2), tdsql_nextval(huyidb.s2), tdsql_nextval(huyidb.s2)) ; 
    ERROR 609 (HY000): Proxy ERROR:get sequence id from db error
    
    #查看当前最大序例
    MySQL [(none)]>  select tdsql_lastval(huyidb.s2);     
    +---+
    | 4 |
    +---+
    | 4 |
    +---+
    
    
    # 模拟proxy 故障前,我们查看s3序例的当前值为2
    insert into huyidb.test1 (a,b,c) values (tdsql_nextval(huyidb.s1), tdsql_nextval(huyidb.s1), tdsql_nextval(huyidb.s3)) ;
    
    MySQL [(none)]> select tdsql_lastval(huyidb.s3);
    
    +---+
    | 2 |
    +---+
    | 2 |
    +---+
    
    #kill proxy 
    ps -ef |grep gateway |grep 15002 | grep -v 'grep'| awk '{print $2}' | xargs kill -9
    
    
    #在次登录 检查huyidb.s3序例是否连续
    MySQL [(none)]> truncate table  huyidb.test1 ;
    
    
     MySQL [(none)]> insert into huyidb.test1 (a,b,c) values (tdsql_nextval(huyidb.s1), tdsql_nextval(huyidb.s1), tdsql_nextval(huyidb.s3)) ; 
    Query OK, 1 row affected (0.01 sec)
    
    MySQL [(none)]> select tdsql_lastval(huyidb.s3);
    +---+
    | 3 |
    +---+
    | 3 |
    +---+
    1 row in set (0.00 sec)
    
    
    #我们登录proxy2 上插入 s3序例 
    mysql -uhuyi -phuyi -h10.85.10.52 -P15002 -c  
    MySQL [(none)]> insert into huyidb.test1 (a,b,c) values (tdsql_nextval(huyidb.s1), tdsql_nextval(huyidb.s1), tdsql_nextval(huyidb.s3)) ; 
    Query OK, 1 row affected (0.02 sec)
    
    
    MySQL [(none)]> select tdsql_lastval(huyidb.s3);
    +---+
    | 4 |
    +---+
    | 4 |
    +---+  

    通过上面实验可以看出sequence可以保证全局唯一,且连续增长。解决了mysql自增例不连续,多个表不能引用同一个自增例,同一个表不能用多个自增例等问题。 但也同时带来了新的问题。那就是sequence目前为保证分布式全局唯一,性能较差,适用于并发不高的场景。因为序例值是存在DB中的,每一次使用时,都需要临时去取。

    #可以通过管理帐号权限在DB上查得当前的序例号。
    mysql> select * from auto_inc_table ;
    +-----------+----------+
    | db_table  | auto_inc |
    +-----------+----------+
    | huyidb.s1 |        5 |
    +-----------+----------+
    1 row in set (0.02 sec)
    
    mysql> select * from xa.auto_inc_table ;
    +-----------+----------+
    | db_table  | auto_inc |
    +-----------+----------+
    | huyidb.s1 |        5 |
    | huyidb.s2 |        4 |
    | huyidb.s3 |        5 |
    +-----------+----------+
    2 rows in set (0.02 sec)
    
    
    #查看下一个序例值:
    MySQL [huyi]> select next value for test.s3 ;
    或
    MySQL [huyi]> select tdsql_nextval(huyidb.s3);
    
    #查看当前序例值:
    MySQL [huyi]> select tdsql_lastval(huyidb.s3);  

    其它待确认问题:

    • 创建sequence 时,cache 关键字未生效
    • Sequence 创建成功,mysql.tdsql_sequences 无数据
    • Sequence每次从DB中取值对并发性能的影响
    • Sequence 的maxvalue通过proxy 限制
  • 相关阅读:
    day33-1 线程队列
    day32-4 GIL全局解释锁
    day32-3 阻塞非阻塞同步异步&异步回调
    day32-2 线程池与进程池
    day32-1 事件Event
    Chrome设置--disable-web-security解决跨域问题
    去除系统部分属性触摸是出现的色值
    初始化一个React项目
    ## normalize.css 中文版
    vue组件的3种书写形式
  • 原文地址:https://www.cnblogs.com/cqdba/p/14333542.html
Copyright © 2020-2023  润新知