INFORMATION_SCHEMA is usually the place to go when you want to get facts about a system (how many tables do we have? what are the 10 largest tables? What is data size and index size for table t?, etc). However it is also quite common that such queries are very slow and create lots of I/O load. Here is a tip to avoid theses hassles: set innodb_stats_on_metadata to OFF.

This is a topic we already talked about, but given the number of systems suffering from INFORMATION_SCHEMA slowness, I think it is good to bring innodb_stats_on_metadata back on the table.

The problem

Let’s look at a system I’ve seen recently: MySQL 5.5, working set fitting in memory but not the whole dataset, around 4000 InnoDB tables.

The I/O load is very light as the server is an idle replica. You can see the I/O load from this partial pt-diskstats output:

 #ts device    rd_s rd_avkb    wr_s wr_avkb  busy in_prg
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 0.0 0.0 16.0 9.2 0% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 0.0 0.0 2.0 4.0 0% 0

The customer wanted to know what could be improved from the schema so we started by finding the 10 largest tables:


mysql> SELECT table_schema as 'DB',
table_name as 'TABLE',
CONCAT(ROUND(( data_length + index_length ) / ( 1024 * 1024 * 1024 ), 2), 'G') 'TOTAL'
FROM information_schema.TABLES
ORDER BY data_length + index_length DESC
LIMIT 10;
[...]
10 rows in set (1 min 32.23 sec)

1mn32s is slow, but it’s not really a problem. But the I/O load triggered by this query IS a problem:

 #ts device    rd_s rd_avkb    wr_s wr_avkb busy in_prg
1.0 sda2 0.0 0.0 18.0 8.7 0% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 100.0 16.0 0.0 0.0 79% 1
1.0 sda2 184.0 16.0 5.0 4.8 96% 1
1.0 sda2 97.0 16.0 0.0 0.0 98% 1
1.0 sda2 140.0 16.0 0.0 0.0 98% 1
1.0 sda2 122.0 16.0 17.0 4.0 98% 1
1.0 sda2 147.0 16.0 0.0 0.0 98% 1
[...]
1.0 sda2 136.0 16.0 0.0 0.0 98% 1
1.0 sda2 139.0 16.0 0.0 0.0 98% 1
1.0 sda2 149.0 16.0 0.0 0.0 98% 1
1.0 sda2 114.0 16.0 0.0 0.0 98% 1
1.0 sda2 147.0 16.0 8.0 4.0 96% 1
1.0 sda2 192.0 16.0 0.0 0.0 97% 1
1.0 sda2 141.0 16.0 0.0 0.0 98% 1
1.0 sda2 167.0 16.0 0.0 0.0 98% 1
1.0 sda2 15.0 16.0 0.0 0.0 6% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 0.0 0.0 16.0 4.0 0% 0

The disks are 100% busy reading InnoDB pages for our query. No doubt that if the server was running queries from the application, they would have been negatively impacted.

Now let’s execute the same query with innodb_stats_on_metadata = OFF;

mysql> SET GLOBAL innodb_stats_on_metadata = OFF;

mysql> SELECT [...]
10 rows in set (0.45 sec)

And let’s look at pt-diskstats:

 #ts device    rd_s rd_avkb    wr_s wr_avkb busy in_prg
1.0 sda2 0.0 0.0 16.0 9.2 0% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 0.0 0.0 16.0 4.0 1% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0
1.0 sda2 0.0 0.0 0.0 0.0 0% 0

No read load this time (and a much faster query!).

What is innodb_stats_on_metadata?

When the option is set to ON, InnoDB index statistics are updated when running SHOW TABLE STATUS, SHOW INDEX or when querying INFORMATION_SCHEMA.TABLES or INFORMATION_SCHEMA.STATISTICS. These statistics include the cardinality and the number of entries, they are used by the optimizer to find an optimal execution plan.

So even if SELECT statements cannot change the real statistics, MySQL updates the statistics for InnoDB tables. This is counterintuitive.

Is it useful? Not really, because InnoDB will always compute statistics when you open a table for the first time and when significant portions of the table have been modified (and when you run ANALYZE TABLE).

Now why did we have such a high read load when innodb_stats_on_metadata was set to ON? For InnoDB, statistics are estimated from random index dives, which translates to random reads.

The problem was magnified in the example because the whole dataset was not fitting in memory, the number of tables was high and the I/O subsystem was not very powerful.

