MySql-InnoDB存储引擎的锁和事务
Posted 等待戈多儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySql-InnoDB存储引擎的锁和事务相关的知识,希望对你有一定的参考价值。
InnoDB存储引擎的关键特性:插入缓冲(性能提升)、两次写(可靠)、自适应哈希索引(查找效率)、异步IO(AIO,提高磁盘操作性能)、刷新邻接页(合并IO)。
InnoDB采用一致性的非锁定读和行级锁,没有额外的开销和锁升级,可以同时得到并发性和一致性。
默认的读取是一致性的非锁定读和Repeatable Read事务隔离级别,在此默认的隔离级别下采用Next-key Lock算法,解决幻象读问题。
锁
锁机制:最大限度的利用数据库的并发访问;确保每个用户都能以一致的方式读取和修改数据。用户管理对共享资源的并发访问。
latch:闩锁(轻量级锁)。锁定时间短,保证并发线程操作的临界资源的正确性,没有死锁检测机制。
lock:lock的对象是事务,锁定表、行、页。具有死锁机制。
InnoDB中有两种行级锁:
共享锁(S Lock)-允许事务读一行数据
排他锁(X Lock)-允许事务删除或者更新一行数据
S锁只与S锁兼容,X锁与任何锁都不兼容。
在对一行数据加锁之前必须对其更粗粒度(表和页)上加意向锁IS Lock或者IX Lock,意向锁由InnoDB控制,用户无需干预。不会阻塞除全表扫描以外的任何请求。意向锁的设计目的是为了在一个事务中揭示下一行即将被请求的锁类型。
意向共享锁IS Lock-事务想要获得一张表中某几行的共享锁
意向排他锁IX Lock-事务想要获得一张表中某几行的排他锁
一致性非锁定读是指通过多版本控制的发方式(Multi Version Concurrency Control ,MVCC)来读取当前执行时间数据库中行的数据。不会等待排它锁的释放,而是读取一个快照数据。如果要一致性锁定读,在select后加上for update(排他)或者lock in share mode(共享)。
InnoDB锁算法:
Record Lock:单个行记录上的锁
Gap Lock:间隙锁,锁定一个范围,不包含记录本身
Next-key Lock:锁定一个范围,且锁定记录本身
锁问题:
脏读:读取到了另一个事务中未提交的数据,违反了数据的隔离性。(低级别才会发生,从节点的查询不需要特别精确的返回值可以使用)
不可重复读:读到另一个事务中已经提交的数据,违反事务的一致性。一个事务没有提交之前读取到另一个事务提交之前和之后的数据不一样,即不可重复读。
幻读:虽然没有发生不可重复读,但是可能发生幻读。当一个事务读取数据时,另一个事务修改了行并进行提交,这个事务会读取到这个修改的行。或者另一个事务插入新行并进行提交,当这个事务再次读取时不会发现新的行但是却不可重复插入。(Next-key Lock 算法解决:对于索引的扫描,不仅是锁住扫描到的索引,而且是锁住这些索引覆盖的范围。因此在这个范围内的插入都是不允许的,这样就避免了另一个事务在这个范围内插入数据导致的不可重复读的问题)因此在MySql默认的事务隔离级别下,不会发生幻读。
丢失更新:一个事务的更新操作会被另一个事务的更新操作覆盖。(让操作串行化而不是并行化)
锁升级
InnoDB不存在锁升级的问题,即将细粒度的锁升级为粗粒度的锁。因为其不是根据每个记录来产生行锁的,其是根据每个事务访问的每个页对锁进行管理的,采用的是位图的方式。所以不管是锁住一个记录还是多行记录,其开销通常都是一致的。
事务
事务是访问并更新数据库中各种数据项的一个程序执行单元,可由一个sql或者多个sql组成、事务的目的:事务操作中,要么都做修改要么都不做。
InnoDB存储引擎的事务完全符合ACID特性:
原子性(atmoicity):整个数据库事务是不可分割的工作单位。任何一个sql失败,执行成功的sql必须撤销。
一致性(consistency):事务开始之前和结束之后,数据库完整性约束没有被破坏。
隔离性(isolation):事务提交前对其他事务都不可见。(并发控制,可串行化,锁。由锁实现)
持久性(durability):事务一旦提交,结果是永久性的。
事务分类:
扁平事务-使生产环境用最为频繁
带有保存点的扁平事务-保存点用来通知系统记住事务的当前状态,方便错误时恢复。
链事务-可以看到上一个事务的处理结果
嵌套事务-层次结构,顶层事务嵌套子事务
分布式事务-分布式环境中的扁平事务
事务的实现
原子性、持久性通过redo log(重做日志)实现,一致性通过undo log实现。
事务的持久性由内存中的重做日志缓冲(redo log buffer)和重做日志文件(redo log)两部分组成。
redo:通常是物理日志,记录的是页的物理操作。为保证每次日志文件都写入重做日志文件,在每次将重做日志缓冲写入重做日志文件后,InnoDB存储引擎都需要调用一次fsync操作,将重做日志写入磁盘。
undo:逻辑日志,根据每行记录进行记录。用来帮助事务的回滚和MVCC功能,知识将数据库逻辑的恢复到原来的样子,实际上在并发系统中数据库结构和页本身在回滚之后可能大不相同。
事务的隔离级别:隔离级别越低,事务请求的锁越少或保持锁的时间越短。
read uncommitted-浏览访问(发生脏读)
read committed-游标稳定(发生不可重复读)
repeatable read-2.9999度的隔离(InnoDB默认)(发生幻读)
serializable-隔离,3度隔离(串行化操作)
分布式事务
InnoDB存储引擎提供了对XA(eXtended Architecture)事务的支持,并通过XA事务来支持分布式事务的实现。
分布式事务是指允许多个独立的事务资源(transactional resources)参与到一个全局的事务中。事务资源通常是指关系型数据库系统,也可以是其他类型资源。XA事务允许不同数据库之间的分布式事务。
XA事务
资源管理器:一个或多个数据库,提供访问事务资源的方法。
事务管理器:协调参与全局事务中的各个事务。需要和参与全局事务的所有资源管理器通信。
应用程序:定义事务的边界,指定全局事务中的操作。
分布式事务使用两段式提交的方式:
1.所有参与全局事务的节点都开始准备(prepare,与本地事务的区别),告诉事务管理器他们准备好提交了 2.事务管理器告诉资源管理器执行rollback或者commit。
最常见的内部XA事务存在于binlog和InnoDB之间。
不好的事务习惯
在循环中提交
使用自动提交
使用自动回滚
默认配置下mysql数据库总是默认提交的。
以上是关于MySql-InnoDB存储引擎的锁和事务的主要内容,如果未能解决你的问题,请参考以下文章