MongoDB日常运维命令合计

1、查询当前库慢查询的SQL:

db.system.profile.find({millis:{$gt:5000}}).sort({ts:-1}) ---查询时间超过5s的最近SQL

 只显示某些重要指标:

db.system.profile.find({millis:{$gt:1000}},{allUsers:1,client:1,millis:1,nns:1,op:1,query:1,ts:1}).sort({ts:-1})

切割日志文件

db.runCommand({logRotate:1})

但是当实例量非常大的时候,可以直接用如下OS层面的操作来切割日志文件

killall -SIGUSR1 mongod

2、查看当前活跃的连接,运行时间超过3秒,在db1库上进行的操作

db.currentOp({"active":true,"ns":/^exclusive_ipdb./})

2.1、 查询某个IP发起的所有活跃进程

db.currentOp(

{

    "active":true,

    //"secs_running":{"$gt":3},

    "ns":/^exclusive_ipdb\./,

    "op" : "update",

    //"client":/^10.64.92.74/

}

)

打印某个库下所有活跃连接的IP地址

db.currentOp(

{

    "active":true,

"ns":/^exclusive_ipdb\./,

   // "secs_running":{"$gt":3}

}

).inprog.forEach(function(x){

    print("ip:"+x["client"]+x["ns"])

})

mongos下的活跃连接查看

db.currentOp({"active":true}).inprog.forEach(function(x){

    print("ip:"+x["client_s"]+x["ns"])

})

查看某一个client ip下的连接

db.currentOp(true).inprog.forEach(function(x){

    var client_str = new String(x["client_s"])

    var client_arr = client_str.split(':')

    var client_ip = client_arr[0]

    if (client_ip == "**10.160.158.93**")

    {

        print("ip:"+client_str+x["ns"]);

        print(tojson(x));

    }

})

kill掉相关进程

db.killOp(164686820) ---括号里直接写opid

db.killOp("r37504-2699:17601") ---kill 分片的session需要拷贝整个opid

mongod批量删除进程

db.currentOp(

{

    "active":true,

    "ns":/^zhike_im/

}

).inprog.forEach(function(x){

    print("killed:"+x["client"]+" : "+x["ns"]);        

    db.killOp(x["opid"]);    

})

批量kill掉某一种操作

"op" : "remove" //删除操作

"op" : "query" //查询操作

"op" : "update" //更新操作

循环kill某些SQL

var count=0;

while (count < 100) {

db.currentOp({

    "active": true,

    "op": "query",

    "ns": /^argus_antifraud\./,

    "secs_running": {"$gt": 1}

}).inprog.forEach(function(x) {

    print("opid:"+x["opid"]+" : "+x["ns"]+"--secs_running:"+x["secs_running"]+ "--ip:"+x["client"]);

     db.killOp(x["opid"]);    

});

print(count);

sleep(1000);

count++;

}

在mongos上批量kill进程

db.currentOp(

{

    "active":true,

    "ns":/^netlab_pdns.flint/,

    "op" : "remove"

}

).inprog.forEach(function(x){

    print("killed:"+x["client_s"]+" : "+x["ns"]);        

    db.killOp(x["opid"]);    

})

kill掉全表扫描的操作

db.currentOp(

{

   "active":true,

    "ns":/^res\./,

    "planSummary" : "COLLSCAN"

}

).inprog.forEach(function(x){

    print("killed:"+x["client_s"]+" : "+x["ns"]);        

    db.killOp(x["opid"]);    

})

3.锁相关

3.1、查看当前等待锁状态的进程id

db.currentOp().inprog.forEach(

function(item)

{if (item.waitingForLock == true)

    {print(item.opid);}

});

3.2、查看当前持有X锁状态的session

db.currentOp(

{

    "active":true,

    //"waitingForLock" : true,    //等待获取锁

    $or:[{"locks.Global":"W"},{"locks.Database":"W"}],    //当前持有X锁的session

    //"locks.Database" : "W"

}

)

3.3 打印锁信息

db.currentOp().inprog.forEach(function(item){print(tojson(item.locks));})

4、列出所有的连接信息

注:不加true的话表示正在运行的

db.currentOp(true)

在系统层面查看当前端口27047的连接情况(IP地址产生的连接数)

[mongo@mongosms01 ~]netstat -nal |grep ":27047"|awk '{print5}'|awk -F ':' '{print $1}' | sort | uniq -c | sort -nr

633 10.26.231.103

472 10.26.231.106

378 10.26.231.101

345 10.26.231.102

5、查看当前实例的参数

db.runCommand({getParameter:"*"})

获取当前mongod 或 mongos启动时的配置文件参数

db.serverCmdLineOpts()

6、查看集合和文件的对应关系

db.getMongo().getDBNames().forEach(function(x) {

db.getSiblingDB(x).getCollectionNames().forEach(function(y) {

var z = db.getSiblingDB(x).getCollection(y).stats({

  indexDetails: true,

  scale: 1024 * 1024 * 1024

});

print(x + "." + y + ", " + z["storageSize"] + " = " + tojson(z["wiredTiger"]["uri"]).replace(/^.icket*:/, "").replace(/.$/, ".wt"));

for ( var key in z["indexSizes"]) {

  print(x + "." + y + "." + key + ", " + z["indexSizes"][key] + " = " + tojson(z["indexDetails"][key]["uri"]).replace(/^.*:/, "").replace(/.$/, ".wt"));

}

})

})

查看库下集合的大小

//---数据文件大小

db.getCollectionNames().forEach(function(y) {

var z = db.getCollection(y).stats({

  indexDetails: true,

  scale: 1024 * 1024

})

print(y + "--------storageSize:-----" + z["storageSize"] +"MB");

})

//---集合总大小(包含索引)

db.getCollectionNames().forEach(function(y) {

var z = db.getCollection(y).stats({scale: 1024 * 1024 * 1024});

var total_size=0;

var storageSize_GB=z["storageSize"];

var indexSize_GB=z["totalIndexSize"];

total_size+=storageSize_GB

total_size+=indexSize_GB

print(y + "---total_size:" + total_size +"GB");

})

查看集合的索引大小

//---集合索引总大小

db.getCollectionNames().forEach(function(y) {

var z = db.getCollection(y).stats({scale: 1024 * 1024 });

var total_size=0;

var indexSize_GB=z["totalIndexSize"];

print(y + "---total_index:" + indexSize_GB +"MB");

})

7、查看当前库下所有表的索引名

db.getCollectionNames().forEach(function(x){

var y = db.getCollection(x).getIndexes();

print(y[0].ns)

for (var i=0,len=y.length;i<len;i++){

    print(y[i].name)

}

})

7.1 提取库下某一个表的索引创建语句

var x = 'isc_strategy_user'

var y = db.getCollection(x).getIndexes();

for (var i=0,len=y.length;i<len;i++){

var idx_info=y[i];    

if (idx_info.name != "_id_")

{

    var fields=idx_info.key;

    delete idx_info['v'];

    delete idx_info['key'];

    delete idx_info['ns'];        

    print("db."+x+".createIndex\("+tojson(fields)+","+tojson(idx_info)+"\)");

}

}

7.2 提取库下所有表的索引创建语句(MongoDB 5.0之前)

db.getCollectionNames().forEach(function(collname){

if (collname.substring(0,6) == "system"){

    return;

}

var y = db.getCollection(collname).getIndexes();

for (var i=0,len=y.length;i<len;i++){

    var idx_info=y[i];    

    if (idx_info.name != "_id_")

    {

        var fields=idx_info.key;

        delete idx_info['v'];

        delete idx_info['key'];

        delete idx_info['ns'];

        if ('background' in idx_info){

            print("db."+collname+".createIndex\("+tojson(fields)+","+tojson(idx_info)+"\)");

        }

        else {

            print("db."+collname+".createIndex\("+tojson(fields)+","+tojson(idx_info)+",{background:true}\)");

        }    

    }

}

})

提取库下所有表的索引创建语句(MongoDB 5.0及以后)

db.getCollectionNames().forEach(function(collname){

if (collname.substring(0,6) == "system"){

    return;

}

var y = db.getCollection(collname).getIndexes();

for (var i=0,len=y.length;i<len;i++){

    var idx_info=y[i];    

    if (idx_info.name != "_id_")

    {

        var fields=idx_info.key;

        delete idx_info['v'];

        delete idx_info['key'];

        delete idx_info['ns'];

        if ('background' in idx_info){

            print("db."+collname+".createIndex\("+**JSON.stringify**(fields)+","+**JSON.stringify**(idx_info)+"\)");

        }

        else {

            print("db."+collname+".createIndex\("+**JSON.stringify**(fields)+","+**JSON.stringify**(idx_info)+",{background:true}\)");

        }    

    }

}

})

注:新版本后,原旧MongoDB shell的一些内置函数不再支持,例如tojson(), 而在新版本mongosh中可以直接用JavaScript的内置方法来替代;

7.3 提取所有库下所有表的索引创建语句

