一、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.高效的...