mysql中有哪些锁?

  1. 共享锁(Shared Locks 或 S 锁)

    共享锁允许多个事务同时读取同一数据,但不允许任何事务在同一数据上进行写操作;

  2. 排他锁(Exclusive Locks 或 X 锁)

    排他锁阻止其他事务读取或修改同一数据,当一个事务需要更新或删除数据时,它会获取排他锁;

  3. 意向共享锁(Intent Shared Locks 或 IS 锁)&& 意向排他锁(Intent Exclusive Locks 或 IX 锁)

    加锁的时候可能锁某一行或几行的数据,也可能锁整个表,但共享锁只能和共享锁兼容,排他锁和两者(共享锁、排他锁)都不兼容。举一个极端的例子,如果共享锁锁表(全表扫描查询),难道需要一行行遍历看数据是否被排他锁锁过吗?同理,排他锁锁表时,就需要一行行遍历是否存在数据被共享锁或者排他锁占用。

    所以提出了IS锁和IX锁,减少行级锁和表级锁的冲突,以下是共享锁、排他锁、意向共享锁、意向排他锁的兼容关系

    X(排他锁) IX(意向排他锁) S(共享锁) IS(意向共享锁)
    X
    IX
    S
    IS

    Tip: IX和IX能兼容是因为多个IX锁时获取不同行数据的行锁,可以同时存在;同理,IX和IS兼容也是一样;

  4. 记录锁(Record Locks)

    锁定特定记录或行,锁定的行数是固定的;

  5. 间隙锁(Gap Locks):左开右开

    间隙锁的目的是在RR级别下,防止幻读,幻读的产生是当前事务多次的查询结果的数量不一致;间隙锁的目的就是保证当前范围内的数据不会被更改,所以它会锁住某些区间的数据

  6. 临键锁(Next-Key Locks):左开右闭

    等于记录锁+间隙锁,所以我们只需要知道两个锁的定义就行,Mysql在隔离级别为RR时,默认是Next-key锁;

  7. 表级锁(Table Locks)

  8. 行级锁(Row Locks)

    这种锁是最细粒度的锁,只锁定被事务访问的具体行。Innodb存储引擎支持行级锁;

  9. 页级锁(Page Locks)

    页级锁锁定的是数据库页,这是介于行级锁和表级锁之间的中间级别。某些存储引擎可能会使用页级锁,但InnoDB主要使用行级锁;

索引底层是如何实现的?

Mysql中默认的存储引擎是Innodb,其索引是使用B+树实现的。B+树是一种多路搜索树,它的叶子节点存储了所有的数据行信息,叶子节点之间使用指针连接,方便范围查询和排序等操作,非叶子节点存储的是索引字段的值(主键索引存存的是id);

为什么要选择B+树:

  1. 查询效率:

    • 内存:B+树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比B树(即存数据又存索引)大大节省了内存空间
    • IO操作:B+树的层级比B树更少,查询所需的IO操作更少;
  2. 插入和删除效率:

    B+树相比于B树新增和删除节点不用复杂的结构变化;

  3. 查询范围:

    B+树的叶子节点有指针连接方便进行范围查找

聚簇索引和非聚簇索引的区别?

聚簇索引和非聚簇索引的区别主要在数据的存储和查询:

  • 数据存储:

    聚簇索引(也即主键索引)的叶子节点存储的是主键对应的一行完整的数据,非聚簇索引(非主键索引)的叶子节点存储的是主键值,然后回表查询主键信息;

  • 范围查询:

    聚簇索引中的数据行与索引行一一对应的,因此聚簇索引通常比非聚簇索引更适合范围查询,而非聚簇索引需进行而进行二次查询:首先查找索引,然后查找数据行,这会导致性能问题,特别是大型表上进行范围查询;

什么情况会导致索引失效?

  • 不符合最左匹配原则
  • 使用列运算
  • 使用函数
  • 使用类型转换
  • is not null
  • 错误的模糊查询

mysql事务有哪些特性?

  • 原子性(A):事务中执行的操作要么全部成功,要么全部失败;
  • 一致性(C):事务执行前后事务的一致性没有被破坏,只能从一个一致性状态到另一个一致性状态;这里常说A转账B的问题,不管转账成功失败,A+B的总金额应该是不变的
  • 隔离性(I):事务之间相互隔离,每个事务对其他事务的操作都是透明的;
  • 持久性(D):事务完成后,对数据库的修改将永久保存在数据库中,即使系统故障也不会丢失;

