溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Innodb中insert第一次進(jìn)行樂觀插入邏輯分析

發(fā)布時間:2021-11-10 11:31:15 來源:億速云 閱讀:139 作者:iii 欄目:MySQL數(shù)據(jù)庫

這篇文章主要講解了“Innodb中insert第一次進(jìn)行樂觀插入邏輯分析”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Innodb中insert第一次進(jìn)行樂觀插入邏輯分析”吧!

實(shí)際在這之前記錄是每行每行的插入,而且是每行每個索引的插入,這里僅僅講述的是某行關(guān)于某個二級索引的樂觀插入流程,所謂樂觀就是不會引起索引樹的結(jié)構(gòu)更改,換而言之當(dāng)前塊有足夠的空間進(jìn)行插入。

本文僅僅記錄樂觀插入的流程,和函數(shù)的入口,實(shí)際上很多我們關(guān)心的東西在哪里比如,這里沒有考慮壓縮頁:

  • 重用空間只會檢查del鏈表的第一個成員,因此塊中可能存在碎片

  • 是否觸發(fā)悲觀插入是通過計(jì)算整個塊的剩余空間和插入記錄的長度比較得出的結(jié)果,剩余空間包含了碎片空間

  • 對于插入印象鎖需要根據(jù)下一條記錄是否上鎖來判斷是否需要加并且等待

  • 可能會觸發(fā)鎖繼承

  • 唯一檢查會可能觸發(fā)LOCK_S也是這里進(jìn)入的

  • 插入之前要定位數(shù)據(jù)

  • undo在redo生成之前生成

邏輯入口如下:

->row_ins_sec_index_entry_low 第一次進(jìn)行樂觀插入 mode=BTR_MODIFY_LEAF
  -> 是否是唯一鍵 是 row_ins_scan_sec_index_for_duplicate 進(jìn)行唯一性檢查
  -> 進(jìn)行唯一性檢測結(jié)果處理
  -> 進(jìn)行數(shù)據(jù)查找 btr_cur_search_to_nth_level
     ->page_cur_search_with_match_bytes
  -> 如果只是檢查重復(fù)值跳過下面邏輯 if (dup_chk_only) 
  -> 進(jìn)行樂觀插入,假設(shè)不修改B+樹結(jié)構(gòu) btr_cur_optimistic_insert,主要通過BTR_MODIFY_LEAF標(biāo)示識別,此處不考慮壓縮頁
    ->計(jì)算轉(zhuǎn)換邏輯記錄(元組)為物理記錄后的長度 rec_get_converted_size
      ->rec_get_converted_size_comp
    ->是否需要外部存儲page_zip_rec_needs_ext
    ->獲取塊的空閑空間大小 page_get_max_insert_size_after_reorganize 備注(1
    ->進(jìn)行是否需要悲觀插入的邏輯判斷,主要還是空間不夠的情況 備注(2,如果需要悲觀插入則這里返回了
    ->如果是主鍵還需要預(yù)留部分空間 備注(3,如果沒有預(yù)留空間也會進(jìn)入悲觀插入流程
    ->判斷是否需要加鎖和開undo btr_cur_ins_lock_and_undo,此函數(shù)還會返回是否需要做鎖繼承的處理為輸出參數(shù)inherit
      ->檢查是否需要加鎖lock_rec_insert_check_and_lock 插入印象鎖就在這里
      ->記錄undo trx_undo_report_row_operation
      ->更改row undo ptr指針row_upd_index_entry_sys_field
    ->做實(shí)際插入操作 page_cur_tuple_insert
      ->邏輯記錄轉(zhuǎn)換為物理記錄 rec_convert_dtuple_to_rec
      ->獲取每個字段的偏移量 rec_get_offsets
      ->進(jìn)行實(shí)際插入 page_cur_insert_rec_low
        ->獲取記錄的實(shí)際大小
        ->尋找合適的位置進(jìn)行插入,本步驟會找到合適的位置返回給insert_buf
          ->獲取free鏈表的頭部記錄,注意只會檢查第一個記錄,不會做遍歷,因此塊中碎片是極有可能出現(xiàn)的
            只是innodb可以重組
          ->如果合適則使用
          ->不合適則返回
        ->進(jìn)行記錄創(chuàng)建拷貝 memcpy方式復(fù)制數(shù)據(jù)到insert_buf指向的位置,完成這一步記錄加入到了塊中 下面需要維護(hù)各種塊信息  
        ->將記錄加入到記錄鏈表
        ->更新行的N_OWNER為0,以及設(shè)置heap_no
        ->設(shè)置塊的一些最后修改屬性如PAGE_DIRECTION、PAGE_N_DIRECTION、PAGE_LAST_INSERT
        ->更新slot的信息,可能涉及更改owner記錄信息和owner記錄的N_OWNER信息
        ->寫redo信息 page_cur_insert_rec_write_log
      ->返回插入記錄的offset
    ->進(jìn)行AHI維護(hù) btr_search_update_hash_on_insert/btr_search_update_hash_node_on_insert
    ->進(jìn)行可能的鎖的分裂 lock_update_insert 此處主要的判斷是前面的輸出參數(shù)inherit
    ->進(jìn)行CHANGE BUFFER維護(hù) ibuf_update_free_bits_if_full
  -> 如果成功修改最大事物ID PAGE_MAX_TRX_ID page_update_max_trx_id
  -> 返回結(jié)果
  • 備注1) 計(jì)算方式為
    空頁的容量 = 頁大小(比如16K) - 頁頭大小(120) - 頁尾大小(8) - 初始化2個槽大小(4=2*2)
    實(shí)際的數(shù)據(jù)占用空間 = 已經(jīng)分配數(shù)據(jù)空間的最大數(shù)據(jù)偏移量 - 頁頭大小(120) - 已經(jīng)刪除且purge的空間包含碎片空間 + 槽大小

然后用
空頁的容量 - 實(shí)際的數(shù)據(jù)占用空間=實(shí)際可用空間

因?yàn)轫撝须y免會出現(xiàn)一些碎片,但是innodb的page擁有重新組織的能力,能夠釋放這部分空間。其重組函數(shù)為btr_page_reorganize_low

  • 備注2) 邏輯包含
    如果包含碎片空間那么
    -- 如果可用空間不足或者可用空間已經(jīng)少于了重組塊的設(shè)置BTR_CUR_PAGE_REORGANIZE_LIMIT(UNIV_PAGE_SIZE / 32)
    -- 記錄數(shù)量大于1
    -- 可用空間小于了插入記錄的大小
    否則
    -- 可用空間小于了插入記錄的大小

  • 備注3) 邏輯包含
    --葉子結(jié)點(diǎn)
    -- 主鍵
    -- 記錄大于兩行
    -- 剩余的空間 - 行的空間 < page_size/16
    -- 分裂建議建議分裂

感謝各位的閱讀,以上就是“Innodb中insert第一次進(jìn)行樂觀插入邏輯分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Innodb中insert第一次進(jìn)行樂觀插入邏輯分析這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI