mongo 停止建立索引 --noIndexBuildRetry
阿新 • • 發佈:2020-07-20
在資料量超大的情形下,任何資料庫系統在建立索引時都是一個耗時的大工程。MongoDB也不例外。因此,MongoDB索引的建立有兩個選擇,一個是前臺方式,一個是後臺方式。那這兩種方式有什麼差異呢,在建立索引是是否能觀察到索引完成的進度呢。本文將是基於此的描述,同時也描述了索引建立相關的注意事項。
一、索引建立方式
- 前臺方式
- 預設情況下,當為一個集合建立索引時,這個操作將阻塞其他的所有操作。即該集合上的無法正常讀寫,直到索引建立完畢
- 任意基於所有資料庫申請讀或寫鎖都將等待直到前臺完成索引建立操作
- 後臺方式
- 將索引建立置於到後臺,適用於那些需要長時間建立索引的情形
- 這樣子在建立索引期間,MongoDB依舊可以正常的為提供讀寫操作服務
- 等同於關係型資料庫在建立索引的時候指定online,而MongoDB則是指定background
- 其目的都是相同的,即在索引建立期間,儘可能的以一種佔用較少的資源佔用方式來實現,同時又可以提供讀寫服務
- 後臺建立方式的代價:索引建立時間變長
- 後臺建立索引的示例
- db.people.createIndex( { zipcode: 1}, {background: true} )
-
db.people.createIndex( { city: 1}, {background: true, sparse: true } )
- 預設情況下background選項的值為false
二、索引建立期間注意事項
- 如前所述,基於後臺建立索引時,其他的資料庫操作能被完成。但是對於mongo shell會話或者你正在建立索引的這個連線
- 將不可用,直到所有建立完畢。如果需要做一些其它的操作。則需要再建立其它的連線。
- 在索引建立期間,即使完成了部分索引的建立,索引依舊不可用,但是一旦建立完成即可使用。
- 基於後臺建立索引期間不能完成涉及該集合的相關管理操作
- repairDatabase
- db.collection.drop()
-
compact
- 意外中斷索引建立
- 如果在後臺建立索引期間,mongod例項異常終止,當mongod例項重新啟動後,未完成的索引建立將作為前臺程序來執行
- 如果索引建立失敗,比如由於重複的鍵等,mongod將提示錯誤並退出
- 在一個索引建立失敗後啟動mongod,可以使用storage.indexBuildRetry or --noIndexBuildRetry跳過索引建立來啟動
三、索引建立期間效能
- 後臺建立索引比前臺慢,如果索引大於實際可用記憶體,則需要更長的時間來完成索引建立
- 所有涉及到該集合的相關操作在後臺期間其執行效能會下降,應在合理的維護空擋期完成索引的建立
四、索引的命名規則
- 預設情況下,索引名以鍵名加上其建立順序(1或者-1)組合而成。
- db.products.createIndex( { item: 1, quantity: -1 } )
- 比如上面的索引建立後,其索引名為item_1_quantity_-1
- 可以指定自定義的索引名稱
- db.products.createIndex( { item: 1, quantity: -1 } , { name: "inventory_idx" } )
- 如上方式,我們指定了了索引名稱為inventory_idx
五、檢視索引建立進度
- 可使用 db.currentOp() 命令觀察索引建立的完成進度
- > db.currentOp(
- {
- $or: [
- { op: "command", "query.createIndexes": { $exists: true } },
- { op: "insert", ns: /\.system\.indexes\b/ }
- ]
- }
- )
- //下面通過一個索引建立示例來檢視索引完成進度
- //首選建立一個500w文件的集合
- > db.version() // Author : Leshami
- 3.2.10 // Blog : http://blog.csdn.net/leshami
- > for (var i=1;i<=5000000;i++){
- db.inventory.insert({id:i,item:"item"+i,stock:Math.floor(i*Math.random())})
- }
- WriteResult({ "nInserted" : 1 })
- > db.inventory.find().limit(3)
- { "_id" : ObjectId("581bfc674b0d633653f4427e"), "id" : 1, "item" : "item1", "stock" : 0 }
- { "_id" : ObjectId("581bfc674b0d633653f4427f"), "id" : 2, "item" : "item2", "stock" : 0 }
- { "_id" : ObjectId("581bfc674b0d633653f44280"), "id" : 3, "item" : "item3", "stock" : 1 }
- > db.inventory.find().count()
- 5000000
- //下面開始建立索引
- > db.inventory.createIndex({item:1,unique:true})
- //使用下面的命令檢視索引完成進度
- > db.currentOp(
- {
- $or: [
- { op: "command", "query.createIndexes": { $exists: true } },
- { op: "insert", ns: /\.system\.indexes\b/ }
- ]
- }
- )
- //結果如下
- {
- "inprog" : [
- {
- "desc" : "conn1", //連線描述
- "threadId" : "139911670933248", //執行緒id
- "connectionId" : 1,
- "client" : "127.0.0.1:37524", //ip及埠
- "active" : true, //活動狀態
- "opid" : 5014925,
- "secs_running" : 21, //已執行的時間
- "microsecs_running" : NumberLong(21800738),
- "op" : "command",
- "ns" : "test.$cmd",
- "query" : {
- "createIndexes" : "inventory", //這裡描述了基於inventory正在建立索引
- "indexes" : [
- {
- "ns" : "test.inventory",
- "key" : {
- "item" : 1,
- "unique" : true
- },
- "name" : "item_1_unique_true"
- }
- ]
- },
- "msg" : "Index Build Index Build: 3103284/5000000 62%", //這裡是完成的百分比
- "progress" : {
- "done" : 3103722,
- "total" : 5000000
- },
- "numYields" : 0,
- "locks" : { //當前持有的鎖
- "Global" : "w",
- "Database" : "W",
- "Collection" : "w"
- },
- "waitingForLock" : false,
- "lockStats" : { //鎖的狀態資訊
- "Global" : {
- "acquireCount" : {
- "r" : NumberLong(1),
- "w" : NumberLong(1)
- }
- },
- "Database" : {
- "acquireCount" : {
- "W" : NumberLong(1)
- }
- },
- "Collection" : {
- "acquireCount" : {
- "w" : NumberLong(1)
- }
- }
- }
- }
- ],
- "ok" : 1
- }
- //基於後臺方式建立索引
- > db.inventory.createIndex({item:1,unique:true},{background: true})
六、終止索引的建立
db.killOp()
原文連線:https://blog.csdn.net/zhang123456456/article/details/83002168?utm_source=blogxgwz8