02配置篇说到tb1表按照主键id进行了分片, 实际工作中还会经常按业务字段分片, 这次有tb3表, 按user_id分片, 依上文思路, 先调整下涉及到的配置文件.

1. 在schema.xml中, 添加tb3表的配置.

<table name="tb3" dataNode='dnTest1,dnTest2' rule="mod-long-user_id"/>

2. 在rule.xml中, 添加tb3表分片配置, 其中分片算法还是简单取摸.

<tableRule name="mod-long-user_id">

<rule>

<columns>user_id</columns>

<algorithm>mod-long</algorithm>

</rule>

</tableRule>

连接Mycat, 创建tb3的表结构.

mysql> create table tb3(id int auto_increment primary key, user_id int not null default 0, user_name varchar(30) not null default '');

下面插入2条数据.

mysql> insert into tb3(id, user_id, user_name) values(7, 1, 'abcd');

mysql> insert into tb3(id, user_id, user_name) values(7, 2, 'efgh');

查看发现, 虽然id字段为主键, 但在分片情况下, 其已失去了原有的唯一性约束. 原因很简单, 多个MySQL实例上唯一主键可以很自然的出现相同值.

mysql> select * from tb3;

+----+---------+-----------+

| id | user_id | user_name |

+----+---------+-----------+

|  7 |       2 | efgh      |

|  7 |       1 | abcd      |

+----+---------+-----------+

针对上述情况, Mycat中使用全局序列号(简称sequence), 来重塑主键的全局唯一性, 提供了包含本地配置和数据库配置等多种实现方式.

下面使用配置数据库的方式来获取sequence, 先了解下其原理.

在数据库中创建一张表, 存放sequence名称(name列), 当前值(current_value), 和步长(increment, 表每次读取多少个sequence).

sequence的获取, 和维护:

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没有用完, Mycat就停掉了, 则这次读取的sequence剩余值不会再使用.

配置方式:

1. 在server.xml中, 开启使用数据库方式生成sequence的开关.

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

2. 调整schema.xml, 并在Mycat后端某个MySQL实例上创建mycatseq数据库(该库名随意), MYCAT_SEQUENCE表(表名要大写), 和3个函数.

2.1 于schema.xml中添加如下配置.

<dataNode name="gseq" dataHost="Rep1_3306" database="mycatseq"/>

2.2 登陆节点主机Rep1_3306创建相应的数据库和表.

mysql> create database mycatseq;

mysql> use mycatseq;

mysql> create table MYCAT_SEQUENCE(name varchar(50) not null, current_value int not null, increment int not null default 100, primary key(name));

2.3 并创建3个函数.

# mycat_seq_currval

DELIMITER //

CREATE DEFINER=`zzzz`@`192.168.4.%` FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8 COLLATE utf8_bin

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 ;

# mycat_seq_nextval;

DELIMITER //

CREATE DEFINER=`zzzz`@`192.168.4.%` FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8 COLLATE utf8_bin

DETERMINISTIC

BEGIN

UPDATE MYCAT_SEQUENCE

SET current_value = current_value + increment  WHERE name = seq_name;

RETURN mycat_seq_currval(seq_name);

END; //

DELIMITER ;

# mycat_seq_setval;

DELIMITER //

CREATE DEFINER=`zzzz`@`192.168.4.%` FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50), value INTEGER) RETURNS varchar(64) CHARSET utf8 COLLATE utf8_bin

DETERMINISTIC

BEGIN

UPDATE MYCAT_SEQUENCE

SET current_value = value

WHERE name = seq_name;

RETURN mycat_seq_currval(seq_name);

END; //

DELIMITER ;

至此, 使用Mycat sequence的准备工作就绪了, 谁来使用呢, 就是tb3, 怎么使用呢, 看如下步骤.

1. 要在schema.xml中对tb3的配置稍微改造下, 添加autoIncrement="true", 告诉Mycat tb3使用sequence; 添加primaryKey="id", 告诉Mycat主键字段是什么.

<table name="tb3" dataNode='dnTest1,dnTest2' rule="mod-long-user_id" primaryKey="id" autoIncrement="true"/>

