Mycat [database method] realizes the global serial number

Note: This article refers to the official documents provided by mycat, combined with my own practice and understanding, and makes the following arrangements, and attaches an example of inserting data for sub-database and sub-table. 
Principle 
Create a table in the database to store the sequence name (name), the current value of the sequence (current_value), the step size (how many sequences the increment int type reads each time, assuming K) and other information; 
Sequence acquisition steps: 
1) When the sequence is used for the first time, according to the incoming sequence name, read the current_value from the database table, and increment it into MyCat, and set the current_value in the database to the original current_value value + increment value; 
2) MyCat will read the current_value+increment is used as the sequence value to be used this time. When it is used next time, it will be automatically incremented by 1. After using increment times, perform the same operation as step 1). 
3) MyCat is responsible for maintaining this table. Which sequences are used, only You need to insert a record in this table. If the sequence read for a certain time is not used up, the system stops, and the remaining value of the sequence read this time will not be used again. 
Configuration method 
server.xml configuration:

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

Note: sequenceHandlerType needs to be configured to 1, which means that the sequence is generated using the database method. 
Database configuration:  
1) Create a sequence table

CREATE TABLE MYCAT_SEQUENCE (
   name VARCHAR (50) NOT NULL comment  "名称",
   current_value INT NOT NULL  comment  "当前值",
   increment INT NOT NULL DEFAULT 100  comment  "步长",
   PRIMARY KEY (name)
) ENGINE = INNODB;

2) Create related functions

#取当前squence的值
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'
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'
BEGIN
UPDATE MYCAT_SEQUENCE SET current_value = current_value + increment 
WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END$$
DELIMITER ;

3) sequence_db_conf.properties related configuration, specify which node the sequence related configuration is on: 
for example:

COMPANY=dn3

Note: COMPANY is the table name, which must be capitalized, and dn3 is the dataNode node configured in schema.xml. It is recommended to have a separate database to store the sequence table and related functions for easy maintenance, management and isolation.

Note: The MYCAT_SEQUENCE table and the above three functions need to be placed on the same node. Please execute the function directly on the database of the specific node. If it reports: 
you might want to use the less safe log_bin_trust_function_creators variable 
, the database needs to be set as follows: 
under windows my.ini[mysqld] plus log_bin_trust_function_creators=1 
under linux/ After the my.ini[mysqld] under etc/my.cnf and log_bin_trust_function_creators=1 
are modified, the above function can be executed in the mysql database. 
Example of use:

SELECT next value for MYCATSEQ_SAM_TEST
insert into sam_test(id_,name_) values(next value for MYCATSEQ_SAM_TEST,'test');
# 数据库表定义了自增,在mycat也定义了主键和自增,可以用如下方式
insert into sam_test(name_) values('test');

test

1. Placement schema.xml

    <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
        <table name="company" dataNode="dn1,dn2" rule="companyRule" primaryKey="id" autoIncrement="true"   />
    </schema>

    <dataNode name="dn1" dataHost="localhost1" database="mycat_test" />
    <dataNode name="dn2" dataHost="localhost1" database="mycat_test2" />
    <dataNode name="dn3" dataHost="localhost2" database="testmycat" />

    <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="hostM1" url="192.168.1.95:3306" user="admin" password="admin"/>
        <writeHost host="hostM2" url="192.138.1.112:3306" user="root" password="root"/>
    </dataHost>
    <!-- 存放sequence数据库 -->
    <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="localhost2M2" url="192.138.1.112:3306" user="root" password="root"/>
    </dataHost>

2. Configure server.xml

<property name="sequnceHandlerType">1</property><!-- 1:使用数据库方式生成sequence -->

3. Configure rule.xml

    <tableRule name="companyRule">
        <rule>
            <columns>id</columns>
            <algorithm>mod-long</algorithm>
        </rule>
    </tableRule>
    <function name="mod-long" class="org.opencloudb.route.function.PartitionByMod">
        <!-- how many data nodes -->
        <property name="count">2</property>
    </function>

4. Configure sequence_db_conf.properties

COMPANY=dn3

5. Modify the database configuration file my.ini

log_bin_trust_function_creators=1
# 忽略大小写
lower_case_table_names=1

6. Database table 
1) Create the following tables in the mycat_test database and mycat_test2 database of 192.168.1.95 respectively. Since they are sub-databases and sub-tables, both sides must be created.

DROP TABLE IF EXISTS `company`;
CREATE TABLE `company` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Note: Only the database and mycat both set AUTO_INCREMENT to obtain the inserted id through the mycat command LAST_INSERT_ID() 
2) The above creation sequence and function process are executed in the testmycat database of 192.168.1.112. 
3) Insert data into MYCAT_SEQUENCE table

insert into MYCAT_SEQUENCE(name,current_value,increment) values('COMPANY',19,5);

7. After the mycat test 
is configured, restart mycat 
to execute

insert into company(id,name) values (next value for MYCATSEQ_COMPANY,"test")
insert into company(name) values ("test")


Execute after inserting data successfully 

select LAST_INSERT_ID()

You can see the id inserted this time

Summary 
If you want to get the id after inserting data, you must set the auto-increment of the table in mysql and mycat at the same time. 
The table names configured in sequence_db_conf.properties must be capitalized. 
Store the sequence table and function in the same database, and there is only one. 
The above [Sequence acquisition steps] is the principle of mycat, pay attention to understanding.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325496081&siteId=291194637