mysql之常见问题

  1. MyISAM与InnoDB关于锁方面的区别是什么

    • MyISAM默认用的是表级锁,不支持行级锁

      对MyISAM表进行查询时,MyISAM会给表加上读锁(共享锁),其他线程要对表数据进行增删改操作时,会被阻塞,直到查询完成释放读锁,才能加上写锁(排它锁、互斥锁)进行操作。

    • InnoDB默认用的是行级锁,也支持表级锁

      如果表没有走索引,InnoDB会给表加表级锁,若走索引,则加行级锁+gap锁(默认可重复读事务隔离级别下)

  2. MyISAM适合的场景

  • 频繁执行全表count语句(MyISAM保存了count数据)
  • 对数据进行增删改的频率不高,查询非常频繁
  • 没有事务
  1. InnoDB适合的场景

    • 数据增删改查都相当频繁
    • 可靠性要求比较高,要求支持事务
  2. 数据库锁的分类

    • 按锁的粒度划分,可分为表级锁,行级锁,页级锁
    • 按锁级别划分,可分为共享锁、排它锁
    • 按加锁方式划分,可分为自动锁、显式锁
    • 按操作划分,可分为DML锁、DDL锁
    • 按使用方式划分,可分为乐观锁、悲观锁
  3. 数据库事务的四大特性

    ACID

    1. 原子性(Atomicity) 事务被视为不可分割的最小单元,事务的所有操作要么全部提交成功,要么全部失败回滚。 回滚可以用回滚日志来实现,回滚日志记录着事务所执行的修改操作,在回滚时反向执行这些修改操作即可。
    2. 一致性(Consistency) 数据库在事务执行前后都保持一致性状态。在一致性状态下,所有事务对一个数据的读取结果都是相同的。
    3. 隔离性(Isolation) 一个事务所做的修改在最终提交以前,对其它事务是不可见的。
    4. 持久性(Durability)

    一旦事务提交,则其所做的修改将会永远保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失。 使用重做日志来保证持久性。

  4. mysql事务并发访问引发的问题以及事务隔离机制

    • 事务并发访问引起的问题以及如何避免

      • 更新丢失—mysql所有事务隔离级别在数据库层面上均可避免
      • 脏读—READ-COMMITED事务事务隔离级别以上可避免
      • 不可重复读—REPEATABLE-READ事务隔离级别以上可避免
      • 幻读—SERIALIZABLE事务隔离级别可避免

mysql默认使用的是repeatable-read隔离级别,可通过select @@tx_isolation;查看当前数据库隔离级别;

  • read-uncommited:允许读取其他事务未提交的数据,会引发脏读问题。

  • read-commited:只允许读取其他事务已经提交的数据,可避免发生脏读。

  • repeatable-read:保证在同一个事务中多次读取同样数据的结果是一样的。

  • serializabel:强制事务串行执行。

    1557027257006

    1. InnoDB可重复读隔离级别下如何避免幻读

      • 表象:快照读(非阻塞读)——伪MVCC
      • 内在:next-key锁(行锁+gap锁)
    • 对于主键索引或unique索引mysql如何使用gap锁:

      • 如果where条件全部命中,则不会要Gap锁,只会加记录锁
      • 如果where条件部分命中或者全不命中,则会加Gap锁
    • Gap锁会用在非唯一索引或者不走索引的当前读中

      • 非唯一索引

      1557035076182

    如果在(6,9】,(9,11】不加Gap锁,而由于id是普通索引,没有唯一约束,其他事务就可能插入相同id=9的记录,这样就会导致当前事务发生幻读。

    • 不走索引

    1557035824056

如果不走索引当前读,mysql会加上所有Gap锁,等同于全表锁,这样代价太大,效率太低。