2. 那Mycat如何知道去哪个节点主机获取sequence呢, 需要在一个新的配置文件sequence_db_conf.properties中标明表名(要大写)和分片节点的对应关系.

#testdb

TB3=gseq

3. 登陆节点主机Rep1_3306, 初始化tb3表的sequence.

mysql> insert into MYCAT_SEQUENCE(name, current_value, increment) values('TB3', 400, 100);

mysql> select * from MYCAT_SEQUENCE;

+------+---------------+-----------+

| name | current_value | increment |

+------+---------------+-----------+

| TB3  |           400 |       100 |

+------+---------------+-----------+

登陆Mycat, 验证sequence可以正常使用.

mysql> select next value for MYCATSEQ_TB3;

+-----+

| 500 |

+-----+

| 500 |

+-----+

此时, tb3表使用sequence的工作准备好了, 下面插入数据看看.

mysql> insert into tb3(user_name) values('igkl');

ERROR 1064 (HY000): bad insert sql (sharding column:USER_ID not provided,INSERT INTO tb3 (ID, user_name)

VALUES (501, 'igkl')

mysql> insert into tb3(id, user_id, user_name) values(9, 4, 'igkl');

由于Mycat负责主键值id的生成, SQL语句中可省去id字段不写(若像上面, 指定id为某值, 也没问题).

mysql> insert into tb3(user_id, user_name) values(59, 'mnop');

mysql> select * from tb3 where user_id = 59;

+-----+---------+-----------+

| id  | user_id | user_name |

+-----+---------+-----------+

| 502 |      59 | mnop      |

+-----+---------+-----------+

查看日志, 发现Mycat对原始SQL语句进行了改写, 添加了id字段.

03/18 20:46:36.798  DEBUG [$_NIOREACTOR-1-RW] (ServerQueryHandler.java:56) -ServerConnection [id=1, schema=testdb, host=192.168.4.184, user=test_user,txIsolation=3, autocommit=true, schema=testdb]insert into tb3(user_id, user_name) values(59, 'mnop')

03/18 20:46:36.800  DEBUG [Thread-1] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=testdb, host=192.168.4.184, user=test_user,txIsolation=3, autocommit=true, schema=testdb]insert into tb3(ID,user_id, user_name) values( 502,59, 'mnop'), route={

1 -> dnTest2{insert into tb3(ID,user_id, user_name) values( 502,59, 'mnop')}

03/18 20:46:36.800  DEBUG [Thread-1] (MySQLConnection.java:459) -con need syn ,total syn cmd 2 commands SET names utf8;SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;schema change:false con:MySQLConnection [id=2, lastTime=1521377196800, user=zzzz, schema=test2, old shema=test2, borrowed=true, fromSlaveDB=false, threadId=81, charset=utf8, txIsolation=0, autocommit=true, attachment=dnTest2{insert into tb3(ID,user_id, user_name) values( 502,59, 'mnop')}, respHandler=SingleNodeHandler [node=dnTest2{insert into tb3(ID,user_id, user_name) values( 502,59, 'mnop')}, packetId=0], host=192.168.4.151, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]

03/18 20:46:36.802  DEBUG [$_NIOREACTOR-2-RW] (NonBlockingSession.java:229) -release connection MySQLConnection [id=2, lastTime=1521377196792, user=zzzz, schema=test2, old shema=test2, borrowed=true, fromSlaveDB=false, threadId=81, charset=utf8, txIsolation=3, autocommit=true, attachment=dnTest2{insert into tb3(ID,user_id, user_name) values( 502,59, 'mnop')}, respHandler=SingleNodeHandler [node=dnTest2{insert into tb3(ID,user_id, user_name) values( 502,59, 'mnop')}, packetId=1], host=192.168.4.151, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]

若感兴趣可关注订阅号”数据库最佳实践”(DBBestPractice).

转载于:https://blog.51cto.com/coveringindex/2088271

Mycat的使用 - 03.全局序列号相关推荐

  1. mysql序列号生成_一文看懂mycat的6种全局序列号实现方式

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

  2. Mycat探索之旅(3)----Mycat的全局序列号

    一.本地文件方式 原理:此方式MyCAT将sequence配置到文件中,当使用到sequence中的配置后,MyCAT会更下classpath中的sequence_conf.properties文件中 ...

  3. MyCAT全局序列号-数据库方式

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

  4. Mycat 设置全局序列号

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

  5. 分布式全局序列号生产,Twitter Snowflake算法,雪花算法

    为什么80%的码农都做不了架构师?>>>    snowflake的结构如下(每部分用-分开): 0 - 0000000000 0000000000 0000000000 00000 ...

  6. 03全局类IMApplication添加操作联系人(好友)列表的方法和设置用户名和密码的方法

    1.关于操作联系人(好友)列表: 就是一个field和他的setter,getter: private Map<String, User> contactList; public Map& ...

  7. Mycat 源码修改-实现分表规则:按天分表和取摸分表查询

    Mycat 源码修改-实现分表规则:按天和取摸功能.之前修改过源码,发现其实没什么高深的只需要自己耐心点,多花点时间去调试就可以做到了.通过调试,找到自己想要改的地方,这是关键的:在代码中表现为修改相 ...

  8. Mycat 分片表全局自增主键实现及测试

    目录 一.全局序列号介绍 1.本地文件方式 2.数据库方式 3.本地时间戳方式 4.分布式 ZK ID 生成器 5.ZK 递增方式 6.其它方式 二.准备工作 环境 1.在 MySQL 建库 2.在  ...

  9. 数据库中间件 MyCAT源码分析:【单库单表】插入【推荐阅读】

    ???关注微信公众号:[芋艿的后端小屋]有福利: RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表 RocketMQ / MyCAT / Sharding-JDB ...

  10. Mycat 读写分离、主从切换、分库分表的操作记录

    Mycat 读写分离.主从切换.分库分表的操作记录 系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等 ...

最新文章

  1. Django项目中的子项目中自动生成自己想要的文件内容
  2. 清除应用程序所有缓存
  3. oracle 取系统当前年份_Oracle中如何获取系统当前时间
  4. 自动拷贝远程服务器文件夹,怎么从远程服务器上拷贝文件夹
  5. java堆内存与栈内存
  6. 总算完成了第一个项目,宿管系统,和感想
  7. (转) hash 函数及其重要性
  8. 2016年下半年软考网络工程师真题解析精编版
  9. 上位机和下位机的概念
  10. cef 前进后台 实现_使用CefSharp前端后台交换
  11. LeetCode 75 分类颜色
  12. 对象存储oss挂载工具ossfs的使用
  13. 初级计算机英语,初级英语口语怎么学?
  14. 通达信指标公式常用绘图函数(2)——DRAWLINE、DRAWKLINE、STICKLINE
  15. MessageBox confirm弹框确认和取消按钮的使用-回调
  16. 编写高质量的代码—从命名入手(命名…
  17. 高速光耦(PS8101,TLP112A,TLP109)基本工作原理应用实例
  18. 窥探Flutter的前世今身
  19. 寒门再难出贵子(下)
  20. 各种进制转换最简单总结(附任意进制转换代码)

热门文章

  1. python分布式爬虫系统_python简单分布式爬虫
  2. pandas的基本函数
  3. 如何查询远程计算机的名称,如何解析远程计算机名称以获取它在java中的IP地址...
  4. ibatis java 项目_iBatis搭建JAVA项目
  5. 编程判断元素归类_编程:找出所有符合条件的元素
  6. 纵坐标是横的还是竖的_通感在书法“竖”中的运用,详解竖的知识和技法(硬笔为例)...
  7. java中mysql.ini_为什么找不到mysql.ini文件,我是放在scr目录下的
  8. 华农c语言期末试卷答案,华南农业大学2013学年第1学期程序设计(C语言)期末考试试卷(A卷)...
  9. spss主成分综合得分_权重赋值之“主成分分析法”
  10. 从 Promise、Async/Await 、Generator等角度实现一个 sleep 函数