背景
为了提供优化器支持,InnoDB维护了每个表的索引统计信息(index statistics)。在之前的一篇文章中作过介绍。
文章里面介绍到索引统计信息有几个更新策略,并建议允许关闭动态更新。顺便提及,5.6已经提供了Persistent Statistics 选项,达到相同的目的。
在5.5版本还是必须动态更新。本文介绍在动态更新时的一个问题。
索引统计的动态更新策略
这个策略是比较简单的。每个表维护一个stat_modified_counter,每次增、删、改一行时加1,当counter满足一下两个条件之一时,则进行依次动态统计,之后清0 (5.5.29)
1) 1) counter > 2000000000
2) 2) counter > 16 + table->stat_n_rows / 16
table->stat_n_rows表的总行数目(估计值)
row_update_statistics_if_needed( /*============================*/ dict_table_t* table) /*!< in: table */ { ulint counter;
counter = table->stat_modified_counter; table->stat_modified_counter = counter + 1;
if (counter > 2000000000 || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) {
dict_update_statistics(table, FALSE /* update even if stats are initialized */); } |
执行索引统计的函数是dict_update_statistics,在执行统计期间,对stat加一个x锁。
存在问题
由于这个值不要求精确,因此在counter更新时并未加锁。这个问题并不大,但是未加锁导致另外一个问题:短时间内多次调用dict_update_statistics。
stat_modified_counter清0是在dict_update_statistics中调用的,但若有多个线程同时判断后进入dict_update_statistics,则会导致多次调用。
在一个测试场景我们从现场看到同一个时刻用11个用户线程调用dict_update_statistics。这意味着至少多调用了10次索引统计。而索引统计的方法是通过从表中取样本估算的,如果表数据较多,这个索引统计的浪费就很明显了。对查询和更新性能都会有影响。
简单修改
dict_update_statistics的逻辑流程是
1) 1) 加x锁
2) 2) 索引统计
3) 3) stat_modified_counter 置0
4) 4) 解锁
简单修改可以在加x锁之后再次判断stat_modified_counter是否需要进行索引统计,若不需要则解锁返回即可。
5.6已经提供了Persistent Statistics 选项,但若关闭,也会有这个问题。
相关推荐
py_innodb_page_info工具为《INNODB存储引擎》作者姜承尧写的。 该工具用来分析表空间中的各页得类型和信息,用python编写。 网上多是python2版本的,这里给出python3版本的。
innodb_data_file_path用来指定innodb tablespace文件,如果我们不在My.cnf文件中指定innodb_data_home_dir和innodb_data_file_path那么默认会在datadir目录下创建ibdata1 作为innodb tablespace。 说明 在测试环境...
《mysql技术内幕-InnoDB存储引擎》中使用的页分析工具类py_innodb_page_info
使用py_innodb_page_info 查看分析各种log以及data file,深入研究mysql的存储引擎底层原理与实现。 mysql innodb undo redo
使用py_innodb_page_info 查看分析各种log以及data file,深入研究mysql的存储引擎底层原理与实现
主要介绍了使用innodb_force_recovery解决MySQL崩溃无法重启问题,这只一个成功案例,并不是万能的解决方法,需要酌情考虑,需要的朋友可以参考下
在innodb存储引擎中数据访问以page为单位,page也是innodb管理数据库的最小磁盘单位,每个page的默认大小为16KB(可以通过参数innodb_page_size进行调整,在5.7增加了对32KB和64KB的大小支持,在此之前的版本支持4KB,...
内容包括: 1.MySQL的Innodb引擎配置 1.如何配置MySQL服务器的最大连接数量 2.如何配置innodb_open_files,table_open_cache,innodb_file_io_threads和innodb_buffer_pool_size,innodb_log_file_size
mysql 5.6 新特性 innodb
mysql 存储引擎 innodb 日志结构 非常好用,欢迎大家下载!
InnoDB存储引擎中默认每个页的大小为16KB,可通过参数innodb_page_size将页的大小设置为4K、8K、16K,在MySQL中可通过如下命令查看页的大小: mysql> show variables like 'innodb_page_size'; 而系统一个磁盘块的...
如果你的服务器的CPU或者IO使用接受饱和,特别是偶尔出现峰值,这时候系统想在超载时能正常处理查询,那么强烈建议关注innodb_thread_concurrency
MySQL Innodb 参数详解与优化实践
4> innodb_data_home_dir = /usr/local/mysql/var/存放innodb表引擎表空间的地方 5> innodb_data_file_path = ibdata1:10M:autoextend表空间的名字以8M增长,可以将其大小修改:例如50M 6> innodb_log_group_home_...
MySQL技术InnoDB存储引擎_姜承尧_第2版
innodb_autoinc_lock_mode这个参数控制着在向有auto_increment 列的表插入数据时,相关锁的行为; 通过对它的设置可以达到性能与安全(主从的数据一致性)的平衡 【0】我们先对insert做一下分类 首先insert大致上可以...
innodb 存储引擎性能优化,mysql 5.6
MyISAM可以在默认的 key_buffer_size 设置下运行的可以,然而Innodb在默认的 innodb_buffer_pool_size 设置下却跟