MongDB5踩坑之旅

1,099 阅读12分钟

简介

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的,此文档主要记录MongoDB5在linux机器上的安装、配置、及node连接方式等,
更多操作可参考:www.runoob.com/mongodb/nos…

安装部署

1:安装

这里我们选择 tgz 下载,下载完安装包,并解压 tgz


[root@test /]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-5.0.0.tgz        # 下载

[root@test /]# tar -zxvf mongodb-linux-x86_64-rhel80-5.0.0.tgz        # 解压

[root@test /]# mv mongodb-linux-x86_64-rhel80-5.0.0  /usr/local/mongodb5        # 将解压包拷贝到指定目录(实际看个人情况,路径不一定要相同)

MongoDB的可执行文件位于bin目录下,如果需要全局使用相关命令,要将其添加到PATH路径中


[root@test /]# export PATH=<mongodb-install-directory>/bin:$PATH

<mongodb-install-directory>为你 MongoDB 的安装路径。如本文的 /usr/local/mongodb5


[root@test /]# export PATH=/usr/local/mongodb5/bin:$PATH

上面的添加PATH方式在部分机器上可能无效,可以使用这种方式,把其相关命令链接到全局


[root@test /]# ln -s /usr/local/mongodb5/bin/mongo /usr/local/bin/mongo
[root@test /]# ln -s /usr/local/mongodb5/bin/mongod /usr/local/bin/mongod 

2:配置

2.1 创建数据库和日志目录

默认情况下 MongoDB 启动后会初始化以下两个目录:

  • 数据存储目录:/var/lib/mongodb
  • 日志文件目录:/var/log/mongodb

我们在启动前可以先创建这两个目录并设置当前用户有读写权限(实际看个人情况去创建目录,路径不一定要相同):


[root@test /]# mkdir -p /usr/local/mongodb5/datas
[root@test /]# mkdir -p /usr/local/mongodb5/logs
[root@test /]# chown `whoami` /usr/local/mongodb5/datas     # 设置权限
[root@test /]# chown `whoami` /usr/local/mongodb5/logs      # 设置权限

2.2 创建mongodb配置文件

创建配置文件夹


[root@test /]# mkdir -p  /usr/local/mongodb5/etc

创建配置文件mongodb.conf


[root@test /]# cd /usr/local/mongodb5/etc
[root@test etc]# vi mongodb.conf

内容如下:

systemLog:
  destination: file
  path: "/usr/local/mongodb5/logs/mongodb.log" # 指定日志文件的路径
  logAppend: true # 是否追加方式写入日志,默认True
storage:
  dbPath: "/usr/local/mongodb5/datas" # 指定数据存储路径
  journal:
    enabled: true # 启用日志文件,默认启用
processManagement:
  fork: true # 是否以守护进程方式运行,默认false
net:
  bindIp: 127.0.0.1 # 设置ip
  port: 27017 # 设置端口
  

2.3 服务的启动和停止

以命令参数方式启动


[root@test /]# mongod --dbpath /usr/local/mongodb5/datas --logpath /usr/local/mongodb5/logs/mongodb.log --fork

以配置文件方式启动(-f 或 --config)


[root@test /]# mongod -f /usr/local/mongodb5/etc/mongodb.conf

停止服务


[root@test /]# mongod --shutdown --dbpath /usr/local/mongodb5/datas   # 需要指定数据存储路径

2.4 加入开机自启

debian12系统,创建/etc/systemd/system/mongod.service文件,写入以下内容

[Unit]
Description=MongoDB Database Server
After=network.target

[Service]
Type=forking
Environment="OPTIONS=--quiet -f /usr/local/mongodb5/etc/mongod.conf"
ExecStart=/usr/local/mongodb5/bin/mongod -f /usr/local/mongodb5/etc/mongodb.conf
ExecStop=/usr/local/mongodb5/bin/mongod --shutdown --dbpath /usr/local/mongodb5/datas
Restart=always

