mycat全局系列号


1.为什么需要全局系列号:


1.1产品介绍:


在实现分库分表的情况下,数据库自增主键无法保证自增主键的全局唯一。为此,mycat提供了全局sequence,

并且提供了包含本地配置和数据库配置多种实现方式。


1.2模拟自增主键会出现的问题:


脑瓜子有点笨,一直没太搞清楚为什么分表分库情况下,无法保证自增主键的全局唯一?所以,动手测试模拟出自增主键的问题?


以下操作是基于正常mycat使用环境下

	


我的mycat有一张表t1分库分表,在dn1,dn2两个node都有这个表格,使用分表的规则是sharding-by-intfile


规则配置文件如下:

	
		
			city
			hash-int
		
	
		partition-hash-int.txt
		0
	
	[root@ha1 conf]# cat partition-hash-int.txt 
	gz=0
	sz=1


以上的整体含义是:city是gz的数据放到dn1的表格t1,city是sz的数据放到dn2的表格t1。


我准备修改这个表格,添加一个主键,并且设定这个主键自增。

mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(15) | NO   |     | NULL    |                |
| bu    | varchar(10) | NO   |     | NULL    |                |
| city  | varchar(5)  | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)


插入4条数据,其中两条city设置成sz,两条city设置成gz

mysql> select * from t1;
Empty set (0.03 sec)

mysql> insert into t1(name,bu,city) value('am1','cs','sz');
Query OK, 1 row affected (0.08 sec)

mysql> insert into t1(name,bu,city) value('am2','cs','gz'),('am3','net','sz');
Query OK, 2 rows affected (0.06 sec)

mysql> insert into t1(name,bu,city) value('am4','net','gz');
Query OK, 1 row affected (0.04 sec)


检索看看:

mysql> select * from t1;
+----+------+-----+------+
| id | name | bu  | city |
+----+------+-----+------+
|  4 | am1  | cs  | sz   |
|  5 | am3  | net | sz   |
|  3 | am2  | cs  | gz   |
|  4 | am4  | net | gz   |
+----+------+-----+------+


哈哈哈,问题出现了。id出现一样的,这就是全局系列号的存在的重大意义所在。


2.全局系列号的配置:


2.1本地文件方式


此方式mycat将sequence配置到文件中,使用到sequence中的配置后,mycat会更下classpath中的sequence_conf.properties文件中的

sequence当前的值。


这段解释看得不是一般的拗口。不动手根本不知道在说什么。


首先是sequence读取的配置文件:

[root@ha1 conf]# pwd
/usr/local/mycat/conf
[root@ha1 conf]# ls |grep sequ
sequence_conf.properties
sequence_db_conf.properties
sequence_distributed_conf.properties
sequence_time_conf.properties
[root@ha1 conf]#


本地配置文件读取的是:sequence_conf.properties


看看内容:

[root@ha1 conf]# cat sequence_conf.properties 
#default global sequence
GLOBAL.HISIDS=
GLOBAL.MINID=10001
GLOBAL.MAXID=20000
GLOBAL.CURID=10000

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

CUSTOMER.HISIDS=
CUSTOMER.MINID=1001
CUSTOMER.MAXID=2000
CUSTOMER.CURID=1000

ORDER.HISIDS=
ORDER.MINID=1001
ORDER.MAXID=2000
ORDER.CURID=1000

HOTNEWS.HISIDS=
HOTNEWS.MINID=1001
HOTNEWS.MAXID=2000
HOTNEWS.CURID=1000


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


server.xml中配置:

0

注:sequnceHandlerType需要配置为0,表示使用本地文件方式。


实际操作:

[root@ha1 conf]# pwd 
/usr/local/mycat/conf
[root@ha1 conf]# ls |grep server.xml 
server.xml


在server.xml 段结尾处加入

0

参考如下:

		
		true

		
		0

	


然后重启mycat。


测试:


就拿前面的表格t1来测试。


清空t1

mysql> truncate table t1;
Query OK, 0 rows affected (0.15 sec)

mysql> select * from t1;
Empty set (0.01 sec)


插入数据:

mysql> insert into t1(id,name,bu,city)values(next value for MYCATSEQ_GLOBAL,'am1','sys','gz');
Query OK, 1 row affected (0.05 sec)

mysql> insert into t1(id,name,bu,city)values(next value for MYCATSEQ_GLOBAL,'am2','sys','sz');
Query OK, 1 row affected (0.05 sec)

mysql> insert into t1(id,name,bu,city)values(next value for MYCATSEQ_GLOBAL,'am3','sys','sz');
Query OK, 1 row affected (0.03 sec)

mysql> insert into t1(id,name,bu,city)values(next value for MYCATSEQ_GLOBAL,'am4','sys','gz');
Query OK, 1 row affected (0.05 sec)


检索看看:

mysql> select * from t1;
+-------+------+-----+------+
| id    | name | bu  | city |
+-------+------+-----+------+
| 10002 | am1  | sys | gz   |
| 10005 | am4  | sys | gz   |
| 10003 | am2  | sys | sz   |
| 10004 | am3  | sys | sz   |
+-------+------+-----+------+
4 rows in set (0.02 sec)


实现了自增键的全局唯一。


缺点:当MyCAT重新发布后,配置文件中的sequence会恢复到初始值。

优点:本地加载,读取速度较快。


mycat重新发布的意思有点不明白。后面在测试。