Innodb:insert 第一次進行樂觀插入邏輯(二級索引)
水平有限,能力有限
實際在這之前記錄是每行每行的插入,而且是每行每個索引的插入,這裡僅僅講述的是某行關於某個二級索引的樂觀插入流程,所謂樂觀就是不會引起索引樹的結構更改,換而言之當前塊有足夠的空間進行插入。
本文僅僅記錄樂觀插入的流程,和函式的入口,實際上很多我們關心的東西在哪裡比如,這裡沒有考慮壓縮頁:
-
重用空間只會檢查del連結串列的第一個成員,因此塊中可能存在碎片
-
是否觸發悲觀插入是透過計算整個塊的剩餘空間和插入記錄的長度比較得出的結果,剩餘空間包含了碎片空間
-
對於插入印象鎖需要根據下一條記錄是否上鎖來判斷是否需要加並且等待
-
可能會觸發鎖繼承
-
唯一檢查會可能觸發LOCK_S也是這裡進入的
-
插入之前要定位資料
-
undo在redo生成之前生成
邏輯入口如下:
->row_ins_sec_index_entry_low 第一次進行樂觀插入 mode=BTR_MODIFY_LEAF -> 是否是唯一鍵 是 row_ins_scan_sec_index_for_duplicate 進行唯一性檢查 -> 進行唯一性檢測結果處理 -> 進行資料查詢 btr_cur_search_to_nth_level ->page_cur_search_with_match_bytes -> 如果只是檢查重複值跳過下面邏輯 if (dup_chk_only) -> 進行樂觀插入,假設不修改B+樹結構 btr_cur_optimistic_insert,主要透過BTR_MODIFY_LEAF標示識別,此處不考慮壓縮頁 ->計算轉換邏輯記錄(元組)為物理記錄後的長度 rec_get_converted_size ->rec_get_converted_size_comp ->是否需要外部儲存page_zip_rec_needs_ext ->獲取塊的空閒空間大小 page_get_max_insert_size_after_reorganize 備註(1 ->進行是否需要悲觀插入的邏輯判斷,主要還是空間不夠的情況 備註(2,如果需要悲觀插入則這裡返回了 ->如果是主鍵還需要預留部分空間 備註(3,如果沒有預留空間也會進入悲觀插入流程 ->判斷是否需要加鎖和開undo btr_cur_ins_lock_and_undo,此函式還會返回是否需要做鎖繼承的處理為輸出引數inherit ->檢查是否需要加鎖lock_rec_insert_check_and_lock 插入印象鎖就在這裡 ->記錄undo trx_undo_report_row_operation ->更改row undo ptr指標row_upd_index_entry_sys_field ->做實際插入操作 page_cur_tuple_insert ->邏輯記錄轉換為物理記錄 rec_convert_dtuple_to_rec ->獲取每個欄位的偏移量 rec_get_offsets ->進行實際插入 page_cur_insert_rec_low ->獲取記錄的實際大小 ->尋找合適的位置進行插入,本步驟會找到合適的位置返回給insert_buf ->獲取free連結串列的頭部記錄,注意只會檢查第一個記錄,不會做遍歷,因此塊中碎片是極有可能出現的 只是innodb可以重組 ->如果合適則使用 ->不合適則返回 ->進行記錄建立複製 memcpy方式複製資料到insert_buf指向的位置,完成這一步記錄加入到了塊中 下面需要維護各種塊資訊 ->將記錄加入到記錄連結串列 ->更新行的N_OWNER為0,以及設定heap_no ->設定塊的一些最後修改屬性如PAGE_DIRECTION、PAGE_N_DIRECTION、PAGE_LAST_INSERT ->更新slot的資訊,可能涉及更改owner記錄資訊和owner記錄的N_OWNER資訊 ->寫redo資訊 page_cur_insert_rec_write_log ->返回插入記錄的offset ->進行AHI維護 btr_search_update_hash_on_insert/btr_search_update_hash_node_on_insert ->進行可能的鎖的分裂 lock_update_insert 此處主要的判斷是前面的輸出引數inherit ->進行CHANGE BUFFER維護 ibuf_update_free_bits_if_full -> 如果成功修改最大事物ID PAGE_MAX_TRX_ID page_update_max_trx_id -> 返回結果
-
備註1) 計算方式為
空頁的容量 = 頁大小(比如16K) - 頁頭大小(120) - 頁尾大小(8) - 初始化2個槽大小(4=2*2)
實際的資料佔用空間 = 已經分配資料空間的最大資料偏移量 - 頁頭大小(120) - 已經刪除且purge的空間包含碎片空間 + 槽大小
然後用
空頁的容量 - 實際的資料佔用空間=實際可用空間
因為頁中難免會出現一些碎片,但是innodb的page擁有重新組織的能力,能夠釋放這部分空間。其重組函式為btr_page_reorganize_low
-
備註2) 邏輯包含
如果包含碎片空間那麼
-- 如果可用空間不足或者可用空間已經少於了重組塊的設定BTR_CUR_PAGE_REORGANIZE_LIMIT(UNIV_PAGE_SIZE / 32)
-- 記錄數量大於1
-- 可用空間小於了插入記錄的大小
否則
-- 可用空間小於了插入記錄的大小 -
備註3) 邏輯包含
--葉子結點
-- 主鍵
-- 記錄大於兩行
-- 剩餘的空間 - 行的空間 < page_size/16
-- 分裂建議建議分裂
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2218565/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【Mysql】InnoDB 中的聚簇索引、二級索引、聯合索引MySql索引
- 故障分析 | 從 Insert 併發死鎖分析 Insert 加鎖原始碼邏輯原始碼
- 二分搜尋樹系列之[ 插入操作 (insert) ]
- 二分搜尋樹系列之「 插入操作 (insert) 」
- MySQL:一段innodb buffer instance和cleaner執行緒計算邏輯MySql執行緒
- 關於MySQL InnoDB表的二級索引是否加入主鍵的總結MySql索引
- Phoenix 二級索引索引
- Phoenix二級索引索引
- MySQL InnoDB 索引MySql索引
- innodb索引篇索引
- SQL INSERT批次插入方式SQL
- insert批量插入優化方案優化
- 【邏輯DG滾動升級二】ORACLE11204 邏輯DG滾動升級至12C---DG端前期準備Oracle
- [20210220]全索引掃描快速索引掃描的邏輯讀.txt索引
- 基於centos7的MySQL8.0二進位制安裝包的邏輯升級CentOSMySql
- 基於centos7的MySQL5.7二進位制安裝包的邏輯升級CentOSMySql
- MySQL/InnoDB中,樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念的理解MySql
- InnoDB 索引詳解索引
- mysql innodb索引高度MySql索引
- innodb 引擎索引 (一)索引
- 使用 AI 進行 - 視覺化 - 業務&系統邏輯AI視覺化
- MOSN熱升級邏輯淺析
- 從InnoDB 索引執行簡述 聚集索引和非聚集索引、覆蓋索引、回表、索引下推索引
- pandas 設定二級索引索引
- 【C進階】15、邏輯運算子
- pandas筆記(一)-- 大的國家(邏輯索引、切片)筆記索引
- [20180425]為什麼走索引邏輯讀反而高.txt索引
- [LeetCode] 57. Insert Interval 插入區間LeetCode
- Oracle批量插入資料insert all into用法Oracle
- 【邏輯DG滾動升級三】ORACLE11204 邏輯DG滾動升級至12C---正式升級Oracle
- kubebuilder operator的執行邏輯UI
- InnoDB意向鎖和插入意向鎖
- mysql基礎問題三問(底層邏輯;正在執行;日誌觀察)MySql
- 淺析InnoDB引擎的索引和索引原理索引
- Oracle 9i升級19C 邏輯遷移詳細方法(二)Oracle
- 記一次 對 xfs格式 邏輯捲進行擴縮容
- [譯] 使用 PyTorch 在 MNIST 資料集上進行邏輯迴歸PyTorch邏輯迴歸
- 經典示例-在快樂中鍛鍊程式邏輯