Mongodb原始碼分析--刪除記錄
在之前的一篇文章 中,介紹了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
相關文章
- MongoDB 刪除文件MongoDB
- Kubernetes原始碼分析之Pod的刪除原始碼
- mysql刪除一條記錄MySql
- 刪除Oracle重複記錄Oracle
- oracle刪除重複記錄Oracle
- MongoDB原始碼分析之MongosXFMongoDB原始碼
- seajs3.0.0原始碼分析記錄JSS3原始碼
- 用“稽核物件”功能記錄檔案刪除記錄物件
- windows10更新記錄刪除_怎樣刪除win10更新歷史記錄WindowsWin10
- 刪除不掉的資料記錄
- 從原始碼分析DEARGUI之互動新增和刪除元件原始碼GUI元件
- oracle 快速刪除大批量資料方法(全部刪除,條件刪除,刪除大量重複記錄)Oracle
- MongoDB之資料刪除MongoDB
- mysql表刪除重複記錄方法MySql
- DB2 刪除重複記錄DB2
- 找回Oracle中Delete刪除的記錄Oracledelete
- oracle 快速刪除大批量資料方法(全部刪除,條件刪除,刪除大量重複記錄) 轉Oracle
- 【轉】oracle 快速刪除大批量資料方法(全部刪除,條件刪除,刪除大量重複記錄)Oracle
- jQuery的ajax實現的刪除記錄程式碼例項jQuery
- MongoDB 記錄MongoDB
- Mongodb原始碼分析之balancer(均衡)KBMongoDB原始碼
- mongodb刪除重複資料MongoDB
- mysql支援跨表delete刪除多表記錄MySqldelete
- Oracle使用over()partition by刪除重複記錄Oracle
- Oracle如何刪除表中重複記錄Oracle
- 如何刪除oracle庫中相同的記錄Oracle
- db2刪除重複的記錄DB2
- jquery刪除記錄彈出提示框jQuery
- oracle-快速刪除重複的記錄Oracle
- 查詢刪除表中重複記錄
- SQLServer刪除登入記錄使用者名稱和密碼SQLServer密碼
- 【Zookeeper】原始碼分析目錄原始碼
- win10更新失敗記錄怎麼刪除_win10更新失敗記錄刪除操作方法Win10
- Mongodb write寫(增、刪、改)模組原始碼實現MongoDB原始碼
- win10 開始選單照片記錄怎麼刪除 win10刪除開始選單記錄方法Win10
- mongodb核心原始碼實現及效能優化系列:Mongodb write寫(增、刪、改)模組原始碼實現MongoDB原始碼優化
- sql刪除重複記錄只保留一條SQL
- Gerrit上分支操作記錄(建立分支、刪除分支)