首页 数据库 mysql教程 MySQL在创建索引之前一定要想到的事情

MySQL在创建索引之前一定要想到的事情

Jun 07, 2016 pm 04:40 PM

Oracle的事务指的是需要分配回滚段的SQL语句,也就是说select并不是oracle事务的一部分.比如运行一个查询,然后在另外一个会话查询

MySQL在5.5.3版本引入了metadata lock
他的本意是解决之前版本事务隔离特性的几个bug,但是引入的问题也不小.

先说说MySQL的事务吧.
Oracle的事务指的是需要分配回滚段的SQL语句,也就是说select并不是oracle事务的一部分.
比如运行一个查询,然后在另外一个会话查询v$transaction,并不会有任何相关的信息.直到事务中出现insert,update,delete。
 而innodb的事务包括select查询.
无论事务隔离级别是可重复读,还是读提交,只要有查询,事务就开始了
 下图证明了在5.6.15,设置了autocommit=0之后,运行一个查询就可以开启一个事务.
第一个会话运行查询.

MySQL在创建索引之前一定要想到的事情

第二个会话,运行 show engine innodb status\G 查看事务情况

MySQL在创建索引之前一定要想到的事情

 可以看到id为1的线程,已经开始了一个事务.

为什么Oracle的事务仅包括insert,update和delete的语句,而innodb的事务包括所有的语句呢?
我觉得这个和厂商支持的隔离级别有很大的关系.
众所周知,Oracle仅仅支持读提交和串行化两种事务隔离级别,而读提交是绝大多数数据库的选择.
读提交意味着可以出现幻读和不可重复读,那么从实现原理的角度,Oracle可以在语句(Statement级别)开始的时候,记录SCN然后应用MVCC查询.每个查询只需要记录自己开始的SCN即可.而语句开始的SCN和事务并没有关系.所以Oracle的事务,并不包括查询.

而innodb支持可重复读隔离级别,也就是说在一个事务中,无论运行多少次查询,结果都必须是一致的.
 (innodb不仅支持可重复读,并且使用间隙锁在可重复读级别避免了幻读,当然这也带来了很多问题..)
所以它记录的不是每个查询语句的LSN,而是事务第一个语句发生时的LSN,无论第一个语句是查询,还是修改.
innodb在可重复读的级别下,查询用事务开始时的LSN应用MVCC,与Oracle不同的是,innodb查询回滚段中小于事务开始的LSN的数据版本,
而oracle查询回滚段中小于语句SCN的数据版本.
也就是说,同样都是MVCC,oracle是语句级的,innodb是事务级的

 这里有一个问题,按说事务包括查询是因为可重复读隔离级别的需要,但是innodb读提交隔离级别同样也将查询作为了事务的一部分.
可能是因为架构或者代码实现层面的问题吧.
不管怎么样,Innodb就是这么做了.

然后再说说metadata lock
在5.5.3之前,metadata lock是语句级的,这实际上破坏了事务的一致性.
比如一个事务,在可重复读隔离级别,运行两次查询,居然结果不一致.

MySQL在创建索引之前一定要想到的事情

这正是因为metadata lock是语句级造成的问题,
在两个查询的间隔,另外一个会话执行了truncate table.
所以再次运行查询,没有任何结果.

MySQL为了解决这个问题,在5.5.3将metadata lock提升为事务级别的锁.
任何DDL都需要先获得metadata lock,但是这个锁需要等事务结束的时候释放.
同样的实验,在5.6.13就变成这样的了.
第一个会话的事务没有结束,那么第二个会话的DDL就被阻塞

MySQL在创建索引之前一定要想到的事情

 使用show processlist可以看到DDL语句在等待第一个会话事务的metadata lock

MySQL在创建索引之前一定要想到的事情

通过这种方式,就保证了可重复读隔离级别下,事务的一致性.

和之前提到的查询也作为事务的一部分一样,innodb并没有为读提交量身定制一些东西,
比如读提交并不需要查询作为事务的一部分
 和读提交并不需要事务级别的metadata lock.
可能是出于架构层面的问题,很多可重复读的特性强加在了读提交上,
所以一旦这些特性出现问题,即使将隔离级别降为读提交也不能避免.

接下来问题来了,
刚才的DDL被metadata lock阻塞,这个DDL还会进一步阻塞其他的事务.甚至是查询(查询是innodb事务的一部分.)

这就有点抓狂了,因为这个时候,系统其实已经Hung了.
假设id为1的线程持有metadata lock 没有提交,
id为2的线程进行DDL,然后被阻塞在线程1的metadata锁上,
这时,数据库依次来了8个查询,他们都阻塞在了线程2上.
假如线程1的事务不结束,其他的线程都被阻塞.
即使线程1的事务结束了..也是后面8个事务依次获得metadata锁,与此同时,这个DDL可能又阻塞了80个事务..

这时候,系统的并发为1,这个DDL可能永远不能执行.并且这种情况不在死锁检测的范围内.
它的锁超时时间,由lock_wait_timeout参数控制,默认是31536000(一年,坑爹吧)

