mongo 停止創建索引 --noIndexBuildRetry


在數據量超大的情形下,任何數據庫系統在創建索引時都是一個耗時的大工程。MongoDB也不例外。因此,MongoDB索引的創建有兩個選擇,一個是前台方式,一個是后台方式。那這兩種方式有什么差異呢,在創建索引是是否能觀察到索引完成的進度呢。本文將是基於此的描述,同時也描述了索引創建相關的注意事項。

一、索引創建方式

  1.  
    前台方式
  2.  
    缺省情況下,當為一個集合創建索引時,這個操作將阻塞其他的所有操作。即該集合上的無法正常讀寫,直到索引創建完畢
  3.  
    任意基於所有數據庫申請讀或寫鎖都將等待直到前台完成索引創建操作
  4.  
     
  5.  
    后台方式
  6.  
    將索引創建置於到后台,適用於那些需要長時間創建索引的情形
  7.  
    這樣子在創建索引期間, MongoDB依舊可以正常的為提供讀寫操作服務
  8.  
    等同於關系型數據庫在創建索引的時候指定 online,而MongoDB則是指定background
  9.  
    其目的都是相同的,即在索引創建期間,盡可能的以一種占用較少的資源占用方式來實現,同時又可以提供讀寫服務
  10.  
    后台創建方式的代價:索引創建時間變長
  11.  
     
  12.  
    后台創建索引的示例
  13.  
    db.people.createIndex( { zipcode: 1}, {background: true} )
  14.  
    db.people.createIndex( { city: 1}, {background: true, sparse: true } )
  15.  
     
  16.  
    缺省情況下 background選項的值為false

二、索引創建期間注意事項

  1.  
    如前所述,基於后台創建索引時,其他的數據庫操作能被完成。但是對於 mongo shell會話或者你正在創建索引的這個連接
  2.  
    將不可用,直到所有創建完畢。如果需要做一些其它的操作。則需要再建立其它的連接。
  3.  
     
  4.  
    在索引創建期間,即使完成了部分索引的創建,索引依舊不可用,但是一旦創建完成即可使用。
  5.  
     
  6.  
    基於后台創建索引期間不能完成涉及該集合的相關管理操作
  7.  
    repairDatabase
  8.  
    db.collection.drop()
  9.  
    compact
  10.  
     
  11.  
    意外中斷索引創建
  12.  
    如果在后台創建索引期間, mongod實例異常終止,當mongod實例重新啟動后,未完成的索引創建將作為前台進程來執行
  13.  
    如果索引創建失敗,比如由於重復的鍵等, mongod將提示錯誤並退出
  14.  
    在一個索引創建失敗后啟動 mongod,可以使用storage.indexBuildRetry or --noIndexBuildRetry跳過索引創建來啟動

三、索引創建期間性能

  1.  
    后台創建索引比前台慢,如果索引大於實際可用內存,則需要更長的時間來完成索引創建
  2.  
    所有涉及到該集合的相關操作在后台期間其執行效能會下降,應在合理的維護空擋期完成索引的創建

四、索引的命名規則

  1.  
    缺省情況下,索引名以鍵名加上其創建順序(1或者 -1)組合而成。
  2.  
    db.products.createIndex( { item: 1, quantity: -1 } )
  3.  
    比如上面的索引創建后,其索引名為 item_1_quantity_-1
  4.  
    可以指定自定義的索引名稱
  5.  
     
  6.  
    db.products.createIndex( { item: 1, quantity: -1 } , { name: "inventory_idx" } )
  7.  
     
  8.  
    如上方式,我們指定了了索引名稱為 inventory_idx

