读书笔记—高性能MySQL(第3版)—第1章—MySQL架构与历史

1、锁粒度

一种提高共享资源并发性的方式就是让锁定对象更有选择性。尽量只锁定需要修改的部分数据,而不是所有的资源。更理想的方式是,只对会修改的数据片进行精确的锁定。任何时候,在给定的资源上,锁定的数据量越少,则系统的并发程度越高,只要相互之间不发生冲突即可。

  • 表锁(table lock)

表锁是MySQL中最基本的锁策略,并且是开销最小的策略。它会锁定整张表,一个用户在对表进行写操作(插入、删除、更新等)前 ,需要先获得写锁,这会阻塞其他用户对该表的所有读写操作。只有没有写锁时,其他读取的用户才能获得读锁,读锁之间是不相互阻塞的。另外,写锁比读锁有更高的优先级,因此一个写锁请求可以会被插入到读锁队列的前面(写锁可以插入到锁队列中读锁的前面,反之读锁不能插入到写锁的前面)。

  • 行级锁(row lock)

行级锁可以最大程度地支持并发处理(同时也带来了最大的锁开销)。行级锁只在存储引擎层实现,而MySQL服务器层没有实现,服务器层完全不了解存储引擎中的锁实现。

2、事务

事务就是一组原子性的SQL查询,或者说一个独立的工作单元。事务内的语句,要么全部执行成功,要么全部执行失败。

  • 原子性(atomicity)

一个事务必须被视为一个不可feng分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。

  • 一致性(consistency)

数据库总是从一个一致性的状态转换到另外一个一致性的状态。

  • 隔离性(isolation)

通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。

  • 持久性(durability)

一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。

3、隔离等级

  • READ UNCOMMITTED(未提交读)

在READ UNCOMMITTED级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读(Dirty Read)。除非真的有非常必要的理由,在实际应用中一般很少使用。

  • READ COMMITTED(提交读)

大多数数据库系统的默认隔离级别都是READ COMMITTED(但MySQL不是)。一个事务从开始一直到提交之前,所做的任何修改对其他事务都是不可见的,这个级别有时候也叫做不可重复读(nonrepeatable read),因为两次执行同样的查询,可能会得到不一样的结果。

  • REPEATABLE READ(可重复读)

REPEATABLE READ解决了脏读的问题,该级别保证了在同一个事务中多次读取同样记录的结果是一致的。但理论上,可重复读隔离级别还是无法解决另外一个幻读(Phantom Read)的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)。InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)解决了幻读的问题。

  • SERIALIZABLE(可串行化)

SERIALIZABLE是最高的隔离级别,它通过强制事务串行执行,避免了前面说的幻读的问题。简单来说,SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。

4、死锁

死锁是指两个或者多个事务在同一资源上相互占用锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能产生死锁。多个事务同时锁定同一个资源时,也会产生死锁。

5、事务日志

事务日志可以帮助提高事务的效率。使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘。

6、隐式和显式锁定

InnoDB采用的是两阶段锁定协议(two-phase locking protocol)。在事务执行过程中,随时可以执行锁定,锁只有在执行COMMIT或者ROLLBACK的时候才会释放,并且所有的锁是在同一时刻被释放,InnoDB会根据隔离级别在需要的时候自动加锁。

你可能感兴趣的:(MYSQL)