MySql高性能笔记 - (一)Mysql基础知识

MySql高性能笔记 - (一)Mysql基础知识

1. 读写锁:###

  1. 读锁 - 共享锁:互相不阻塞的。多个客户在同一刻可以同时读取同一个资源,而互不干扰。
  2. 写锁 - 排它锁:一个写锁会阻塞其他的写锁和读锁,保证只有一个用户能执行写操作,防止其他用户读取正在写入的同一资源。

2. 锁粒度:##

  1. 尽量只锁定要修改的部分数据。
  2. 表锁:开销小,它会锁定整张表。
  3. 行级锁:可以最大程度的支持并发处理,同时带来最大的锁开销。行级锁是在存储引擎层实现的,InnoDB和XtraDB实现了行级锁,

3. 死锁:

  1. 发生举例:
    • 第一条sql进行update A行数据,锁定了A行数据,尝试去执行update B行数据。
    • 第二条sql进行update B行数据,锁定了B行数据,尝试去执行update A行数据。
  2. 解决方案:
    • InnoDB会提前检测死锁循环依赖,返回错误。发生以后目前处理方法是,将持有最少行级排他锁的事务进行回滚。

4. 事务:

  1. 事务是一组原子性的sql语句,如果数据库成功地执行所有语句,那么久执行。如果一条语句崩溃,那就所有语句都不会执行。要么全执行,要么全失败。

  2. ACID:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)

    • 原子性:一个事务必须视为一个不可再分的最小工作单元。整个事务要么都提交成功,要么都失败回滚。
    • 一致性:数据库总是从一个一致性状态转换到另一个一致性状态。
    • 隔离性:一个事务在最终提交之前,对其他事务是不可见的。
    • 持久性:一旦事务提交,讲永久保存在数据库中。及时系统崩溃,也不会丢失。
  3. Mysql默认采用自动提交事务模式 autocommit。

     `show variables like 'autocommit';
     +---------------+-------+
     | Variable_name | Value |
     +---------------+-------+
     | autocommit    | ON    |
     +---------------+-------+
     1 行于数据集 (0.04 秒)
     `
    

5.隔离级别:

  1. Read Uncommitted(未提交读):事务中的修改,及时没有提交,对其他事务也是课件的。其他事务可以读取未提交的数据,成为脏读。一般很少使用。
  2. Read Committed(提交读)(不可重复读):事务的修改,在提交之前对其他事务都不可见。会导致A事务在修改一行数据之前,B 输入做过读取;A事务提交成功以后,B事务在读取引起不一样的结果。
  3. Repeatable Read(可重复读):解决在同一事务多次读取同样记录的结果一致,读取的数据在本事务内防止其他事务对其修改。但是防止不了此时做新增,引起幻读幻读问题。InnoDB和XtraDB通过版本并发控制MVCC,解决幻读问题。Mysql默认隔离级别。
  4. Serializable(可串行化):最高的隔离级别。通过强制的事务串行执行,避免幻读问题。在读取每一行数据上都加锁,导致大量的锁征用问题。

Innodb对四种类型都支持,脏读和串行化应用场景不多,读提交、重复读用的比较广泛。

隔离级别 脏读可能性 不可重复读可能性 幻读可能性 加锁读
Read Uncommitted Yes Yes Yes No
Read Committed No Yes Yes No
Repeatable Read No No Yes No
Serializable No No No Yes

6. 版本并发控制MVCC

可以认为MVCC是行级锁的一个变种,但是他避免了很多情况的加锁操作,降低开销。实现了非阻塞的读操作,和写操作的锁定必要行。MVCC的实现是通过保存数据在某个时间点的快照实现的。分为乐观并发控制、悲观并发控制。

InnoDB的MVCC是通过在没行记录后面保存三个隐藏的列。

  • DB_TRX_ID:6byte的标识,每处理一个事务,就自动+1.
  • DB_ROLL_PTR:7byte的标识,一条undo log记录,记录操作前的ROW值。
  • DB_ROW_ID:6byte,若没有主键才会有。
  1. select操作:
    • 对于select的操作,只有同时满足如下2个条件才返回行记录
    • 行的修改版本号小于等于该事务版本号
    • 行的删除版本号要么没有被定义,要么大于事务版本号。
    • 如果行的修改或者删除版本号大于事务号,说明行是被修改事务后启动的事务修改或者删除的。在可重复读的隔离级别下,后开始的事务堆数据的影响不应该被先开始的事务看见,所以应该忽略后开始的事务的更新或者删除操作。
  2. insert操作:
    新插入的行,行的修改版本号为更新为该事务的事务号。
  3. update操作:
    更新行的时候,InnoDB会把原来行复制一份,并把当前的事务号作为改行的修改版本号。把原来的记录标记为已删除版本号是事务版本号。
  4. delete操作:
    对于删除,InnoDB直接把改行的删除版本号修改为当前事务号,相当于标记为删除,而不是物理的删除。真是的删除是在InnoDB的purge线程去做的。

你可能感兴趣的:(MySql高性能笔记 - (一)Mysql基础知识)