程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> Mycat 全局系列號,mycat全局系列號

Mycat 全局系列號,mycat全局系列號

編輯:MySQL綜合教程

Mycat 全局系列號,mycat全局系列號


標簽:utf8

概述  

本篇文章介紹mycat怎樣在分庫分表的情況下保證主鍵的全局唯一方法,接下來就來分析三種方法各自的優缺點。

 

配置  

文件方式獲取

1.修改server配置文件

 vim server.xml

<system><property name="sequnceHandlerType">0</property></system>
注:sequnceHandlerType 配置為0表示使用本地文件讀取。

 

2.配置sequence_conf.properties配置文件

3.在mycat中運行語句測試(在邏輯庫中測試)

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

缺點:在 MyCAT 重啟後,配置文件中癿 sequence 會恢復到初始值。
優點:本地加載,讀取速度較快。

 

數據庫方式獲取

1.修改server配置文件

 vim server.xml

<system><property name="sequnceHandlerType">1</property></system>
注:sequnceHandlerType 配置為1表示從數據庫表中讀取。

2.配置讀取的節點,就是配置全局表在哪個節點上面,我這裡配置在dn1節點上面。

vim sequence_db_conf.properties

 3.創建全局表和函數

選擇mysql物理庫的dn1節點上執行下面語句,我配置的dn1即db1數據庫

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 ;

 4.測試插入數據,也是在mycat邏輯庫上執行

insert into user(id,name) values(next value for MYCATSEQ_GLOBAL,'中文');


優點:在 MyCAT 重啟後,sequence 值不會被初始化,比如當前MYCAT_SEQUENCE的初始值是100000,當mycat的重啟之後再執行插入數據後MYCAT_SEQUENCE的初始值就加100變成100100,新插入到表的值也是在加100的基礎上開始遞增,

缺點:當配置了主從復制時(A主B從),一開始主從上面的MYCAT_SEQUENCE表的current_value初始值是100000;當前配置的讀寫分離方案是A負責寫B負責讀當A宕機之後B負責寫A變成了讀,加入現在的全局ID已經到了 100103,這個時候如果A宕機了,

mycat應該是存在緩存current_value還是記錄的是A的值,不會立馬切換使用B上的current_value的值,如果這個時候mycat重啟了,這個時候全局系列號就開始使用B中的current_value值由於B值也是從100100開始那麼這個時候插入全局記錄到B中的表中就會和之前生成的100100到100103主鍵沖突了。不知道這算不算是一個BUG,所以當A宕機之後需要趕緊把A重啟好,這樣的話就算mycat重啟之後還是從A開始讀,這個時候全局ID就從100200開始了。

還有一種方法是當A宕機之後由於mycat還沒有重啟全局序列的ID還是緩存之前A的,這個時候把B的current_value增加100,這個時候如果切換到了A由於B的值是從100100開始不會和之前的沖突,如果這個時候A修復啟動了這個時候也要把A的current_value增加200避免切換到A之後又和現在的值沖突。

 

本地時間戳方式獲取

1.修改server配置文件

 vim server.xml

<system><property name="sequnceHandlerType">2</property></system>
注:sequnceHandlerType 配置為2表示時間戳方式。

 

2.測試插入數據,也是在mycat邏輯庫上執行,注意時間戳的長度有18位,保證表的字段長度足夠

insert into user(id,name) values(next value for MYCATSEQ_GLOBAL,'中文');

優點:不存在上面兩種方案因為mycat的重啟導致id重復的現象

缺點:數據類型太長

總結

 三種方式各有優缺點,根據自己的需求選擇。

 

 

 

備注:

    作者:pursuer.chen

    博客:http://www.cnblogs.com/chenmh

本站點所有隨筆都是原創,歡迎大家轉載;但轉載時必須注明文章來源,且在文章開頭明顯處給明鏈接。

《歡迎交流討論》

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved