一、简介

上一篇文件介绍了MyCat全局序列的本地文件方式,由于 MyCat 重新发布后,配置文件中的 sequence 会恢复到初始值(当这台机器宕机时会出现,序列文件丢失,造成序列冲突问题),所以在实际项目中并不会采用本地文件生成序列,更多是采用数据库的方式,本文就将对如何在MyCat中使用数据库实现全局序列主键唯一。

二、数据库方式

  • 实现方式:在数据库中建立一张表MYCAT_SEQUENCE ,用于存放 序列sequence 名称(name),sequence 当前值(current_value),步长(increment int 类型每次读取多少个 sequence。
  • 获取步骤大概如下三个:
  1. 初次获取sequence时,根据传入的序列名称,从数据库表中获取current_value,increment到MyCat中,并将数据库中的current_value更新为current_value + increment。
  2. MyCat将读取到的current_value + increment作为本次的序列,在下次使用时,将序列的值 + 1,当使用increment次后,重复第一个步骤。
  3. MyCat负责维护序列表MYCAT_SEQUENCE,当用到序列时,往数据库表中插入一条记录即可。如果某次读取完的序列还没有用完数据库就崩了,那么剩余的没有使用的序列将会被废弃掉。

三、实现方式

环境信息:MySQL5.6.45、Mycat-server-1.6、虚拟机IP地址192.168.1.11,

本文采用一台数据库服务器192.168.1.11里边的两个数据库(testdb_seq1、testdb_seq2)进行测试,详细的实现步骤如下:

【a】在数据库服务器192.168.1.11上面创建数据库(testdb_seq1、testdb_seq2)以及测试表test1。

create database testdb_seq1;
create database testdb_seq2;use testdb_seq1;
create table test1(id int auto_increment primary key,xm varchar(32));use testdb_seq2;
create table test1(id int auto_increment primary key,xm varchar(32));

【b】创建MYCAT_SEQUENCE表(这里使用testdb_seq1数据库(dn1节点)作为生成主键的节点)

注意:MYCAT_SEQUENCE表和以上的3个function,需要放在同一个节点(dn1)上。

DROP TABLE IF EXISTS MYCAT_SEQUENCE;
CREATE TABLE `MYCAT_SEQUENCE` (`NAME` varchar(50) NOT NULL comment  "名称",`current_value` int(11) NOT NULL comment "当前值",`increment` int(11) NOT NULL DEFAULT '100' comment "步长",PRIMARY KEY (`NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

并且在表中初始化一条记录,指定序列名称TESTDBSEQ,序列当前值为100000,每次从数据库中取出100个序列,用完再取。

insert into MYCAT_SEQUENCE(name, current_value, increment) values ('TESTDBSEQ', 100000, 100);
-- 注意这里的TESTDBSEQ要大写,对应上 sequence_db_conf.properties 的配置use testdb_seq1;
select * from MYCAT_SEQUENCE;

【c】创建生成序列的函数(同样在testdb_seq1数据库上面执行)

这里主要有三个函数:

  • 返回当前的sequence的值
DROP FUNCTION IF EXISTS mycat_seq_currval;
DELIMITER $$
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50))RETURNS VARCHAR(64) CHARSET 'utf8'
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'
BEGINUPDATE 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'
BEGIN
UPDATE MYCAT_SEQUENCE SET current_value = current_value + increment
WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END$$
DELIMITER ;

【d】server.xml指定序列生成方式为数据库方式

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

【e】配置  sequence_db_conf.properties :TESTDBSEQ 为全局序列的名称,dn1 表示分片节点

TESTDBSEQ=dn1

注意:MYCAT_SEQUENCE 表和以上的 3 个 function,需要放在同一个节点上,然后重启 mycat服务。

vim sequence_db_conf.properties

【f】配置schema.xml: 配置分片节点、分片规则等

<mycat:schema xmlns:mycat="http://io.mycat/"><schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"><table name="test1" dataNode="dn1,dn2" primaryKey="id" autoIncrement="true" type="global" /></schema><dataNode name="dn1" dataHost="localhost1" database="testdb_seq1" /><dataNode name="dn2" dataHost="localhost1" database="testdb_seq2" /><dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100"><heartbeat>select user()</heartbeat><!-- can have multi write hosts --><writeHost host="hostM1" url="192.168.1.11:3306" user="root"password="0905"></writeHost></dataHost></mycat:schema>

【g】使用示例:

登录mycat,注意端口是8066

mysql -uroot -p0905 -h192.168.1.11 -P8066 

插入语句进行测试:

insert into test1(id,xm) values(next value for MYCATSEQ_TESTDBSEQ,'zhangsan');
insert into test1(id,xm) values(next value for MYCATSEQ_TESTDBSEQ,'lisi'); 

测试结果:

testdb_seq1数据库:

testdb_seq2数据库:

重启MyCat:

cd /bin./mycat restart

继续插入数据进行测试:

insert into test1(id,xm) values(next value for MYCATSEQ_TESTDBSEQ,'wangwu');

查看 mycat_sequence 数据:发现序列当前值在上次的基础上100100增加了100(即变为100200),重启后的id重100200开始计数。

【h】其他配置server.xml执行逻辑库地址、访问的数据库用户信息等

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/"><system><property name="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 --><property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 --><property name="sequnceHandlerType">1</property><!--  <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议--><!--  <property name="fakeMySQLVersion">5.6.20</property>--> <!--设置模拟的MySQL版本号--><!-- <property name="processorBufferChunk">40960</property> --><!-- <property name="processors">1</property> <property name="processorExecutor">32</property> --><!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena--><property name="processorBufferPoolType">0</property><!--默认是65535 64K 用于sql解析时最大文本长度 --><!--<property name="maxStringLiteralLength">65535</property>--><!--<property name="sequnceHandlerType">0</property>--><!--<property name="backSocketNoDelay">1</property>--><!--<property name="frontSocketNoDelay">1</property>--><!--<property name="processorExecutor">16</property>--><!--<property name="serverPort">8066</property> <property name="managerPort">9066</property> <property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property> <property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> --><!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志--><property name="handleDistributedTransactions">0</property><!--off heap for merge/order/group/limit      1开启   0关闭--><property name="useOffHeapForMerge">1</property><!--单位为m--><property name="memoryPageSize">1m</property><!--单位为k--><property name="spillsFileBufferSize">1k</property><property name="useStreamOutput">0</property><!--单位为m--><property name="systemReserveMemorySize">384m</property><!--是否采用zookeeper协调切换  --><property name="useZKSwitch">true</property></system><!-- 全局SQL防火墙设置 --><!-- <firewall> <whitehost><host host="127.0.0.1" user="mycat"/><host host="127.0.0.2" user="mycat"/></whitehost><blacklist check="false"></blacklist></firewall>--><user name="root"><property name="password">0905</property><property name="schemas">TESTDB</property><!-- 表级 DML 权限设置 --><!--        <privileges check="false"><schema name="TESTDB" dml="0110" ><table name="tb01" dml="0000"></table><table name="tb02" dml="1111"></table></schema></privileges>     --></user><user name="user"><property name="password">0905</property><property name="schemas">TESTDB</property><property name="readOnly">true</property></user></mycat:server>

四、总结

以上就是关于在MyCat中怎么使用数据库方式实现全局序列主键,主要需要注意点有:

  • 在数据库中创建全局序列表,并且在同一个数据库中创建三个函数;
  • server.xml指定全局序列方式为数据库方式(sequnceHandlerType=1);
  • 配置  sequence_db_conf.properties指定全局序列在哪个数据节点;
  • 如果某次读取完的序列还没有用完数据库就宕机了,那么没有使用的序列将会被废弃掉;

以上就是笔者学习期间的一些实践总结,希望能对大家有所帮助,如有不对之处,还望指点出来。

MyCat全局序列之数据库方式相关推荐

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

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

  2. 分表扩展全局序列原理_高可用_单表存储千万级_海量存储_分表扩展---MyCat分布式数据库集群架构工作笔记0025

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后我们来说一下全局序列,现在我们做了分布式以后,东西都是全局的了 都要加个全局,以前可是没有,都 ...

  3. 分表扩展全局序列实际操作_高可用_单表存储千万级_海量存储_分表扩展---MyCat分布式数据库集群架构工作笔记0026

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后我们动手配置: 全局序列,来给咱们的集群,保证id的自增长和不重复. 首先我们在dn1上创建这 ...

  4. MyCat —— 性能最好的数据库中间件

    课程介绍 1. MyCat简介 1.1 MyCat 引入 如今随着互联网的发展,数据的量级也是成指数式的增长,从GB到TB到PB.对数据的各种操作也是愈 加的困难,传统的关系性数据库已经无法满足快速查 ...

  5. MyCat:取代Cobar数据库中间件

    Cobar 是阿里巴巴开源的一个数据库中间件,为了解决类似proxy这类的问题.目前同类型的有奇虎360开源的Atlas.类似的有基本在线上用起来很不爽,问题多多的比如MySQL Proxy和SQL ...

  6. mycat全局表一致性检查

    mycat全局表一致性检查通过内部列_mycat_op_time来实现,具体实现方式如下 1.检测全局表的内部列是否存在 checker.checkInnerColumnExist(); 检测的实现是 ...

  7. springboot整合quartz,实现数据库方式执行定时任务

    springboot整合quartz,实现数据库方式执行定时任务.把定时任务信息存进数据库,项目启动后自动执行定时任务. 1.引入依赖包: <dependency><groupId& ...

  8. AAAI 2022 | Diaformer: 采用症状序列生成的方式做自动诊断

    本文约5000字,建议阅读10分钟 本文为你介绍在智能医学应用领域 AI Drive 分享了他们的工作"Diaformer". 自动诊断是智能医学应用领域的一个重要方向,其多阶段的 ...

  9. PHP 自定义session储存 数据库 方式类   高洛峰 细说PHP

    自定义session储存 数据库 方式类 在php.ini配置文件中更改设置 (Registered_save_handlers 有三种方式 files user memcache) session. ...

  10. Spring-Security (学习记录四)--配置权限过滤器,采用数据库方式获取权限

    目录 1. 需要在spring-security.xml中配置验证过滤器,来取代spring-security.xml的默认过滤器 2. 配置securityMetadataSource,可以通过ur ...

最新文章

  1. GridView 模版列编辑状态Dropdownlist 事件
  2. Caffe学习系列(11):图像数据转换成db(leveldb/lmdb)文件
  3. 论大型信息系统集成项目的人力资源管理
  4. 微信小程序 小程序源码包括后台完整版分享
  5. 数据归一化的作用--在svm 训练的时候特别有用
  6. swap函数_[C++基础入门] 6、函数
  7. Python 进阶 —— 使用修饰器执行函数的参数检查
  8. python 中的魔法类
  9. ANSYS 闪退问题解决办法
  10. 计算机制作通知的具体步骤,步骤 10:创建通知模板和订阅(可选)
  11. FOR ALL ENTRIES IN
  12. wfp 禁用ip_Win64 驱动内核编程-16.WFP网络监控驱动(防火墙)
  13. 无法割舍的乡情--去外公家
  14. 全栈工程师为啥值40W的年薪?
  15. 什么是指纹浏览器(浏览器指纹7个重要参数)
  16. 我的微信扫描二维码实现登录のJava
  17. mysql 转义字符 escape_mysql 的Escape转义字符串
  18. 2021高考汇文中学成绩查询,2021年北京高考英语阅读理解评析(北京汇文中学)...
  19. 小程序开发学习(3)---.wxss详解篇
  20. 当动作捕捉应用到教学教研工作领域

热门文章

  1. Pyspark:随机森林
  2. React Native之原理浅析, iOS原理分析与实践解析、Android原理分析与实践解析
  3. NumPy库---数组进阶操作
  4. assert断言的概念
  5. 深度学习笔记(二):简单神经网络,后向传播算法及实现
  6. 【面向代码】学习 Deep Learning(二)Deep Belief Nets(DBNs)
  7. Map先排序value小->大再排序key小->大,ArrayList与Stream分别实现
  8. 51.N皇后 (力扣leetcode) 博主可答疑该问题
  9. 153.寻找旋转排序数组中的最小值(力扣leetcode) 博主可答疑该问题
  10. 网络安全基础——批处理编写