博客
关于我
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/

你可能感兴趣的文章
mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
查看>>
Webpack 基本环境搭建
查看>>
mysql5.7 安装版 表不能输入汉字解决方案
查看>>
MySQL5.7.18主从复制搭建(一主一从)
查看>>
MySQL5.7.19-win64安装启动
查看>>
mysql5.7.19安装图解_mysql5.7.19 winx64解压缩版安装配置教程
查看>>
MySQL5.7.37windows解压版的安装使用
查看>>
mysql5.7免费下载地址
查看>>
mysql5.7命令总结
查看>>
mysql5.7安装
查看>>
mysql5.7性能调优my.ini
查看>>
MySQL5.7新增Performance Schema表
查看>>
Mysql5.7深入学习 1.MySQL 5.7 中的新增功能
查看>>
Webpack 之 basic chunk graph
查看>>
Mysql5.7版本单机版my.cnf配置文件
查看>>
mysql5.7的安装和Navicat的安装
查看>>
mysql5.7示例数据库_Linux MySQL5.7多实例数据库配置
查看>>
Mysql8 数据库安装及主从配置 | Spring Cloud 2
查看>>
mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
查看>>
MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
查看>>