首页 > 数据库 >技术分享 | MySQL:change buffer 何时生效

技术分享 | MySQL:change buffer 何时生效

时间:2022-12-20 15:32:47浏览次数:36  
标签:insert buffer mark 索引 MySQL id change delete


作者:胡呈清

爱可生 DBA 团队成员,擅长故障分析、性能优化,个人博客:https://www.jianshu.com/u/a95ec11f67a8,欢迎讨论。



已知 change buffer 的原理


对于普通二级索引,当插入、修改、删除二级索引记录时,即使数据不在 innodb buffer pool 中,也不需要先把数据从磁盘读取到内存。只需要在 change buffer 中完成 DML 操作,下次读取时才会从磁盘读取数据页到内存,并与 change buffer 进行 merge,从而得到正确的数据。这减少了 DML 时的随机 IO。

疑问

按照上述原理,使用 change buffer 二级索引不需要读取磁盘,那 delete、update 是如何得到 affected rows 的?

不妨先作出假设:

  • 如果 delete、update 是以主键、唯一索引做为筛选条件,则读取磁盘或者 innodb buffer pool 中的主键、唯一索引来确定 affected rows。对于普通索引页上记录的删除或者修改,还是直接使用 change buffer,不需要单独将普通索引页从磁盘上读取到内存。
  • 如果 delete、update 是以普通二级索引做为筛选条件,以 delete 为例(update 内部实现是先 delete 再 insert):delete from t where a=100; 如果索引页不在内存中,则需要先从磁盘读取 a 索引,找到 a = 100 的记录对应的 id(主键值),再从磁盘扫描主键索引(回表)将 id 满足条件的记录读取到内存。然后在 innodb buffer pool 中把对应的主键索引页、二级索引页中的记录删除。这里不使用 change buffer。

验证

接下来设计两个实验来验证上述假设。

实验1-以主键为筛选条件做 delete

用 sysbench 造一张 100 万行的表,表中有一个主键和一个普通索引:

