MyCAT全域序號

來源:互聯網
上載者:User

MyCAT全域序號

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

本地檔案方式

原理:此方式MyCAT將sequence配置到檔案中,當使用到sequence中的配置後,MyCAT會更下conf中的sequence_conf.properties檔案中sequence當前的值。

譬如:

#default global sequence
GLOBAL.HISIDS=
GLOBAL.MINID=10001
GLOBAL.MAXID=20000
GLOBAL.CURID=10000

其中HISIDS表示使用過的曆史分段(一般無特殊需要可不配置),MINID表示最小ID值,MAXID表示最大ID值,CURID表示當前ID值。

使用方式:

在server.xml中配置如下:

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

其中0,表示使用本地檔案方式。

測試如下:

 

mysql> create table test(id int,name varchar(20));
Query OK, 0 rows affected (0.13 sec)

mysql> insert into test(id,name) values(next value for MYCATSEQ_GLOBAL,@@hostname);
Query OK, 1 row affected, 1 warning (0.03 sec)

mysql> select * from test;
+-------+--------------+
| id    | name        |
+-------+--------------+
| 10001 | mysql-slave2 |
+-------+--------------+
1 row in set (0.02 sec)

 

此時,sequence_conf.properties中GLOBAL.CURID值為10001。當然,可以使用sequence_conf.properties中定義的任何規則,譬如:

# self define sequence
COMPANY.HISIDS=
COMPANY.MINID=1001
COMPANY.MAXID=2000
COMPANY.CURID=1000

 

mysql> insert into test(id,name) values(next value for MYCATSEQ_COMPANY,@@hostname);
Query OK, 1 row affected, 1 warning (0.02 sec)

mysql> select * from test;
+-------+--------------+
| id    | name        |
+-------+--------------+
| 10001 | mysql-slave1 |
|  1001 | mysql-slave1 |
+-------+--------------+
2 rows in set (0.10 sec)

 

這個可自訂。

 

資料庫方式

原理

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

Sequence擷取步驟:

1).第一次使用該sequence時,根據傳入的sequence名稱,從資料庫這張表中讀取current_value,和increment到MyCat中,並將資料庫中的current_value設定為原current_value值+increment值(實現方式是基於後續的儲存函數)

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

使用方式:

1. 配置server.xml檔案

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

1代表使用資料庫方式產生sequence

2. 設定資料庫

在其中一個分區點對應的資料庫中建立表和預存程序

因我在schem.xml中datanode的配置資訊如下:

<dataNode name="dn$1-3" dataHost="localhost1" database="db$1-3" />

譬如我在dn2中建立,對應的資料庫名為db2(為什麼這裡會涉及到datanode,因為後續的sequence_db_conf.properties檔案會使用到),注意,是登入到資料庫中建立,而不是在mycat中建立

1> 建立MYCAT_SEQUENCE表

mysql> DROP TABLE IF EXISTS MYCAT_SEQUENCE;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> 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;
Query OK, 0 rows affected (0.07 sec)

其中: – name sequence名稱
        – current_value 當前value
        – increment 增長步長! 可理解為mycat在資料庫中一次讀取多少個sequence. 當這些用完後, 下次再從資料庫中讀取.

注意:MYCAT_SEQUENCE必須大寫。

2> 插入sequence記錄

mysql> INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('mycat', 1, 100);
Query OK, 1 row affected (0.01 sec)

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

3> 建立儲存函數。

注意:必須在同一個資料庫中建立,在本例中,是db2。一共要建立三個。

– 擷取當前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 ;

 

– 設定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 ;

 

– 擷取下一個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 ;

 

至此,資料庫方面的準備工作已結束完畢。

3. 在mycat conf目錄下的sequence_db_conf.properties檔案中添加如下內容:

MYCAT=dn2

其中,dn2對應的是資料庫db2的datanode

注意:MYCAT必須為大寫,這個與表的資料是否大寫無關,事實上,MYCAT_SEQUENCE中name是否大小寫對結果沒有影響。

開始測試:

登入mycat用戶端

# mysql -h127.0.0.1 -utest -ptest -P8066 -DTESTDB

建立測試表

mysql> create table test(id int,name varchar(10));
Query OK, 0 rows affected (0.22 sec)

插入資料

插入的格式如下:

insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,'test');

 

mysql> mysql> insert into test(id,name) values(next value for MYCATSEQ_MYCAT,'test1');
ERROR 1003 (HY000): mycat sequnce err.org.opencloudb.config.util.ConfigException: can't find definition for sequence :MYCAT
mysql> insert into test(id,name) values(next value for MYCATSEQ_MYCAT,'test1');
Query OK, 1 row affected (0.11 sec)

mysql> select * from test;
+------+-------+
| id  | name  |
+------+-------+
|  101 | test1 |
+------+-------+
1 row in set (0.09 sec)

 

第一次會報如下錯誤:

ERROR 1003 (HY000): mycat sequnce err.org.opencloudb.config.util.ConfigException: can't find definition for sequence :MYCAT

因為對於sequence_db_conf.properties的修改當前的mycat並不知曉,這時候,可重啟mycat或者登入9066管理連接埠進行 reload @@config;

至此,測試完畢,關鍵還是兩點:MYCAT_SEQUENCE必須大寫,sequence_db_conf.properties檔案中MYCAT=dn2必須大寫。

MyCAT實現MySQL讀寫分離實踐 

MyCAT實現MySQL的讀寫分離 

MyCAT ER分區的驗證

本文永久更新連結地址:

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.