mongodb常用操作命令

0x00 前言

mongodb是一款基于分布式文件存储的数据库,具有高性能、可扩展、易部署、易使用等特点。官方也提供了丰富的命令行工具来操作。

0x01 部署mongodb服务

部署mongodb服务可以直接使用docker镜像:

  1. $ docker search mongo
  2. NAME DESCRIPTION STARS OFFICIAL AUTOMATED
  3. mongo MongoDB document databases provide high avai 6656 [OK]
  4. mongo-express Web-based MongoDB admin interface, written w 640 [OK]
  5. tutum/mongodb MongoDB Docker image listens in port 27017 230 [OK]
  6. bitnami/mongodb Bitnami MongoDB Docker Image 109 [OK]
  7. mongoclient/mongoclient Official docker image for Mongoclient, featu 79 [OK]
  8. mongooseim/mongooseim Small docker image for MongooseIM - robust a 19
  9. frodenas/mongodb A Docker Image for MongoDB 18 [OK]
  10. cvallance/mongo-k8s-sidecar Kubernetes side car to setup and maintain a 14 [OK]
  11. centos/mongodb-32-centos7 MongoDB NoSQL database server 8
  12. circleci/mongo CircleCI images for MongoDB 8 [OK]
  13. arm64v8/mongo MongoDB document databases provide high avai 7
  14. istepanov/mongodump Docker image with mongodump running as a cro 6 [OK]
  15. centos/mongodb-36-centos7 MongoDB NoSQL database server 5
  16. eses/mongodb_exporter mongodb exporter for prometheus 5 [OK]
  17. centos/mongodb-26-centos7 MongoDB NoSQL database server 5
  18. webhippie/mongodb Docker images for MongoDB 4 [OK]
  19. requilence/mongodb-backup mongo backup container 4 [OK]
  20. centos/mongodb-34-centos7 MongoDB NoSQL database server 3
  21. neowaylabs/mongodb-mms-agent This Docker image with MongoDB Monitoring Ag 3 [OK]
  22. ansibleplaybookbundle/mongodb-apb An APB to deploy MongoDB. 1 [OK]
  23. ekesken/mongo docker image for mongo that is configurable 1 [OK]
  24. andreasleicher/mongo-azure-backup a docker container to backup a mongodb using 1 [OK]
  25. openshift/mongodb-24-centos7 DEPRECATED: A Centos7 based MongoDB v2.4 ima 1
  26. ccitest/mongo CircleCI test images for Mongo 0 [OK]
  27. targetprocess/mongodb_exporter MongoDB exporter for prometheus 0 [OK]
  28. $ docker pull mongo:latest
  29. $ docker run -itd --name mongo -p 27017:27017 mongo --auth
COPY

此时,mongodb服务已经正常运行起来了,还需要配置下账号。

使用docker exec -it mongo bash命令进入到shell环境后,输入mongo命令进入交互式命令行:

  1. > use admin
  2. switched to db admin
  3. > db.createUser({ user: "root", pwd: "root", roles: [{ role: "root", db: "admin" }] })
  4. Successfully added user: {
  5. "user" : "root",
  6. "roles" : [
  7. {
  8. "role" : "root",
  9. "db" : "admin"
  10. }
  11. ]
  12. }
COPY

权限角色说明:

Read:允许用户读取指定数据库

readWrite:允许用户读写指定数据库

dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile

userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户

clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限

readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限

readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限

userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限

dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限

root:只在admin数据库中可用。超级账号,超级权限

0x02 安装mongo客户端

  1. $ apt install mongodb-clients
COPY

进入mongo shell:

  1. $ mongo ${mongo_server}:${mongo_port} -u ${username} -p ${password} --authenticationDatabase admin
COPY

mongodb中分为不同的数据库,默认数据库为test,使用use db切换数据库时,如果数据库不存在会自动创建。

