MySQL案例 | consider increasing server sort buffer

简介: MySQL案例 | consider increasing server sort buffer

今天一个错误反馈到我这边,我还是第一次遇到这种错误,然后就分析了一下,因为以前曾经做过filesort流程分析,新书《深入理解MySQL主从原理》中也有一节专门介绍这部分。这里简单做了一下debug后分析出原因。

问题版本5.7.27,我的测试版本5.7.22。

一、问题模拟

mysql> show create table testsorterr3 \G
*************************** 1. row ***************************
       Table: testsorterr3
Create Table: CREATE TABLE `testsorterr3` (
  `id` int(11) DEFAULT NULL,
  `name1` varchar(510) NOT NULL,
  `name2` varchar(510) NOT NULL,
  UNIQUE KEY `name1` (`name1`,`name2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> select count(*) from testsorterr3 ;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

mysql> show variables like 'sort_buffer_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| sort_buffer_size | 32768 |
+------------------+-------+
1 row in set (0.02 sec)


mysql>  select id from testsorterr3 order by id;
ERROR 1038 (HY001): Out of sort memory, consider increasing server sort buffer size

当然问题解决很简单,加大sort_buffer_size 设置即可。

但是这里实际上为32K,我只是按照一个int类型的4字节类型进行排序而已,并且表中一条数据都没有报错显然有点让人摸不到头脑说sort_buffer_size设置小了。

再说sort_buffer_size不够不是可以使用临时文件做归并排序嘛?

二、问题分析

注意这里只谈 original filesort algorithm(回表排序)。

先来看看抛错点

    if (memory_available < min_sort_memory)

{
my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERRORLOG + ME_FATALERROR));
goto err;
}

这里memory_available 就是我们sort_buffer_size 的设置大小,这里就是32K。min_sort_memory则是通过计算得到的如下:

    const ulong min_sort_memory=
max<ulong>(MIN_SORT_MEMORY,
ALIGN_SIZE(MERGEBUFF2 (param.rec_length + sizeof(uchar))));

其中MIN_SORT_MEMORY为32K,MERGEBUFF2 为15。

那么剩下的变量实际上就只有param.rec_length一个了,这实际上是计算出来的排序字段的长度。

而对于original filesort algorithm(回表排序)而言这个值实际上包含的是:

我们来简单debug一下:

(gdb) p ref_length
$28 = 3064
(gdb) p sort_length
$29 = 5
(gdb)

可以看到这里3064字节,大概就是51023的长度,因为我们这里非空唯一键为(`name1`,`name2`),Innodb表正是按照它进行组织的,而sort_length为5是int类型(4字节)再加上可以为null(1字节)也就是5字节。

好了,我们大概计算一下,那么

忽略一个指针的大小,大概就是

比sort_buffer_size设置的32K还要大,所以报错了。

并且整个计算过程还没有真正的进行排序,因此即便是空表也会进行计算,和数据量无关。就是本案中MySQL认为sort_buffer_size连一行排序数据都装不下产生报错的原因。

三、如何避免

显然这个问题和表的设计有关,如果遵循开发设计规范,采用自增INT做主键,问题自然解决,这是治本

当然简单地加大sort_buffer_size,这是治标


全文完。

Enjoy MySQL :)

            </div>
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
小程序 搜索推荐
uniapp中如何使用image图片
uniapp中如何使用image图片
2562 0
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的二手儿童绘本交易系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的二手儿童绘本交易系统附带文章和源代码部署视频讲解等
139 7
|
前端开发 Java API
淘系接口推荐:淘宝图片搜索商品数据接口,轻松获取相似商品
淘系接口推荐:淘宝图片搜索商品数据接口,轻松获取相似商品
1288 6
|
前端开发
uniapp 实现退出登录 清除Token
uniapp 实现退出登录 清除Token
466 0
|
2天前
|
数据采集 人工智能 安全
|
11天前
|
云安全 监控 安全
|
3天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1020 151
|
3天前
|
编解码 人工智能 机器人
通义万相2.6,模型使用指南
智能分镜 | 多镜头叙事 | 支持15秒视频生成 | 高品质声音生成 | 多人稳定对话
|
16天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1716 9