一. Double Write
1 Double Write介绍

• Double Write的目的是为了保证数据写入的可靠性, 避免partial write 的情况◦ partial write(部分写)◾ 16K的页只写入了4K,6K,8K,12K的情况(此时是不完整、不干净的页);◾ 不可以 通过redo log进行恢复;◾ redo恢复的前提是该 页 必须是 完整、干净 的;
• Double Write是 全局 的
• 共享表空间存在一个 段对象 double write,然后这个段 由2个区( 1M)组成
• 2M固定大小(both file and memory)
• 页在刷新时,首先 顺序 的写入到double write
• 然后再刷回磁盘(ibd)

# 有点类似 RAID-1 的机制,总有一份数据是正确的
# 简单说来,就是在脏页刷新到磁盘前,先要有个地方记录这个脏页的副本

1. 将脏页copy到Double Write Buffer对象中,默认2M大小;
2. 将Double Write Buffer中的对象 先写入 到共享表空间(ibdata1)中的Double Write;◦ 2M循环覆盖◦ 顺序 写入(一次IO)
3. 再根据(space,page_no)写入到原来的ibd文件中;
4. 如果是在写到ibdata1中的Double Write时,发生宕机;此刻原来的ibd file 仍然是完整、干净的 ,下次启动后是可以用redo文件进行恢复的。
5. 如果是写到ibd文件时,发生了宕机;此刻在原来的 ibdata1中存在副本 ,可以直接覆盖到ibd文件(对应的页)中去,然后再进行redo进行恢复
redo是 物理逻辑 的, 物理 表示记录的日志针对的是 页( page) 的修改, 逻辑 表示记录日志的内容是逻辑的。

mysql> show variables like "%doublewrite%";+--------------------+-------+| Variable_name | Value |+--------------------+-------+| innodb_doublewrite | ON |+--------------------+-------+1 row in set (0.00 sec)

2. Double Write的开销

• 假设每个页大小为16K,则2M的Double Write中存放了128个页,在使用了Double Write之后,IO从原来的128次IO变成了 128 + 1 次IO,而 不是128 + 128 次IO。
• Double Write的2M数据是 顺序 刷入磁盘的,是 一次IO ,该次IO的大小为2M。
• 开启Double Write的性能降低5% ~ 25%(IO Bound场景下降的最厉害)
• slave服务器同样 需要开启

3. Double Write可以关闭的前提

1. 支持 原子 写的设备
◦ 磁盘◾ Funsion-IO◾ 宝存
◦ 文件系统◾ ZFS (Linux上不推荐使用)◾ btrfs(Linux上不推荐使用)◾ 使用 copy on wirte 机制, 不进行原地更新 ,而是开辟新的位置,写成功后,将原来的页 释放◾ 本质上的思路还是 保留一个副本
2. innodb_doublewrite=0 可以关闭double write功能

二. Insert/Change Buffer
1. Insert/Change Buffer介绍

• MySQL5.5版本以前叫做 insert buffer ,现在叫做 change buffer
• 提高辅助索引的插入性能
• 非唯一 的二级索引(non-unique secondary index)
• Insert/Change Buffer 是一个 持久化 的对象(在ibdata1中,同时也会写redo日志)
• Insert/Change Buffer页是一棵B+树,每次最缓存 2K 的记录
• 开启后有30%的性能提升(默认开启)
• MySQL5.5版本之前,最大可以设置为Buffer Pool的 1/2 ,现在最大只能设置为 1/4
• 当Insert Buffer进行 合并 的时候, 性能下降
mysql> show variables like "%change_buffer%";
+-------------------------------+-------+
| Variable_name           | Value |
+-------------------------------+-------+
| innodb_change_buffer_max_size | 25    |
| innodb_change_buffering       | all   |
+-------------------------------+-------+
2 rows in set (0.00 sec)

2. Insert/Change Buffer举例

CREATE TABLE t (
a INT AUTO_INCREMENT, -- a 列是自增的
b VARCHAR(30), -- b 列是varchar
PRIMARY KEY(a) -- a 是主键
key(b) -- b 是二级索引(如果是name之类的,可以看成是非唯一的)
);
• 对于 主键 (a列),每次插入都要立即插入对应的 聚集索引 页中(在内存中就直接插入,不在内存就先读取到内存)
• 对于 二级索引 (secondary index)(b列)1. 在 没有 Insert/Change Buffer时,每次插入一条记录,就要读取一次页(读取内存,或者从磁盘读到内存),然后将记录插入到页中;2. 在 有 Insert/Change Buffer时,当插入一条记录时, 先判断 记录对应要插入的 二级索引 (secondary index)页 是否 在Buffer Pool中:◾ 如果该 二级索引 (secondary index)页 已经在Buffer Pool中 ,则 直接插入 ;◾ 反之,先将其 Cache 起来,放到Insert/Change Buffer中,等到该 二级索引 (secondary index)页被 读到 时,将Insert/Change Buffer中该页对应的记录 合并 (Merge)进去,从而减少I/O操作;
Insert/Change Buffer就是用来 提升二级索引插入的性能 。
使用空间换时间,批量插入的方式(二级索引可以不急着插入,只要主键已经插入了即可)

3. Insert/Change Buffer 性能

1. 左图使开启了Insert/Change Buffer,而右图未开启;
2. 一开始都比较高是因为还没有全量的进行刷磁盘(脏页全部在Buffer Pool中,还没满)
◦ 如开始介绍时所说,当Insert Buffer进行合并的时候,性能进行下降
3. 开启Insert/Change Buffer后,insert的常量值在 5K 左右;
4. SSD场景下也建议开启;

4. Insert/Change Buffer 查看

mysql> show engine innodb status\G
-- -----------省略其他输出-------------
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges -- 这里为0 ,可能是Buffer Pool足够大,-- 数据页都缓存在内存中了,就用不到buffer了
merged operations:
insert 0, delete mark 0, delete 0
discarded operations:
insert 0, delete mark 0, delete 01. seg size: 页 的数量,例如当前页为8K,则 seg_size * 8K 就是Insert/Change Buffer使用的内存大小;
2. merges:合并了多少 页 ;
3. merged insert:插入了多少条 记录 ;◦ insert / merges 就是插入的效率 (插入一条记录,就要读取一次页);
4. discarded operations:应该是很小的值,或者为0;当记录写入到Insert/Change Buffer后,对应的表被删除了,则相应的Buffer中的记录就应该被丢弃;
使用Insert/Change Buffer的前提时,需要 使用随机IO ,这时才放入Buffer中,如果页已经在Buffer Pool(内存)中,就 不需要 使用Insert/Change Buffer了

5. Change Buffer

• 从MySQL 5.5 以后,改名为Change Buffer,表示不仅仅适用于insert。1. Insert2. Delete-Marking(标记删除)3. Purge(清除)4. innodb_change_buffering = all◾ all◾ none (禁用)◾ inserts◾ deletes◾ changes =(insert & delete-marking)◾ purg

三. Adaptive Hash Index(自适应Hash索引)

• 搜索的时间复杂度◦ B+树 O(T),只能定位到该记录所在的页;◦ 哈希表 O(1),可以直接定位到记录;
• 可以自己判断是否是活跃的页,如果是活跃的页,可以自动做Hash,管理员无需人工干预;
• MySQL5.6版本后,官方 不推荐 使用自适应Hash索引◦ CPU 使用率变高,但是性能没有提升;
• MySQL5.7中增加了 innodb_adaptive_hash_index_parts ,增加分片,以减少竞争;
• 只对等值的操作有意义;

四. Flush Neighbor Page (FNP)

• 刷新 脏页所在区 (extent)的 所有脏页 ,合并IO,随机转顺序的优化;◦ 写入的数据太多◦ 如果业务确实是频繁更新,那刷新也会很频繁
• 对传统机械磁盘有意义;◦ innodb_flush_neighbors={0|1|2} (>=MySQL 5.6)◦ 0:表示关闭该功能◦ 1:表示刷新一个区内的脏页◦ 2:表示刷新几个 连续 的脏页
• SSD建议关闭次功能;
mysql> show variables like "%flush_neigh%";
+------------------------+-------+
| Variable_name       | Value |
+------------------------+-------+
| innodb_flush_neighbors | 2     | -- 非SSD建议使用2
+------------------------+-------+
1 row in set (0.00 sec)

转载于:https://www.cnblogs.com/hbxZJ/p/10160919.html