0x03 常用mongo命令

  1. > show dbs
  2. admin 0.000GB
  3. config 0.000GB
  4. local 0.000GB
  5. > use test
  6. switched to db test
  7. > db
  8. test
  9. > db.table.insert({"title":"drunkdream", "body": "Hello world"})
  10. WriteResult({ "nInserted" : 1 })
  11. > db.table.count()
  12. 1
  13. > db.table.dataSize()
  14. 66
  15. > db.table.insert({"title":"drunkdream123", "body": "Test"})
  16. WriteResult({ "nInserted" : 1 })
  17. > db.table.find().skip(1).limit(1)
  18. { "_id" : ObjectId("5e706e4651e5f0d32c1eb3e0"), "title" : "drunkdream123", "body" : "Test" }
  19. > db.table.find({title: /^drunkdream/})
  20. { "_id" : ObjectId("5e706a7051e5f0d32c1eb3df"), "title" : "drunkdream", "body" : "Hello world" }
  21. { "_id" : ObjectId("5e706e4651e5f0d32c1eb3e0"), "title" : "drunkdream123", "body" : "Test" }
  22. > db.getCollectionNames()
  23. [ "table" ]
  24. > db.printCollectionStats()
  25. table
  26. {
  27. "ns" : "test.table",
  28. "size" : 66,
  29. "count" : 1,
  30. "avgObjSize" : 66,
  31. "storageSize" : 20480,
  32. "capped" : false,
  33. ...
  34. }
  35. > db.stats()
  36. {
  37. "db" : "test",
  38. "collections" : 1,
  39. "views" : 0,
  40. "objects" : 1,
  41. "avgObjSize" : 66,
  42. "dataSize" : 66,
  43. "storageSize" : 4096,
  44. "numExtents" : 0,
  45. "indexes" : 1,
  46. "indexSize" : 4096,
  47. "scaleFactor" : 1,
  48. "fsUsedSize" : 34517733376,
  49. "fsTotalSize" : 109059317760,
  50. "ok" : 1
  51. }
COPY

find命令支持的查询条件:

$gt: >

$lt: <

$gte: >=

$lte: <=

$ne: !=

例如:{age: {$gte: 23, $lte: 26}}

0x04 其它mongo命令

  • db.table.drop() - 删除集合

  • db.dropDatabase() - 删除当前数据库

  • db.repairDatabase() - 修复数据库

  • db.getPrevError() - 查询之前的错误信息

0x05 迁移数据

mongodump

  1. $ mongodump -h ${mongo_server} --port ${mongo_port} -d ${db_name} -o ${save_dir} -u ${username} -p ${password} --authenticationDatabase admin
COPY

该命令可以将整个数据库dump到本地,如果只需要dump其中的一个集合,可以使用以下参数:--collection ${coll_name}

mongorestore

  1. $ mongorestore -h ${mongo_server} --port ${mongo_port} -d ${db_name} ${save_dir}/${db_name} -u ${username} -p ${password} --authenticationDatabase admin
COPY

该命令可以将备份下来的数据库还原到目标数据库中,修改-d参数可以修改目标数据库的名称。

如果目标数据库存在,需要增加--drop参数进行还原,避免报错。

迁移脚本

写了个简单的迁移脚本:

  1. # -*- coding: utf-8 -*-
  2. import argparse
  3. import os
  4. import tempfile
  5. import time
  6. def sync_mongo(src_host, src_port, dst_host, dst_port, db, collection=None, username='root', password='root', drop=False):
  7. time0 = time.time()
  8. backup_dir = tempfile.mkdtemp('.backup').split(os.path.sep)[-1]
  9. auth_cmdline = ' -u %s -p %s --authenticationDatabase admin' % (username, password)
  10. cmdline = 'mongodump -h %s --port=%d -d %s -o %s' % (src_host, src_port, db, backup_dir)
  11. if collection:
  12. cmdline += ' --collection %s' % collection
  13. cmdline += auth_cmdline
  14. print(cmdline)
  15. os.system(cmdline)
  16. time1 = time.time()
  17. print('backup %s from %s complete, cost %fs\n' % (db, src_host, time1 - time0))
  18. cmdline = 'mongorestore -h %s --port=%d -d %s %s/%s' % (dst_host, dst_port, db, backup_dir, db)
  19. if drop:
  20. cmdline += ' --drop'
  21. cmdline += auth_cmdline
  22. print(cmdline)
  23. os.system(cmdline)
  24. time1 = time.time()
  25. print('sync data from %s/%s to %s/%s complete, total cost %fs' % (src_host, db, dst_host, db, time1 - time0))
  26. if __name__ == '__main__':
  27. parser = argparse.ArgumentParser(description='Mongodb sync data script.')
  28. parser.add_argument('src_host', help='source host')
  29. parser.add_argument('dst_host', help='destination host')
  30. parser.add_argument('db_name', help='database name')
  31. parser.add_argument('--src-port', type=int, help='source port', default=27017)
  32. parser.add_argument('--dst-port', type=int, help='destination port', default=27017)
  33. parser.add_argument('--collection', help='collection to sync')
  34. parser.add_argument('--drop', help='drop collection before restore', default=False, action='store_true')
  35. args = parser.parse_args()
  36. sync_mongo(args.src_host, args.src_port, args.dst_host, args.dst_port, args.db_name, args.collection, drop=args.drop)