五、查看索引創建進度

  1.  
    可使用 db.currentOp() 命令觀察索引創建的完成進度
  2.  
     
  3.  
    > db.currentOp(
  4.  
    {
  5.  
    $or: [
  6.  
    { op: "command", "query.createIndexes": { $exists: true } },
  7.  
    { op: "insert", ns: /\.system\.indexes\b/ }
  8.  
    ]
  9.  
    }
  10.  
    )
  11.  
     
  12.  
    //下面通過一個索引創建示例來查看索引完成進度
  13.  
    //首選創建一個500w文檔的集合
  14.  
     
  15.  
    > db.version() // Author : Leshami
  16.  
    3.2.10 // Blog : http://blog.csdn.net/leshami
  17.  
     
  18.  
    > for (var i=1;i<=5000000;i++){
  19.  
    db.inventory.insert({ id:i,item:"item"+i,stock:Math.floor(i*Math.random())})
  20.  
    }
  21.  
    WriteResult({ "nInserted" : 1 })
  22.  
     
  23.  
    > db.inventory.find().limit( 3)
  24.  
    { "_id" : ObjectId("581bfc674b0d633653f4427e"), "id" : 1, "item" : "item1", "stock" : 0 }
  25.  
    { "_id" : ObjectId("581bfc674b0d633653f4427f"), "id" : 2, "item" : "item2", "stock" : 0 }
  26.  
    { "_id" : ObjectId("581bfc674b0d633653f44280"), "id" : 3, "item" : "item3", "stock" : 1 }
  27.  
     
  28.  
    > db.inventory.find().count()
  29.  
    5000000
  30.  
     
  31.  
    //下面開始創建索引
  32.  
    > db.inventory.createIndex({ item:1,unique:true})
  33.  
     
  34.  
    //使用下面的命令查看索引完成進度
  35.  
    > db.currentOp(
  36.  
    {
  37.  
    $or: [
  38.  
    { op: "command", "query.createIndexes": { $exists: true } },
  39.  
    { op: "insert", ns: /\.system\.indexes\b/ }
  40.  
    ]
  41.  
    }
  42.  
    )
  43.  
     
  44.  
    //結果如下
  45.  
    {
  46.  
    "inprog" : [
  47.  
    {
  48.  
    "desc" : "conn1", //連接描述
  49.  
    "threadId" : "139911670933248", //線程id
  50.  
    "connectionId" : 1,
  51.  
    "client" : "127.0.0.1:37524", //ip及端口
  52.  
    "active" : true, //活動狀態
  53.  
    "opid" : 5014925,
  54.  
    "secs_running" : 21, //已執行的時間
  55.  
    "microsecs_running" : NumberLong(21800738),
  56.  
    "op" : "command",
  57.  
    "ns" : "test.$cmd",
  58.  
    "query" : {
  59.  
    "createIndexes" : "inventory", //這里描述了基於inventory正在創建索引
  60.  
    "indexes" : [
  61.  
    {
  62.  
    "ns" : "test.inventory",
  63.  
    "key" : {
  64.  
    "item" : 1,
  65.  
    "unique" : true
  66.  
    },
  67.  
    "name" : "item_1_unique_true"
  68.  
    }
  69.  
    ]
  70.  
    },
  71.  
    "msg" : "Index Build Index Build: 3103284/5000000 62%", //這里是完成的百分比
  72.  
    "progress" : {
  73.  
    "done" : 3103722,
  74.  
    "total" : 5000000
  75.  
    },
  76.  
    "numYields" : 0,
  77.  
    "locks" : { //當前持有的鎖
  78.  
    "Global" : "w",
  79.  
    "Database" : "W",
  80.  
    "Collection" : "w"
  81.  
    },
  82.  
    "waitingForLock" : false,
  83.  
    "lockStats" : { //鎖的狀態信息
  84.  
    "Global" : {
  85.  
    "acquireCount" : {
  86.  
    "r" : NumberLong(1),
  87.  
    "w" : NumberLong(1)
  88.  
    }
  89.  
    },
  90.  
    "Database" : {
  91.  
    "acquireCount" : {
  92.  
    "W" : NumberLong(1)
  93.  
    }
  94.  
    },
  95.  
    "Collection" : {
  96.  
    "acquireCount" : {
  97.  
    "w" : NumberLong(1)
  98.  
    }
  99.  
    }
  100.  
    }
  101.  
    }
  102.  
    ],
  103.  
    "ok" : 1
  104.  
    }
  105.  
     
  106.  
    //基於后台方式創建索引
  107.  
     
  108.  
    > db.inventory.createIndex({ item:1,unique:true},{background: true})

六、終止索引的創建

    db.killOp() 

原文連接:https://blog.csdn.net/zhang123456456/article/details/83002168?utm_source=blogxgwz8


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM