全局序列号介紹
在實作分庫分表的情況下,資料庫自增主鍵已無法保證自增主鍵的全局唯一。為此,mycat 提供了全局sequence,并且提供了包含本地配置和資料庫配置等多種實作方式。
本地檔案方式
原理:此方式mycat将sequence配置到檔案中,當使用到sequence中的配置後,mycat會更下classpath中的sequence_conf.properties檔案中sequence目前的值。
配置方式:
在sequence_conf.properties檔案中做如下配置:
global_seq.hisids=
global_seq.minid=1001
global_seq.maxid=1000000000
global_seq.curid=1000
其中hisids表示使用過的曆史分段(一般無特殊需要可不配置),minid表示最小id值,maxid表示最大id值,curid表示目前id值。
server.xml中配置:
1
<code><</code><code>property</code> <code>name</code><code>=</code><code>"sequncehandlertype"</code><code>>0</</code><code>property</code><code>></code>
注:sequncehandlertype需要配置為0,表示使用本地檔案方式。 1表示資料庫方式
使用示例:
<code>insert</code> <code>into</code> <code>table1(id,</code><code>name</code><code>) </code><code>values</code><code>(</code><code>next</code> <code>value </code><code>for</code> <code>mycatseq_global,‘test’);</code>
缺點:當mycat重新釋出後,配置檔案中的sequence會恢複到初始值。
優點:本地加載,讀取速度較快。
資料庫方式
原理:在資料庫中建立一張表,存放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剩餘值不會再使用。
server.xml配置:
<code><</code><code>property</code> <code>name</code><code>=</code><code>"sequncehandlertype"</code><code>>1</</code><code>property</code><code>></code>
注:sequncehandlertype 需要配置為1,表示使用資料庫方式生成sequence.
資料庫配置:
1) 建立mycat_sequence表
– 建立存放sequence的表
drop table if exists mycat_sequence;
– name sequence名稱
– current_value 目前value
– increment 增長步長! 可了解為mycat在資料庫中一次讀取多少個sequence. 當這些用完後, 下次再從資料庫中讀取.
2
3
4
5
6
<code>create</code> <code>table</code> <code>mycat_sequence (</code>
<code>name</code> <code>varchar</code> <code>(50) </code><code>not</code> <code>null</code><code>,</code>
<code>current_value </code><code>int</code> <code>not</code> <code>null</code><code>,</code>
<code>increment </code><code>int</code> <code>not</code> <code>null</code> <code>default</code> <code>100,</code>
<code>primary</code> <code>key</code> <code>(</code><code>name</code><code>)</code>
<code>) engine = innodb;</code>
– 插入一條sequence
<code>insert</code> <code>into</code> <code>mycat_sequence(</code><code>name</code><code>,current_value,increment) </code><code>values</code> <code>(‘</code><code>global</code><code>’, 100000, 100);</code>
2) 建立相關function
– 擷取目前sequence的值 (傳回目前值,增量)
7
8
9
10
11
12
13
14
<code>drop</code> <code>function</code> <code>if exists `mycat_seq_currval`;</code>
<code>delimiter ;;</code>
<code>create</code> <code>definer=`root`@`%` </code><code>function</code> <code>`mycat_seq_currval`(seq_name </code><code>varchar</code><code>(50)) </code>
<code>returns</code> <code>varchar</code><code>(64) charset latin1</code>
<code> </code><code>deterministic</code>
<code>begin</code>
<code> </code><code>declare</code> <code>retval </code><code>varchar</code><code>(64);</code>
<code> </code><code>set</code> <code>retval=</code><code>"-999999999,null"</code><code>; </code>
<code> </code><code>select</code> <code>concat(</code><code>cast</code><code>(current_value </code><code>as</code> <code>char</code><code>),</code><code>","</code><code>,</code><code>cast</code><code>(increment </code><code>as</code> <code>char</code><code>) ) </code><code>into</code> <code>retval </code>
<code> </code><code>from</code> <code>mycat_sequence </code><code>where</code> <code>name</code> <code>= seq_name; </code>
<code> </code><code>return</code> <code>retval ; </code>
<code>end</code>
<code>;;</code>
<code>delimiter ;</code>
– 設定sequence值
<code>drop</code> <code>function</code> <code>if exists `mycat_seq_nextval`;</code>
<code>create</code> <code>definer=`root`@`%` </code><code>function</code> <code>`mycat_seq_nextval`(seq_name </code><code>varchar</code><code>(50)) </code><code>returns</code> <code>varchar</code><code>(64)</code>
<code> </code><code>charset latin1</code>
<code> </code><code>update</code> <code>mycat_sequence </code>
<code> </code><code>set</code> <code>current_value = current_value + increment </code>
<code> </code><code>where</code> <code>name</code> <code>= seq_name; </code>
<code> </code><code>return</code> <code>mycat_seq_currval(seq_name); </code>
– 擷取下一個sequence值
<code>drop</code> <code>function</code> <code>if exists `mycat_seq_setval`;</code>
<code>create</code> <code>definer=`root`@`%` </code><code>function</code> <code>`mycat_seq_setval`(seq_name </code><code>varchar</code><code>(50), value </code><code>integer</code><code>) </code>
<code> </code><code>set</code> <code>current_value = value </code>
<code> </code><code>where</code> <code>name</code> <code>= seq_name; </code>
3) sequence_db_conf.properties相關配置,指定sequence相關配置在哪個節點上:
例如:
user_seq=test_dn1
注意:mycat_sequence表和以上的3個function,需要放在同一個節點上。function請直接在具體節點的資料庫上執行,如果執行的時候報:
you might want to use the less safe log_bin_trust_function_creators variable
需要對資料庫做如下設定:
windows下my.ini[mysqld]加上log_bin_trust_function_creators=1
linux下/etc/my.cnf下my.ini[mysqld]加上log_bin_trust_function_creators=1
修改完後,即可在mysql資料庫中執行上面的函數.
本文摘自:《mycat權威指南》
特别說明:尊重作者的勞動成果,轉載請注明出處哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt332