目录

  • 一、逻辑结构
  • 二、安装
  • 1、系统准备
  • 2、安装
  • ① 创建所需用户
  • ② 创建mongodb所需目录结构
  • ③ 上传mongdb软件并解压
  • ④ 设置目录结构权限
  • ⑤ 设置用户环境变量
  • ⑥ 命令行启动mongodb
  • ⑦ 登录mongodb
  • ⑧ 使用配置文件
  • ⑨ 使用systemd管理
  • 三、mongodb常用操作
  • 1、mongodb默认存在的库
  • 2、mongodb对象操作
  • ① 库的操作
  • ② 集合的操作
  • ③ 文档的操作
  • 四、用户及权限管理
  • 1、注意事项
  • 2、用户创建语法
  • 3、创建管理员例子
  • 4、登录验证
  • 5、查看用户
  • 6、创建应用用户
  • 7、删除用户(root身份登录,use到用户的验证库)
  • 8、用户管理注意事项
  • 五、mongodb复制集RS
  • 1、基本原理
  • 2、配置多实例mongodb
  • ① 环境准备
  • ② 准备相关目录
  • ③ 编写mongod配置文件
  • ④ 启动多个实例
  • 3、配置普通复制集
  • ① 复制集管理操作
  • ② 添加、删除节点
  • ③ 特殊从节点介绍
  • ④ 配置延时节点
  • ⑤ 副本集常用命令集合
  • 六、MongoDB Sharding Cluster分片集群
  • 1、环境准备
  • 2、配置Shard节点
  • ① 创建所需目录
  • ② 编写配置文件
  • ③ 启动所有shard节点,搭建复制集群
  • 3、配置config节点
  • ① 创建所需目录
  • ② 编写配置文件
  • ③ 启动config节点,配置复制集
  • 4、mongos节点配置
  • ① 创建所需目录
  • ② 编写配置文件
  • ③ 启动mongos
  • 5、分片集群添加节点
  • 6、使用分片集群
  • ① RANGE分片配置及测试
  • ② Hash分片
  • 7、分片集群的查询及管理
  • 8、删除节点
  • 七、balancer操作
  • 1、balancer简介
  • 2、自定义自动平衡进行的时间段
  • 八、备份与恢复
  • 1、备份工具介绍
  • 2、备份工具区别
  • 3、导出工具mongoexport
  • ① 单表备份至json格式
  • ② 单表备份至csv格式
  • 4、导入工具mongoimport
  • ① 恢复json格式表数据到test1
  • ② 恢复csv格式的文件到ltest2
  • 九、异构平台迁移案例
  • 1、mysql开启安全路径
  • 2、导出zabbix库下的hosts表数据(以,号分隔)
  • 3、导出zabbix库下的hosts表列名(以,号分隔)
  • 4、在mongodb中导入备份
  • 十、mongodump和mongorestore
  • 1、mongodump介绍
  • 2、mongodump用法
  • 3、mongodump和mongorestore基本使用
  • ① 全库备份
  • ② 备份lvzhenjiang库
  • ③ 备份lvzhenjiang库下的host表
  • ④ 压缩备份
  • ⑤ 恢复lvzhenjiang库
  • ⑥ 恢复lvzhenjiang库下的host表
  • 七、drop表示恢复的时候把之前的集合drop掉(危险)
  • 十一、mongodump和mongorestore高级企业应用(--oplog)
  • 1、oplog介绍
  • 2、oplog企业级应用
  • 3、oplog高级应用

一、逻辑结构

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
$ mongo
>        # 出现该符号表示登录成功
⑧ 使用配置文件
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

① 环境准备
  • 三个以上的mongodb节点(或多实例),这里采用多实例的方式;
  • 端口准备:28017,28018,28019,28020;
② 准备相关目录
$ 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      # 确认28017..28020端口正常

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>         # 稍等一下,便会选举出主节点
  • 一主一从一Arbiter
$ 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})   # test库vast表,创建索引
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)    # 默认就是true
mongos> db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "0:00", stop : "5:00" } } }, true )
# 设置balancer从0点开始工作,5点结束
mongos> sh.getBalancerWindow()         # 查看balancer工作时间
{ "start" : "0:00", "stop" : "5:00" }
mongos> sh.status()      # 也可以查看到balancer 工作时间

关于集合的balancer(了解下)
mongos> sh.disableBalancing("students.grades")    # 关闭某个集合的balance
mongos> sh.enableBalancing("students.grades")     # 打开某个集合的balancer
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具体用法如下所示:

$ mongoexport --help

参数说明:

  • -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

$ mongoimport --help

参数说明:

  • -h:指明数据库宿主机的IP;
  • -u:指明数据库的用户名;
  • -p:指明数据库的密码;
  • -d:指明数据库的名字;
  • -c:指明collection的名字;
  • -f:指明要导入那些列;
  • -j: --numInsertionWorkers=<number> number of insert operations to run concurrently (defaults to 1)//并行
① 恢复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用法

$ mongodump --help

参数说明:

  • -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表

db.ci.drop()
show tables;

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/