相关文章推荐
唠叨的桔子  ·  使用`scipy.interpolate.g ...·  1 年前    · 
力能扛鼎的豌豆  ·  Linux内核分析 - ...·  1 年前    · 

由于公司业务需求,对于3个月前的过期数据需要进行删除动作,以释放空间和方便维护

本来想的是使用crontab写个脚本定时执行,但是看到Mongo本身就有自动删除过期数据的功能,所以还是用一下吧

这个方法就是使用TTL索引,后续我再写一个脚本定时删除的任务

TTL索引是MongoDB中一种特殊的索引, 可以支持文档在一定时间之后自动过期删除,目前TTL索引只能在单字段上建立,

并且字段类型必须是date类型或者包含有date类型的数组(如果数组中包含多个date类型字段,则取最早时间为过期时间)

官网介绍链接: https://docs.mongodb.com/v3.2/core/index-ttl/

当你在集合中某一个字段建立TTL索引后,后台会有一个单线程,通过不断查询(默认60s一次)索引的值来判断document是否有过期,

并且删除文档的动作还依据mongod实例的负载情况,如果负载很高,可能会稍微延后一段时间再删除。

还有一个需要注意的地方,在复制集成员中,TTL后台线程只删除primary的过期数据,如果此实例变为secondary角色,则后台线程闲置

创建TTL索引方法:

和普通索引的创建方法一样,只是会多加一个属性而已

例:在log_events的集合中,createTime 字段上建立一小时后过期的TTL索引

>db.log_events.createIndex( { "createTime": 1 },     ---字段名称

{ expireAfterSeconds: 60*60 } )     ---过期时间(单位秒)

>db.log_events.getIndexes()     ---查看索引

"v" : 1,

"key" : {

"_id" : 1

"name" : "_id_",

"ns" : "tt.t1"

"v" : 1,

"key" : {

"createTime" : 1

"name" : "createTime_1",

"ns" : "tt.t1",

"expireAfterSeconds" : 3600

db.runCommand( { collMod: "log_events",     ---集合名

index: { keyPattern: { createTime: 1 },     ---createTime为具有TTL索引的字段名

expireAfterSeconds: 7200          ---修改后的过期时间(秒)

虽然上面的方法可以实现自动过期删除,但是如果白天业务很忙,频繁的删除数据势必会增加负载,所以我想着晚上定时删除过期数据(如果晚上业务量少的话)

方法如下:

增加一个expireTime字段(用于指定过期时间),expireAfterSeconds属性值设置为0,

注:上面的createTime字段就不需要再有TTL索引了,这个expireTime的时间就需要在插入时指定上

>db.log_events.createIndex( { "expireTime": 1 },     ---字段名称

{ expireAfterSeconds: 0 } )     ---过期时间(单位秒)

>db.log_events.insert( {

"expireTime": new Date('Jan 22, 2016 23:00:00'),     ---此文档将在2016-1-22的23点自动删除

"logEvent": 2,

"logMessage": "Success!"} )

①TTL索引是单字段索引,混合索引不支持TTL,并且也会忽略expireAfterSeconds属性

②在_id 主键上不能建立TTL索引

③在capped collection中不能建立TTL索引,因为MongoDB不能从capped collection中删除文档

④你不能使用createIndex()去更改已经存在的TTL索引的expireAfterSeconds值,如果想更改expireAfterSeconds,可以使用collMod命令,

否则你只能删除索引,然后重建了

⑤你不能在已有索引的字段上再创建TTL索引了,如果你想把非TTL索引改为TTL索引,那就只能删除重建索引了

https://blog.csdn.net/jianlong727/article/details/54631124