溫馨提示×

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

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

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

發(fā)布時(shí)間:2021-11-10 15:52:47 來(lái)源:億速云 閱讀:170 作者:iii 欄目:關(guān)系型數(shù)據(jù)庫(kù)

本篇內(nèi)容主要講解“insert進(jìn)行第一次樂(lè)觀插入邏輯分析”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“insert進(jìn)行第一次樂(lè)觀插入邏輯分析”吧!

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

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

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

  • undo在redo生成之前生成

邏輯入口如下:

->row_ins_sec_index_entry_low 第一次進(jìn)行樂(lè)觀插入 mode=BTR_MODIFY_LEAF
  -> 是否是唯一鍵 是 row_ins_scan_sec_index_for_duplicate 進(jìn)行唯一性檢查
  -> 進(jìn)行唯一性檢測(cè)結(jié)果處理
  -> 進(jìn)行數(shù)據(jù)查找 btr_cur_search_to_nth_level
     ->page_cur_search_with_match_bytes
  -> 如果只是檢查重復(fù)值跳過(guò)下面邏輯 if (dup_chk_only) 
  -> 進(jìn)行樂(lè)觀插入,假設(shè)不修改B+樹(shù)結(jié)構(gòu) btr_cur_optimistic_insert,主要通過(guò)BTR_MODIFY_LEAF標(biāo)示識(shí)別,此處不考慮壓縮頁(yè)
    ->計(jì)算轉(zhuǎn)換邏輯記錄(元組)為物理記錄后的長(zhǎng)度 rec_get_converted_size
      ->rec_get_converted_size_comp
    ->是否需要外部存儲(chǔ)page_zip_rec_needs_ext
    ->獲取塊的空閑空間大小 page_get_max_insert_size_after_reorganize 備注(1
    ->進(jìn)行是否需要悲觀插入的邏輯判斷,主要還是空間不夠的情況 備注(2,如果需要悲觀插入則這里返回了
    ->如果是主鍵還需要預(yù)留部分空間 備注(3,如果沒(méi)有預(yù)留空間也會(huì)進(jìn)入悲觀插入流程
    ->判斷是否需要加鎖和開(kāi)undo btr_cur_ins_lock_and_undo,此函數(shù)還會(huì)返回是否需要做鎖繼承的處理為輸出參數(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
      ->獲取每個(gè)字段的偏移量 rec_get_offsets
      ->進(jìn)行實(shí)際插入 page_cur_insert_rec_low
        ->獲取記錄的實(shí)際大小
        ->尋找合適的位置進(jìn)行插入,本步驟會(huì)找到合適的位置返回給insert_buf
          ->獲取free鏈表的頭部記錄,注意只會(huì)檢查第一個(gè)記錄,不會(huì)做遍歷,因此塊中碎片是極有可能出現(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ì)算方式為 
    空頁(yè)的容量 = 頁(yè)大小(比如16K) - 頁(yè)頭大小(120) - 頁(yè)尾大小(8) - 初始化2個(gè)槽大小(4=2*2) 
    實(shí)際的數(shù)據(jù)占用空間 = 已經(jīng)分配數(shù)據(jù)空間的最大數(shù)據(jù)偏移量 - 頁(yè)頭大小(120) - 已經(jīng)刪除且purge的空間包含碎片空間 + 槽大小

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

因?yàn)轫?yè)中難免會(huì)出現(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 
    -- 分裂建議建議分裂

到此,相信大家對(duì)“insert進(jìn)行第一次樂(lè)觀插入邏輯分析”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

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

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

AI