一. 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 0
1. 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. Insert
  2. 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)

22.doublewrite/ChangeBuffer/AHI/FNP的更多相关文章

  1. 【转】推荐几本学习MySQL的好书-MySQL 深入的书籍

    MySQL的使用 1 MySQL技术内幕InnoDB存储引擎 2 MySQL的官方手册 3 MySQL排错指南 4 高性能MySQL 5 数据库索引设计与优化 6 Effective MySQL系列 ...

  2. mysql innodb的重要组件

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

  3. centos 7.0 编译安装mysql 5.6.22 再次总结 成功编译安装~ 越来越熟练了~

    查找php.ini文件所在位置 [root@localhost /]# find -name php.ini ./usr/etc/php/etc/php.ini mysql官网的安装说明http:// ...

  4. centos 7.0 编译 安装mysql 5.6.22 过程 已完成~ 成功~ 撒花~

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

  5. insert buffer/change buffer double write buffer,双写 adaptive hash index(AHI) innodb的crash recovery innodb重要参数 innodb监控

    https://yq.aliyun.com/articles/41000 http://blog.itpub.net/22664653/viewspace-1163838/ http://www.cn ...

  6. CENTOS 6.5 平台离线编译安装 Mysql5.6.22

    一.下载源码包 http://cdn.mysql.com/archives/mysql-5.6/mysql-5.6.22.tar.gz 二.准备工作 卸载之前本机自带的MYSQL 安装 cmake,编 ...

  7. EC笔记:第4部分:22、所有成员都应该是private的

    EC笔记:第4部分:22.所有成员都应该是private的 更简单的访问 用户不用记得什么时候该带上括号,什么时候不用带上括号(因为很确定的就要带上括号) 访问限制 对于public的成员变量,我们可 ...

  8. Hadoop学习笔记—22.Hadoop2.x环境搭建与配置

    自从2015年花了2个多月时间把Hadoop1.x的学习教程学习了一遍,对Hadoop这个神奇的小象有了一个初步的了解,还对每次学习的内容进行了总结,也形成了我的一个博文系列<Hadoop学习笔 ...

  9. 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验

    在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...

随机推荐

  1. 51NOD1174 区间最大数 && RMQ问题(ST算法)

    RMQ问题(区间最值问题Range Minimum/Maximum Query) ST算法 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度 ...

  2. luogu4159 迷路 (矩阵加速)

    考虑如果只有距离为1的边,那我用在时间i到达某个点的状态数矩阵 乘上转移矩阵(就是边的邻接矩阵),就能得到i+1时间的 然后又考虑到边权只有1~9,那可以把边拆成只有距离为1的 具体做法是一个点拆成9 ...

  3. [FJOI2016]神秘数(脑洞+可持久化)

    题目描述 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13}, 1 = 1 2 = 1+1 3 = 1+1+1 4 = 4 5 = 4+1 6 = ...

  4. LNOI2014LCA(树链剖分+离线操作+前缀和)

    题意:给一棵有根树,有多组询问,询问为l r z,求下标为l到r之间的点和z的lca的深度和. 如果我们一个一个求.emmmmm... 考虑答案怎么产生,仔细想一想,如果我们把l到r的所有点到根都加上 ...

  5. hasattr

    语法: hasattr(object,name) 检测类对象是否具有该name属性或方法

  6. Composer 安装时要求输入授权用户名密码?

    D:\work\dreamland-yii>composer require "saviorlv/yii2-dysms:dev-master" Authentication ...

  7. docker 拷贝镜像文件

    1.概述 我们制作好镜像后,有时需要将镜像复制到另一台服务器使用. 能达到以上目的有两种方式,一种是上传镜像到仓库中(本地或公共仓库),但是另一台服务器很肯能只是与当前服务器局域网想通而没有公网的,所 ...

  8. [HEOI2014]平衡

    [HEOI2014]平衡 转化为求选择k个数,和为(n+1)*k的方案数 保证,每个数[1,2*n+1]且最多选择一次. 限制k个很小,所以用整数划分的第二种方法 f[i][j],用了i个,和为j 整 ...

  9. 跟我一起用node-express搭建一个小项目(mongodb)[二]

    我的小项目主要是会用到MongoDB. 呵呵,我也是现学现卖. 都说小公司十八般武艺样样稀疏,没有办法啊! 兵来兵挡,将来将挡!自己是个兵呢?还是一个将呢! 没有公司培养,就自己培养自己呗.差的远一点 ...

  10. 使用Microsoft Toolkit 2.5 激活windows server 2012 R2与office

    本人亲测可以激活windows server 2012 R2版 关于此软件介绍如下: 这是一款可以用来管理或者配置 Microsoft Office 和 Windows 的许可证(密钥)的工具,也用来 ...