Conclusion

It’s worth mentioning that the default value is now OFF with MySQL 5.6. So if you’re using MySQL 5.6, there’s no need to change anything. If you’re using MySQL 5.1 or 5.5, set innodb_stats_on_metadata to OFF and show your boss how you were able to get a 200x performance boost on some queries! And if you’re using MySQL 5.0 or below, you’ve just found another reason to upgrade!

————————————————————————————————————————

关于innodb_stats_on_metadata的另外一篇文章:

————————————————————————————————————————

这个问题来自冷之同学测试时候碰到的一个“诡异现象”。

1、 测试现象

测试的库有很多数据,但是重启之后,只对一个表的5w条记录作查询。查询条件客户端控制,确保查询范围。innodb_buffer_pool_size设置为35G。

现象1:查询性能会出现大幅度抖动;

现象2:介入追查后发现,Innodb_buffer_pool_pages_free = 0

其中bp剩余量这个是最直观异常的,因为访问的5w行记录撑死也不可能把35G内存吃光的。在QA同学确认没有别人在使用这个库的情况下。

2、过程和原因

其实几乎确定还是有别的查询在访问的。所以打开general_log。 发现除了QA同学压的语句外,这个Server上还有一些监控语句。

其中一个语句如下

select constraint_schema,table_name,constraint_name,constraint_type from information_schema.table_constraints where table_schema not in ('information_schema', 'mysql', 'test');

这个语句访问了表 information_schema.table_constraints.

跟踪发现这个语句触发了读盘操作。原因是需要访问引擎的info()接口,而InnoDB此时又“顺手”做了更新索引统计的操作dict_update_statistics。

更新索引统计的基本流程是随机读取部分demo行。所以这个操作实际上是访问了这个Server里面的所有表,因此不只是访问5w

而且由于别的表事先没有被访问,就会导致读盘操作,也包括BP的LRU更新。

3、哪些表会触发

不只是上面提到的table_constraints,information_schema库下的一下几个表,访问时候都会触发这个“顺手”操作。

information_schema.TABLES

information_schema.STATISTICS

information_schema.PARTITIONS

information_schema.KEY_COLUMN_USAGE

information_schema.TABLE_CONSTRAINTS

information_schema.REFERENTIAL_CONSTRAINTS

其实还有 show table status ,也会触发这个操作,只是只处理单表,所以影响没那么明显。

4、修改

头痛医头的方法是把这些监控去掉。但实际上像TABLES、TABLE_CONSTRAINTS这些表,都是静态数据,访问时不作索引统计也没关系的。

另外一个方法就是把innodb_stats_on_metadata设置成off,这样上述说到的这些表访问都不会触发索引统计。

实际上这个动态统计的功能已经不推荐了,官方已经在6.0以后增加参数控制DML期间也不作动态统计了。因此这个参数配置成off更合理些(默认是on).

注:

  1. Innodb引擎是通过抽样的方式来计算统计信息的,首先随机地读取少量的索引页面,然后以此为样本计算索引的统计信息。Innodb通过参数innodb_stats_sample_pages来设置样本页的数量。设置更大的值,理论上来说可以帮助生成更准确的索引信息。
  2. Innodb会在表首次打开,或者执行analyze table,或表的大小发生非常大的变化时计算索引的统计信息。
  3. Innodb在打开某些information_schema表,或者使用show table status 和show index,或在mysql客户端开启自动补全功能的时候都会触发索引统计信息的更新。
  4. 可在配置文件中设置                                                                                                                                                                [mysqld]
    innodb_stats_on_metadata = OFF

参考:

http://www.mysqlperformanceblog.com/2013/12/03/innodb_stats_on_metadata-slow-queries-information_schema/

http://dinglin.iteye.com/blog/1575840