22.doublewrite/ChangeBuffer/AHI/FNP相关推荐

  1. mysql必须的组件_mysql innodb的重要组件

    innodb包涵如下几个组件 一.innodb_buffer_pool: 1 它主要用来缓存数据与索引(准确的讲由于innodb中的表是由聚集索引组织的,所以数据只不是过主键这个索引的叶子结点). 二 ...

  2. CentOS6.4离线安装mysql5.6.22

    我们前面已经记录过一篇linux系统有网的情况下在线安装的情况. CentOS6.4安装mysql5.6.14 有一种情况是 linux系统没外网,但是需要安装mysql,这种情况的话 我们需要把包用 ...

  3. centos 安装mysql5.6.22_centos 7.0 编译 安装mysql 5.6.22 过程 已完成~ 成功~ 撒花~

    mysql 下载目录/usr/local/src mysql 解压目录 /usr/local/bin/mysql GitHub https://github.com/mysql/mysql-serve ...

  4. MySQL系列-innodb doublewrite

    DBW(double write) double wirte是innodb存储引擎为了保证数据页的安全性而引入的一项技术,那么数据库安全性从何说起呢? 就从数据磁盘的一次io是4KB说起,一项简单的命 ...

  5. 零起点学算法22——华氏摄氏温度转换

    零起点学算法22--华氏摄氏温度转换 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lld Description 输入一个华氏 ...

  6. mysql8导入 psc 没有数据_新特性解读 | MySQL 8.0.22 任意格式数据导入

    作者:杨涛涛 资深数据库专家,专研 MySQL 十余年.擅长 MySQL.PostgreSQL.MongoDB 等开源数据库相关的备份恢复.SQL 调优.监控运维.高可用架构设计等.目前任职于爱可生, ...

  7. c语言计算M=11 22 33,四川计算机C语言考试笔试真题33次..doc

    四川省普通高等学校计算机应用知识和能力 第三十三次等级考试 二级(C与C++语言) 笔 试 试 卷 时间: 2010年10月 23 日 上午 9:00-11:00 第一部分 软件技术基础 (共15分) ...

  8. linux mysql 5.6.22_LinuxCentOS6.0下编译安装MySQL5.6.22

    Linux CentOS6.5下编译安装MySQL 5.6.22[给力详细教程] 一.编译安装MySQL前的准备工作 安装编译源码所需的工具和库(安装过程注意有没出错) yum install gcc ...

  9. 优达学城《DeepLearning》2-2:迁移学习

    目录 加载和预处理数据 转换数据 数据加载器和数据可视化 定义模型 最终分类器层 指定损失函数和优化器 训练 测试 可视化样本测试结果 大多数时候,你不会想自己训练一个完整的卷积网络.像ImageNe ...

最新文章

  1. Java:取得当前日期一周之前/之后的日期,或者是一月之前/之后的日期
  2. Oracle用户密码过期和用户被锁解决方法【转】
  3. 正式发布!中国首个LF Edge捐赠项目Baetyl 2.2发布
  4. PLSQL developer 连接64位oracle 11.2G
  5. ubuntu终端下快捷键,字体放大缩小等【逐渐完善篇】
  6. 35.使用拦截器实现权限验证
  7. AIDL实现不同应用间的通信
  8. 三、函数的嵌套、作用域链、函数名的应用、闭包。
  9. HDU Calling Extraterrestrial Intelligence Again
  10. oracle数据库ora01012错误,Oracle自定义异常收集(二)
  11. 闪讯钳制下Linux系统上网解决方案
  12. 游戏是怎么赚钱的 - 科普篇
  13. 电路设计_MOS管导通条件
  14. JAVA 实现《萝卜勇者》游戏
  15. 费马大定理与费马小定理
  16. 浅谈车联网与大数据分析
  17. python求反余弦_余弦相似度计算公式:python代码找出相似文章
  18. echarts动态legend不变更
  19. 懒懒的周末 (r8笔记第30天)
  20. 网狐 协调服务器 作用,网狐架构之登录服务器

热门文章

  1. jenkins 用户授权
  2. Mouse Detected Problem
  3. AIX7.1环境打补丁缺少bash OPATCHAUTO-72049
  4. npm 报错 Module build failed: Error: No PostCSS Config found in:
  5. 九 web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解...
  6. 思卡乐科技发布SR3系列RFID产品
  7. 我的学习网址(未完)
  8. Linux内核实验作业七
  9. 谷歌,火狐浏览器不能禁用自动补齐的bug缺陷
  10. JS实现下一天的显示