mysql的partition与auto_increment

mysql 5.1之后,开始新增了partition功能,可以做到对代码透明的情况下进行数据分区。但是从实际使用中来看,限制颇多:

    • 如果用来分区的字段和主键不是同一个,则不能分区
    • 见很早前的一篇译文mysql 5.1新功能 -- 按日期分区,如果查询条件中没有正确利用到分区的字段,那么partition的效果为零
    • mysql 5.1.31之前的partition功能有较大的bug,会导致自增字段不能正常自增,怎么个不正常法?auto_increment值会非正常增长,突然比当前的最大id小很多,插入数据时导致duplicate key错误。

这些问题都能凑合着对付过去,但是partition功能和auto_increment似乎是天生的敌人。从使用习惯上来说,我们会把auto_increment字段设置为主键,这个字段要是unique的才比较稳妥,这个情况下如果希望用其它字段来进行分区的话,几乎就成了不可能的任务。以这张表为例:


CREATE TABLE user (  
  id int auto_increment PRIMARY KEY,
  uid int,
  foo varchar(32)
) engine=myisam;

这个时候试图以uid进行分区会怎么样?是以怎样的惨淡结局收场?变通的办法是对自增字段做一些调整,从mysql的手册来看,自增字段不一定要设置成主键,仅仅是普通的index也可以,那么把表结构换成下面这个样子,就可以分区成功。


CREATE TABLE user (  
  id int auto_increment,
  uid int,
  foo varchar(32),
  index (id)
) engine=innodb PARTITION BY HASH (uid) PARTITIONS 4;

我在实际环境中有一张表达到了几亿条数据,如果要用时下流行的sharding策略,必须在代码上做一些改动,当时偷了点懒直接使用partition功能,用了大半年倒也相安无事。只是分区表占用内存相当的大,如果有其它的表经常出现慢查询耗费服务器资源,那么雪崩效应就出现了,所有的查询都会堵塞变得非常慢。

作者: 发表于December 11, 2009 at 10:18 pm

版权信息: 可以任意转载, 转载时请务必以超链接形式标明文章原始出处作者信息及此声明

Tags:

2 条评论

  1. xLight 于 2009-12-12 @ 23:23:51 留言

    MySQL啊MySQL
    5.1版就是个噩梦

  2. Volcano 于 2009-12-13 @ 17:51:56 留言

    percona的5.1值得试试,还比较稳定

RSS 为此帖反馈评论