› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
freemoon
V2EX  ›  MySQL

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

  •  
  •   freemoon · Aug 8, 2021 · 3582 views
    This topic created in 1875 days ago, the information mentioned may be changed or developed.

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

    8 replies  •  2021-08-10 12:20:17 +08:00
    IamUNICODE
        1
    IamUNICODE  
       Aug 8, 2021
    是这个不
    http://mysql.babo.ist/#/en/mysql-affected-rows.html
    freemoon
        2
    freemoon  
    OP
       Aug 8, 2021
    @IamUNICODE 这只是解释什么是 affected rows
    IamUNICODE
        3
    IamUNICODE  
       Aug 8, 2021
    @lasuar 那个 example 没用么
    crclz
        4
    crclz  
       Aug 8, 2021
    我不知道首影响的行数是否与 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
        5
    louettagfh  
       Aug 9, 2021
    InnoDB 的删除逻辑是先删聚簇索引, 再删除二级索引(标记删除), 所以当主键索引发现 DB_RECORD_NOT_FOUND 就会返回, 所以不会触发缓存不存在的索引数据
    freemoon
        6
    freemoon  
    OP
       Aug 9, 2021
    @louettagfh 官文中对于 change buffer 的描述是,它可以缓存所有对于 buffer pool 中不存在的二级索引的 DML 操作,可以不用去读磁盘获取实际数据(是有原话的)。我的疑问就是 update/delete 操作如果不读磁盘怎么可能拿得到 affected rows,换言之,我认为不论是 change buffer 还是 buffer pool,二者之一是一定去读了磁盘的,但不清楚具体逻辑,就很懵逼,全网搜遍也查不到相关资料,我要是会 Cpp 就直接去看源码了。

    你的意思是当 buffer pool 中不存在待修改的二级索引时,innodb 还是会去读磁盘通过 B+树找到页,再找到记录并进行删除(标记),然后再去删除(标记)二级索引。 有相关资料描述这个过程吗?
    louettagfh
        7
    louettagfh  
       Aug 9, 2021
    @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 操作, 再返回给用户.


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

    然后才是轮到索引页的更新,change buffer 是针对索引页更新的优化,我之前没理清楚整个过程。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2824 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 14:06 · PVG 22:06 · LAX 07:06 · JFK 10:06
    ♥ Do have faith in what you're doing.