mysql之常见问题
MyISAM与InnoDB关于锁方面的区别是什么
MyISAM默认用的是表级锁,不支持行级锁
对MyISAM表进行查询时,MyISAM会给表加上读锁(共享锁),其他线程要对表数据进行增删改操作时,会被阻塞,直到查询完成释放读锁,才能加上写锁(排它锁、互斥锁)进行操作。
InnoDB默认用的是行级锁,也支持表级锁
如果表没有走索引,InnoDB会给表加表级锁,若走索引,则加行级锁+gap锁(默认可重复读事务隔离级别下)
MyISAM适合的场景
- 频繁执行全表count语句(MyISAM保存了count数据)
- 对数据进行增删改的频率不高,查询非常频繁
- 没有事务
InnoDB适合的场景
- 数据增删改查都相当频繁
- 可靠性要求比较高,要求支持事务
数据库锁的分类
- 按锁的粒度划分,可分为表级锁,行级锁,页级锁
- 按锁级别划分,可分为共享锁、排它锁
- 按加锁方式划分,可分为自动锁、显式锁
- 按操作划分,可分为DML锁、DDL锁
- 按使用方式划分,可分为乐观锁、悲观锁
数据库事务的四大特性
ACID
- 原子性(Atomicity) 事务被视为不可分割的最小单元,事务的所有操作要么全部提交成功,要么全部失败回滚。 回滚可以用回滚日志来实现,回滚日志记录着事务所执行的修改操作,在回滚时反向执行这些修改操作即可。
- 一致性(Consistency) 数据库在事务执行前后都保持一致性状态。在一致性状态下,所有事务对一个数据的读取结果都是相同的。
- 隔离性(Isolation) 一个事务所做的修改在最终提交以前,对其它事务是不可见的。
- 持久性(Durability)
一旦事务提交,则其所做的修改将会永远保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失。 使用重做日志来保证持久性。
mysql事务并发访问引发的问题以及事务隔离机制
事务并发访问引起的问题以及如何避免
- 更新丢失—mysql所有事务隔离级别在数据库层面上均可避免
- 脏读—READ-COMMITED事务事务隔离级别以上可避免
- 不可重复读—REPEATABLE-READ事务隔离级别以上可避免
- 幻读—SERIALIZABLE事务隔离级别可避免
mysql默认使用的是repeatable-read隔离级别,可通过select @@tx_isolation;查看当前数据库隔离级别;
read-uncommited:允许读取其他事务未提交的数据,会引发脏读问题。
read-commited:只允许读取其他事务已经提交的数据,可避免发生脏读。
repeatable-read:保证在同一个事务中多次读取同样数据的结果是一样的。
serializabel:强制事务串行执行。
InnoDB可重复读隔离级别下如何避免幻读
- 表象:快照读(非阻塞读)——伪MVCC
- 内在:next-key锁(行锁+gap锁)
对于主键索引或unique索引mysql如何使用gap锁:
- 如果where条件全部命中,则不会要Gap锁,只会加记录锁
- 如果where条件部分命中或者全不命中,则会加Gap锁
Gap锁会用在非唯一索引或者不走索引的当前读中
- 非唯一索引
如果在(6,9】,(9,11】不加Gap锁,而由于id是普通索引,没有唯一约束,其他事务就可能插入相同id=9的记录,这样就会导致当前事务发生幻读。
- 不走索引
如果不走索引当前读,mysql会加上所有Gap锁,等同于全表锁,这样代价太大,效率太低。