CREATE TABLE `sbtest1` (
`id` int NOT NULL AUTO_INCREMENT,
`k` int NOT NULL DEFAULT '0',
`c` char(120) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
`pad` char(60) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_2` (`k`)
);

重启 mysqld ,清空 innodb buffer pool,注意参数:

innodb_buffer_pool_size = 64M
innodb_buffer_pool_load_at_startup = 0
innodb_buffer_pool_dump_at_shutdown = 0
innodb_buffer_pool_dump_pct = 0

执行 delete,并使用​​show engine innodb status\G​​​观察​​INSERT BUFFER AND ADAPTIVE HASH INDEX​​ 部分信息,判断是否使用 change buffer:

mysql> delete from sbtest1 where id=1;
Query OK, 1 row affected (0.00 sec)
mysql> show engine innodb status\G
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 29, seg size 31, 1 merges
merged operations:
insert 0, delete mark 1, delete 0
discarded operations:
insert 0, delete mark 0, delete 0

mysql> delete from sbtest1 where id=2;
Query OK, 1 row affected (0.00 sec)
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 29, seg size 31, 2 merges
merged operations:
insert 0, delete mark 2, delete 0
discarded operations:
insert 0, delete mark 0, delete 0

mysql> delete from sbtest1 where id=3;
Query OK, 1 row affected (0.00 sec)
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 29, seg size 31, 3 merges
merged operations:
insert 0, delete mark 3, delete 0
discarded operations:
insert 0, delete mark 0, delete 0

mysql> select * from sbtest1 where id=4;
mysql> delete from sbtest1 where id=4;
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 29, seg size 31, 4 merges
merged operations:
insert 0, delete mark 4, delete 0
discarded operations:
insert 0, delete mark 0, delete 0

上述实验说明:如果 delete 是以主键做为筛选条件,对于普通索引k,如果索引页不在内存中(select * from sbtest1 where id=4 读取的只是主键索引页,不会读取k索引页),会使用 change buffer(每次 delete 后,delete mark 都增加1)。

实验2-以普通索引为筛选条件做 delete

重新造数据,重启 mysqld 清空 buffer pool。下面实验结果说明:如果 delete 以普通索引做为筛选条件,对于普通索引k,如果索引页不在内存中,不会使用 change buffer。言外之意就是需要读取磁盘了。

##delete where id=1,delete mark +1,说明使用了change buffer
mysql> delete from sbtest1 where id=1;
Query OK, 1 row affected (0.01 sec)
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 29, seg size 31, 1 merges
merged operations:
insert 0, delete mark 1, delete 0
discarded operations:
insert 0, delete mark 0, delete 0

##delete where k=367246,delete mark 不变,说明没有使用change buffer
mysql> select * from sbtest1 where id=2;
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k | c | pad |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| 2 | 367246 | 42909700340-70078987867-62357124096-35495169193-85675377266-14643719347-30417020186-80900182681-50382374444-66260611196 | 74781290517-41121402981-50604677924-34464478849-89102349959 |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> delete from sbtest1 where k=367246;
Query OK, 1 row affected (0.01 sec)

-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 29, seg size 31, 1 merges
merged operations:
insert 0, delete mark 1, delete 0
discarded operations:
insert 0, delete mark 0, delete 0


标签:insert,buffer,mark,索引,MySQL,id,change,delete
From: https://blog.51cto.com/u_15077536/5955951

相关文章

  • 技术分享 | 网络带宽如何影响 MySQL 性能
    作者:VadimTkachenko翻译:管长龙网络是数据库基础架构的主要部分。但是,通常性能基准测试是在本地计算机上完成的,客户端和服务器并置在一起。这样做是为了简化结构并排除一个......
  • 技术分享 | 实战 MySQL 8.0.17 Clone Plugin
    作者:陈俊聪背景很神奇,5.7.17和8.0.17,连续两个17小版本都让人眼前一亮。前者加入了组复制(GroupReplication)功能,后者加入了克隆插件(ClonePlugin)功能。今天我们实战测......
  • 故障分析 | MySQL:唯一键约束失效
    作者:胡呈清爱可生DBA团队成员,擅长故障分析、性能优化,个人博客:https://www.jianshu.com/u/a95ec11f67a8,欢迎讨论。最近遇到一个故障:单主模式5节点MGR集群,在使用mysqlshe......
  • docker-compose 编排Net6项目,redis/mysql/nlog实战
    十年河东,十年河西,莫欺少年穷学无止境,精益求精1、新建net6webapi项目一个非常简单的net6项目,使用mysql数据库,redis做缓存   关于项目的搭建,这里不做说明,本篇主......
  • 在MySQL中INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 有什么区别?
    我们有两张表:TableA:id  firstName                  lastName.......................................1   arun               ......
  • mysql查看表结构和注释
    mysql查看表结构和注释查看表结构descusers;查看表结构以及注释showfullcolumnsfromusers;......
  • 技术分享 | MySQL 数据库如何改名?
    作者:杨涛涛资深数据库专家,专研MySQL十余年。擅长MySQL、PostgreSQL、MongoDB等开源数据库相关的备份恢复、SQL调优、监控运维、高可用架构设计等。目前任职于爱可生,为......
  • 技术分享 | MySQL 存储过程中的只读语句超时怎么办?
    作者:杨涛涛资深数据库专家,专研MySQL十余年。擅长MySQL、PostgreSQL、MongoDB等开源数据库相关的备份恢复、SQL调优、监控运维、高可用架构设计等。目前任职于爱可生,为......
  • 第07期:有关 MySQL 字符集的 SQL 语句
    本篇为理清字符集的续篇​​(上一篇:第06期:梳理MySQL字符集的相关概念)​​,重点讲述字符集涉及到的sql语句用法。一、characterintroducer翻译过来就是字符引导。也就是针......
  • 故障分析 | MySQL OOM 故障应如何下手
    作者:孙祚龙爱可生南区分公司交付服务部成员,实习工程师。负责公司产品问题排查及日常运维工作。。引言前阵子处理这样一个案例,某客户的实例mysqld进程内存经常持续增加导......