db.getMongo().getDBNames().forEach(function(dbname) {

if (dbname == "admin" ||dbname == "local" || dbname == "config"){

    return;

}

print("use "+dbname);

var dbname="utas";

db.getSiblingDB(dbname).getCollectionNames().forEach(function(collname){

    if (collname.substring(0,6) == "system"){

        return;

    }

    var y = db.getSiblingDB(dbname).getCollection(collname).getIndexes();

    for (var i=0,len=y.length;i<len;i++){

        var idx_info=y[i];    

        if (idx_info.name != "_id_")

        {

            var fields=idx_info.key;

            delete idx_info['v'];

            delete idx_info['key'];

            delete idx_info['ns'];

            if ('background' in idx_info){

                print("db."+collname+".createIndex\("+tojson(fields)+","+tojson(idx_info)+"\)");

            }

            else {

                print("db."+collname+".createIndex\("+tojson(fields)+","+tojson(idx_info)+",{background:true}\)");

            }    

        }

    }

})

})

8、查看当前在建索引进度

db.currentOp({"active":true, "msg":/^Index/}).inprog.forEach(function(item){ print(item.command.createIndexes+":"+item.msg+" run_time:"+item.secs_running+"s");})

db.currentOp({"active":true, "msg":/^Index/}).inprog.forEach(function(item){ print(item.command.createIndexes+":"+item.command.indexes[0].name+":"+item.msg+" run_time:"+item.secs_running+"s");})

db.currentOp({"active":true, "msg":/^Index/}).inprog.forEach(function(item){ print(tojson(item))})

3.4版本

db.currentOp({"active":true, "msg":/^Index/}).inprog.forEach(function(item){ print(tojson(item.msg))})

mongos分片集群查看索引进度

db.currentOp({"active":true, "msg":/^Index/}).inprog.forEach(function(item){ print(tojson(item.opid));print(tojson(item.msg))})

9、查看初始化节点的同步进度

当你rs.add()新加入一个空节点时,会进行数据的初始化同步,此时如果你想查看同步到什么位置了,可以通过log日志查看

PROD [mongo@db02-drccn1mong sms]#tail -f /data/logs/rs1_logs/rs1.log | grep "clone progress"

2019-04-23T16:31:08.006+0800 I - [repl writer worker 10] APP_MSG_GW.Message collection clone progress: 226280033/462630280 48% (documents copied)

2019-04-23T16:32:18.671+0800 I - [repl writer worker 10] APP_MSG_GW.Message collection clone progress: 229333629/462630280 49% (documents copied)

2019-04-23T16:33:27.810+0800 I - [repl writer worker 10] APP_MSG_GW.Message collection clone progress: 232224979/462630280 50% (documents copied)

2019-04-23T16:34:53.254+0800 I - [repl writer worker 10] APP_MSG_GW.Message collection clone progress: 235135641/462630280 50% (documents copied)

2019-04-23T16:36:15.938+0800 I - [repl writer worker 10] APP_MSG_GW.Message collection clone progress: 238116155/462630280 51% (documents copied)

10、临时备份少量数据:

类似于insert into table_bk select xxxx from t1 where field=xxx;

db.t1.find({username:'xxx'}).forEach(function(x){

db.t1_bk.insert(x);

});

11、获取当前库下所有表的可收缩空间:

db.getCollectionNames().forEach(function(x){

var y = db.getCollection(x).stats().wiredTiger['block-manager']['file bytes available for reuse'];

print(x +":"+ y/1024/1024);

})

12、查看server上某个端口实例的连接数情况

netstat -nal |grep ":27097"|awk '{print 5}'|awk -F ':' '{print1}' | sort | uniq -c | sort -nr

188 10.67.4.6

164 10.67.231.92

156 10.67.4.8

150 10.67.4.7

13.Sharding基本操作

查看分片状态:sh.status() 或 db.printShardingStatus()

查看分片库有哪些:

use config

db.databases.find( { "partitioned": true } )

查看当前有哪些分片:db.adminCommand( { listShards : 1 } )

14.权限

查看角色权限:

db.runCommand({rolesInfo:'read',showPrivileges:1})

分配权限给角色

db.grantPrivilegesToRole("dbarole",[{resource:{db:"config","collection":"collections"},actions:["find"]}])

回收权限从角色

db.revokePrivilegesFromRole("dbarole",[{resource:{db:"config","collection":"collections"},actions:["find"]}])

批量回收角色上的权限

db.runCommand({rolesInfo:'dbarole',showPrivileges:1}).roles[0].inheritedPrivileges.forEach(function(x)

{print('db.revokePrivilegesFromRole("dbarole",[{resource:'+ tojson(x['resource']) + ',actions:["dropIndex"]}])');}

)

注:当然你也可以使用以上脚本来生成批量赋予权限的命令;

15.获取sharding下的节点信息

mongos> db.adminCommand({listShards:1}).shards.forEach(function(x){print(x["host"]);})

7565/10.208.134.95:7565,10.208.61.223:7565

7567/10.208.136.238:7567,10.208.37.36:7567

7250/10.208.58.54:7250,10.208.64.117:7250

