本帖最后由 dqq 于 2023-4-10 17:27 编辑
背景:
由于现场并发更新文件组,实体信息,可能会导致同一个素材里面出现相同文件组的情况。
现象:
修复逻辑:
找出mongo DB文件组集合里面所有重复的文件组信息,保留任意一个文件组,最后为文件组加上唯一索引,避免下次再次出现此问题。
1.创建临时索引
db.SH_D_FILEGROUPS.createIndex({"resourceId":1,"dataregion.creator":1,"dataregion.groupName":1}, {"unique":false, background: true,name:"fileg_temp"});
2.验证是否有重复文件组存在
统计重复文件组数量,如果结果count大于0, 说明存在需要修复的文件组。 db.SH_D_FILEGROUPS.aggregate( [ { $group: { _id: {groupName_:'$dataregion.groupName', creator_:'$dataregion.creator', resourceId_:'$resourceId'}, groupName:{$addToSet: '$dataregion.groupName'}, creator:{$addToSet: '$dataregion.creator'}, resourceId:{$addToSet:'$resourceId'}, count:{$sum:1} } }, { $match: {count: {$gt:1}} }, {$count:"count"} ], { allowDiskUse: true } );
3.修复操作
1. 备份mongo数据库下hivedb里面的"SH_D_FILEGROUPS"集合。
2. 根据发现有问题的文件组个数来决定使用手动修复还是脚本修复(主要脚本修复是随机保留一个文件组, 保留的可能并不是期望的),比如需要修复的只有几个文件组就可以考虑手动修复,下面分别说明两种修复方式。
3-1.手动修复
执行下面脚本,获取需要修复文件组的信息
db.SH_D_FILEGROUPS.aggregate( [ { $group: { _id: {groupName_:'$dataregion.groupName', creator_:'$dataregion.creator', resourceId_:'$resourceId'}, groupName:{$addToSet: '$dataregion.groupName'}, creator:{$addToSet: '$dataregion.creator'}, resourceId:{$addToSet:'$resourceId'}, count:{$sum:1} } }, { $match: {count: {$gt:1}} } ], { allowDiskUse: true } );
结果如图:
根据返回的resourceId,groupName_,creator查询出重复的文件组信息,如图:
确认里面数据,删除多余的文件组(直接按Delete键就可以删除)
3-2.脚本修复
直接执行下面脚本: db.SH_D_FILEGROUPS.aggregate( [ { $group: { _id: {groupName_:'$dataregion.groupName', resourceId_:'$resourceId', creator:'$dataregion.creator'}, realId:{$push:'$_id'}, count:{$sum:1} } }, { $match: {count: {$gt:1}} } ], { allowDiskUse: true } ).forEach(function(item) { var length = item.realId.length; /* 直接跳过第一个, 不删除 */ for (i=1; i < length; i++) { var tmpId = item.realId; // 根据_id把原来的文件组查询出来 var fileGroup = db.SH_D_FILEGROUPS.findOne({ "_id": tmpId}); // 备份原始数据 db.FILEGROUP_REPEAT.insert(fileGroup); // 删除重复数据 db.SH_D_FILEGROUPS.deleteOne({"_id": tmpId}); } });
4.修复完成后删除临时索引, 并创建唯一索引,避免再次出现重复。 4-1.删除临时索引 db.SH_D_FILEGROUPS.dropIndex("fileg_temp"); 4-2.创建唯一索引 db.SH_D_FILEGROUPS.createIndex({"resourceId":1,"dataregion.creator":1,"dataregion.groupName":1}, {"unique":true, background: true});
|