Mongodb原始碼分析--刪除記錄

daizhj發表於2011-04-06

    在之前的一篇文章 中,介紹了assembleResponse函式(位於instance.cpp第224行),它會根據op操作列舉型別來呼叫相應的crud操作,列舉型別定義如下:

 

 


    可以看到dbDelete = 2002 為刪除操作列舉值。當客戶端將要刪除的記錄(或條件的document)發到服務端之後,mongodb通過訊息封裝方式將資料包中的位元組流解析轉成 message型別,並進一步轉換成dbmessage之後,mongodb就會根據訊息型別進行判斷,以決定接下來執行的操作),下面我們看一下 assembleResponse在確定是刪除操作時呼叫的方法,如下:

   


    從上面程式碼可以看出,系統在確定dbDelete操作時,呼叫了receivedDelete()方法(位於instance.cpp檔案第323行),下面是該方法的定義:

 



    上面方法主要是對訊息中的flag資訊進行解析,以獲取訊息中的刪除條件等資訊,並最終呼叫 deleteObjects方法,該方法位於query.cpp檔案中,如下:

 


    上面的程式碼主要執行構造查詢遊標,並將遊標指向地址的記錄取出來與查詢條件進行匹配,如果匹配命中,則進行刪除。這裡考慮到如果記錄在記憶體時,如果刪除 記錄後,記憶體中的b樹結構會有影響,所以在刪除記錄前/後分別執行noteLocation/checkLocation方法以校正 查詢cursor的當前位置。因為這裡是一個while迴圈,它會找到所有滿足條件的記錄,依次刪除它們。因為這裡使用了MultiCursor,該遊標在我看來就是一個複合遊標 ,它不僅包括了cursor 中所有功能,還支援or條件操作。而有關遊標的構造和繼承實現體系,mongodb做的有些複雜,很難幾句說清,我會在本系列後面另用篇幅進行說明,敬請期待
    注意上面程式碼段中的這行程式碼:


    上面刪除記錄方法deleteRecord中,執行的刪除順序與我之前寫的那篇插入記錄方式正好相反(那篇文章中是選在記憶體中分配記錄然後將地址放到b樹 中),這裡是先將要刪除記錄的索引資訊刪除,然後再刪除指定記錄(更新記憶體中的記錄資訊而不是真的刪除,稍後會進行解釋)。

    首先我們先看一下上面程式碼段的unindexRecord方法:

    


     上面程式碼主要是把要刪除的記錄的B樹鍵值資訊取出,然後通過迴圈(可能存在多鍵索引,具體參見我之前插入記錄那篇文章中B樹索引構造的相關內容)刪除相應B樹索引資訊,下面程式碼段就是在B樹中查詢(locate)並最終刪除(delKeyAtPos)的邏輯:



      在刪除b樹索引之後,接著就是“刪除記憶體(或磁碟,因為mmap機制)中的記錄”了,也就是之前DataFileMgr::deleteRecord()方法的下面程式碼:

  

   
    其定義如下:

 


     這裡有一個資料結構要先解析一下,因為mongodb在刪除記錄時並不是真把記錄從記憶體中remove出來,而是將該刪除記錄資料置空(寫0或特殊數字加 以標識)同時將該記錄所在地址放到一個list列表中,也就是上面程式碼註釋中所說的“釋放列表”,這樣做的好就是就是如果有使用者要執行插入記錄操作 時,mongodb會首先從該“釋放列表”中獲取size合適的“已刪除記錄”地址返回,這種廢物利用 的 方法會提升效能(避免了malloc記憶體操作),同時mongodb也使用了bucket size陣列來定義多個大小size不同的列表,用於將要刪除的記錄根據其size大小放到合適的“釋放列表”中(deletedList),有關該 deletedList內容,詳見namespace.h檔案中的註釋內容。
    上面程式碼中如果記錄的ns 在索引中則進行使用memset方法重置該記錄資料,否則才執行將記錄新增到“釋放列表”操作,如下:

     

 

     這樣,就完成了將記錄放到“釋放列表”中的操作,上面的bucket中提供的大小款式 如下:

  


    
    最後,用一張時序圖回顧一下刪除記錄時mongodb服務端程式碼的執行流程:

 

 

     好了,今天的內容到這裡就告一段落了,在接下來的文章中,將會介紹客戶端發起Update操作時,Mongodb的執行流程和相應實現部分。

    原文連結:http://www.cnblogs.com/daizhj/archive/2011/04/06/2006740.html
    作者: daizhj, 代震軍   
    微博: http://t.sina.com.cn/daizhj
    Tags: mongodb,c++,source code

相關文章