Skip to content

InnoDB Linux 原生 AIO 完成路径在持有数组互斥锁的状态下做页解密/解压,导致所有 I/O 线程串行化 #113

Description

@puli2300

问题描述

TXSQL 基于 MySQL 8.0.30。InnoDB Linux 原生 AIO 的完成处理路径中,
LinuxAIOHandler::find_completed_slot()(storage/innobase/os/os0file.cc,约 L2265)
在持有 AIO 数组互斥锁(m_array->m_mutex)的状态下返回已完成的槽位(原注释
"Note: We don't release the mutex."),随后整条完成处理链——
check_state()AIOHandler::post_io_processing()io_complete()
对加密/压缩表空间调用 Encryption 的整页解密/解压——都在该锁内执行。

这把锁同时被所有 I/O 提交方使用(AIO::reserve_slot() 申请槽位也要拿它),
因此:同一时刻全库只有一个线程能处理完成请求,所有 IO handler 线程、以及
前台提交读/写请求的线程,全部在这把锁后面排队。整个数据库的 I/O 完成吞吐
被钉死在“1 ÷ 单页处理时间”,与 handler 线程数无关。

为什么上游从未暴露

AES-NI 硬件加速下解密一个 16KB 页约 16 微秒,锁内处理时间极短,影响不可见。
但对 TDE 使用较慢的软件密码实现(约 40+ 微秒/页)时,后果是全局性的:
读完成串行化把聚合读吞吐压到约 40 MB/s 量级,且页清洗(写盘提交)也会在
读完成的解密后面排队。

实测数据(同一份代码系,冷全表扫描负载:16 表 × 50 万行,buffer pool 128M,内存盘)

场景 8 线程 修复前 8 线程 修复后 提升
不加密 1.488 GB/s 1.490 GB/s 1.00x(对照组,不受影响)
TDE AES-NI 0.491 GB/s 1.450 GB/s 2.95x
TDE 软件 SM4 0.038 GB/s 1.180 GB/s 31.0x

单线程下 TDE 慢算法同样有 ~10 倍提升(前台提交请求也要抢这把锁,修复前
后台在锁内解密多久、前台就等多久)。

修复思路

采用“认领协议”把处理移出锁外:

  1. find_completed_slot() 扫描到完成槽位时,在锁内
    slot->io_already_done 置为 false 完成认领,然后放锁再返回
  2. 内核事件已由 collect() 收割,槽位不会被再次标记,其他 handler 线程
    扫描到 false 会跳过——处理依然严格“恰好一次”;
  3. 调用方此后独占该槽位,完成处理(含页解密)在无锁状态执行;
  4. poll() 仅在短读重提交(resubmit() 前后)和归还槽位
    AIO::release(slot) 前)重新拿锁。

这与仓库既有模式一致:写路径的页压缩与加密本来就在数组锁外执行
AIO::reserve_slot() 显式放锁后加密),模拟 AIO 引擎的完成处理也不用这把锁,
本次修改只是让 Linux 原生 AIO 的读完成路径对齐同样的模式。

正确性验证(已在同源 8.0 代码上完成)

  • 新旧二进制读同一张加密表,全表 CRC32 校验值完全一致;
  • MTR encryption 套件在 debug 构建上全部通过(15/15);
  • 不加密场景吞吐分毫未变(1.00x),证明提升仅来自锁释放;
  • 已完成 TXSQL 8.0.30 分支的移植与 make innobase 编译验证。

稍后提交 PR,本 issue 作为关联说明。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions