创建两个数据库,并都创建test表
#创建数据库
create database mycat;
#添加表
use mycat
#创建表test
create table test3(id int auto_increment primary key,name varchar(32)) ;
#创建数据库
create database mycat3;
#添加表
use mycat 2
#创建表test
create table test3(id int auto_increment primary key,name varchar(32)) ;
我将自增长的函数都创建在了mycat这个db中
DROP TABLE IF EXISTS MYCAT_SEQUENCE;
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 ;
INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ('GLOBAL', 100000, 100);
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 ;
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 ;
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 ;
#查询当前所在db ,这个语句只是想给大家证明,我是在mycat 这个数据库里面添加的函数
select database();
#查询doubi这张表里面的数据
select mycat_seq_nextval('doubi');
插入数据的时候,一定要注意,自己需要插入的表,一定要是大写的
#设定TEST3表的增长方式为 步进为1 ,
insert into MYCAT_SEQUENCE (name,current_value,increment) values ('TEST3',0,1);
#查询结果
select * from MYCAT_SEQUENCE;
vim conf/schemal.xml, 数据库的表名称为test2,设定表的主键,这样mycat好给我们生成主键,而且我们是自增长,所以需要配置autoIncrement="true"
,这个里面 type="global"
表示是全局的表, 每个子节点,都会存在
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="yellowcong" checkSQLschema="true" sqlMaxLimit="1000">
<table name="test3" dataNode="jdbc_node1,jdbc_node2" primaryKey="id" autoIncrement="true" type="global"/>
schema>
<dataNode name="jdbc_node1" dataHost="localhost" database="mycat" />
<dataNode name="jdbc_node2" dataHost="localhost" database="mycat2" />
<dataHost name="localhost" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()heartbeat>
<writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="root" />
dataHost>
mycat:schema>
需要修改sequnceHandlerType 为1,
vim conf/server.xml
0 表示是表示使用本地文件方式。
1 表示的是根据数据库来生成,就是我们自己配置的自增长
2 表示时间戳的方式 ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)
<property name="sequnceHandlerType">1property>
下面是全部配置
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="serverPort">8066property>
<property name="useSqlStat">0property>
<property name="useGlobleTableCheck">0property>
<property name="sequnceHandlerType">1property>
<property name="processorBufferPoolType">0property>
<property name="handleDistributedTransactions">0property>
<property name="useOffHeapForMerge">1property>
<property name="memoryPageSize">1mproperty>
<property name="spillsFileBufferSize">1kproperty>
<property name="useStreamOutput">0property>
<property name="systemReserveMemorySize">384mproperty>
<property name="useZKSwitch">trueproperty>
system>
<user name="root">
<property name="password">rootproperty>
<property name="schemas">yellowcongproperty>
user>
<user name="user">
<property name="password">userproperty>
<property name="schemas">yellowcongproperty>
<property name="readOnly">trueproperty>
user>
mycat:server>
#配置默认的表自增长设置
vim ./conf/sequence_db_conf.properties
#添加需要自增长的表名称
TEST3=jdbc_node1
重启mycat服务后,连接数据库,测试插入数据到TEST3表
#连接mycat
mysql -h 127.0.0.1 -P 8066 -u root -proot
#使用yellowocng 数据库
use yellowcong ;
#查看表信息
show tables ;
#插入数据
#插入多条数据
insert into test3 (name) values ('doubi1'),('doubi2'),('doubi3'),('yellowcong');
#查询数据
select * from test3;
查询数据,结果可以看到,角标的增长很完美。是增长的步进是1.
查看子节点,可以看到对mycat操作后,由于是全局表,所以每个子节点数据中,都存在表信息。
包这个问题的原因很明显,就是我们没有设置mycat中虚拟表的id自增,所以导致没有获取到id,所以导致了这个问题。
#修改后的语句
insert into test2(name) values('doubi1'),('doubi2'),('doubi3'),('yellowcong');
必须提供添加的列,直接插入,导致了问题,所以我们需要修该插入语句
#原来语句
insert into test2 (null,'doubi1'),(null,'doubi2'),(null,'doubi3'),(null,'yellowcong');
#修改后的语句
insert into test2(name) values('doubi1'),('doubi2'),('doubi3'),('yellowcong');
导致这个问题的大致原因可能是由于mycat生成的id和数据库的字符长度对不上,超过了数据库配置的默认长度所导致的。解决办法,就是修改数server.xml,设定id生成策略是根据数据库生成的。
vim conf/server.xml
0 表示是表示使用本地文件方式。
1 表示的是根据数据库来生成
2 表示时间戳的方式 ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)
<property name="sequnceHandlerType">1property>
mycat对应sequence_db_conf.properties增加相应设置
#配置默认的表自增长设置
vim ./conf/sequence_db_conf.properties
#添加需要自增长的表名称
TEST3=jdbc_node1
报错,说没办法获取到 id,从数据库中,这个说明我们sequence_db_conf.properties 的配置文件有问题
说没有mycat.mycat_seq_nextval 这个函数,说明在rule.xml中还需要添加这个配置
#添加表
DROP TABLE IF EXISTS MYCAT_SEQUENCE;
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 ;
INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('GLOBAL', 100000, 100);
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 ;
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 ;
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 ;
#插入一条数据,这条数据是我们这个表所需要的。
#必须是大写的字符,不然就会报错
#插入需要自增张的表的策略
insert into MYCAT_SEQUENCE (name,current_value,increment) values ('TEST3',0,1);