MySQL虽然保证了事务的一致性,避免了bug,但是引入的问题却可能让我这样的初级dba丢了饭碗..

最后梳理一下可能引发metadata lock连环阻塞的情况
1.在有其他事务运行的时候,进行DDL操作(alter table;truncate;)
 2.在mysqldump运行的时候,进行DDL操作.(想想就觉得坑爹)
3.在Master-Slave复制环境,在Slave运行查询,会导致Master传过来的DDL阻塞.导致复制延迟增大.
4.创建索引(...)

作为初级dba来说,为了保住饭碗,可以有两个动作
1.将lock_wait_timeout参数调低
2.在运行DDL之前,查看事务是否频繁,在运行DDL之后,开启另外一个会话,使用show processlist查看是否被metadata lock阻塞.
一旦阻塞,先Kill ddl的操作.

MySQL索引之隔离列 

MySQL索引之哈希索引

MySQL索引之前缀索引和索引选择性

MySQL索引使用率监控

MySQL索引优化和in or替换为union all

MySQL索引设计的原则

本文永久更新链接地址:

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

与MySQL中使用索引相比,全表扫描何时可以更快? 与MySQL中使用索引相比,全表扫描何时可以更快? Apr 09, 2025 am 12:05 AM

全表扫描在MySQL中可能比使用索引更快,具体情况包括:1)数据量较小时;2)查询返回大量数据时;3)索引列不具备高选择性时;4)复杂查询时。通过分析查询计划、优化索引、避免过度索引和定期维护表,可以在实际应用中做出最优选择。

说明InnoDB全文搜索功能。 说明InnoDB全文搜索功能。 Apr 02, 2025 pm 06:09 PM

InnoDB的全文搜索功能非常强大,能够显着提高数据库查询效率和处理大量文本数据的能力。 1)InnoDB通过倒排索引实现全文搜索,支持基本和高级搜索查询。 2)使用MATCH和AGAINST关键字进行搜索,支持布尔模式和短语搜索。 3)优化方法包括使用分词技术、定期重建索引和调整缓存大小,以提升性能和准确性。

可以在 Windows 7 上安装 mysql 吗 可以在 Windows 7 上安装 mysql 吗 Apr 08, 2025 pm 03:21 PM

是的,可以在 Windows 7 上安装 MySQL,虽然微软已停止支持 Windows 7,但 MySQL 仍兼容它。不过,安装过程中需要注意以下几点:下载适用于 Windows 的 MySQL 安装程序。选择合适的 MySQL 版本(社区版或企业版)。安装过程中选择适当的安装目录和字符集。设置 root 用户密码,并妥善保管。连接数据库进行测试。注意 Windows 7 上的兼容性问题和安全性问题,建议升级到受支持的操作系统。

InnoDB中的聚类索引和非簇索引(次级索引)之间的差异。 InnoDB中的聚类索引和非簇索引(次级索引)之间的差异。 Apr 02, 2025 pm 06:25 PM

聚集索引和非聚集索引的区别在于:1.聚集索引将数据行存储在索引结构中,适合按主键查询和范围查询。2.非聚集索引存储索引键值和数据行的指针,适用于非主键列查询。

mysql:简单的概念,用于轻松学习 mysql:简单的概念,用于轻松学习 Apr 10, 2025 am 09:29 AM

MySQL是一个开源的关系型数据库管理系统。1)创建数据库和表:使用CREATEDATABASE和CREATETABLE命令。2)基本操作:INSERT、UPDATE、DELETE和SELECT。3)高级操作:JOIN、子查询和事务处理。4)调试技巧:检查语法、数据类型和权限。5)优化建议:使用索引、避免SELECT*和使用事务。

说明不同类型的MySQL索引(B树,哈希,全文,空间)。 说明不同类型的MySQL索引(B树,哈希,全文,空间)。 Apr 02, 2025 pm 07:05 PM

MySQL支持四种索引类型:B-Tree、Hash、Full-text和Spatial。1.B-Tree索引适用于等值查找、范围查询和排序。2.Hash索引适用于等值查找,但不支持范围查询和排序。3.Full-text索引用于全文搜索,适合处理大量文本数据。4.Spatial索引用于地理空间数据查询,适用于GIS应用。

mysql用户和数据库的关系 mysql用户和数据库的关系 Apr 08, 2025 pm 07:15 PM

MySQL 数据库中,用户和数据库的关系通过权限和表定义。用户拥有用户名和密码,用于访问数据库。权限通过 GRANT 命令授予,而表由 CREATE TABLE 命令创建。要建立用户和数据库之间的关系,需创建数据库、创建用户,然后授予权限。

mysql 和 mariadb 可以共存吗 mysql 和 mariadb 可以共存吗 Apr 08, 2025 pm 02:27 PM

MySQL 和 MariaDB 可以共存,但需要谨慎配置。关键在于为每个数据库分配不同的端口号和数据目录,并调整内存分配和缓存大小等参数。连接池、应用程序配置和版本差异也需要考虑,需要仔细测试和规划以避免陷阱。在资源有限的情况下,同时运行两个数据库可能会导致性能问题。

See all articles