博客
关于我
MySQL的KEY分区存在BUG,请慎用
阅读量:171 次
发布时间:2019-02-28

本文共 1567 字,大约阅读时间需要 5 分钟。

问题现象

上个星期在排查一个外包项目时,发现了一个非常奇怪的现象。该项目使用MySQL 5.7数据库管理几个频繁操作的表,并对这些表进行了key分区划分,分区数为10和100。创建表的语句类似于以下所示:

CREATE TABLE `tbl_key_partition` (    `id` varchar(64) NOT NULL COMMENT 'id',    `updateTime` datetime DEFAULT NULL    PRIMARY KEY (`id`)  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4  PARTITION BY KEY ()  PARTITIONS 100 ;

在观察过程中,发现所有的数据都分布在了偶数编号的分区上,而奇数编号的分区几乎没有数据。通过查询information_schema.partitions表或直接执行select count(*) from tbl_key_partition partition(p91),可以看到奇数编号分区的ibd文件大小始终固定为96K,而实际数据并未插入其中。这表明奇数编号分区完全没有数据。

问题重现

为了验证问题,用户在MySQL中手动创建了tbl_key_partition表,并使用load_data存储过程插入了10万条数据。存储过程的源码如下:

delimiter $$  CREATE PROCEDURE load_data (in num int)  BEGIN    DECLARE v INT DEFAULT 0;    WHILE v < num DO      INSERT INTO tbl_key_partition VALUES (concat(substring(md5(rand()), 1, 10), v), date_add('2020-01-01 00:00:00', interval v second));      SET v = v + 1;    END WHILE;  END$$  delimiter ;  call load_data(100000);

在插入数据后,用户发现数据基本上都写到了偶数编号的分区上,而奇数编号的分区只写了极少数的数据。同时,奇数编号分区的ibd文件大小始终保持在96K,这进一步证明了奇数编号分区没有实际数据。

原因分析

MySQL key 分区原理

key分区的原理是通过MySQL内置的哈希算法对分片键计算哈希值后,再对分区数取模来实现数据的分布分区。与哈希分区类似,key分区的哈希函数由MySQL服务器提供。在NDB集群中,通常使用MD5()函数来实现哈希计算。而对于其他存储引擎的表,MySQL服务器使用基于PASSWORD()函数的内部散列函数来生成哈希值。

原因

通过对问题的深入分析,发现这是一个MySQL 5.7的已知bug,尽管官方没有明确说明,但许多技术文章和论坛讨论了这一问题。具体来说,当分区数为偶数时,key分区的哈希函数可能存在偏移,导致数据无法均匀分布到所有分区中。例如,当分区数为10或100时,数据主要分布在偶数编号的分区,而奇数编号的分区几乎没有数据。

此外,许多文章指出,只有当分区数为质数时,key分区才能保证数据的均匀分布。例如,分区数为11、13或17时,数据分布较为均匀。而如果分区数为偶数(如64或128),则会导致奇数编号的分区完全没有数据。对于奇数但非质数的分区数(如63或121),数据分布虽然不均匀,但仍然会有数据存在于所有分区中。

综上所述,使用key分区在分区数为偶数时存在问题,建议避免使用key分区,而改用hash分区或范围分区来实现数据的分布分区。

转载地址:http://iubc.baihongyu.com/

你可能感兴趣的文章
mysql时间相减的问题
查看>>
mysql时间表示和计算
查看>>
MySQL是如何做容器测试的?
查看>>
mysql更改数据库表utf-8_修改mysql数据库为 utf-8
查看>>
mysql更改表引擎INNODB为MyISAM的方法总结
查看>>
mysql更新一个表里的字段等于另一个表某字段的值
查看>>
Mysql更新时间列只改日期为指定日期不更改时间
查看>>
MySQL更新锁(for update)摘要
查看>>
mysql更新频率_MySQL优化之如何了解SQL的执行频率
查看>>
mysql替换表的字段里面内容
查看>>
MySQL最多能有多少连接
查看>>
MySQL最大建议行数 2000w,靠谱吗?
查看>>
MySQL有哪些锁
查看>>
MySQL服务器安装(Linux)
查看>>
mysql服务器查询慢原因分析方法
查看>>
mysql服务无法启动的问题
查看>>
MySQL杂谈
查看>>
mysql权限
查看>>
mysql条件查询
查看>>
MySQL条件查询
查看>>