1. MongoDB 慢查詢記錄功能簡介
如何定位 MongoDB 數據庫的慢查詢,我想應該是很多剛使用 MongoDB 數據庫的朋友最想知道的問題。通過慢查詢的定位,可以輔助對 MongoDB 中的 collection 進行優化。
MongoDB 數據庫的慢查詢數據其實存放在一個數據庫集合 ( collection ) 中(system.profile),如果你不主動創建 system.profile 這個集合,那這個集合就固定1M大小,當慢查詢記錄超過1M,就會將歷史數據覆蓋,循環使用,所以在這裏需要根據業務實際情況設置集合大小。
在 MongoDB 中慢查詢功能(Profiling)設置有三個級別,分別代表如下含義:
- 0:代表關閉,不收集任何慢查詢
- 1:收集慢查詢數據,默認收集超過100毫秒的慢查詢
- 2:收集任何操作記錄數據
可以通過在 MongoDB 中執行如下命令查看當前數據庫的配置,需要特別注意的是,如果你在某一數據庫中調整了該設置,那麼該操作只對該數據庫有效,其他數據庫仍需要單獨設置:
use test
'switched to db test'
db.getProfilingStatus()
{
was: 1, slowms: 1000, sampleRate: 1, ok: 1 }
2. 如何設置慢查詢
2.1 檢查慢查詢是否開啓
執行 db.getProfilingStatus()
查詢數據庫,返回結果是 was: 0 代表 MongoDB 沒有開啓慢查詢功能;對應的如果不是 0 則表示開啓了慢查詢監控功能。
2.2 開啓慢查詢功能
如果你想指定監控慢查詢在某一毫秒值之上的查詢,例如超過 1000 毫秒的查詢被記錄,可以通過如下語句進行設置:
db.setProfilingLevel(1, {
slowms: 1000 })
下面這個例子表示將慢查詢的級別設置爲 2
db.setProfilingLevel(2)
{
was: 1, slowms: 500, sampleRate: 1, ok: 1 }
db.getProfilingStatus()
{
was: 2, slowms: 500, sampleRate: 1, ok: 1 }
關掉慢查詢功能
db.setProfilingLevel(0)
3. 如何查詢慢查詢日誌
假設上面我們已經開啓了慢查詢監控功能,那在數據庫使用過程中,會將 1000 ms 以上的執行查詢進行記錄,下面我們來看一下如何查詢這些慢查詢。
3.1 慢查詢日誌查看
查詢最近的 10 個慢查詢日誌 (運行時間大於等於 8000 毫秒)
db.system.profile.find({
"millis":{
$gte:8000}}).limit(10).sort( {
ts : -1 } ).pretty()
查詢大於 100 秒的日誌
db.system.profile.find( {
millis : {
$gt : 100000 } } ).pretty()
查詢時間從 2023-01-03 15 點整到 2023-01-03 15點30分 之間的日誌
db.system.profile.find({
ts : {
$gt: new ISODate("2023-01-03T07:00:00Z"),$lt: new ISODate("2023-01-03T07:30:00Z")}}).pretty()
備註:注意 Mongo 裏面存儲的 ISO 時間是格林尼治時間,我們當前CST時間爲北京時間,需要在 ISO 上 +8,所以你可以看到上面我查詢輸入的時間爲 7 點,但實際上查詢的是 15 點的數據。
清理慢查詢日誌,設置大小
db.setProfilingLevel(0)
db.system.profile.drop()
db.createCollection( "system.profile", { capped: true, size: 1024*1024*10 } )
db.setProfilingLevel(1, { slowms: 500 })