假设3个节点的replica Set,其中有一个collection包含索引已经50GB了,所在的数据库分区空间剩余不足50GB。
需要将这个collection转换成cappedCollection。
需要注意哪些?
先来看看转换操作的特点:
1. 首先convertToCapped操作包含了以下内容,
"cloneCollectionAsCapped" : "$yourCollection",
"toCollection" : ".tmp.convertToCapped.$yourCollection",
"size" : $定义的大小
其实是先创建好cappedCollection,然后克隆数据。
2. convertToCapped操作还是一个写锁操作,非常危险。
convertToCapped: write-lock
{ convertToCapped:<fromCollectionName>, size:<sizeInBytes> }
结合这两点,我们应该注意啥呢?
1. 避免直接在PRIMARY节点操作. 可以选择先将其中的一个SECONDARY节点从replicaSet去除, 转换好在加进来并且转换为PRIMARY角色。
2. 由于是拷贝的操作,所以需要有足够的剩余空间,但是显然这里剩余空间是不够的,所以需要先腾出足够的空间来做转换操作。(可能需要重建库才能缩减存储空间)
3. cappedCollection在_ID上是不建索引的,并且事先建立索引也将影响拷贝速度,所以建议先将索引全部删除再开始转换操作。
另外需要注意的是,节点拆除之后,被拆除的节点需要进入非replicaSet启动模式,否则启动后不能做写操作。例如注释掉两行:
# replSet=blss
# autoresync=true
再次加入replicaSet之后,启动的时候需要将注释去掉,并且加入启动参数 :
--replSet blss/192.168.xxx.xxx:xxxx,192.168.xxx.xxx:xxxx,192.168.xxx.xxx:xxxx
replSet这里要写全,否则新加入的节点会认为自己的配置文件里面没有自己,无法加入到replicaSet.
PRIMARY节点报错 :
{
"_id" : 2,
"name" : "192.168.xxx.xxx:xxxx",
"health" : 0,
"state" : 6,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"t" : 0,
"i" : 0
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2011-11-01T23:53:44Z"),
"errmsg" : "still initializing"
}
新加入中的节点报错 :
Wed Nov 2 07:50:20 [startReplSets] replSet caught exception in startReplSets thread: replSet error self not present in the configur
ation
【其他参考】
30G的collection,转cappedCollection.
耗时73688秒,还没有转结束。
> db.currentOp()
{
"inprog" : [
{
"opid" : 24,
"active" : true,
"waitingForLock" : false,
"secs_running" : 73688,
"op" : "query",
"ns" : "blss..tmp.convertToCapped.$myCollection",
"query" : {
"cloneCollectionAsCapped" : "$myCollection",
"toCollection" : ".tmp.convertToCapped.$myCollection",
"size" : 30000000000
},
"client" : "0.0.0.0:0",
"desc" : "conn"
}
]
}