写**(聚簇索引 + 二级索引)**

graph TB
    Start[INSERT操作开始] --> BuildRow[构建完整行数据]
    
    BuildRow --> Phase1[阶段1: 聚簇索引写入]
    Phase1 --> ClustSearch[搜索聚簇索引位置]
    ClustSearch --> ClustLock[检查锁冲突]
    ClustLock --> WriteUndo[写Undo日志<br/>trx_undo_report_row_operation]
    WriteUndo --> GetRollPtr[获取roll_ptr回滚指针]
    GetRollPtr --> FillRollPtr[将roll_ptr填入记录]
    
    FillRollPtr --> ClustInsert{页面在<br/>buffer pool?}
    ClustInsert -->|否| ReadClustPage[从磁盘读取页面]
    ReadClustPage --> DoClustInsert
    ClustInsert -->|是| DoClustInsert[物理插入记录<br/>page_cur_tuple_insert]
    
    DoClustInsert --> ClustRedo[写Redo日志<br/>记录聚簇索引页修改]
    ClustRedo --> CommitMtr1[提交mtr]
    CommitMtr1 --> Phase2[阶段2: 二级索引写入]
    
    Phase2 --> BuildSecEntry[构建二级索引entry]
    BuildSecEntry --> SecSearch[搜索二级索引位置<br/>btr_cur_search_to_nth_level]
    
    SecSearch --> SecInBuf{索引页在<br/>buffer pool?}
    
    SecInBuf -->|是| DirectInsert[直接插入页面<br/>row_ins_sec_index_entry_low]
    SecInBuf -->|否| CheckBuffer{检查Change Buffer<br/>使用条件}
    
    CheckBuffer -->|满足条件| UseChangeBuffer[使用Change Buffer路径]
    CheckBuffer -->|不满足| ForceRead[强制读取页面]
    
    UseChangeBuffer --> CheckCond1{是非唯一<br/>二级索引?}
    CheckCond1 -->|否<br/>唯一索引| ForceRead
    CheckCond1 -->|是| CheckCond2{无buffer pool<br/>watch?}
    CheckCond2 -->|有watch| ForceRead
    CheckCond2 -->|无| CheckCond3{Change Buffer<br/>未满?}
    CheckCond3 -->|已满| ForceRead
    CheckCond3 -->|未满| InsertIbuf[插入到Change Buffer B-tree<br/>ibuf_insert_low]
    
    InsertIbuf --> UpdateBitmap[更新ibuf bitmap<br/>记录页面空间]
    UpdateBitmap --> IbufRedo[写Redo日志<br/>记录Change Buffer操作]
    IbufRedo --> IbufReturn[返回BTR_CUR_INSERT_TO_IBUF<br/>异步完成]
    
    ForceRead --> ReadSecPage[从磁盘读取索引页到buffer pool]
    ReadSecPage --> DirectInsert
    
    DirectInsert --> SecRedo[写Redo日志<br/>记录二级索引页修改]
    SecRedo --> CommitMtr2[提交mtr<br/>同步完成]
    
    IbufReturn --> End[插入操作完成]
    CommitMtr2 --> End
    
    style WriteUndo fill:#FFD700
    style InsertIbuf fill:#90EE90
    style IbufReturn fill:#87CEEB
    style ForceRead fill:#FFA07A
    style DoClustInsert fill:#DDA0DD

change buffer刷新写入合并

graph TB
    Start[后台触发合并] --> Trigger{触发时机}
    
    Trigger -->|方式1| PageRead[索引页被查询<br/>读入buffer pool]
    Trigger -->|方式2| MasterThread[Master线程<br/>定期合并]
    Trigger -->|方式3| Shutdown[数据库关闭<br/>强制合并]
    
    PageRead --> Merge1[buf_read_page完成后<br/>调用ibuf_merge_or_delete_for_page]
    MasterThread --> Merge2[ibuf_merge_in_background<br/>批量合并]
    Shutdown --> Merge3[ibuf_merge_space<br/>表空间合并]
    
    Merge1 --> MergeProcess
    Merge2 --> MergeProcess
    Merge3 --> MergeProcess
    
    MergeProcess[合并过程] --> Step1[1. 查找Change Buffer中<br/>该页的所有操作记录]
    Step1 --> Step2[2. 按顺序应用到索引页<br/>ibuf_insert_to_index_page_low]
    Step2 --> Step3[3. 写Redo日志<br/>记录页面修改]
    Step3 --> Step4[4. 从Change Buffer删除记录<br/>ibuf_delete_rec]
    Step4 --> Step5[5. 更新ibuf bitmap]
    Step5 --> Complete[合并完成]
    
    style PageRead fill:#90EE90
    style MasterThread fill:#87CEEB
    style Shutdown fill:#FFB6C1

是否用change buffer

graph TB
    Start[尝试使用Change Buffer] --> Check1{索引类型检查}
    
    Check1 -->|聚簇索引| Fail1[❌ 不能使用]
    Check1 -->|二级索引| Check2{唯一性检查}
    
    Check2 -->|唯一索引| Fail2[❌ 不能使用<br/>需检查重复]
    Check2 -->|非唯一索引| Check3{页面状态检查}
    
    Check3 -->|页面在buffer pool| Fail3[❌ 不使用<br/>直接在内存操作更快]
    Check3 -->|页面不在buffer pool| Check4{Buffer Pool Watch检查}
    
    Check4 -->|有watch哨兵<br/>buf_page_get_also_watch!=NULL| Fail4[❌ 不能使用<br/>有purge线程正在操作该页<br/>避免并发冲突]
    Check4 -->|无watch| Check5{Change Buffer容量检查}
    
    Check5 -->|已满| Fail5[❌ 不能使用<br/>需要先合并]
    Check5 -->|未满| Check6{记录大小检查}
    
    Check6 -->|过大| Fail6[❌ 不能使用]
    Check6 -->|合适| Success[✅ 可以使用Change Buffer]
    
    Success --> UseIbuf[插入到Change Buffer<br/>异步完成]
    
    Fail1 --> SyncWrite[同步写入路径]
    Fail2 --> SyncWrite
    Fail3 --> SyncWrite
    Fail4 --> SyncWrite
    Fail5 --> SyncWrite
    Fail6 --> SyncWrite
    
    SyncWrite --> ReadPage[读取页面到buffer pool]
    ReadPage --> DirectWrite[直接在页面上操作]
    
    style Fail4 fill:#FF6B6B
    style Success fill:#90EE90
    style UseIbuf fill:#87CEEB