[Install]
WantedBy=multi-user.target
[root@test /]# sudo systemctl daemon-reload   #刷新配置(在启动前,必须先执行,否则报警告)
[root@test /]# sudo systemctl start mongod    #启动服务
[root@test /]# sudo systemctl stop mongod     #关闭服务
[root@test /]# sudo systemctl enable mongod   #服务加入开机自启
[root@test /]# sudo systemctl status mongod   #查看状态

3:权限

3.1 权限、角色说明

角色:


数据库用户角色:read、readWrite
数据库管理角色:dbAdmin、dbOwner、userAdmin
集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager
备份恢复角色:backup、restore
所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
超级用户角色:root

权限:


Read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限
root:只在admin数据库中可用。超级账号,超级权限

总结:


1:mongodb是没有默认管理员账号,所以要先切换到admin数据库添加管理员账号,再开启权限认证
2:账号只能在创建时所处的那个数据库登录,包括管理员账号
3:账号的权限是根据创建时指定的db和roles来的

创建账号:db.createUser({ user: "test", pwd: "12345", roles: [{ role: "readWrite", db: "blog" }]})
删除账号:db.dropUser('test')

3.2 添加/删除账号

进入MongoDB 后台管理 Shell(使用mongo命令)


[root@test ~]# mongo
MongoDB shell version v5.0.0
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("7cc650b5-d449-4cc9-958c-bcc9ecbc8134") }
MongoDB server version: 5.0.0
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
We recommend you begin using "mongosh".
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
>

查看所处数据库(db),进入shell后台后,默认处在test数据库

> db
test
>

查看有哪些数据库(show dbs),默认有以下三个数据库


> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
>

切换到admin数据库(use <db_name>)


> use admin      # 如果数据库存在,则切换到指定数据库,如果不存在,则创建数据库并切换到该数据库。
switched to db admin
> db
admin
>

创建超级管理员账号(db.createUser)
多个权限使用:roles: [{role:'角色1', db: '数据库1'},{role:'角色2', db: '数据库2'}]


> use admin
switched to db admin

> db
admin

> db.createUser({ user: "root", pwd: "root", roles: [{ role: "root", db: "admin" }] })  # 创建账号
Successfully added user: {
        "user" : "root",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
> db.auth('root','root') # 验证创建的账号否可以通过用户认证
1
>

查看有哪些账号(show users)

> show users
{
        "_id" : "admin.root",
        "userId" : UUID("bd3c86c8-c9f2-4f1e-8dfe-90b912c17044"),
        "user" : "root",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ],
        "mechanisms" : [
                "SCRAM-SHA-1",
                "SCRAM-SHA-256"
        ]
}

> db.system.users.find()
{ "_id" : "admin.root", "userId" : UUID("bd3c86c8-c9f2-4f1e-8dfe-90b912c17044"), "user" : "root", "db" : "                                                                                                                                   admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "9o2HA0Hfc2/cnghXyQw+bg==",                                                                                                                                    "storedKey" : "qaRzwqOfJvJwgAdPgEVCG59llD0=", "serverKey" : "5XilaK8HzqhsWZoNZpXe6lvoCks=" }, "SCRAM-SHA-                                                                                                                                   256" : { "iterationCount" : 15000, "salt" : "7GQgqiMMm2f/qt4P7XbTk0XejA7pmtORg4Jjzg==", "storedKey" : "ZGj                                                                                                                                   Br04INa2MxlWM26f7usdeDvkiiVxUQAyDmlF9PxQ=", "serverKey" : "fPRS60idqGSLzo4fYLcyqh32X4bzUO76qvUT8KWhjGU=" }                                                                                                                                    }, "roles" : [ { "role" : "root", "db" : "admin" } ] }

创建数据库blog,并添加读写权限的账号


> use blog
switched to db blog
> db
blog
> db.createUser({ user: "test", pwd: "12345", roles: [{ role: "readWrite", db: "blog" }]})  # 创建账号
Successfully added user: {
        "user" : "test",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "blog"
                }
        ]
}

