MySQL 5.6

InnoDB 存储引擎系列文章

以下是我发布在我们团队的(Aliyun RDS MySQL 开发组)每月内核月报上关于InnoDB的几篇文章,不断更新中….. 如下是传送门: MySQL · 引擎特性 · InnoDB undo log 漫游 MySQL · 引擎特性 · InnoDB redo log漫游 MySQL · 引擎特性 · InnoDB 崩溃恢复过程 MySQL · 引擎特性 · Innodb change buffer介绍 MySQL · 引擎特性 · InnoDB Adaptive hash index介绍 MySQL · 引擎特性 · InnoDB 全文索引简介 MySQL · 引擎特性 · InnoDB 事务子系统介绍 MySQL · […]


MySQL5.6.27 Release Note解读(innodb及复制模块)

新功能 问题描述(Bug #18871046, Bug #72811): 主要为了解决一个比较“古老”的MySQL在NUMA架构下的“swap insanity”问题,其表现为尽管为InnoDB buffer pool分配了足够多的内存,但依然会产生swap。而swap对数据库系统性能而言是比较致命的。 当我们配置的buffer pool超过单个node的内存时,例如总共64GB内存,每个节点32GB,分配buffer pool为40GB,默认情况下,会先用满node 0,再在node1上分配8GB内存。如果绑定到node 0上的线程需要申请新的内存时,不是从node1上申请(还有24GB空余),而是swap node0的内存,再做申请。 这个问题在社区讨论了很久,大神Jeremy Cole 对该问题有写博客做过详细的介绍(http://blog.jcole.us/2010/09/28/mysql-swap-insanity-and-the-numa-architecture/) 解决: 增加了一个只读的新参数innodb_numa_interleave选项,当开启该选项,可以允许在NUMA架构下采取交叉分配内存的方式。 在启动MySQL时,采用MPOL_INTERLEAVE方式分配内存,如上例,在启动时每个node上分配20GB内存,保证每个node依然有空闲内存可用;在完成InnoDB buffer pool内存分配后,再将内存分配策略设置为MPOL_DEFAULT,之后的线程申请内存,都在各自的节点完成。 补丁: https://github.com/mysql/mysql-server/commit/242fa2c92de304637e794e531df1f1b86b8d1dee https://github.com/mysql/mysql-server/commit/d2578b57ba7d90a00281ae124a1cd6c83193f62a InnoDB bugfix 问题描述: 当一个表被驱逐并重新导入时,如果表的内容是空的(例如先插入大量数据,再一次全删除时,auto_increment不为0),就会导致AUTO_INCREMENT的值被重置。(Bug #21454472, Bug #77743) 这是因为每次打开表时,总是通过计算表上记录最大自增列值的方式来重新设置,当表被打开时,如果没有数据,AUTO_INCREMENT就会被重置成最小值。 解决: 在驱逐表时,将这个表的AUTO_INCREMENT值存储在内存中(dict_sys->autoinc_map),当表重新读入时,再恢复其AUTO_INCREMENT值。 这个Fix并不算一个完整的修复,当实例重启时,AUTO_INCREMENT依然会被重置(参阅bug#199), RDS MYSQ已经Fix了这个bug,能够持久化自增列到物理文件中,在重启后不会丢失。 补丁: https://github.com/mysql/mysql-server/commit/d404923aad4693dc152d02461f858d7ef218c336 问题描述: Memcached的一段开启事务的代码在assert中调用,而根据assert的文档定义( http://man7.org/linux/man-pages/man3/assert.3.html ),他的行为是未知的,受NDEBUG控制,可能assert会被定义成空函数,导致assert中的函数调用被忽略掉。这个bug在某些平台下可能极易触发。使用memcached的同学需要注意下。 (Bug #21239299, Bug #75199) 解决: 将函数调用从assert中移出来,只assert函数返回值。 补丁: https://github.com/mysql/mysql-server/commit/db5dc6fd3abe855685a554bc3c555b1b63914b60 问题描述: 在ARM64平台上, GCC的内建的TAS操作函数__sync_lock_test_and_set 可能不准确,这和平台内存模型有关,锁的行为错误,导致进一步的数据损坏。(Bug […]


MySQL 5.6.26 Release Note解读

最近上游发布了MySQL 5.6.26版本,从release note来看,MySQL5.6版本已经相当成熟,fix的bug数越来越少了。本文主要分析releae note上fix的相关bug,去除performance scheama、mac及windows平台、企业版、package相关内容。 InnoDB storage engine 问题描述: 在类unix平台上,当innodb_flush_method设置为O_DIRECT时,函数os_file_create_simple_no_error_handling_func没有使用O_DIRECT方式打开数据文件。例如在函数fil_node_open_file中,可能先以函数os_file_create_simple_no_error_handling_func打开文件,确定文件的大小,然后关闭文件;再以os_file_create打开数据文件,前者使用Buffered IO,后者使用DIRECT IO。这种混合使用可能引发性能问题。 根据man手册建议: Applications should avoid mixing O_DIRECT and normal I/O to the same file, and especially to overlapping byte regions in handles the coherency issues in this situation, overall I/O the same file. Even when the filesystem correctly throughput is likely to be slower […]


[MySQL bug] unique key corruption again…..

最近Percona的研发人员report了一个uk corruption的bug,这个Bug不同于之前发现的bug(见我的另外一篇博客http://mysqllover.com/?p=1041),而是影响从5.1 到5.8全系列MySQL版本,应该算是设计上的缺陷吧。 原创文章,转载请注明: 转载自Simple Life 本文链接地址: [MySQL bug] unique key corruption again….. Post Footer automatically generated by wp-posturl plugin for wordpress.


InnoDB foreign key 实现

本文是对Innodb外键实现代码路径的简单记录,对外键实现逻辑熟悉的同学直接忽略吧。。。。。 前言 外键代表两张表之间的引用约束关系:在子表上出现的列记录,必须在父表上已经存在。通过外键,我们可以确保业务上的逻辑一致性,同时还能实现一些级联操作;MySQL目前只有InnoDB引擎支持外键,类似MyISAM、Tokudb等引擎都不支持外键。 InnoDB支持建立多个列的外键,但被外键约束的父表上必须对这些列建立索引,并且子表上的外键列 和父表上索引上的顺序是一致的。默认情况下,当删除父表中被外键约束的记录时,会产生报错,但我们也可以通过在建外键索引时加上ON DELETE CASCADE 来级联的更新子表,更新同理。其他行为包括RESTRICT(限制父表的外键改动,默认值)、CASCADE(跟随父表的改动)、SET NULL(子表对应列设置为NULL)、SET DEFAULT(设置为默认值,InnoDB不支持,但Server层支持)、NO ACTION(无动作)。 原创文章,转载请注明: 转载自Simple Life 本文链接地址: InnoDB foreign key 实现 Post Footer automatically generated by wp-posturl plugin for wordpress.


InnoDB IO子系统介绍

本文我们来简单过一下InnoDB的IO子系统相关模块的代码逻辑。主要包括IO读写线程、预读逻辑、InnoDB读写Page以及社区的一些改进。 前言 InnoDB对page的磁盘操作分为读操作和写操作。   对于读操作,在将数据读入磁盘前,总是为其先预先分配好一个block,然后再去磁盘读取一个新的page,在使用这个page之前,还需要检查是否有change buffer项,并根据change buffer,进行数据变更。   读操作分为两种场景:普通的读page及预读操作,前者为同步读,后者为异步读   Page写操作也分为两种,一种是batch write,一种是single page write。写page默认受double write buffer保护,因此对double write buffer的写磁盘为同步写,而对数据文件的写入为异步写。   同步读写操作通常由用户线程来完成,而异步读写操作则需要后台线程的协同。 原创文章,转载请注明: 转载自Simple Life 本文链接地址: InnoDB IO子系统介绍 Post Footer automatically generated by wp-posturl plugin for wordpress.


MySQL: 并发replace into的死锁问题分析

测试版本:MySQL5.6.23测试表: create table t1 (a int auto_increment primary key, b int, c int, unique key (b));并发执行SQL: replace into t1(b,c) values (2,3)  //使用脚本,超过3个会话 原创文章,转载请注明: 转载自Simple Life 本文链接地址: MySQL: 并发replace into的死锁问题分析 Post Footer automatically generated by wp-posturl plugin for wordpress.


Multi Range Read 代码路径

所谓MRR,简单的说就是当使用二级索引进行检索并且查询的列需要回表时,先根据检索到的PK值进行排序,然后再回表依次查询聚集索引,从而避免过多的随机IO。 原创文章,转载请注明: 转载自Simple Life 本文链接地址: Multi Range Read 代码路径 Post Footer automatically generated by wp-posturl plugin for wordpress.


Innodb drop index 流程小记

最近在做一个小特性,让InnoDB支持repair table来重建corrupted的索引,本文描述的是实现过程中遇到的一个小问题,主要和innodb drop index相关的一些随笔记录。 原创文章,转载请注明: 转载自Simple Life 本文链接地址: Innodb drop index 流程小记 Post Footer automatically generated by wp-posturl plugin for wordpress.


库表字符集不一致导致的全表扫描问题

背景: 当数据库的建库字符集和表不一样时,在库下针对表创建存储过程可能导致全表扫描 如下例: drop database if exists xx1; drop database if exists xx2; create database xx1 character set utf8; create database xx2 character set gbk;   然后分别在xx1 和 xx2下执行: CREATE TABLE t1 ( `col1` varchar(10) NOT NULL, `col2` bigint(11) NOT NULL DEFAULT ‘0’, PRIMARY KEY (`col1`)) ENGINE=InnoDB DEFAULT CHARSET=gbk; insert into t1 values (‘ac’,2),(‘del’,3),(‘sp’,5),(‘tr’,12); DELIMITER […]