query操作的加鎖過程和時間統計

2021-07-11 01:35:53 字數 3180 閱讀 9830



一、query完成加讀鎖的機制和流程

1.mongodb借用系統提供的pthread_rwlock_t實現它資料庫級的讀寫鎖

2.封裝之的讀寫鎖名為rwlockbase,rwlockbase又進一步封裝成******rwlock,僅是封裝沒有太多有用功。

class rwlockbase

void unlock()

void lock_shared()

void unlock_shared()

};3.mongodb使用全域性的map對映為每個被訪問過的資料庫建立一把讀寫鎖

4.mongodb借助lock::dbread實現對讀寫鎖的「讀許可權請求」和「讀許可權歸還」。

class dbread : public scopedlock

~dbread()

};5.lock::dbread構成了query操作「讀上下文」的一部分。由於構造client::readcontext的過程中lock::dbread也被構造,所以建立「讀上下文」就會自動對資料庫加讀鎖。

client::readcontext::readcontext(const string& ns, const std::string& path)

6. 以最簡單的查詢queryidhack函式為例,它在呼叫helpers::findbyid獲取記錄之前會先創造「讀上下文」

bool queryidhack( const char* ns, const bsonobj& query, const parsedquery& pq, curop& curop, message& result )

以上6條就是query完成加讀鎖的框架機制流程

二、鎖占用時間的統計

1、mongodb對鎖占用時間的統計包括「獲取鎖(獲取許可權)所需要時間」和「占用鎖(行使許可權)所需要時間」兩部分。

2、mongodb使用timer型別的變數記錄與讀寫鎖有關的時間,timer在自身的建構函式中就開始計時。

3、timer型別的變數是每個lock::dbread例項的一部分,dbread負責記錄「獲取鎖(獲取許可權)所需要時間」和「占用鎖(行使許可權)所需要時間」

其實timer型別的變數是每個scopedlock例項的一部分,但lock::dbread派生自scopedlock,所以上面的說法沒問題。

class scopedlock

}4、建立「讀上下文」的過程即是獲取鎖的過程,也就是開始統計用鎖時間的過程。

4.1、建立「讀上下文」的過程附帶建立了dbread例項,timer的構造此時已記錄下了開始獲取鎖的時間點。

4.2、dbread在它的建構函式中呼叫lockdb,在加鎖的過程中,實現了對時間的計算。

class dbread : public scopedlock

}5、lock::dbread借助acquiring類的析構,自動計算「獲取鎖(獲取許可權)所需要時間」,並對」占用鎖「開始計時

class acquiring

~acquiring()

private:

lock::scopedlock* _lock;

lockstate& _ls;

};6、鎖的最終釋放

如果到query操作結束一直未釋放過鎖,dbread的析構會呼叫unlockdb最終釋放鎖,其中包括對「占用鎖(行使許可權)所需要時間」的計算

class dbread : public scopedlock

}以上鎖占用時間的統計粗略過程

三、query操作時長統計

1、mongodb使用「當前操作」類curop,跟蹤query操作所用時長。

2、curop類有三個函式對應計時開始與計時結束。

2.1)ensurestarted函式,如果沒有開始計時,就立即開始計時

void curop::ensurestarted()

2.2)開始當前操作,並計時

void curop::enter( client::context * context )

2.3)計時結束

void done()

3、query建立「讀上下文」的過程中:在獲取讀寫鎖的以後,才開始對query操作時長計時。

readcontext在構造中利用了context的建構函式。

client::readcontext::readcontext(const string& ns, const std::string& path)

4.context的建構函式獲取了 「當前操作」curop類,並呼叫了它的enter函式記錄了query操作的開始時間點

client::context::context(const string& path, const string& ns, database *db , bool doauth)

5.操作的結束時間點由assembleresponse函式統一呼叫curop::done函式記錄並生成報告。

因為所有操作都是經由assembleresponse排程的,所以除query之外的操作時長也都是在這裡統計得到的。

void assembleresponse( message &m, dbresponse &dbresponse, const hostandport& remote )

SQLAlchemy的查詢操作Query

查詢操作 查詢子句使用session的.query 方法來獲取query查詢物件。查詢物件能夠使用一些方法來對應一些查詢子句,比如.order by limit filter 等。查詢物件有這麼幾種方法.one all scalar one or none get 以及.first 等。下面對這幾個...

mysql時間操作函式和儲存過程

由於業務需要統計一批資料,用到關於mysql的時間操作函式和儲存過程,問題已經基本解決,把過程記錄下 1.mysql的語句中不支援直接用迴圈,迴圈只能在儲存過程中使用 2.寫為檔案時,注意一些隱藏的字元,造成語法錯誤。本例中注釋中包含一些不可見字元,沒有找到。3.儲存過程中盡量多使用分好,分割開語句...

MySql的Query和Insert效能測試

通過對典型的query和insert操作的測試,暫時能得出如下結論 可能會受mysql版本,機器配置的影響 關於query 1.100w是個無索引查詢效能的分水嶺。2.資料量在30w 200w的區間,在索引高效的情況下,資料庫資料量的變化,基本對查詢不會產生明顯的影響 這也跟查詢原理相符 3.高效的...