关于 mysql change buffer 的 update/delete 操作如何获取到 affected rows 的问题

2021-08-08 13:05:36 +08:00
 lasuar

我仔仔细细把官网 ChangeBuffer 部分的章节看完了,仍然得不到这个问题的答案;请教知道的大佬解答一下,十分感谢!

2352 次点击
所在节点    MySQL
8 条回复
IamUNICODE
2021-08-08 14:59:50 +08:00
是这个不
http://mysql.babo.ist/#/en/mysql-affected-rows.html
lasuar
2021-08-08 18:28:41 +08:00
@IamUNICODE 这只是解释什么是 affected rows
IamUNICODE
2021-08-08 18:46:17 +08:00
@lasuar 那个 example 没用么
crclz
2021-08-08 22:51:38 +08:00
我不知道首影响的行数是否与 change buffer 有关(之前不知道 changebuffer 这个概念)。

但是抛开 change buffer 不谈,可以使用 ROW_COUNT()获取上一条语句( update or delete )影响的行数。
https://www.cnblogs.com/langtianya/p/4776531.html

至于具体的代码...你可以让你的连接执行 2 次查询,第一次执行 update 或者 delete,第二次获取 ROW_COUNT()。如果想要一次性拿到,可以看看特定 ORM 的文档。

例如.net 的 dapper,就可以执行多个 sql,拿到多个结果。https://github.com/DapperLib/Dapper#multiple-results
louettagfh
2021-08-09 11:24:08 +08:00
InnoDB 的删除逻辑是先删聚簇索引, 再删除二级索引(标记删除), 所以当主键索引发现 DB_RECORD_NOT_FOUND 就会返回, 所以不会触发缓存不存在的索引数据
lasuar
2021-08-09 18:11:46 +08:00
@louettagfh 官文中对于 change buffer 的描述是,它可以缓存所有对于 buffer pool 中不存在的二级索引的 DML 操作,可以不用去读磁盘获取实际数据(是有原话的)。我的疑问就是 update/delete 操作如果不读磁盘怎么可能拿得到 affected rows,换言之,我认为不论是 change buffer 还是 buffer pool,二者之一是一定去读了磁盘的,但不清楚具体逻辑,就很懵逼,全网搜遍也查不到相关资料,我要是会 Cpp 就直接去看源码了。

你的意思是当 buffer pool 中不存在待修改的二级索引时,innodb 还是会去读磁盘通过 B+树找到页,再找到记录并进行删除(标记),然后再去删除(标记)二级索引。 有相关资料描述这个过程吗?
louettagfh
2021-08-09 23:33:45 +08:00
@lasuar

和 buffer pool 没有关系, buffer pool 不感知 B+ tree.


删除一条 record, 不可能只删除二级索引,所以 InnoDB 先删除主键索引,再删除二级索引, 所以假如你要删除的 Record 比如 id (主键), age (二级索引) 的时候主键不存在,二级索引也就不用找了.

修改也同理


buffer pool 没有聚簇索引的 page 会去读,因为 change buffer 不缓存聚簇索引, 二级索引的 Page 假如符合使用 change buffer 的条件没有的话就不去读,直接使用 change buffer 的 page, change buffer 的 page 是连续分配的. 写入完成后,假如用户的一次查询用到了这个二级索引的 Page,就把二级索引的数据页读上来和 change buffer 的 Page 做一个 merge 操作, 再返回给用户.


没有相关资料 看源码吧
lasuar
2021-08-10 12:20:17 +08:00
@louettagfh 嗯,我昨天想明白了。不管有没有 change buffer,对于不在内存中的聚簇索引页,innodb 都会去读磁盘,然后内存修改聚簇索引页中的元数据,其实这个时候就已经拿到了 affected rows 。

然后才是轮到索引页的更新,change buffer 是针对索引页更新的优化,我之前没理清楚整个过程。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/794388

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX