基础
常见问题
数据库锁的分类
- 按锁的粒度划分,可分为表级锁、行级锁、页级锁(BDB引擎)
- 按锁的级别划分,可分为共享锁、排它锁
- 按加锁方式划分,可分为自动锁、显示锁
- 按操作划分,可分为DML锁(对数据进行操作的锁,增删改查)、DDL锁(对表结构进行变更)
- 按使用方式划分,可分为乐观锁、悲观锁
MyISAM于InnoDB关于锁方面的区别是什么
- MyISAM默认使用表级锁,不支持行级锁
- InnoDB默认使用行级锁,也支持表级锁
- InnoDB在没有使用索引的时候用的是表级锁
MyISAM适用场景
- 频繁执行全表count语句
- 对数据进行增删改的频率不高,查询非常频繁
- 没有事物
InnoDB适用场景
- 数据增删改查相当频繁
- 可靠性要求比较高,要求支持事物
数据库事务的四大特性(ACID)
- 原子性(Atomic):事务包含的所有操作要么执行,要么全部失败回滚--要么全做,要么全都不做
- 一致性(Consistency):事务应确保数据库的状态从一个一致到另外一个一致状态,一致状态的含义:数据库中的数据应满足完整性约束(例:A、B共有200,不管A、B之间转了多少钱,A和B共有的钱始终是200)
隔离性(Isolation):多个事物并发操作,一个事物的执行不能影响其他事物的执行- 持久性(Durability):一个事物的提交,它对数据库的修改应该永久保存在数据库中。确保已提交的事物可以回滚。主要在于DDMS的回复性能
事务并发访问以及产生的问题以及事物隔离机制
隔离级别:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交(Read Uncommit) | × | × | × |
| 读已提交(Read Commit) | √ |
× | × |
| 不可重复读(Repeatable Read) | √ |
√ |
× |
| 串行序列化(Serializable) | √ |
√ |
√ |
× 表示不能隔离,会出现此种不一致错误
√表示可以隔离,不会出现该不一致错误 关于三种不一致问题,将会在数据库并发控制里讨论 注意:在实现了mvcc的innodb和postgresql的数据库对应的RR隔离级别,也不会出现幻读错误。
事务并发访问引发的问题以及如何避免
- 更新丢失:mysql所有事务隔离级别在数据库层面上均可避免(数据库引擎基本避免了此问题)
- 脏读:一个事物读到另一个事物未提交的更新数据
----避免:RC(READ-COMMITED)事务隔离级别以上可避免 - 不可重复读:事务A多次读取统一数据,事务B在事务A多次读取的过程中更新并提交,导致事务A多次读取数据不一致
----避免:Repeatable-Read事务隔离级别以上可避免 - 幻读:事务A读取当前数据,事务B增加或删除其中的一条数据,当事务A在去读取数据时,发现数据发生了换行
----避免:Serializable事务隔离级别可避免 #####当前读和快照读 ######当前读 定义 加了锁的增删改查语句。读取的是最新版本,并且其他事物不能修改当改当前记录 包含 - 当前读:select...lock in share mode,select...for update
- 当前读:update, delete,insert ######快照读
- 快照读:不加锁的非阻塞读,select #####InnoDB可重复读隔离级别下如何避免幻读 通过我们上面的结论得出只有在serializable级别下才能避免幻读,但是实际InnoDB可重复读隔离级别下避免了幻读
- 表象:快照读(非阻塞读)--伪MVCC
- 内在:next-key锁(行锁+gap锁)
- Gap锁用在非唯一索引或者不走索引的当前读中
RC、RR级别下的InnoDB的非阻塞读如何实现
- 数据行里的DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID
- undo日志
- read view