现象:
MongoDB 发生大面积连接、执行异常
监控:
其它服务器资源都很正常,但有大量globalLock
原因分析:
1、执行db.serverStatus().globalLock
{
"totalTime" : NumberLong(5064962000),
"currentQueue" : {
"total" : NumberInt(13),
"readers" : NumberInt(9),
"writers" : NumberInt(4)
},
"activeClients" : {
"total" : NumberInt(236),
"readers" : NumberInt(5),
"writers" : NumberInt(23)
}
}
currentQueue > 0,activeClients > 0,其它服务器资源都很正常,因此说明单个请求的处理时间太慢需要优化。
2、使用db.currentOp()查看活跃连接的执行情况,可了解连接语法执行的具体情况。
3、查询慢操作连接:
var j = 0;
var _DEF_TIME = 10; //设置慢查询时间
var currentOPs = db.currentOP().inprog;
for (var i in currentOPs) {
var op = "";
var opid;
var memProg = {}
if (typeof(undefined) == typeof(currentOPs[i])) {
continue;
}
memProg = currentOPs[i];
op = memProg.op;
opid = memProg.opid;
// if (op == "query")
{ // 此处过滤类型为查询,如果是更新操作为"update"
if (memProg.hasOwnProperty('secs_running')) {
var useTime = memProg.secs_running;
if (useTime >= _DEF_TIME) {
print("index: " + i + ", secs_running " + useTime + "s, op: " + memProg.op + ", ns: " + memProg.ns + ", msg: " + memProg.msg);
}
}
}
}
其中的msg信息,可查看到索引创建进度:
4、使用脚本kill查询时间超过指定时间的慢查询连接:
var j = 0;
var _DEF_TIME = 10; //设置慢查询时间
var currentOPs = db.currentOP().inprog;
for (var i in currentOPs) {
var op = "";
var opid;
var memProg = {}
if (typeof(undefined) == typeof(currentOPs[i])) {
continue;
}
memProg = currentOPs[i];
op = memProg.op;
opid = memProg.opid;
print(i);
if (op == "query") { // 此处过滤类型为查询,如果是更新操作为"update"
if (memProg.hasOwnProperty('secs_running')) {
var useTime = memProg.secs_running;
if (useTime >= _DEF_TIME) {
db.killOp(opid);
j++;
print("killed " + j + " Query Operation!");
}
}
}
}
解决方案:
使用阿里云的CloudDBA生成索引推荐,优化查询效率低的语法:
合并推荐索引,实际的key应该是最左边的字段,course_id字段应该可以不用建独立索引:
参考:
网友评论