> db.auth('test','12345') # 验证创建的账号否可以通过用户认证
1

> db.createCollection("test")   # 创建test集合
{ "ok" : 1 }

> show tables   # 查看该数据库下有哪些集合 或者使用 show collections
test

> db.test.insert({title: '测试插入数据'});    # 插入一条测试数据 或者使用save方法
WriteResult({ "nInserted" : 1 })

> db.test.find().pretty()    # 查询表内容
{ "_id" : ObjectId("61a0b40b4e1e673a60a16d1d"), "title" : "测试插入数据" }
>

3.3 mongodb开启用户认证

在mongodb.conf尾部加入以下代码


security:
  authorization: enabled # 开启以安全认证方式运行,默认是不认证的非安全方式
  

重启服务


[root@test /]# mongod --shutdown --dbpath /usr/local/mongodb5/datas
[root@test /]# mongod -f /usr/local/mongodb5/bin/mongodb.conf

验证是否开启用户认证


[root@test ~]# mongo
================
> show dbs   # 查看有哪些数据库,结果为空

> db   # 查看所处的数据库
test

> use admin      # 切换到admin数据库
switched to db admin
> db.auth('root','root')     # 登录超级管理员账号
1

> show dbs    #  再次查看有哪些数据库,出现结果,说明用户认证是成功开启了的
admin   0.000GB
config  0.000GB
local   0.000GB
blog    0.000GB
>

开启复制集的实例开启用户认证可参考:www.kancloud.cn/studyforeve…

数据备份与恢复

mongodb数据备份和恢复主要分为二种:
一种是针对库的mongodump和mongorestore,
一种是针对库中表的mongoexport和mongoimport,
需要使用mongodb-tools工具,
参考前面的方式,解压、拷贝、设置全局命令


[root@test ~]# wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel80-x86_64-100.3.1.tgz        # 下载

1:备份


[root@test ~]# mongodump -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -o 备份存放路径

参数说明:

  • -h 指明数据库宿主机的IP
  • --port 指明数据库的端口
  • -u 指明数据库的用户名
  • -p 指明数据库的密码
  • -d 指明数据库的名字
  • -o 指明备份的数据存放位置 如果没有用户,可以去掉-u和-p。
    如果导出本机的数据库,可以去掉-h。
    如果是默认端口,可以去掉--port。
    如果想导出所有数据库,可以去掉-d

2:恢复


[root@test ~]# mongorestore -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 --drop  --dir 备份存放的路径

参数说明:

  • -h 指明数据库宿主机的IP
  • --port 指明数据库的端口
  • -u 指明数据库的用户名
  • -p 指明数据库的密码
  • -d 指明数据库的名字
  • --drop 恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除
  • <path> mongorestore 最后的一个参数,设置备份存放的路径,例如:/root/dbback。
  • --dir 指定备份存放的路径,不能同时指定 <path>--dir 选项

3:导出

3.1 导出整个集合


[root@test ~]# mongoexport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 集合  -o 导出的路径

[root@test ~]# mongoexport -h 127.0.0.1 --port 27017 -u test -p 12345 -d blog -c test  -o /root/blog-test.json
2021-11-29T10:59:09.519+0800    connected to: mongodb://127.0.0.1:27017/
2021-11-29T10:59:09.523+0800    exported 1 record

参数说明:

  • -h 指明数据库宿主机的IP
  • --port 指明数据库的端口
  • -u 指明数据库的用户名
  • -p 指明数据库的密码
  • -d 指明数据库的名字
  • -c 指明集合的名字
  • -o 指明导出的路径 例如: /root/db-test.json 注: 测试发现,只有在blog数据库创建的账号,才能导出blog库的数据,
    其他库创建的账号哪怕roles里面指定的db是blog库也不行

3.2 导出集合中的部分字段


[root@test ~]# mongoexport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 集合 --csv -f 字段,字段 -o 导出的路径

[root@test ~]# mongoexport -h 127.0.0.1 --port 27017 -u test -p 12345 -d blog -c test --csv -f title,_id -o /root/blog-test.csv
2021-11-29T11:12:16.369+0800    csv flag is deprecated; please use --type=csv instead
2021-11-29T11:12:16.402+0800    connected to: mongodb://127.0.0.1:27017/
2021-11-29T11:12:16.408+0800    exported 1 record

参数说明:

  • -h 指明数据库宿主机的IP
  • --port 指明数据库的端口
  • -u 指明数据库的用户名
  • -p 指明数据库的密码
  • -d 指明数据库的名字
  • -c 指明集合的名字
  • --csv 表示导出的文件格式为csv的,这个比较有用,因为大部分的关系型数据库都是支持csv
  • -f 导出指字段,以字号分割,-f _id,test导出_id,title这2个字段
  • -q 指明导出数据的过滤条件
  • -o 指明导出的路径 例如: /root/blog-test.csv

4:导入

4.1 导入整个集合


[root@test ~]# mongoimport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 集合 --file 文件

[root@test ~]# mongoimport -h 127.0.0.1 --port 27017 -u test -p 12345 -d blog -c test2 --file /root/blog-test.json
2021-11-29T14:31:15.544+0800    connected to: mongodb://127.0.0.1:27017/
2021-11-29T14:31:15.652+0800    1 document(s) imported successfully. 0 document(s) failed to import.

参数说明:

  • -h 指明数据库宿主机的IP
  • --port 指明数据库的端口
  • -u 指明数据库的用户名
  • -p 指明数据库的密码
  • -d 指明数据库的名字
  • -c 指明集合的名字
  • --file 指明导入的文件 注意:如果集合不存在,则会创建集合,如果集合存在,则会插入现有集合中不存在的记录(根据_id判断)

4.2 导入csv


[root@test ~]# mongoimport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 集合 --type csv --headerline --file 文件

[root@test ~]# mongoimport -h 127.0.0.1 --port 27017 -u test -p 12345 -d blog -c test3 --type csv --headerline --file /root/blog-test.csv
2021-11-29T14:45:33.442+0800    connected to: mongodb://127.0.0.1:27017/
2021-11-29T14:45:33.456+0800    1 document(s) imported successfully. 0 document(s) failed to import.

参数说明:

  • -h 指明数据库宿主机的IP
  • --port 指明数据库的端口
  • -u 指明数据库的用户名
  • -p 指明数据库的密码
  • -d 指明数据库的名字
  • -c 指明集合的名字
  • --type 指明导入的文件格式
  • -headerline 指明第一行是列名,不需要导入
  • --file 指明导入的文件

node连接mongodb

安装npm包mongodb


npm install mongodb --save

连接数据库


mongodb://username:password@hostname:port/dbname

参数说明:

  • username 账号
  • password 密码
  • hostname 服务器ip
  • port 端口
  • dbname 数据库名

注意:账号必须是在dbname这个库中创建的才行

创建db.js文件


const MongoClient = require("mongodb").MongoClient;
const url = `mongodb://test:12345@127.0.0.1:27017/blog`; // 使用前面创建的test账号连接blog库
module.exports = {
    db: null,
    open() {
        return new Promise((resolve, reject) => {
            MongoClient.connect(url, (err, db)=>{
                if(err) {
                    reject(new Error(err));
                };
                this.db = db;
                let dbase = db.db('blog'); // 连接成功后指定数据库为blog,根据账号创建时的`roles`指定的权限和库
                resolve(dbase);
            })
        })
    },
    close() {
        if(this.db) {
            this.db.close();
        }
    }
}

调用db.js


const path = require('path');
const dbClent = require(path.join(__dirname, './../db.js'));
dbClent.open().then(db => {
    // 在 blog 库的 users 表中,插入一条记录
    db.collection('users').insertOne(user, (err,result) => {
        if(err) {
            reject(new Error(err))
        };
        dbClent.close(); // 关闭连接
        resolve();
    })
}).catch(err => {
        reject(err);
})

node操作mongodb更多用法可参考:www.runoob.com/nodejs/node…