概述
InnoDB是mysql默认的事务性引擎,也是mysql最重要的,使用最广泛的存储引擎。他被设计出来处理大量的短期事务,短期事务大部分情况是正常提交的,很少会被回滚。InnoDB的性能和自动崩溃恢复特性,使得他在非事务型存储需求中也很流行。除非要特别重要的原因需要使用其他存储引擎,否则应该优先考虑InnoDB。
数据存储
InnoDB的数据存储在表空间中,表空间是由InnoDB管理的一个黑盒子,由一系列数据文件组成。
InnoDB的表空间是由一个innodb_file_per_table参数来决定。如果这个参数的值为:ON,则会为mysql中的每个表建立一个以 tablename.ibd 为扩展名的数据文件;如果这个参数的值为:OFF,则会把库中的表存储在一个为ibdataX(X为一个数字)的共享表空间中。
系统表空间和独立表空间对比:
- 系统表空间无法简单的收缩文件大小:即使我们删除了表中的数据,但是表空间并不会变小,如果需要收缩系统空间,则导出库中的所有表,停掉mysql服务,删除表空间文件,重启mysql,然后重新导入表
- 独立表空间可以通过 optimize table 命令收缩系统文件:对一个大表进行数据清理之后可以使用optimize table命令对这个表进行重建
- 系统表空间会产生IO瓶颈:系统表空间所有操作都对一个文件进行读取
- 独立表空间可以同时向多个文件刷新数据
建议使用独立表空间配置,并且现在独立表空间是mysql的默认配置
特性
InnoDB是一种事务性存储引擎
完全支持事务的ACID特性:原子性,一致性,隔离性,持久性
Redo Log 和 Undo Log
Redu Log:重做日志,存储的是已经提交的事务,把已经提交的事务重做一遍,用于实现数据的持久性。由两部分组成,一个是日志中的重做日志缓冲区(innodb_log_buffer_size参数控制缓冲文件大小),另一个是重做日志文件。
Undo Log:回滚日志,是把所有没有COMMIT的事务回滚到事务开始前的状态。undo log实现事务的原子性,还用来实现多版本并发控制。
Undo Log的原理:在操作任何数据之前,首先将数据备份到Undo Log。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。
锁
- 支持行级锁
- 在进行写操作时可以最大程度的支持并发
行级锁是由存储引擎层实现的
什么是锁
- 锁的主要作用是管理共享资源的并发访问
- 锁用于实现事物的隔离性
锁的类型
- 共享锁(读锁):读锁是共享的,或者说是互不阻塞的。多个客户在同一时刻可以同时读取同一个资源,而互不干扰。
- 独占锁(写锁、排他锁):写锁是排他的,也就是说一个写锁会堵塞其他写锁和读锁,只有这样,才能确保在给定的时间里,只有一个用户能执行写入,并防止其他用户读取正在写入的同一资源。
锁的粒度
- 表锁:mysql中最基本的锁策略,也是开销最小的锁策略。
- 行级锁:行级锁可以最大程度的支持并发处理。行级锁只在存储引擎层实现,而Mysql服务层没有实现。服务层完全不了解存储引擎的所实现。
阻塞
阻塞是由于锁之间的兼容性关系引起的,在有些时候,一个事务中的锁需要等另一个事务中的锁释放才能执行。例如,一个用户在对表进行写操作前,需要先获得写锁,这会阻塞其他用户对该表/行的所有读写操作。只有没有写锁时,其他读取的用户才能获得读锁,读锁之间是不互相堵塞的。
死锁
死锁是两个或者两个以上的事务互相占用了对方等待的资源。系统会自动发现死锁,并在数据库事务中找到一个资源占用最少的来进行回滚操作。
InnoDB 状态检测
innodb提供了一个系统监控工具:show enging innodb status