设为首页 收藏本站
查看: 1396|回复: 0

[经验分享] MySQL information_schema表查询导致内存暴涨

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-7-24 09:00:38 | 显示全部楼层 |阅读模式
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临时表。

如下图:

    231918584472785.jpg


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,1);
        table_list->table->null_row= 0;
      }
      else
        table_list->table->file->stats.records= 0;
      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)
$4 = { min_malloc = 32, block_size = 8160, block_num = 748, first_block_usage = 0,

Breakpoint 1, JOIN::exec (this=0x7f9a2c01f508) at sql/sql_select.cc:1843
(gdb) p *(this->thd->mem_root)
$5 = { min_malloc = 32, block_size = 8160, block_num = 758, first_block_usage = 0,

Breakpoint 1, JOIN::exec (this=0x7f9a2c01f508) at sql/sql_select.cc:1843
(gdb) p *(this->thd->mem_root)
$6 = {f min_malloc = 32, block_size = 8160, block_num = 767, first_block_usage = 0,





所以:这个sql,因为open太多表,执行时间过长, 而thd内存因为语句没有结束,无法释放,内存一直往上涨, 等语句结束,thd->mem_root的内存全部通过free释放掉。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-22586-1-1.html 上篇帖子: 数据库查询优化方案(处理上百万级记录如何提高处理查询速度) 下篇帖子: MySQL SQL优化 Windows 课程 如何 网站
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表