MyCAT全局序列號-數據庫方式


1.MyCat中的全局序列號介紹

在實現分庫分表的情況下,數據庫自增主鍵已無法保證自增主鍵的全局唯一。為此,MyCat 提供了全局 sequence,並且提供了包含本地配置和數據庫配置等多種實現方式。

2.數據庫方式

原理:在數據庫中建立一張表,存放 sequence 名稱(name),sequence 當前值(current_value),步長(increment int 類型每次讀取多少個 sequence,假設為 K)等信息;

獲取步驟:

當初次使用該 sequence 時,根據傳入的 sequence 名稱,從數據庫這張表中讀取 current_value,和 increment 到 MyCat 中,並將數據庫中的 current_value 設置為原 current_value 值+increment 值; .

MyCat 將讀取到 current_value+increment 作為本次要使用的 sequence 值,下次使用時,自動加 1,當 使用 increment 次后,執行步驟 1)相同的操作. MyCat 負責維護這張表,用到哪些 sequence,只需要在這張表中插入一條記錄即可。若某次讀取的 sequence 沒有用完,系統就停掉了,則這次讀取的 sequence 剩余值不會再使用。

3.配置數據庫方式

<3.1> 修改Mycat配置文件server.xml

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

1代表使用數據庫方式生成sequence

<3.2> 修改Mycat配置文件schema.xml

<table name="test" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="mod-long"/>
<table name="mycat_sequence" primaryKey="name" dataNode="dn2"/>

<3.3> 修改Mycat 配置文件 sequence_db_conf.properties,添加MYCAT=dn2

#sequence stored in datanode
GLOBAL=dn1
COMPANY=dn1
CUSTOMER=dn1
ORDERS=dn1
MYCAT=dn2

<3.4> 在dn2節點的 db2 數據庫中添加 MYCAT_SEQUENCE表

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;

<3.5> 在dn2節點的 db2 數據庫中的 MYCAT_SEQUENCE 表插入sequence初始記錄

INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('mycat', -99, 100);

代表插入了一個名為mycat的sequence,當前值為-99,步長為100。

<3.6> 在dn2節點的 db2 數據庫中創建存儲過程

(3.6.1) 獲取當前sequence的值:

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 ;

  (3.6.2) 設置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
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = value
WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END $
DELIMITER ;

  (3.6.3) 獲取下一個sequence值:

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 ;

獲取全局id的配置已經准備完畢。

4.測試獲取全局自增ID

(4.1) 向dn1,dn2,dn3 中的db1,db2,db3 分別添加測試表 test

create table test(id int,name varchar(10));

(4.2) 重啟mycat ,使用WorkBench鏈接mycat

SELECT * FROM db2.mycat_sequence;

這是Mycat重啟之前的的 mycat_sequence初始化數據

這室mycat 重啟之后的  mycat_sequence 數據

(4.3) 向test表中添加測試數據,多次執行以下語句,這里我執行了9次添加數據

insert into test(id,name) values(next value for MYCATSEQ_MYCAT,(select database()));

(4.4) 查詢添加的數據

SELECT * FROM test order by id asc;

全局自增id生成成功,同時數據被水平切分到 3個分片上

(4.5) 再次重啟mycat,執行(4.3)步驟,添加多次數據,之后查看 mycat_sequence 數據

發現在上次的基礎上增加了100

重啟后的id重101開始計數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM