一, 数据库结构:
1.1 Server 层:
连接器 权限验证 尽量使用长连接, 但是长连接会消耗内存, 可以定时清理, 也可以重新初始化链接资源
查缓存 (一般不用, 除非读多写少 8.0 移除)
分析器 词法分析, 语法分析, 语法解析
优化器 使用哪个索引 表连接顺序
执行器 执行语句, 查询是否具有读写权限
1.2 存储引擎层
- InnoDB(默认存储引擎)
- MyISAM(不支持事务)
二, 数据库日志
2.1 redo log
1.redo log 是 InnoDB 引擎特有的日志 循环写入固定大小内存
2.WAL, 先写日志再写磁盘
innodb_flush_log_at_trx_commit 参数 决定写磁盘时机
设置为 1: 系统默认模式, 每次事务提交时 MySQL 都会把 log buffer 的数据写入 log file, 并且 flush(刷到磁盘) 中
2.2 binlog
追加写入文件, 到达指定大小切换另一个文件
三个用途:
1. 恢复: 利用 binlog 日志恢复数据库数据
2. 复制: 主从同步
3. 审计: 通过二进制日志中的信息来进行审计, 判断是否有对数据库进行注入攻击
三种模式:
1.statement 记录的是修改 SQL 语句
2.row 记录的是每行实际数据的变更, 记两条, 更新前和更新后
3.mixed statement 和 row 模式的混合
2.3 两阶段提交策略
1. 先在引擎层写 redolog,redolog 处于 prepare
2. 然后在 server 写 binlog
3. 事务提交, redolog commit 提交写入磁盘
崩溃恢复 在 1 阶段完成后崩溃, 回滚写入的 redolog
在 2 阶段完成后崩溃, 因为已经写入 binlog 所以不回滚
三, 事物隔离级别
事物隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted) | 是 | 是 | 是 |
读已提交(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
脏读
在一个事务中, 读取了其他事务未提交的数据
不可重复读
在一个事务中, 同一行记录被访问了两次却得到了不同的结果
幻读
在一个事务中, 同一个范围内的记录被读取时, 其他事务向这个范围添加了新的记录.
前面脏读和不可重复读容易理解, 幻读稍微难一点
假设图一 test 开始是空表, 事物 1 第一次查询得到空表, 事物 2 在事物 1 执行期间插入一条数据, 事物 1 第二次查询由于满足可重复读, 所以查询结果依然为空, 但是事物 1 插入同样一条数据, 报重复主键错误
serialzable 级别下可以避免以上三种情况
事务隔离的实现
视图: 视图可以理解为数据副本
不同时刻开启的事务会创建不同的视图, 后续直接从视图读取数据, 达到数据隔离, 当然数据隔离还需要数据库锁的帮助.
同一数据库记录可以在系统中存在多个版本, 这就是 MVCC.
长事务意味着系统里面会存在很老的事务视图. 由于这些事务随时可能访问数据库里面的 任何数据, 所以这个事务提交之前, 数据库里面它可能用到的回滚记录都必须保留, 这就 会导致大量占用存储空间. 所以需要避免长事务
最后
读到最后的朋友可以点点喜欢和关注下, 以后会更新更多精选干货文章!
来源: http://www.jianshu.com/p/ef1bbd00c7a9