一、逻辑结构
Mongodb |
Mysql |
库(database) |
库 |
集合(collection) |
表 |
文档(document) |
数据行 |
二、安装
1、系统准备
① redhat或centos 6.2 以上系统
② 系统开发包完整
③ ip地址和hosts解析正常
④ iptables、firewalld、selinux关闭
⑤ 关闭大页内存
| # root 用户执行以下操作 |
| $ vi /etc/rc.local |
| # 末尾添加 |
| if test -f /sys/kernel/mm/transparent_hugepage/enabled; then |
| echo never > /sys/kernel/mm/transparent_hugepage/enabled |
| fi |
| if test -f /sys/kernel/mm/transparent_hugepage/defrag; then |
| echo never > /sys/kernel/mm/transparent_hugepage/defrag |
| fi |
| $ source /etc/rc.local |
| # 确认配置生效(默认情况下always) |
| $ cat /sys/kernel/mm/transparent_hugepage/enabled |
| always madvise [never] |
| $ cat /sys/kernel/mm/transparent_hugepage/defrag |
| always madvise [never] |
本次博客采用centos 7.2系统,其他系统如何关闭大页内存,可参考官方文档:https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
2、安装
① 创建所需用户
| $ useradd mongo |
| $ echo '123456' | passwd --stdin mongo |
② 创建mongodb所需目录结构
| $ mkdir /mongodb/{conf,log,data} -p |
③ 上传mongdb软件并解压
| $ cd /mongodb/data/ |
| $ tar zxf mongodb-linux-x86_64-rhel70-3.6.20.tgz |
| $ mv mongodb-linux-x86_64-rhel70-3.6.20/bin/ /mongodb/ |
④ 设置目录结构权限
| $ chown mongo.mongo /mongodb/ -R |
⑤ 设置用户环境变量
| $ su - mongod |
| $ vim .bash_profile |
| export PATH=/mongodb/bin:$PATH |
| $ source .bash_profile |
⑥ 命令行启动mongodb
| $ mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork |
- --dbpath:指定数据存储路径;
- --logpath:指定日志存储路径;
- --port:指定监听端口;
- --logappend :指定日志存储方式为追加;
- --fork:指定启动方式为后台启动;
⑦ 登录mongodb
⑧ 使用配置文件
| YAML模式 |
| |
| NOTE: |
| YAML does not support tab characters for indentation: use spaces instead. |
| |
| --系统日志有关 |
| systemLog: |
| destination: file |
| path: "/mongodb/log/mongodb.log" --日志位置 |
| logAppend: true --日志以追加模式记录 |
| |
| --数据存储有关 |
| storage: |
| journal: |
| enabled: true |
| dbPath: "/mongodb/data" --数据路径的位置 |
| |
| -- 进程控制 |
| processManagement: |
| fork: true --后台守护进程 |
| pidFilePath: <string> --pid文件的位置,一般不用配置,可以去掉这行,自动生成到data中 |
| |
| --网络配置有关 |
| net: |
| bindIp: <ip> -- 监听地址 |
| port: <port> -- 端口号,默认不配置端口号,是27017 |
| |
| -- 安全验证有关配置 |
| security: |
| authorization: enabled --是否打开用户名密码验证 |
| |
| ------------------以下是复制集与分片集群有关---------------------- |
| |
| replication: |
| oplogSizeMB: <NUM> |
| replSetName: "<REPSETNAME>" |
| secondaryIndexPrefetch: "all" |
| |
| sharding: |
| clusterRole: <string> |
| archiveMovedChunks: <boolean> |
| |
| ---for mongos only |
| replication: |
| localPingThresholdMs: <int> |
| |
| sharding: |
| configDB: <string> |
| --- |
| |
YAML例子:
| $ cat > /mongodb/conf/mongo.conf <<EOF |
| systemLog: |
| destination: file |
| path: "/mongodb/log/mongodb.log" |
| logAppend: true |
| storage: |
| journal: |
| enabled: true |
| dbPath: "/mongodb/data/" |
| processManagement: |
| fork: true |
| net: |
| port: 27017 |
| bindIp: 192.168.100.239,127.0.0.1 |
| EOF |
| $ mongod -f /mongodb/conf/mongo.conf --shutdown # 停止mongodb |
| $ mongod -f /mongodb/conf/mongo.conf # 启动mongodb |
⑨ 使用systemd管理
root身份执行以下命令:
| $ cat > /etc/systemd/system/mongod.service <<EOF |
| [Unit] |
| Description=mongodb |
| After=network.target remote-fs.target nss-lookup.target |
| [Service] |
| User=mongo |
| Type=forking |
| ExecStart=/mongodb/bin/mongod --config /mongodb/conf/mongo.conf |
| ExecReload=/bin/kill -s HUP $MAINPID |
| ExecStop=/mongodb/bin/mongod --config /mongodb/conf/mongo.conf --shutdown |
| PrivateTmp=true |
| [Install] |
| WantedBy=multi-user.target |
| EOF |
| $ systemctl restart mongod |
| $ systemctl start mongod |
三、mongodb常用操作
1、mongodb默认存在的库
- test:登录时默认存在的库;
- admin:系统预留库,mongodb系统管理库(系统库);
- local:本地预留库,存储关键日志信息(系统库);
- config:mongodb配置信息库(系统库);
| > show databases/show dbs |
| > show tables/show collections |
| > use admin |
| > db |
2、mongodb对象操作
① 库的操作
| > use test |
| > db.dropDatabase() |
| { "ok" : 1 } |
② 集合的操作
| > use lvzhenjiang |
| > db.stu.insert({name: "zhangsan"}) |
| > db.stu.insert({id: 100,name: "lisi",age: 20,gender: "man"}) |
| > show tables; |
| stu |
③ 文档的操作
| # 批量录入数据 |
| > for(i=0;i<10000;i++){db.test.insert({"uid":i,"name":"lzj","age":6,"date":new |
| Date()})} |
| |
| # 查询数据行数 |
| > db.test.count() |
| 10000 |
| |
| # 全表查询 |
| > db.test.find() |
| |
| # 设置每页显示50行 |
| > DBQuery.shellBatchSize=50; |
| |
| # 按照条件查询 |
| > db.test.find({uid: 50}) |
| |
| # 以标准的json格式显示 |
| > db.test.find({uid: 50}).pretty() |
| |
| # 删除集合中所有记录 |
| > db.test.remove({}) |
| |
| # 集合中索引+数据压缩存储之后的大小 |
| > db.test.totalSize() |
四、用户及权限管理
1、注意事项
| 验证库: 建立用户时use到的库,在使用用户时,要加上验证库才能登陆。 |
| |
| 对于管理员用户,必须在admin下创建. |
| 1. 建用户时,use到的库,就是此用户的验证库 |
| 2. 登录时,必须明确指定验证库才能登录 |
| 3. 通常,管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库 |
| 4. 如果直接登录到数据库,不进行use,默认的验证库是test,不是我们生产建议的. |
| 5. 从3.6 版本开始,不添加bindIp参数,默认不让远程登录,只能本地管理员登录。 |
2、用户创建语法
| use admin |
| db.createUser |
| { |
| user: "<name>", |
| pwd: "<cleartext password>", |
| roles: [ |
| { role: "<role>", |
| db: "<database>" } | "<role>", |
| ... |
| ] |
| } |
| |
| 基本语法说明: |
| user:用户名 |
| pwd:密码 |
| roles: |
| role:角色名 |
| db:作用对象 |
| role:root, readWrite,read |
| 验证数据库: |
| mongo -u lvzhenjiang -p 123456 192.168.100.239/lvzhenjiang |
3、创建管理员例子
| 创建超级管理员:管理所有数据库(必须use admin再去创建) |
| $ mongo |
| > use admin |
| > db.createUser( |
| { |
| user: "root", |
| pwd: "123456", |
| roles: [ { role: "root", db: "admin" } ] |
| } |
| ) |
| > db.auth('root','123456') |
mongodb配置文件中,加入以下配置:
| security: |
| authorization: enabled |
重启mongodb:
| $ mongod -f /mongodb/conf/mongo.conf --shutdown |
| $ mongod -f /mongodb/conf/mongo.conf |
4、登录验证
| $ mongo -uroot -p123456 admin |
| $ mongo -uroot -p123456 192.168.100.239/admin |
5、查看用户
| > use admin |
| > db.system.users.find().pretty() |
6、创建应用用户
| > use lvzhenjiang |
| > db.createUser( |
| { |
| user: "lvzhenjiang", |
| pwd: "123456", |
| roles: [ { role: "readWrite" , db: "lvzhenjiang" } ] |
| } |
| ) |
| |
| $ mongo -ulvzhenjiang -p123456 192.168.100.239/lvzhenjiang |
| > db |
| lvzhenjiang |
7、删除用户(root身份登录,use到用户的验证库)
| $ mongo -uroot -p123456 192.168.100.239/admin |
| > use lvzhenjiang |
| > db.dropUser("lvzhenjiang") |
| > use admin |
| > db.system.users.find().pretty() |
8、用户管理注意事项
| 1. 建用户要有验证库,管理员admin,普通用户是要管理的库 |
| 2. 登录时,注意验证库 |
| mongo -ulvzhenjiang -p123456 192.168.100.239:27017/lvzhenjiang |
| 3. 重点参数 |
| net: |
| port: 27017 |
| bindIp: 192.168.100.239,127.0.0.1 |
| security: |
| authorization: enabled |
五、mongodb复制集RS
1、基本原理
- 基本构成都是1主2从的结构,自带了互相监控投票机制(Raft);
- 如果主库发生宕机,复制集内会进行投票机制,选择一个新的主库替代原有主库继续对外提供服务。同时复制集会自动通知;
- 客户端程序,主库已经发生切换了。应用自然就会连接到新的主库;
2、配置多实例mongodb
① 环境准备
② 准备相关目录
| $ for i in {28017..28020};do mkdir -p /mongodb/${i}/{conf,data,log};done |
③ 编写mongod配置文件
| $ cat > /mongodb/28017/conf/mongod.conf <<EOF |
| systemLog: |
| destination: file |
| path: /mongodb/28017/log/mongodb.log |
| logAppend: true |
| storage: |
| journal: |
| enabled: true |
| dbPath: /mongodb/28017/data |
| directoryPerDB: true |
| #engine: wiredTiger |
| wiredTiger: |
| engineConfig: |
| cacheSizeGB: 1 |
| directoryForIndexes: true |
| collectionConfig: |
| blockCompressor: zlib |
| indexConfig: |
| prefixCompression: true |
| processManagement: |
| fork: true |
| net: |
| bindIp: 192.168.100.239,127.0.0.1 |
| port: 28017 |
| replication: |
| oplogSizeMB: 2048 |
| replSetName: my_repl |
| EOF |
| |
| $ for i in {28018..28020};do \cp /mongodb/28017/conf/mongod.conf /mongodb/${i}/conf/;done |
| $ for i in {28018..28020};do sed -i "s/28017/${i}/g" /mongodb/${i}/conf/mongod.conf;done |
④ 启动多个实例
| $ for i in {28017..28020};do mongod -f /mongodb/${i}/conf/mongod.conf;done |
| $ ss -lntp | grep 280 |
3、配置普通复制集
| $ mongo 127.0.0.1:28017/admin |
| > config = {_id: 'my_repl', members: [ |
| {_id: 0, host: '192.168.100.239:28017'}, |
| {_id: 1, host: '192.168.100.239:28018'}, |
| {_id: 2, host: '192.168.100.239:28019'}] |
| } |
| > rs.initiate(config) |
| > rs.status(); |
| my_repl:PRIMARY> # 稍等一下,便会选举出主节点 |
| $ mongo 127.0.0.1:28017/admin |
| > config = {_id: 'my_repl', members: [ |
| {_id: 0, host: '192.168.100.239:28017'}, |
| {_id: 1, host: '192.168.100.239:28018'}, |
| {_id: 2, host: '192.168.100.239:28019',"arbiterOnly":true}] |
| } |
| > rs.initiate(config) |
| > rs.status(); |
| my_repl:PRIMARY> |
① 复制集管理操作
| rs.status(); # 查看整体复制集状态 |
| rs.isMaster(); # 查看当前是否是主节点 |
| rs.conf(); # 查看复制集配置信息 |
② 添加、删除节点
| rs.remove("ip:port"); // 删除一个节点 |
| rs.add("ip:port"); // 新增从节点 |
| rs.addArb("ip:port"); // 新增仲裁节点 |
示例:
| 添加 arbiter节点 |
| 1、连接到主节点 |
| $ mongo 127.0.0.1:28017/admin |
| 2、添加仲裁节点 |
| my_repl:PRIMARY> rs.addArb("192.168.100.239:28020") |
| 3、查看节点状态 |
| my_repl:PRIMARY> rs.isMaster() |
| { |
| "hosts" : [ |
| "192.168.100.239:28017", |
| "192.168.100.239:28018", |
| "192.168.100.239:28019" |
| ], |
| "arbiters" : [ |
| "192.168.100.239:28020" |
| ], |
| |
| rs.remove("ip:port"); # 删除一个节点 |
| 例子: |
| my_repl:PRIMARY> rs.remove("192.168.100.239:28019"); |
| my_repl:PRIMARY> rs.isMaster() |
| |
| rs.add("ip:port"); # 新增从节点 |
| 例子: |
| my_repl:PRIMARY> rs.add("192.168.100.239:28019") |
| { "ok" : 1 } |
| my_repl:PRIMARY> rs.isMaster() |
③ 特殊从节点介绍
- arbiter节点:主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务;
- hidden节点:隐藏节点,不参与选主,也不对外提供服务;
- delay节点:延时节点,数据落后于主库一段时间,因为数据是延时的,也不应该提供服务或参与选主,所以通常会配合hidden(隐藏);
一般情况下会将delay+hidden一起配置使用!
④ 配置延时节点
| my_repl:PRIMARY> cfg.members[3].priority=0 # 节点优先级设置为0 |
| my_repl:PRIMARY> cfg.members[3].hidden=true # 设置为隐藏节点 |
| my_repl:PRIMARY> cfg.members[3].slaveDelay=120 # 节点延时时间为120秒 |
| my_repl:PRIMARY> cfg.members[3].votes=0 # 节点票数为0(不能参与投票) |
| my_repl:PRIMARY> rs.reconfig(cfg) # 重新加载配置 |
| my_repl:PRIMARY> rs.conf() # 查询配置后的属性 |
取消以上配置:
| my_repl:PRIMARY> cfg.members[3].priority=1 |
| my_repl:PRIMARY> cfg.members[3].hidden=false |
| my_repl:PRIMARY> cfg.members[3].slaveDelay=0 |
| my_repl:PRIMARY> cfg.members[3].votes=1 |
| my_repl:PRIMARY> rs.reconfig(cfg) |
| my_repl:PRIMARY> rs.conf() |
⑤ 副本集常用命令集合
| rs.conf() # 查看副本集的配置信息 |
| rs.status() # 查看副本集各成员的状态 |
| |
| # 副本集角色切换(不要人为随便操作) |
| rs.stepDown() # |
| 降级主节点的秒数,在此期间,降级成员不符合成为主节点的资格。如果指定非数字值,该命令将使用60秒。 |
| rs.freeze(300)# 锁定从,使其不会转变成主库 |
| # freeze()和stepDown单位都是秒。 |
| |
| # 设置副本节点可读:在副本节点执行 |
| > rs.slaveOk() |
| > use app |
| > db.createCollection('a') |
| |
| # 查看副本节点(监控主从延时) |
| > rs.printSlaveReplicationInfo() |
六、MongoDB Sharding Cluster分片集群
1、环境准备
| 10个实例:38017-38026 |
| 1)configserver:38018-38020 |
| 3台构成的复制集(1主两从,不支持arbiter)38018-38020(复制集名字configsvr) |
| 2)shard节点: |
| sh1:38021-23 (1主两从,其中一个节点为arbiter,复制集名字sh1) |
| sh2:38024-26 (1主两从,其中一个节点为arbiter,复制集名字sh2) |
| 3) mongos: 38017 |
2、配置Shard节点
① 创建所需目录
| $ for i in {38021..38026};do mkdir -p /mongodb/${i}/{conf,log,data};done |
② 编写配置文件
- sh1:38021-38023(1主1从1Arbiter)
| $ cat > /mongodb/38021/conf/mongodb.conf <<EOF |
| systemLog: |
| destination: file |
| path: /mongodb/38021/log/mongodb.log |
| logAppend: true |
| storage: |
| journal: |
| enabled: true |
| dbPath: /mongodb/38021/data |
| directoryPerDB: true |
| #engine: wiredTiger |
| wiredTiger: |
| engineConfig: |
| cacheSizeGB: 1 |
| directoryForIndexes: true |
| collectionConfig: |
| blockCompressor: zlib |
| indexConfig: |
| prefixCompression: true |
| net: |
| bindIp: 192.168.100.239,127.0.0.1 |
| port: 38021 |
| replication: |
| oplogSizeMB: 2048 |
| replSetName: sh1 |
| sharding: |
| clusterRole: shardsvr |
| processManagement: |
| fork: true |
| EOF |
| $ for i in {38022..38023};do \cp /mongodb/38021/conf/mongodb.conf /mongodb/${i}/conf/ && sed "s/38021/${i}/g" /mongodb/${i}/conf/mongodb.conf -i;done |
- sh2:38024-38026(1主1从1Arbiter)
| $ cat > /mongodb/38024/conf/mongodb.conf <<EOF |
| systemLog: |
| destination: file |
| path: /mongodb/38024/log/mongodb.log |
| logAppend: true |
| storage: |
| journal: |
| enabled: true |
| dbPath: /mongodb/38024/data |
| directoryPerDB: true |
| wiredTiger: |
| engineConfig: |
| cacheSizeGB: 1 |
| directoryForIndexes: true |
| collectionConfig: |
| blockCompressor: zlib |
| indexConfig: |
| prefixCompression: true |
| net: |
| bindIp: 192.168.100.239,127.0.0.1 |
| port: 38024 |
| replication: |
| oplogSizeMB: 2048 |
| replSetName: sh2 |
| sharding: |
| clusterRole: shardsvr |
| processManagement: |
| fork: true |
| EOF |
| $ for i in {38025..38026};do \cp /mongodb/38024/conf/mongodb.conf /mongodb/${i}/conf/ && sed "s/38024/${i}/g" /mongodb/${i}/conf/mongodb.conf -i;done |
③ 启动所有shard节点,搭建复制集群
| $ for i in {38021..38026};do mongod -f /mongodb/${i}/conf/mongodb.conf;done |
| |
| $ mongo 127.0.0.1:38021/admin |
| > config = {_id: 'sh1', members: [ |
| {_id: 0, host: '192.168.100.239:38021'}, |
| {_id: 1, host: '192.168.100.239:38022'}, |
| {_id: 2, host: '192.168.100.239:38023',"arbiterOnly":true}] |
| } |
| |
| > rs.initiate(config) |
| |
| $ mongo 127.0.0.1:38024/admin |
| > config = {_id: 'sh2', members: [ |
| {_id: 0, host: '192.168.100.239:38024'}, |
| {_id: 1, host: '192.168.100.239:38025'}, |
| {_id: 2, host: '192.168.100.239:38026',"arbiterOnly":true}] |
| } |
| |
| > rs.initiate(config) |
3、配置config节点
① 创建所需目录
| $ for i in {38018..38020};do mkdir -p /mongodb/${i}/{conf,log,data};done |
② 编写配置文件
| $ cat > /mongodb/38018/conf/mongodb.conf <<EOF |
| systemLog: |
| destination: file |
| path: /mongodb/38018/log/mongodb.conf |
| logAppend: true |
| storage: |
| journal: |
| enabled: true |
| dbPath: /mongodb/38018/data |
| directoryPerDB: true |
| #engine: wiredTiger |
| wiredTiger: |
| engineConfig: |
| cacheSizeGB: 1 |
| directoryForIndexes: true |
| collectionConfig: |
| blockCompressor: zlib |
| indexConfig: |
| prefixCompression: true |
| net: |
| bindIp: 192.168.100.239,127.0.0.1 |
| port: 38018 |
| replication: |
| oplogSizeMB: 2048 |
| replSetName: configReplSet |
| sharding: |
| clusterRole: configsvr |
| processManagement: |
| fork: true |
| EOF |
| $ for i in {38019..38020};do \cp /mongodb/38018/conf/mongodb.conf /mongodb/${i}/conf/ && sed "s/38018/${i}/g" /mongodb/${i}/conf/mongodb.conf -i;done |
③ 启动config节点,配置复制集
| $ for i in {38018..38020};do mongod -f /mongodb/${i}/conf/mongodb.conf;done |
| $ mongo 127.0.0.1:38018/admin |
| > config = {_id: 'configReplSet', members: [ |
| {_id: 0, host: '192.168.100.239:38018'}, |
| {_id: 1, host: '192.168.100.239:38019'}, |
| {_id: 2, host: '192.168.100.239:38020'}] |
| } |
| > rs.initiate(config) |
注意:
- configserver 可以是一个节点,官方建议复制集。configserver不能有arbiter;
- 新版本中,要求必须是复制集;
- mongodb 3.4之后,虽然要求config server为replica set,但是不支持arbiter;
4、mongos节点配置
① 创建所需目录
| $ mkdir -p /mongodb/38017/{conf,log} |
② 编写配置文件
| $ cat > /mongodb/38017/conf/mongos.conf <<EOF |
| systemLog: |
| destination: file |
| path: /mongodb/38017/log/mongos.log |
| logAppend: true |
| net: |
| bindIp: 192.168.100.239,127.0.0.1 |
| port: 38017 |
| sharding: |
| configDB: configReplSet/192.168.100.239:38018,192.168.100.239:38019,192.168.100.239:38020 |
| processManagement: |
| fork: true |
| EOF |
③ 启动mongos
| $ mongos -f /mongodb/38017/conf/mongos.conf |
5、分片集群添加节点
如果是mongos集群,连接任意一个即可,进行以下配置:
| $ mongo 127.0.0.1:38017/admin |
| |
| mongos> db.runCommand( { addshard : "sh1/192.168.100.239:38021,192.168.100.239:38022,192.168.100.239:38023",name:"shard1"} ) |
| mongos> db.runCommand( { addshard : "sh2/192.168.100.239:38024,192.168.100.239:38025,192.168.100.239:38026",name:"shard2"} ) |
| # 添加分片 |
| mongos> db.runCommand( { listshards : 1 } ) |
| mongos> sh.status() |
6、使用分片集群
① RANGE分片配置及测试
| # 激活test数据库分片功能 |
| |
| $ mongo 127.0.0.1:38017/admin |
| mongos> db.runCommand( { enablesharding : "test" } ) |
| |
| # 指定分片键对集合分片 |
| mongos> use test |
| mongos> db.vast.ensureIndex({id: 1}) |
| mongos> use admin |
| mongos> db.runCommand( { shardcollection : "test.vast",key : {id: 1} } ) |
| # test库vast表创建索引 |
| |
| # 集合分片验证 |
| mongos> use test |
| mongos> for(i=1;i<1000000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); } |
| mongos> db.vast,stats() |
| |
| # 分片结果测试 |
| |
| shard1: |
| mongo 127.0.0.1:38021/admin |
| sh1:PRIMARY> db.vast.count(); |
| 60231 |
| shard2: |
| mongo 127.0.0.1:38024/admin |
| sh2:PRIMARY> db.vast.count(); |
| 39768 |
② Hash分片
对lvzhenjiang库下的vast大表进行hash,创建hash索引!
| $ mongo 127.0.0.1:38017/admin |
| |
| mongos> db.runCommand( { enablesharding : "lvzhenjiang" } ) |
| # lvzhenjiang库开启分片功能 |
| |
| mongos> use lvzhenjiang |
| mongos> db.vast.ensureIndex( { id: "hashed" } ) |
| # lvzhenjiang库vast表建立hash索引 |
| |
| mongos> use admin |
| mongos> sh.shardCollection( "lvzhenjiang.vast", { id: "hashed" } ) |
| # lvzhenjiang库vast表开启分片功能 |
| |
| mongos> for(i=1;i<100000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); } |
| # 录入10W数据进行测试 |
| |
| $ mongo 127.0.0.1:38021/lvzhenjiang |
| sh1:PRIMARY> db.vast.count() |
| 50393 |
| $ mongo 127.0.0.1:38021/lvzhenjiang |
| sh2:PRIMARY> db.vast.count() |
| 49606 |
7、分片集群的查询及管理
| 登录mongos |
| mongos> sh.status() |
8、删除节点
| # 确认blance是否在工作 |
| mongos> sh.getBalancerState() |
| # 删除shard2节点(谨慎) |
| mongos> db.runCommand( { removeShard: "shard2" } ) |
| # 注意:删除操作一定会立即触发blancer。 |
七、balancer操作
1、balancer简介
mongos的一个重要功能,自动巡查所有shard节点上的chunk的情况,自动做chunk迁移。
什么时候工作?
1、自动运行,会检测系统不繁忙的时候做迁移
2、在做节点删除的时候,立即开始迁移工作
3、balancer只能在预设定的时间窗口内运行
| 有需要时可以关闭和开启blancer(备份的时候) |
| mongos> sh.stopBalancer() |
| mongos> sh.startBalancer() |
2、自定义自动平衡进行的时间段
参考官方文档
| $ mongo 127.0.0.1:38017/config |
| mongos> sh.setBalancerState(true) |
| mongos> db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "0:00", stop : "5:00" } } }, true ) |
| # 设置balancer从0点开始工作,5点结束 |
| mongos> sh.getBalancerWindow() |
| { "start" : "0:00", "stop" : "5:00" } |
| mongos> sh.status() |
| |
| 关于集合的balancer(了解下) |
| mongos> sh.disableBalancing("students.grades") |
| mongos> sh.enableBalancing("students.grades") |
| mongos> db.getSiblingDB("config").collections.findOne({_id : "students.grades"}).noBalance; |
| # 确定某个集合的balance是开启或者关闭 |
八、备份与恢复
1、备份工具介绍
| (1)mongoexport/mongoimport |
| (2)mongodump/mongorestore |
2、备份工具区别
| 应用场景总结: |
| mongoexport/mongoimport:json csv |
| 1、异构平台迁移 mysql <---> mongodb |
| 2、同平台,跨大版本:mongodb 2 ----> mongodb 3 |
| |
| mongodump/mongorestore |
| 日常备份恢复时使用. |
3、导出工具mongoexport
mongoexport具体用法如下所示:
参数说明:
- -h:指明数据库宿主机的IP;
- -u:指明数据库的用户名;
- -p:指明数据库的密码;
- -d:指明数据库的名字;
- -c:指明collection的名字;
- -f:指明要导出那些列;
- -o:指明到要导出的文件名;
- -q:指明导出数据的过滤条件
- --authenticationDatabase admin
① 单表备份至json格式
| $ mongoexport -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -c test -o /mongodb/test.json |
注:备份文件的名字可以自定义,默认导出了JSON格式的数据。
② 单表备份至csv格式
如果我们需要导出CSV格式的数据,则需要使用----type=csv参数:
| $ mongoexport -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -c test --type=csv -f uid,name,age,date -o /mongodb/test.csv |
4、导入工具mongoimport
参数说明:
① 恢复json格式表数据到test1
| $ mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -c test1 /mongodb/test.json |
② 恢复csv格式的文件到ltest2
如果要导入CSV格式文件中的内容,则需要通过--type参数指定导入格式,具体如下所示:
错误的恢复
(1)csv格式的文件头行,有列名字
| $ mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -c test2 --type=csv --headerline --file /mongodb/test.csv |
| |
| --headerline:指明第一行是列名,不需要导入。 |
(2)csv格式的文件头行,没有列名字
| $ mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -c test3 --type=csv -f id,name,age,date --file /mongodb/test.csv |
九、异构平台迁移案例
mysql ————> mongodb
偷懒直接就用zabbix的mariadb了,将zabbix库下的hosts表导出,导入到mongodb中!
1、mysql开启安全路径
| $ vim /etc/my.cnf --->添加以下配置 |
| secure-file-priv=/tmp |
| $ systemctl restart mariadb |
2、导出zabbix库下的hosts表数据(以,号分隔)
| $ mysql |
| MariaDB [(none)]> select * from zabbix.hosts into outfile '/tmp/hosts.csv' fields terminated by','; |
3、导出zabbix库下的hosts表列名(以,号分隔)
| MariaDB [(none)]> use zabbix |
| MariaDB [(none)]> select group_concat(COLUMN_NAME)from information_schema.COLUMNS where table_name = 'hosts' |
手工填写到导出的hosts.csv文件(方法比较low)
4、在mongodb中导入备份
| $ mongoimport -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -c host --type=csv --headerline --file /home/mongo/hosts.csv |
| |
| $ mongo -uroot -p123456 admin |
| > use lvzhenjiang |
| > db.host.find({hostid: 10100}).pretty() |
mysql导出csv:
| select * from test_info |
| into outfile '/tmp/test.csv' |
| fields terminated by ',' ------字段间以,号分隔 |
| optionally enclosed by '"' ------字段用"号括起 |
| escaped by '"' ------字段中使用的转义符为" |
| lines terminated by '\r\n'; ------行以\r\n结束 |
mysql导入csv:
| load data infile '/tmp/test.csv' |
| into table test_info |
| fields terminated by ',' |
| optionally enclosed by '"' |
| escaped by '"' |
| lines terminated by '\r\n'; |
十、mongodump和mongorestore
1、mongodump介绍
mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘。但是存在的问题时使用mongodump产生的备份不一定是数据库的实时快照,如果我们在备份时对数据库进行了写入操作,则备份出来的文件可能不完全和Mongodb实时数据相等。另外在备份时可能会对其它客户端性能产生不利的影响。
2、mongodump用法
参数说明:
- -h:指明数据库宿主机的IP;
- -u:指明数据库的用户名;
- -p:指明数据库的密码;
- -d:指明数据库的名字;
- -c:指明collection的名字;
- -o:指明到要导出的文件名;
- -q:指明导出数据的过滤条件;
- -j, --numParallelCollections= number of collections to dump in parallel (4 by default);
- --oplog 备份的同时备份oplog;
3、mongodump和mongorestore基本使用
① 全库备份
| $ mkdir /mongodb/backup |
| $ mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -o /mongodb/backup |
② 备份lvzhenjiang库
| $ mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -o /mongodb/backup/ |
③ 备份lvzhenjiang库下的host表
| $ mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -c host -o /mongodb/backup/ |
④ 压缩备份
| $ mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -o /mongodb/backup/ --gzip |
| $ mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -o /mongodb/backup/ --gzip |
| $ mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -c host -o /mongodb/backup/ --gzip |
⑤ 恢复lvzhenjiang库
| $ mongorestore -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang01 /mongodb/backup/lvzhenjiang |
⑥ 恢复lvzhenjiang库下的host表
| $ mongorestore -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang -c host01 --gzip /mongodb/backup/lvzhenjiang/host.bson.gz |
七、drop表示恢复的时候把之前的集合drop掉(危险)
| $ mongorestore -uroot -p123456 --port 27017 --authenticationDatabase admin -d lvzhenjiang --drop /mongodb/backup/lvzhenjiang |
十一、mongodump和mongorestore高级企业应用(--oplog)
注意:这是replica set或者master/slave模式专用
1、oplog介绍
在replica set中oplog是一个定容集合(capped collection),它的默认大小是磁盘空间的5%(可以通过--oplogSizeMB参数修改).
位于local库的db.oplog.rs,有兴趣可以看看里面到底有些什么内容。
其中记录的是整个mongod实例一段时间内数据库的所有变更(插入/更新/删除)操作。
当空间用完时新记录自动覆盖最老的记录。
其覆盖范围被称作oplog时间窗口。需要注意的是,因为oplog是一个定容集合,
所以时间窗口能覆盖的范围会因为你单位时间内的更新次数不同而变化。
想要查看当前的oplog时间窗口预计值,可以使用以下命令:
| $ mongod -f /mongodb/28017/conf/mongod.conf |
| $ mongod -f /mongodb/28018/conf/mongod.conf |
| $ mongod -f /mongodb/28019/conf/mongod.conf |
| $ mongod -f /mongodb/28020/conf/mongod.conf |
| $ mongo 127.0.0.1:28017/admin |
| use local |
| db.oplog.rs.find().pretty() |
| "ts" : Timestamp(1553597844, 1), # 需要关注的信息 |
| "op" : "n" # 需要关注的信息 |
| "o" : # 需要关注的信息 |
- "i": insert
- "u": update
- "d": delete
- "c": db cmd
| test:PRIMARY> rs.printReplicationInfo() |
| configured oplog size: 1561.5615234375MB <--集合大小 |
| log length start to end: 423849secs (117.74hrs)<--预计窗口覆盖时间 |
| oplog first event time: Wed Sep 09 2015 17:39:50 GMT+0800 (CST) |
| oplog last event time: Mon Sep 14 2015 15:23:59 GMT+0800 (CST) |
| now: Mon Sep 14 2015 16:37:30 GMT+0800 (CST) |
2、oplog企业级应用
(1)实现热备,在备份时使用--oplog选项
注:为了演示效果我们在备份过程,模拟数据插入
(2)准备测试数据
| $ mongo 127.0.0.1:28018/admin |
| use lvzhenjiang |
| for(var i = 1 ;i < 100; i++){ |
| db.foo.insert({a:i}); |
| } |
| |
| my_repl:PRIMARY> db.oplog.rs.find({"op":"i"}).pretty() |
oplog 配合mongodump实现热备
| mongodump --port 28018 --oplog -o /mongodb/backup |
作用介绍:--oplog 会记录备份过程中的数据变化。会以oplog.bson保存下来
恢复
| mongorestore --port 28018 --oplogReplay /mongodb/backup |
3、oplog高级应用
背景:每天0点全备,oplog恢复窗口为48小时
某天,上午10点world.city 业务表被误删除。
恢复思路:
0、停应用
2、找测试库
3、恢复昨天晚上全备
4、截取全备之后到world.city误删除时间点的oplog,并恢复到测试库
5、将误删除表导出,恢复到生产库
恢复步骤:
模拟故障环境:
1、全备数据库
模拟原始数据
| mongo 127.0.0.1:28017/admin |
| use wo |
| for(var i = 1 ;i < 20; i++){ |
| db.ci.insert({a: i}); |
| } |
全备:
| rm -rf /mongodb/backup/* |
| mongodump --port 28018 --oplog -o /mongodb/backup |
- --oplog功能:在备份同时,将备份过程中产生的日志进行备份
- 文件必须存放在/mongodb/backup下,自动命令为oplog.bson
再次模拟数据
| db.ci1.insert({id:1}) |
| db.ci2.insert({id:2}) |
2、上午10点:删除wo库下的ci表
3、备份现有的oplog.rs表
| mongodump --port 28018 -d local -c oplog.rs -o /mongodb/backup |
4、截取oplog并恢复到drop之前的位置
更合理的方法:登陆到原数据库
| $ mongo 127.0.0.1:28018/admin |
| my_repl:PRIMARY> use local |
| db.oplog.rs.find({op:"c"}).pretty(); |
| |
| { |
| "ts" : Timestamp(1553659908, 1), |
| "t" : NumberLong(2), |
| "h" : NumberLong("-7439981700218302504"), |
| "v" : 2, |
| "op" : "c", |
| "ns" : "wo.$cmd", |
| "ui" : UUID("db70fa45-edde-4945-ade3-747224745725"), |
| "wall" : ISODate("2019-03-27T04:11:48.890Z"), |
| "o" : { |
| "drop" : "ci" |
| } |
| } |
| |
| # 获取到oplog误删除时间点位置: |
| "ts" : Timestamp(1553659908, 1) |
5、恢复备份+应用oplog
| $ ls /mongodb/backup/local/ |
| oplog.rs.bson oplog.rs.metadata.json |
| $ cp oplog.rs.bson ../oplog.bson |
| $ rm -rf /mongodb/backup/local/ |
| $ mongorestore --port 38021 --oplogReplay --oplogLimit "1553659908:1" --drop /mongodb/backup/ |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律