Category Archives: MySQL-InnoDB

InnoDB 读写锁rw_lock_t实现

10月忙得像shi一样,不管怎样,忙里偷闲在这个月结束之前写上一篇,介绍InnoDB读写锁的实现

InnoDB读写锁特点

1. 读与读之间不冲突,读与写,写与写之间冲突,这个是读写锁最基本的特征
2. 申请写锁时,如果锁被读持有,将发生写锁等待,该写锁之后的所有读锁会等待该写锁成功获取后才能申请成功,这保证了公平:写锁请求不会被饿死

基本数据结构

sync_array_struct: 保存用于线程同步结构的数组,数组成员类型为sync_cell_struct
sync_cell_struct: 一个线程同步结构体,部分代码:[……]

继续阅读

InnoDB 锁系统及死锁检测实现分析

死锁检测一般采用Wait-For-Graph算法,这个不是非常复杂或者新奇的内容,cs课程中一般都会交代,本文从代码层面解析InnoDB锁系统及死锁检测实现,一方面给自己阅读代码做做笔记,另一方面希望也能够为一些有疑惑的朋友提供帮助

几个问题

1. InnoDB中锁在是怎样表示和维护的
2. 死锁检测发生在什么时候
3. InnoDB中的Wait-For-Graph是如何实现的
4. InnoDB通常在哪些情况下可能发生死锁
[……]

继续阅读

MySQL embedded server prepared statement执行分析

MySQL embedded server简介

MySQL可以作为一个embedded server执行,这时它就充当了一个与应用紧密耦合的轻量级数据中心,适合资源有限、应用需要连接很少(通常1个)的场景,使用方便,编译后就可以随应用一起启动,具有部署方便,速度更快的优点,当然它有很多限制,如:不支持UDF,不支持主备复制,InnoDB层不支持多个连接等,更多请参考 libmysqld, the Embedded MySQL Server Library.

因为DRC团队在使用embedded server的过程中遇到了执行prepared statment时内存泄露的问题,为了定位并fix问题,分析了这部分逻辑
[……]

继续阅读

InnoDB inplace-update加锁流程分析

线上遇到一起死锁问题,一条DELETE语句与一条UPDATE语句产生了死锁,经过和印风的讨论分析找到原因:DELETE语句通过二级索引删除记录,加锁顺序:二级索引(WHERE使用到二级索引)–>主键索引 –> 所有其它二级索引,UPDATE语句的加锁顺序:二级索引(WHERE条件使用二级索引)–>主键索引 –>包含更新字段的其它二级索引,由于DELETE操作更新了UPDATE语句WHERE条件使用到的索引,这导致DELETE与UPDATE加锁顺序相反,导致死锁

为了进一步研究InnoDB update操作加锁流程,进行了下列实验(update操作为inplace-update),关于mysql update的上层调用可以参考: MySQL update语法SQL解析源码分析Oracle/PostgreSQL UPDATE…RETURNING…在MySQL中的实现
[……]

继续阅读

MySQL statement timeout特性

这个特性是twitter开发的,点击查看详情,目前已经backport到AliMySQL中,正在测试中,首先简单介绍一下功能

特性描述:

1)statement timemout特性中,SELECT必须是top-level,不能是子查询或者union中的除第一个SELECT之外的SELECT
2)语句级别:为SELECT增加一个hint: max_statement_time指定查询最大执行时间,当执行时间超过max_statement_time后,查询自动中断(连接不中断)
3)session级别:允许超级用户grant其它用户一个指定的max_statement_time,该用户连接后默认使用该值(用户可在session中临时修改),每个SELECT执行时间都不会超过max_statement_time
4)没有grant max_statement_time或grant max_statement_time 0的用户,除非在query中指定max_statement_time hint,否则查询执行时间不受限制
[……]

继续阅读

一个MySQL子查询与Order By问题分析

问题背景

产品DBA在做日常SQL REVIEW时,遇到一个问题:一个包含子查询的query,使用order by(order by query)竟然比不使用order by(normal query)执行时间更短,而且是在order by无法使用index排序的情况下(使用filesort),这个问题不好解释,只能借助一些工具以及跟踪代码寻找原因

MySQL版本

现象在Percona 5.5.18和Oracle MySQL 5.1.48上都存在,本文数据和分析基于Percona 5.5.18
[……]

继续阅读

MySQL XA限制与修复

背景知识

MySQL的XA分为内部XA和外部XA,采用的协议是经典的2PC(2-Phase-Commit)

MySQL内部XA主要用于多个存储引擎之间的事务处理,由binlog作为Transaction Coordinator,事务提交过程中协调各个参与者(事务存储引擎)prepare,commit/rollback,各个事务存储引擎在prepare阶段基本做完了所有的事情(除了写commit标志,释放资源),对于InnoDB存储引擎,提交一个事务的流程如下:(图片来自登博)

commit
[……]

继续阅读

MySQL 16进制字符串与编码

实验:

a) 系统环境:

$echo $LANG
en_US.UTF-8
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `str` varchar(128) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB

[……]

继续阅读

MySQL binlog字符编码方式

问题背景

希望根据MySQL binlog回滚已经提交的事务,一个重要的应用场景:回滚误操作,淘宝智胜在这方面做了很多工作,详情参考利用MySQL日志模拟恢复数据变化轨迹, 利用MySQL日志模拟恢复数据变化轨迹II,最近遇到了一些字符集相关问题,回滚失败。这篇文章旨在分析MySQl binlog中与表操作相关的字符集。

实验测试:

a) 系统字符集,保证能够支持中文

$echo $LANG
en_US.UTF-8

[……]

继续阅读

FLUSH TABLES WITH READ LOCK

本分析基于 Percona Server 5.5.18

FLUSH TABLES WITH READ LOCK 作用

1. 对于myisam存储引擎,从数据库外部拷贝.frm,.fyd,.fyi文件后,执行FLUSH TABLES/FLUSH TABLES WITH READ LOCK后,就可以使用新表了,这个功能非常有用,备份变得格外简单
2. mysqldump中从主库中拉出一个副本后通过change master后就可以快速搭建slave,为了获得一个一致性点,一般会使用参数–single-transaction和–master-data,它会使用FLUSH TABLES WITH READ LOCK阻塞事务commit写binlog来获得transaction开始时主库binlog位置
3. 与FLUSH TABLES相似,清空table_cache

除了这几个重要作用外,目前还没有发现其他用处,而且对于InnoDB存储引擎,第一条就没用了
[……]

继续阅读