概述:
Capped Collection是一种固定大小的集合,从而支持高吞吐量的insert以及顺序读取。一旦分配的空间被占用满,则new document记录将会覆盖掉老的document记录。遵循FIFO原则。
创建:
db.createCollection("log", { capped : true, size : 5242880, max : 5000 } )
参数:
capped:true 或 false 意思你懂的;
size:固定集合的大小设置,小值4096 bytes
max:(可选)指定一个集合的大文档数量;
注:max是可选参数,MongoDB即使没有达到大max文档数,但是超过了size的大小限制,依然会移除older document;
查询是否创建成功
> db.log.isCapped() ---返回true表示成功
或
> db.log.stats().capped
转换普通集合为Capped collection
> db.runCommand({"convertToCapped":"t1",size:5000})
注:上述转换操作可能会持有一个database级别的锁,想要lock此database的操作将会被阻塞。
索引
默认有_id索引,当然你也可以在其他字段上创建索引,但是索引的数量决定这insert性能,如果集合下有太多的索引,那势必是会影响insert性能;
限制和推荐:
1)支持update操作,并建议在update的查询条件字段上创建索引;
但是如果更新操作改变了document size,则会报错,如下:
2)不能删除数据,否则会报错
>db.log.remove({_id:0})
'errmsg' : 'cannot remove from a capped collection: testdb.log'"
只能通过drop掉集合,重建集合来达到目的。
3)不能分片(shard)一个capped collection
4)aggregate聚合聚合操作中$out不能只想一个capped collection
实验记录
概述:
为了业务不停机情况下,将普通集合转换为capped collection,我打算采用先转换secondary节点的集合t1,之后再降级操作primary节点上的集合t1,结果发生了宕机问题,操作如下,供参考;
1.将secondary节点关闭,并以单节点模式启动,之后转换集合t1
> db.runCommand({"convertToCapped":"t1",size:4096})
成功后,再以复制集模式重启mongod
2.此时在Primary节点t1上插入一条数据后,发现secondary节点上的t1可正常同步数据过来
SIT_RS:PRIMARY> db.t1.insert({_id:2,name:"James"})
WriteResult({ "nInserted" : 1 })
SIT_RS:PRIMARY> db.t1.find()
{ "_id" : 1, "name" : "Kobe" }
{ "_id" : 2, "name" : "James" }
secondary节点查询
SIT_RS:SECONDARY> db.t1.find()
{ "_id" : 1, "name" : "Kobe" }
{ "_id" : 2, "name" : "James" }
3.但是当主库上update操作时,secondary发生了异常宕机
SIT_RS:PRIMARY> db.t1.update({_id:2},{$set:{name:"Jamesssssssssssssssssssssssssss"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
SIT_RS:PRIMARY> db.t1.find()
{ "_id" : 1, "name" : "Kobe" }
{ "_id" : 2, "name" : "Jamesssssssssssssssssssssssssss" }
SIT_RS:PRIMARY>
异常如下:
SIT_RS:SECONDARY> db.t1.find()
Error: error doing query: failed: network error while attempting to run command 'find' on host '10.25.15.71:27027'
2018-11-12T10:59:18.340+0800 I NETWORK [thread1] trying reconnect to 10.25.15.71:27027 (10.25.15.71) failed
2018-11-12T10:59:18.341+0800 W NETWORK [thread1] Failed to connect to 10.25.15.71:27027, in(checking socket for error after poll), reason: Connection refused
2018-11-12T10:59:18.341+0800 I NETWORK [thread1] reconnect 10.25.15.71:27027 (10.25.15.71) failed failed
2018-11-12T10:59:18.343+0800 I NETWORK [thread1] trying reconnect to 10.25.15.71:27027 (10.25.15.71) failed
2018-11-12T10:59:18.343+0800 W NETWORK [thread1] Failed to connect to 10.25.15.71:27027, in(checking socket for error after poll), reason: Connection refused
2018-11-12T10:59:18.343+0800 I NETWORK [thread1] reconnect 10.25.15.71:27027 (10.25.15.71) failed failed
>
>
日志中显示发生了异常进程关闭,原因是在重放新oplog时是一个update操作,而更新文档后的大小触发了capped collection的document size限制(不清楚的话可以看上述讲解)。
4.此时以单节点模式启动从库的mongod,发现oplog.rs中并没有新一条的update操作
5.再以复制集模式重启mongod后,瞬间就又宕机了
查看日志文件发现,还是会出现上述日志中的异常记录;
结论:
说明每次启动此节点,都要去拽取那条update操作t1的oplog进行重放,而一重放就触发报错,从而宕机。