MySQL架构与历史
-
并发控制
- 共享锁(读锁):
共享、互不阻塞的
。多个客户同一时刻可以同时读取一个资源而互不干扰。 - 排他锁(写锁):
排他的、一个写锁会阻塞其他的写锁和读锁
,防止其他用户读取正在写入的同一资源。 - 表锁:
锁定整张表
,一个用户在对表进行写操作前,需要先获得写锁,这会阻塞其他用户对表的读写操作,没有写锁时才能获取到读锁,读锁之间相互不阻塞。 - 行级锁:
最大程度支持并发处理。对数据行进行锁定
,降低了锁粒度,让多个用户能同时对表进行操作。
- 共享锁(读锁):
-
事务
事务是一组原子性的SQL查询,事务内的语句要么全部执行成功,要么全部执行失败。
- ACID特性
- 原子性:一个事务必须被视为一个不可分割的最小工作单元,整个事务中所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作。
- 一致性:几个并发执行的事务,其执行结果必须与按某一顺序串行执行的结果一直。数据库总是从一个一致性的状态转换到另外一个一致性的状态。
- 隔离性:事务执行不受到其他事务的干扰,并行事务之间相互独立,一个事务所做的修改在最终提交以前,对其他事务是不可见的
- 持久性:一旦事务提交,则其所做的修改就会永久保存到数据库中,就算崩溃,修改的数据也不会丢失。
- 四个隔离级别
- 脏读:一个事务执行过程中读取到了另一个事务未提交的数据。
- 丢失修改:一个事务读取一个数据时,另一个事务也访问这个数据,两个事务对这个数据进行了修改,导致第一个修改的结果丢失。
- 不可重复读: 一个事务范围内查询多次,但返回数据值不同,这是因为查询间隔数据被另一个事务修改并提交了。
这里强调的是数据被修改。
- 幻读:一个事务在两次查询同一个内容后返回的结果数量不一致(多或少了一些记录),这是因为另一个并发事务在查询间隔增加了记录导致的。
这里强调的是数据记录的数量变化。
- Read Uncommitted(读未提交):事务可以读取未提交的数据,会导致脏读、幻读、不可重复读,是最低的隔离级别。
- Read Committed(读已提交):只有在事务提交后,更新结果才会被其他事务看见。可以防止脏读,但不能防止幻读和可重复度。
- Repeatable Read(可重复读):保证在同一个事务中,对同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可避免脏读、不可重复读的发生。
- Serializable(串行化):强制事务串行执行,牺牲了系统并发性。该级别可以防⽌脏读、不可重复读以及幻读。
- 死锁:指两个或多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。只有部分或者完全回滚其中一个事务才能打破死锁。InnoDB处理的方法:
将持有最少行级排他锁的事务回滚
。 - 事务日志:事务日志可以提高事务的效率。存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘。事务日志持久以后,内存中被修改的数据在后台可以慢慢地刷回到磁盘。如果系统崩溃且数据还未写回磁盘,存储引擎在重启时还能自动恢复这部分修改的数据。
- ACID特性
-
MVCC多版本并发控制
- MVCC为了解决读写冲突。能在很多情况下避免加锁,开销更低,读操作非阻塞,写操作只锁定必要的行。
- 实现:通过保存数据再某个时间点的快照来实现。不管执行多长时间,每个事务看到的数据都是一致的。根据事务开始时间不同,每个事务对同一张表看到的数据可能不一样。</