7997/10.145.70.113:7997,10.208.61.145:7997

16.获取分片集合的总行数

有时候直接coll.count()得出的结果是统计信息的结果,有可能不准确,此时我们可以使用如下命令:

db.collName.aggregate([

{group:{"_id":"", "count":{"sum":1}}}

])

17.获取sharding架构下,数据总大小

var data=db.stats()['raw']

total_data_size=0

total_index_size=0

total_storageSize=0

for(i in data){

var shard_data=data[i];

var dataSize=shard_data['dataSize'];

var indexSize=shard_data['indexSize'];

var storageSize=shard_data['storageSize'];

total_data_size+=dataSize

total_index_size+=indexSize

total_storageSize+=storageSize

}

print("total_data_size_TB:"+Math.round(total_data_size/1024/1024/1024/1024))

print("total_index_size_TB:"+Math.round(total_index_size/1024/1024/1024/1024))

print("total_storageSize:"+Math.round(total_index_size/1024/1024/1024/1024))

18.获取sharding架构下,每个主分片的storageSize大小

var data=db.stats()['raw']

total_data_size=0

total_index_size=0

total_storageSize=0

for(i in data){

var shard_data=data[i];

var shard_name=i.split(':').slice(-1)[0];

var dataSize=shard_data['dataSize'];

var indexSize=shard_data['indexSize'];

var storageSize=shard_data['storageSize'];

print(shard_name+":"+Math.round(storageSize/1024/1024/1024));

}

19.查看数据库数量

当数据库数量非常多时,我们可能无法直观的得到库的数量,可以通过如下命令查看到

db.runCommand({listDatabases:1}).databases.length

20.提取分片集合的分片结构

即生成集合的分片创建语句,在config库下执行,方便在新库上建立集合分片

db.getSiblingDB('config').collections.find().forEach(function(x){

if (x["dropped"] == true){

    return;

}

var ns = x["_id"]

var shard_key = x["key"]

print("sh.shardCollection\(\"" + ns + "\"," + tojson(shard_key) + "\)");})

21.查看collection下索引的调用情况:

db.MyColl.aggregate([{ $indexStats:{} }]).pretty()

22.降低某一个副本集角色的被选举权

rs.freeze(seconds)

23.批量查询库

当库数量非常大,需要根据库名前缀来查询,可以使用如下脚本:

db.getMongo().getDBNames().forEach(function(dbname) {

if (dbname == "admin" ||dbname == "local" || dbname == "config"){

    return;

}

var regex=/^u/

if (regex.test(dbname)){

    print(dbname);

}

    })

注:可以根据需求来变更regex的正则规则,正则规则参考:https://juejin.cn/post/6844903487155732494

批量删除库:

db.getMongo().getDBNames().forEach(function(dbname) {

if (dbname == "admin" ||dbname == "local" || dbname == "config"){

    return;

}

var regex=/^haha/

if (regex.test(dbname)){

    print(dbname);

    use 

}

    })

24.查看当前所有库下的集合数量

有时候DB数量太多,我们想要只要每一个库下的集合数量

db.getMongo().getDBNames().forEach(function(dbname) {

if (dbname == "admin" ||dbname == "local" || dbname == "config"){

    return;

}

var coll_infos=db.getSiblingDB(dbname).getCollectionNames().length;

print(dbname," coll count: ",coll_infos);

})

25.获取集合中每行的字段数量

因为有的时候业务会随意写数据,每个document的field字段个数也不一样,所以如果想要统计每行的字段数量,可以参考如下脚本:

db.tb2.find().forEach(function(x){

var count=Object.keys(x).length;

print(x["_id"] + ":"+count);

db.tmp1.insert({"_id":x["_id"],"count":count});

})

注:这种是我想到的初级版本,如果集合数据量很大的话,会消耗较多资源

26.强制将剩余可用节点reconfig副本集

有时候副本由于小于大多数,导致副本集不可写,随可以使用如下脚本强制将副本集变为可写

// 获取可用的节点

var availableHost=[];

rs.status().members.forEach(function(obj){

    if (obj.stateStr == "SECONDARY" || obj.stateStr == "PRIMARY"){

            availableHost.push(obj.name);

            print(obj.name);

    }

});

// 获取重新配置的可用节点

var new_conf=rs.config();

rs.config().members.forEach(function(obj,index){

if (!availableHost.includes(obj.host)){

    new_conf.members.splice(index,1);

}

});

// 重新配置

rs.reconfig(new_conf,{force:true});

27、获取当前库下所有表的可收缩空间(数据节点):

db.getCollectionNames().forEach(function(x){

var y = db.getCollection(x).stats().wiredTiger['block-manager']['file bytes available for reuse'];

print(x +"    : "+ Math.round(y/1024/1024) + " MB");

})

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容