COPY

增量备份

oploglocal数据库中的一个固定集合,Secondary就是通过查看Primary的oplog这个集合来进行复制的。每个节点都有oplog,记录这从主节点复制过来的信息,这样每个成员都可以作为同步源给其他节点。

  1. FROM mongo:3.6.3
  2. RUN printf "mongod --replSet rs0 &\nsleep 2\nmongo local --eval \"rs.initiate()\"\nmongo local --eval \"rs.conf()\"\nsleep infinity" > /usr/local/bin/init-mongo.sh
  3. ENTRYPOINT "sh /usr/local/bin/init-mongo.sh"
COPY

可以使用上面的Dockerfile生成一个自动开启oplog的容器。

  1. rs0:PRIMARY> use local
  2. switched to db local
  3. rs0:PRIMARY> db.getCollectionNames()
  4. [
  5. "me",
  6. "oplog.rs",
  7. "replset.election",
  8. "replset.minvalid",
  9. "startup_log",
  10. "system.replset",
  11. "system.rollback.id"
  12. ]
  13. rs0:PRIMARY> db.oplog.rs.find()
  14. { "ts" : Timestamp(1584972071, 1), "h" : NumberLong("7155205047322550757"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:01:11.490Z"), "o" : { "msg" : "initiating set" } }
  15. { "ts" : Timestamp(1584972073, 1), "t" : NumberLong(1), "h" : NumberLong("3098310879886849971"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:01:13.536Z"), "o" : { "msg" : "new primary" } }
  16. { "ts" : Timestamp(1584972073, 2), "t" : NumberLong(1), "h" : NumberLong("7423790971296558722"), "v" : 2, "op" : "c", "ns" : "config.$cmd", "ui" : UUID("ac77fd00-b096-4062-b7ca-ac7f187c1fc7"), "wall" : ISODate("2020-03-23T14:01:13.576Z"), "o" : { "create" : "transactions", "idIndex" : { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "config.transactions" } } }
  17. { "ts" : Timestamp(1584972073, 3), "t" : NumberLong(1), "h" : NumberLong("-2051859930978240465"), "v" : 2, "op" : "c", "ns" : "admin.$cmd", "ui" : UUID("4a0104be-5d4f-49db-9204-d778d83c64dd"), "wall" : ISODate("2020-03-23T14:01:13.606Z"), "o" : { "create" : "system.keys", "idIndex" : { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "admin.system.keys" } } }
  18. { "ts" : Timestamp(1584972073, 4), "t" : NumberLong(1), "h" : NumberLong("-4130342990996856185"), "v" : 2, "op" : "i", "ns" : "admin.system.keys", "ui" : UUID("4a0104be-5d4f-49db-9204-d778d83c64dd"), "wall" : ISODate("2020-03-23T14:01:13.606Z"), "o" : { "_id" : NumberLong("6807403218608324609"), "purpose" : "HMAC", "key" : BinData(0,"h/kcD++ijF/AUzwUqqXHTKG4Jwk="), "expiresAt" : Timestamp(1592748073, 0) } }
  19. { "ts" : Timestamp(1584972073, 5), "t" : NumberLong(1), "h" : NumberLong("3814221418240704217"), "v" : 2, "op" : "i", "ns" : "admin.system.keys", "ui" : UUID("4a0104be-5d4f-49db-9204-d778d83c64dd"), "wall" : ISODate("2020-03-23T14:01:13.606Z"), "o" : { "_id" : NumberLong("6807403218608324610"), "purpose" : "HMAC", "key" : BinData(0,"4Ds1uk/bTNYytP0hMkXX9ilgz38="), "expiresAt" : Timestamp(1600524073, 0) } }
  20. { "ts" : Timestamp(1584972093, 1), "t" : NumberLong(1), "h" : NumberLong("7954269847273383577"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:01:33.576Z"), "o" : { "msg" : "periodic noop" } }
  21. { "ts" : Timestamp(1584972103, 1), "t" : NumberLong(1), "h" : NumberLong("1461838052525134608"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:01:43.576Z"), "o" : { "msg" : "periodic noop" } }
  22. { "ts" : Timestamp(1584972113, 1), "t" : NumberLong(1), "h" : NumberLong("-2878317090536866771"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:01:53.576Z"), "o" : { "msg" : "periodic noop" } }
  23. { "ts" : Timestamp(1584972123, 1), "t" : NumberLong(1), "h" : NumberLong("8386919002466516906"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:02:03.577Z"), "o" : { "msg" : "periodic noop" } }
  24. { "ts" : Timestamp(1584972133, 1), "t" : NumberLong(1), "h" : NumberLong("3752867656297542596"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:02:13.577Z"), "o" : { "msg" : "periodic noop" } }
  25. { "ts" : Timestamp(1584972143, 1), "t" : NumberLong(1), "h" : NumberLong("-6914327186052916342"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:02:23.577Z"), "o" : { "msg" : "periodic noop" } }
  26. { "ts" : Timestamp(1584972153, 1), "t" : NumberLong(1), "h" : NumberLong("4905151581311694538"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:02:33.577Z"), "o" : { "msg" : "periodic noop" } }
  27. { "ts" : Timestamp(1584972163, 1), "t" : NumberLong(1), "h" : NumberLong("2195348018262890539"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:02:43.577Z"), "o" : { "msg" : "periodic noop" } }
  28. { "ts" : Timestamp(1584972173, 1), "t" : NumberLong(1), "h" : NumberLong("-945081611143254792"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:02:53.577Z"), "o" : { "msg" : "periodic noop" } }
  29. { "ts" : Timestamp(1584972183, 1), "t" : NumberLong(1), "h" : NumberLong("-8550993957527781683"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:03:03.577Z"), "o" : { "msg" : "periodic noop" } }
  30. { "ts" : Timestamp(1584972193, 1), "t" : NumberLong(1), "h" : NumberLong("2027336719720729041"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:03:13.578Z"), "o" : { "msg" : "periodic noop" } }
  31. { "ts" : Timestamp(1584972203, 1), "t" : NumberLong(1), "h" : NumberLong("8383046467552376073"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:03:23.578Z"), "o" : { "msg" : "periodic noop" } }
  32. { "ts" : Timestamp(1584972213, 1), "t" : NumberLong(1), "h" : NumberLong("-2718017147947765099"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:03:33.578Z"), "o" : { "msg" : "periodic noop" } }
  33. { "ts" : Timestamp(1584972223, 1), "t" : NumberLong(1), "h" : NumberLong("4265940161146074795"), "v" : 2, "op" : "n", "ns" : "", "wall" : ISODate("2020-03-23T14:03:43.578Z"), "o" : { "msg" : "periodic noop" } }
  34. Type "it" for more
COPY

可以看到,oplog.rs集合里已经有数据了。

备份数据命令:

  1. $ mongodump -h ${mongo_server} --port ${mongo_port} -o ${save_dir} -u ${username} -p ${password} --authenticationDatabase admin --oplog
COPY

使用--oplog参数时不能指定数据库,只能全量备份

还原数据命令:

  1. $ mongorestore -h ${mongo_server} --port ${mongo_port} -u ${username} -p ${password} --authenticationDatabase admin --oplogReplay --dir ${save_dir}
COPY
分享
0 comments
Anonymous
Markdown is supported

Be the first guy leaving a comment!