MySQL information_schema表查询导致内存暴涨
case:下面的一条sql语句,导致mysql实例内存暴涨:
select * from tables where table_name not in(select table_name from partitions group by table_name having count(*)>1 );
mysql 5.5, 1w+的innodb表。
下面看下调查的结果:
1. sql的执行情况以及内存分配:
step1: 构造information_schema.tables临时表
1.1 构造临时表tables结构:
说明:func=create_schema_table; engine=heap
内存: tables是heap引擎的表,临时构造,使用堆内存;语句结束close_tmp_tables释放。
1.2 填充临时表tables数据:一共由三类表来填充tables的内存
1. memory引擎:
说明:information_schema下的表,创建临时table,
内存: 使用堆内存,填充完数据后 close_tmp_tables,释放内存。
2. mysiam引擎:
说明:information_schema下一部分表,是mysiam引擎的临时表。
内存: 使用堆内存,创建磁盘临时文件,close_tmp_tables,释放内存,删除临时文件。
3. innodb引擎和其它:
说明:使用正常的open_tables函数,创建table,table_share, handler对象。
内存: 使用堆内存
step2:构造information_schema.partition临时表
步骤和step1一样,但partition因为blob的原因,系统创建的时候,指定了mysiam引擎的临时表,而非内存heap临时表。
如下图:
2. 构造两张临时表的开销:
实例一共1w张表,加上系统表,大约10200张,为了构造这两个临时表:
a) 一共open了大约 10200*2 次,加上创建临时表,临时磁盘文件。
b) 而table_cache设置的400,所以opened_table基本没有复用,打开后马上关闭了。
两张并不存在的临时表,全部构造完成,以上为了构造临时表而open大量表所使用的堆内存,现在已经释放。
3. 下面可以执行sql
sql的执行计划是:
1 information_schema.tables
n nest loops information_schema.partitions
nest loop即:对于tables每一条记录要扫描一次patitions。
4. 关键的问题是:
执行计划调用如下函数栈:
mysql_select
JOIN::exec
do_select
sub_select
evaluate_join_record
Item_subselect::exec
subselect_single_select_engine::exec
JOIN::exec
在JOIN::exec有以下的判断:
if (table_list->schema_table_state && is_subselect)
{
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
table_list->table->file->ha_delete_all_rows();
free_io_cache(table_list->table);
filesort_free_buffers(table_list->table,);
table_list->table->null_row= ;
}
else
table_list->table->file->stats.records= ;
if (do_fill_table(thd, table_list, tab))
{
即: subselect子查询如果是schema_table, 并且在执行状态中, 需要全部删除 partition里的数据,每次nest loop都重新do_fill_table。
执行的结果就是:
a) 为了构造两个临时表,open了10200*2次表,
b) 又为了每次nest loop,删除并构造了10200次partition表,一共open了10200*10200次表。
table_cache可以完全无视了。
但为什么会占用大量的内存?
在整个构造的过程中:
1. 堆内存 : 在open所有表后,往临时表填充完数据,就free了,不用等语句结束。
2. 线程内存: 为了构造字段,table list这些,内存都是从thd->mem_root线程中分配的,需要等语句结束才释放。
如下,每次子查询执行一次,thd->mem_root增加的memory block;
gdb) p *(this->thd->mem_root)
$ = { min_malloc = , block_size = , block_num = 748, first_block_usage = , Breakpoint , JOIN::exec (this=0x7f9a2c01f508) at sql/sql_select.cc:
(gdb) p *(this->thd->mem_root)
$ = { min_malloc = , block_size = , block_num = 758, first_block_usage = , Breakpoint , JOIN::exec (this=0x7f9a2c01f508) at sql/sql_select.cc:
(gdb) p *(this->thd->mem_root)
$ = {f min_malloc = , block_size = , block_num = 767, first_block_usage = ,
所以:这个sql,因为open太多表,执行时间过长, 而thd内存因为语句没有结束,无法释放,内存一直往上涨, 等语句结束,thd->mem_root的内存全部通过free释放掉。
MySQL information_schema表查询导致内存暴涨的更多相关文章
- MySQL多表查询合并结果union all,内连接查询
MySQL多表查询合并结果和内连接查询 1.使用union和union all合并两个查询结果:select 字段名 from tablename1 union select 字段名 from tab ...
- 记一次mysql多表查询(left jion)优化案例
一次mysql多表查询(left jion)优化案例 在新上线的供需模块中,发现某一个查询按钮点击后,出不来结果,找到该按钮对应sql手动执行,发现需要20-30秒才能出结果,所以服务端程序判断超时, ...
- MySQL多表查询之外键、表连接、子查询、索引
MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...
- Mysql 单表查询 子查询 关联查询
数据准备: ## 学院表create table department( d_id int primary key auto_increment, d_name varchar(20) not nul ...
- (转)Mysql 多表查询详解
MySQL 多表查询详解 一.前言 二.示例 三.注意事项 一.前言 上篇讲到mysql中关键字执行的顺序,只涉及了一张表:实际应用大部分情况下,查询语句都会涉及到多张表格 : 1.1 多表连接有 ...
- MySQL多表查询回顾
----------------------siwuxie095 MySQL 多表查询回顾 以客户和联系人为例(一对多) 1.内连接 /*内连接写法一*/ select * from t_custom ...
- python 3 mysql 单表查询
python 3 mysql 单表查询 1.准备表 company.employee 员工id id int 姓名 emp_name varchar 性别 sex enum 年龄 age int 入职 ...
- python3 mysql 多表查询
python3 mysql 多表查询 一.准备表 创建二张表: company.employee company.department #建表 create table department( id ...
- [自带避雷针]DropShadowEffect导致内存暴涨
原文:[自带避雷针]DropShadowEffect导致内存暴涨 [自带避雷针]DropShadowEffect导致内存暴涨 周银辉 从学习WPF开始, 就知道"位图效果"不是什 ...
随机推荐
- oninput和onpropertychange
时常会有监听输入框输入的场景,比如新浪微博的发微博输入框: 还有边输入边提示: 以及form表单边输入边验证,当内容为空提示或者改变输入框的样式达到提示效果. 在IE中是onpropertychang ...
- bat文件的妙用1-一键开启所有开发软件
每天早上来的第一件事情,就是打开电脑,然后开一堆的软件 1.wamp 开发环境 2.钉钉 通讯工具 3.PHPstrom 开发工具 4.nodejs.bat Nodejs的扩展(node D:/w ...
- 安装Apache Web 服务器软件
Apache下载地址:http://pan.baidu.com/s/1kTKCEOn 1: 右击安装 2: 3: 4: 5:安装成功: 6:测试在浏览器地址栏输入:localhost; 会出现一个页面 ...
- asp.net mvc上传头像加剪裁功能介绍
正好项目用到上传+剪裁功能,发上来便于以后使用. 我不能告诉你们其实是从博客园扒的前台代码,哈哈. 前端是jquery+fineuploader+jquery.Jcrop 后台是asp.net mvc ...
- css文本换行你所不知道的技巧
前言:这是最近翻译的一篇文章 我在header标签开头忘里边加入一个span标签的时候,有一点小问题.我总是想确保在span标签之前能够换行.明确地讲,在标签前边加入<br> 并没有什么错 ...
- mysql更改默认存储引擎
在mysql的官网上看到在mysql5.5以上的版本中已经更改了默认的存储引擎,在5.5版本以前是Myisam以后是Innodb. InnoDB as the Default MySQL Storag ...
- 企业生产环境下不同业务的linux分区建议
常规分区方案: /boot: 100M swap:内存的1至1.5倍 / : 剩余硬盘大小 DB及存储:有大量重要的数据 /boot : 100M swap: 内存的1至1.5倍,如果内存大于等于1 ...
- Vijos P1003 等价表达式 随机数+单调栈
题目链接:https://vijos.org/p/1003 题意: 1. 表达式只可能包含一个变量‘a’. 2. 表达式中出现的数都是正整数,而且都小于10000. 3. 表达式中可以包括四种运算‘+ ...
- [转]python 之字典{}(Hashmap)
字典 python里的字典就像java里的HashMap,以键值对的方式存在并操作,其特点如下 通过键来存取,而非偏移量: 键值对是无序的: 键和值可以是任意对象: 长度可变,任意嵌套: 在字典里,不 ...
- 闲谈前端编码解码、C#编码解码。
最近做项目,出现中文乱码的问题,特地研究一下. GB2312,指的是中文 UTF8,指的是国标,包含中文.英文. 但是通过JQuery.ajax的Get.Post,如果直接传递中文或者特殊字符的特使字 ...