innodb_stats_on_metadata and slow queries on INFORMATION_SCHEMA的更多相关文章

  1. mysql slow query---pt-query-digest----db structure consistency,monitor table records before and after transaction.

    将数据库脚本纳入版本管理是很必要的,尤其对于需要在客户那里部署升级的系统. 对于Python Django等框架,由于数据库是通过Model生成的,因此框架本身包括数据库升级工具,并通过代码版本间接管 ...

  2. mysql slow 分析工具

    慢查询有什么用?         它能记录下所有执行超过long_query_time时间的SQL语句,帮你找到执行慢的SQL,方便我们对这些SQL进行优化. 测试用 MySQL 版本.   Serv ...

  3. mysql常规巡检

    mysql常规巡检   目录 一.巡检脚本 二.下载巡检脚本 三.脚本执行说明 1.inspection.conf 使用说明 2.inspection_mysql.sh 使用说明 3.mysqltun ...

  4. MySQL初始化以及客户端工具的使用

    MySQL初始化以及客户端工具的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是关系型数据库 关系型数据库通常是把所有的数据都组织成二维关系.之所以称为关系型数据库是 ...

  5. MySQL查看数据库相关信息

    使用MySQL时,需要了解当前数据库的情况,例如当前的数据库大小.字符集.用户等等.下面总结了一些查看数据库相关信息的命令   1:查看显示所有数据库 mysql> show databases ...

  6. Ubuntu 12.04 安装MySQL

    本文地址:http://www.cnblogs.com/yhLinux/p/4012689.html 本文适合新手入门. 本文是对 Ubuntu 12.04 环境下安装 MySQL 的记录,通过这两天 ...

  7. spring项目的 context root 修改之后,导致 WebApplicationContext 初始化两次的解决方法

    修改了 spring web 项目的 context root 为 / 之后,在启动项目时,会导致 WebApplicationContext  初始化两次,下面是其初始化日志: 第一次初始化: 四月 ...

  8. mysqladmin note

    hr,fresh meat!! --------------------------------------------------- 15 Practical Usages of Mysqladmi ...

  9. Understanding postgresql.conf : log*

    After loooong pause, adding next (well, second) post to the “series“. This time, I'd like to describ ...

随机推荐

  1. Windows和Linux系统下,虚拟环境安装的全面说明和详细步骤

    虚拟环境的创建和使用 用途: ​ 1.在同一台电脑安装同一个包的不同版本 2.记录项目所用的所有的包的版本,方便部署. 如何使用: 1.创建虚拟环境 mkvirtualenv 虚拟环境名 -p pyt ...

  2. QOS-QOS(服务质量)概述

    QOS-QOS(服务质量)概述 2018年7月7日  20:29 概述及背景: 1.  引入: 传统IP网络仅提供“尽力而为”的传输服务,网络有可用资源就转发,资源不足时就丢弃 新一代IP网络承载了 ...

  3. HyperLedger Fabric 1.4 区块链开发平台(4.1)

    目前区块链开发平台分“公有链平台”和“联盟链系统”两类,“公有链平台”主要以以太坊为主的平台,可以在该类平台上进行代币的发行和根据各种模块搭建应用:“联盟链系统”主要以超级账本为主的开源系统,该类开源 ...

  4. HDU1209:Clock

    参考:https://blog.csdn.net/libin56842/article/details/8990530 https://blog.csdn.net/u011479875/article ...

  5. 「日常训练」「小专题·图论」 Cow Contest (1-3)

    题意 分析 问题是要看出来这是个floyd闭包问题.我没看出来- - 分析之后补充. 代码 // Origin: // Theme: Graph Theory (Basic) // Date: 080 ...

  6. webpack loader之css、scss、less、stylus安装

    1.打包css,需要安装css-loader和style-loader yarn add --dev css-loader style-loader 或者 npm install --save-dev ...

  7. 安装VMware的一般步骤(安装过程总结)

    (安装的是vmwareworkstation11以上) 0.遇到问题为没有权限打开服务“VMAuthdService”时,需要去管理->服务中打开对应的Windows Management In ...

  8. 小心!FOMO3D的坑

    null 01 前方高能 近日,区块链机构安比(SECBIT)实验室审计后确认,FOMO3D游戏的智能合约存在随机数漏洞可被利用,FOMO3D合约及所有抄袭源码的山寨合约均存在该安全漏洞. 原本设计上 ...

  9. NodeJs命令行新建项目实例

    安装Nodejs: 下载地址:http://nodejs.org/download/ 设置环境变量,例如我将nodejs装在D:/program文件夹下,则设以下为系统环境变量 D:\Program\ ...

  10. linux备忘录-正则表达式与文件格式化处理

    正则表达式 POSIX标准的符号 [:alnum:] -> 英文大小写字母和数字 0-9,A-Z,a-z [:alpha:] -> 英文大小写字母 A-Z,a-z [:blank:] -& ...