mongodb 建索引导致数据库阻塞

在MongoDB上建索引可能会对MongoDB集群对可用性产生负面影响。在生产服务上,如果针对一个大集合触发建立索引,且在前台运行,你可能会发现,在索引建完之前,整个集群都无影响。在一个大集合上,这个过程可能会持续几个小时,甚至几天。

解决的方法很简单,MongoDB 提供了两种建索引的访问,一种是 background 方式,不需要长时间占用写锁,另一种是非 background 方式,需要长时间占用锁。使用 background 方式就可以解决问题。 例如,为超大表 posts 建立索引, 千万不用使用
复制代码 代码如下:
db.posts.ensureIndex({user_id: 1})

而应该使用
复制代码 代码如下:
db.posts.ensureIndex({user_id: 1}, {background: 1})

如果已经再建索引了,如何停止?

一旦你触发一个索引,简单的重启服务并不能解决这个问题,因为MongoDB会继续重启前的建索引的工作。如果之前你运行后台建索引任务,在服务重启后它会变成前台运行的任务。在这种情况下,重启会让问题变得更糟糕。

如果你已经启动了建索引的任务,该如何停止它呢?幸运的是,有方法相对简单的停止建索引任务。

选项一:杀掉建索引的进程

使用db.currentOp()定位建索引进程,然后使用db.killOp(<opid>)杀掉操作。建索引大致会是以下的样子:
{ "opid" : 820659355, "active" : true, "lockType" : "write", .... "op" : "insert", "ns" : "xxxx", "query" : { }, "client" : "xxxx", "desc" : "conn", "msg" : "index: (2/3) btree bottom up 292168587/398486401 64%" }
如果正在建索引的节点不能响应新连接,或者killOp不起作用,使用选项二。



选项二:配置“noIndexBuildRetry”并重启

1. 重启mongo 片的服务加上参数 

--noIndexBuildRetry                   don't retry any index builds that were 
                                        interrupted by shutdown

通过mongod --help 查看此参数意义

2. 找到没有建完的索引,删除

3. 去掉noIndexBuildRetry   后重启

猜你喜欢

转载自blog.csdn.net/zhuchunyan_aijia/article/details/83107077
今日推荐