持久性:一个事务一旦提交了,则永久的持久化到本地

就像锁粒度的升级会增加系统开销一样,这种事务处理过程中额外的安全性也会需要数据库系统做更多的额外工作。一个实现了ACID的数据库,相比没有实现ACID的数据库,通常会需要更多的CPU处理能力、更大的内存和更多的磁盘空间,这也正是MySQL的存储引擎可以发挥优势的地方,用户可以根据自身需要来选定存储引擎。

隔离级别

数据库为了压制丢失更新,提出了4类隔离级别[在application配置文件中声明]。

数据库现在的技术完全有办法避免丢失更新,但是这样做的代价是要付出锁的代价。一旦用了过多的锁,出现商品抢购这类功能的时候,很多线程都会被挂起和恢复,因为使用了锁之后,一个时刻只能有一个线程访问数据,这样当多个线程访问时,就会很慢,而且过多的锁会引发宕机,大部分线程被挂起,等待持有锁事务的完成。

隔离性其实比想象的要复杂,我们来看看:

(简单介绍几种)

READ UNCOMMITTED(读取未提交内容)

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

Read Committed(读取提交内容)

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

Repeatable Read(可重读)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

Serializable(可串行化)

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。


es 并发 效率_es 并发 效率

要是再深挖下去,那得是专门的研究员们做的事情了吧,比方说MySQL是如何保证可重复读的实现,比方说幻读是怎么被咔嚓掉的之类的。

后面我看看能不能查到些好的资料贴上来。


死锁

为什么这个死锁不放在上面“锁”的模块里面讲呢?木有事务,谈什么死锁。

死锁的基本概念我也不啰嗦了,为了解决死锁的问题,数据库系统实现了各种死锁检测和超时机制。InnoDB检测死锁的本事就不错,它会抓出死锁的循环依赖,并且抛出一个错误。

InnoDB目前处理死锁的方法:将持有最少行级排他锁的事务进行回滚。

锁的行为和存储引擎是密不可分的,同样的事务执行顺序,有的存储引擎就会死锁,有的就不会。。


事务日志

我觉得可以参考一下redis的日志:全面分析redis持久化机制

吃出不过多赘述,其他篇关于MySQL的博客里已经讲得够多了。

如果觉得确实想要了解一下,这里倒是有一篇写得很全面的:详细分析MySQL事务日志

想赶紧进入存储引擎的模块。


存储引擎


我先不说话,我先放张图,你品,你细品

es 并发 效率_MySQL_02

InnoDB

我还是不说话,我放图:

es 并发 效率_mysql_03

InnoDB后台有多个不同的线程,用来负责不同的任务。

InnoDB 存储引擎是基于磁盘存储的,也就是说数据都是存储在磁盘上的,由于 CPU 速度和磁盘速度之间的鸿沟, InnoDB 引擎使用缓冲池技术来提高数据库的整体性能。缓冲池简单来说就是一块内存区域.在数据库中进行读取页的操作,首先将从磁盘读到的页存放在缓冲池中,下一次读取相同的页时,首先判断该页是不是在缓冲池中,若在,称该页在缓冲池中被命中,直接读取该页。否则,读取磁盘上的页。对于数据库中页的修改操作,首先修改在缓冲池中页,然后再以一定的频率刷新到磁盘,并不是每次页发生改变就刷新回磁盘。

在InnoDB中,缓冲池中的页大小默认为16KB。


InnoDB 给 MySQL 提供了具有事务(transaction)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)、多版本并发控制(multi-versioned concurrency control)的事务安全(transaction-safe (ACID compliant))型表。InnoDB 提供了行级锁(locking on row level),提供与 Oracle 类似的不加锁读取(non-locking read in SELECTs)。InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读。这些特色增加了多用户部署和性能。没有在InnoDB中扩大锁定的需要,因为在InnoDB中行级锁定适合非常小的空间。InnoDB也支持FOREIGN KEY强制。在SQL查询中,你可以自由地将InnoDB类型的表与其它MySQL的表的类型混合起来,甚至在同一个查询中也可以混合。这些特性均提高了多用户并发操作的性能表现。在InnoDB表中不需要扩大锁定(lock escalation),因为 InnoDB 的行级锁定(row level locks)适宜非常小的空间。InnoDB 是 MySQL 上第一个提供外键约束(FOREIGN KEY constraints)的表引擎。


InnoDB采用MVCC来支持高并发,并且实现了四个标准隔离级别。其默认隔离级别是REPEATABLE READ(可重复读),并且通过间隙锁策略防止幻读的出现,间隙锁使得InnoDB不仅仅对锁定查询涉及的行,还会对索引中的间隙进行锁定,以防止幻影行的插入。


不好搞,建议:

推荐:官方文档:InnoDB事务模型和锁

建议:更深入的了解一下InnoDB的MVCC架构。


其他的引擎嘛,其实我只喜欢InnoDB。。。

叶公好龙哈哈哈

其他存储引擎

MyISAM

特性:

  1. 加锁与并发:表锁,读写锁
  2. 修复:可手动或自动执行检查和修复工作,就是慢了点。
  3. 索引特性:支持全文索引
  4. 性能:设计简单,在某些情况下性能很好,嗯,某些情况下。
CSV引擎

CSV引擎可以将普通的CSV文件作为MySQL的表来处理,但这种表并不支持索引。CSV引擎可以在数据库运行的时候拷入或拷出文件,因此CSV作为一种数据交换的机制,非常有用。

Memory引擎

如果需要快速的访问数据,并且这些数据不会被修改,重启后丢失也没有关系,那么可以使用Memory表,因为所有数据都保存在内存中,不需要进行磁盘IO。

Memory表的结构在重启以后还会保留,但数据会丢失。