如何保证事务四大特性(ACID)?

  • 原子性:原子性是通过undo log(回滚日志)保证,InnoDB使用日志(undo log)来记录事务从开始到结束的所有操作,当事务提交失败时,通过undo log日志来回滚执行的数据,来确保事务的原子性;
  • 持久性:持久性是通过redo log(重做日志)保证,在事务提交之前,innodb会将事务的修改操作先写入redo log 中,然后再将数据写入磁盘。即使在系统崩溃或断电的情况下,innodb可以通过重放事务日志来恢复数据,来确保事务的持久性。
  • 隔离性:MVCC(多版本并发控制)和锁机制来保证;
  • 一致性:一致性是通过各种约束,如主键,唯一性约束等,同时加上事务的持久性、原子性、隔离性同时来保证一致性;

不可重复读和幻读的区别?

不可重复读是指多次查询同一行数据,每次查询出来的结果都不同;

幻读是指范围查询时,会出现数据的个数总是在变化;

解决方案: 不可重复读通常通过提高隔离级别为RR或者手动使用行锁;

幻读:通过提高隔离级别为串行或者手动SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE时,InnoDB会在行级加锁的同时,也可能加间隙锁

MVCC是什么?能解决幻读吗?

MVCC是一种并发控制机制,主要用来解决幻读的问题。MVCC的核心思想是将每个事务的读操作与写操作解耦,通过保存数据的历史版本来控制并发,每个事务都会创建一个读视图(read-view),用于确定在事务开始时可见的数据版本,旧版本的事务会保存在undo log中(mysql有undo log缓存)

  • 读操作:当一个事物执行SELECT语句时,会根据读视图的版本号与数据行的版本号就行比对,只读取在事务之前已经提交的数据行。这样,即使其他事务正在并发的插入或者删除数据,事务仍然可以读取到一致的数据。
  • 写操作:当一个事务执行INSERT、UPDATE或DELETE语句时,会生成新的数据版本,并将旧版本的数据保存在undo log中.这样,其他事务在读取数据时仍然可以访问到旧版本的数据,从而避免幻读的问题;

RR+MVCC能解决幻读吗?

不能,即使是在RR级别下,MVCC虽然能解决大部分的幻读问题,但依然存在部分幻读问题无法解决;

在RR模式下,mysql 的innodb引擎读取数据有两种方式快照读(Snapshot Read)和当前读(Current Read)

  • 快照读:读取开启事务时的已经提交的数据,即使后面有修改,当前事务也只能读取这个快照版本之前的事务数据;
  • 当前读:通过 SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE方式执行的查询,会读取最新提交的数据,而不是开启事务之前版本的数据;

TIP:快照读主要适用于需要读取一致性数据的场景,比如报表生成或分析,其中数据的一致性比绝对实时性更重要;当前读适用于需要读取最新数据的场景,比如实时交易系统或需要立即反应最新数据变化的业务逻辑;

解决的方案:

  • 使用串行化(Serializable)隔离级别:官方推荐方案,但这种解决方案,并发性能比较低。
  • RR + 锁:使用 RR 隔离级别,通过 SELECT ... FOR UPDATE加锁,可以保证在查询过程中,不会有别的事务插入数据;

如何保证数据库和缓存双写一致?

解决缓存和数据库一致问题的常见解决方案有以下 4 种:

  1. 先修改数据库,后更新缓存。
  2. 先更新缓存,后修改数据库。
  3. 先修改数据库,后删除缓存。
  4. 先删除缓存,后修改数据库。

前3种都存在第一步执行成功第二步执行失败的问题,所以一般都是使用第4种,先删除缓存在更新数据库的方案,最起码能保证数据的一致性问题;但是这种方案其实也有一些问题,会存在旧值覆盖缓存的问题(先删了缓存,另一个线程看没有缓存,查库更新缓存,导致缓存中是旧值,数据库是新值);如果我们想要达到最大程度的解决双写一致性问题,最终的解决方案就是MQ+延迟双删策略

  1. 引入MQ保证消息不回丢失;
  2. 通过先删除缓存,修改数据库;
  3. 延时一段时间再次删除缓存;

Undo log(回滚日志) 和 redo log(重做日志)是由什么区别?什么时候落盘的?

  • Undo log保证了事务的原子性;redo log保证事务的持久性;
  • undo log在事务开始修改数据时就会生成undo log日志记录,主要记录的是修改前的数据;redo log则是事务开始修改数据时,主要记录的执行的sql;
  • Redo log需要实时的flush到磁盘(Redo log的flush写入磁盘时机是灵活的,InnoDB会根据配置和系统状态决定何时将Redo log从内存flush到磁盘,通常是在事务提交前后、定期或当Redo log buffer达到一定比例时);undo log不需要实时的落盘,因为undo log是事务的一部分,事务提交后仍需要保存一段时间,以便其他事务能够读取旧的行版本(MVCC)。