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

你可能感兴趣的文章
Nacos实战攻略:从入门到精通,全面掌握服务治理与配置管理!(下)
查看>>
Nacos心跳机制实现快速上下线
查看>>
nacos报错com.alibaba.nacos.shaded.io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
查看>>
Nacos服务注册与发现demo
查看>>
Nacos服务注册与发现的2种实现方法!
查看>>
nacos服务注册和发现原理简单实现案例
查看>>
Nacos服务注册总流程(源码分析)
查看>>
nacos服务注册流程
查看>>
Nacos服务部署安装
查看>>
nacos本地可以,上服务器报错
查看>>
Nacos注册中心有几种调用方式?
查看>>
nacos注册失败,Feign调用失败,feign无法注入成我们的bean对象
查看>>
nacos源码 nacos注册中心1.4.x 源码 nacos源码如何下载 nacos 客户端源码下载地址 nacos discovery下载地址(一)
查看>>
nacos源码 nacos注册中心1.4.x 源码 spring cloud alibaba 的discovery做了什么 nacos客户端是如何启动的(二)
查看>>
Nacos简介、下载与配置持久化到Mysql
查看>>
Nacos简介和控制台服务安装
查看>>
Nacos管理界面详细介绍
查看>>
Nacos编译报错NacosException: endpoint is blank
查看>>
nacos自动刷新配置
查看>>
nacos运行报错问题之一
查看>>