mongodb

作者: 挑战_bae7 | 来源:发表于2021-03-12 11:10 被阅读0次

    1.安装 mongodb

    https://www.mongodb.com/try/download/community

    wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.0.23.tgz
    tar xf mongodb-linux-x86_64-rhel70-4.0.23.tgz
    mkdir /mongodb/{conf,log,data} -p
    cp -a mongodb-linux-x86_64-rhel70-4.0.23/bin/ /mongodb/
    useradd mongod -s /sbin/nologin
    
    cat >/etc/profile.d/mongod.sh <<EOF
    export PATH=\$PATH:/mongodb/bin
    EOF
    source /etc/profile.d/mongod.sh
    
    echo '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' >>/etc/rc.local
    chmod +x /etc/rc.d/rc.local
    
    echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled
    echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag 
    
    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: $(ifconfig eth0|awk 'NR==2{print $2}'),127.0.0.1
    EOF
    
    cat > /etc/systemd/system/mongod.service <<EOF
    [Unit]
    Description=mongodb 
    After=network.target remote-fs.target nss-lookup.target
    [Service]
    User=mongod
    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
    
    chown -R mongod:mongod /mongodb
    systemctl enable mongod
    systemctl start mongod
    

    2.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: $(ifconfig eth0|awk 'NR==2{print $2}'),127.0.0.1
    EOF
    chown -R mongod:mongod /mongodb
    su - mongod -s /bin/bash
    mongod -f /mongodb/conf/mongo.conf   
    mongod -f /mongodb/conf/mongo.conf --shutdown 关闭
    su - mongod -s /bin/bash
    mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork 手动启动 无需配置文件
    mongo 登录
    

    3.mongdb 的使用

    3.1 mongdb库

    test:登录时默认存在的库
    管理MongoDB有关的系统库
    admin库:系统预留库,MongoDB系统管理库
    local库:本地预留库,存储关键日志
    config库:MongoDB配置信息库
    
    database        #数据库
    collection  #集合,类似于mysql中的表
    filed           #类似于mysql中字段
    document    #每行的记录
    
    show databases/show dbs
    show tables/show collections 显示表
    use admin 
    db   当期路径
    use admin
    db.shutdownServer() 关闭数据库
    

    3.2 集合 增删改查

    增加: 无需定义字段约束
    use ceshi
    db.myuser.insert({name:"ceshi",age:28})
    show dbs
    show tables
    db.myuser.insert({name:"ceshi1",age:30})
    db.myuser.insert({tel:123456}) 可随便插入 
    查询:
    db.myuser.find() 查询
    db.myuser.find({name:"ceshi1"}) 有条件查询
    db.myuser.find({age:28})
    删除:
    use ceshi
    db.myuser.remove({name:'ceshi1'})
    db.myuser.remove({}) 删除表(集合)中数据
    db.myuser.drop({}) 删除表
    更新:
    db.myuser.update({'tel':123456},{$set:{'tel':7654321}})
    db.myuser.insert({name:'yy',age:22})
    db.myuser.update({name:'yy',age:22},{$set:{name:'ys'}})
    删除数据库
    use ceshi
    db.dropDatabase()
    

    3.3 集合的多种查询

    collection数据准备
    use shijiange
    db.myuser.insert( {name:"shijiange1", age: 20} )
    db.myuser.insert( {name:"shijiange2", age: 28} )
    db.myuser.insert( {name:"shijiange3", age: 38} )
    db.myuser.insert( {name:"zhangsan1", age: 58} )
    db.myuser.insert( {name:"zhangsan2", age: 68} )
    db.myuser.insert( {name:"zhangsan3", age: 25} )
    
    pretty易读的方式
    db.myuser.find().pretty()
    
    limit限制条数查询
    db.myuser.find()
    db.myuser.find().limit(2)       #查看前面两条记录
    
    使用skip跳过记录
    db.myuser.find().skip(2).limit(2)
    
    mongodb分页查询
    db.myuser.find().skip(0).limit(2)
    db.myuser.find().skip(2).limit(2)
    db.myuser.find().skip(4).limit(2)
    
    使用sort进行排序
    db.myuser.find().sort({ age: 1 })   #按age升序
    db.myuser.find().sort({ age: -1 })  #按age降序
    
    根据字段进行数字比较查询
    db.myuser.find({ age: {$lt: 30} })
    $gt #大于
    $lt #小于
    $gte    #大于或等于
    $lte    #小于或等于
    
    查询多种条件的组合
    db.myuser.find( {name: 'shijiange1'} )
    db.myuser.find( {name: 'shijiange2'} )
    db.myuser.find({ $or: [ {name: 'shijiange1'},{name: 'shijiange2'} ] })
    db.myuser.find({ $and: [ {name: 'shijiange1'},{age: 20} ] })
    
    mongodb正则查询,支持普通正则和扩展正则
    db.myuser.find({ name: {$regex: "shijiange[1-9]"} })    #普通正则过滤
    db.myuser.find( {"name":{$regex:"(zhangsan)"}} )        #支持分组正则
    

    3.4 索引查询

    use shijiange
    for(i=1;i<500000;i++){db.myuser.insert({name:'mytset'+i,age:i})}
    db.myuser.count() 查询行号
    mongodb有慢查询的概念,默认是超过100ms会记录慢日志mongodb.log
    db.getProfilingStatus() 打开
    查询age为9999的,查看扫描的行数
    db.myuser.find( {age:9999} )
    db.myuser.find( {age:9999} ).explain(true)  #使用explain可以查看是否全表扫描
    
    tailf /mongodb/log/mongodb.log
    2021-03-11T20:49:29.278+0800 I COMMAND  [conn4] command shijiange.myuser appName: "MongoDB Shell" command: find { find: "myuser", filter: { age: 9999.0 }, lsid: { id: UUID("c32761fb-08d2-4309-82a0-55ebf8932614") }, $db: "shijiange" } planSummary: COLLSCAN keysExamined:0 docsExamined:579377 cursorExhausted:1 numYields:4526 nreturned:3 reslen:282 locks:{ Global: { acquireCount: { r: 4527 } }, Database: { acquireCount: { r: 4527 } }, Collection: { acquireCount: { r: 4527 } } } storage:{} protocol:op_msg 169ms
    
    添加索引,加快查询
    db.myuser.getIndexes()          #获取当前索引,默认有_id的索引,所以用_id查是比较快
    db.myuser.ensureIndex( {age:1} )    #增加age的升序索引
    db.myuser.getIndexes()
    db.myuser.find( {age:9999} ) 再次查询 
    db.myuser.find( {age:9999} ).explain(true)
    db.myuser.dropIndex( {age:1} )  #删除索引
    
    使用正则的话,索引无效果
    db.myuser.find( {"name":"mytest1"} )
    db.myuser.ensureIndex( {name:1} )           #添加索引
    db.myuser.find( {"name":"mytest6"} )
    db.myuser.find( {"name":/99999/} )
    db.myuser.find( {"name":/99999/} ).explain(true)        #使用正则,全表扫描,也是慢
    
    mongodb建立唯一索引,唯一索引对应的值不能重复
    use shijiange
    db.myuser.insert( {userid:1} )
    db.myuser.insert( {userid:1} )
    db.myuser.remove({})        #清空数据
    db.myuser.ensureIndex( {userid:1},{unique:true} )   #创建唯一索引
    db.myuser.insert( {userid:1} )
    db.myuser.insert( {userid:2} )
    db.myuser.insert( {userid:1} )                  #因为是唯一索引,所以会报错
    

    4.用户及权限管理

    验证库: 建立用户时use到的库,在使用用户时,要加上验证库才能登陆。
    
    对于管理员用户,必须在admin下创建.
    1. 建用户时,use到的库,就是此用户的验证库
    2. 登录时,必须明确指定验证库才能登录
    3. 通常,管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库
    4. 如果直接登录到数据库,不进行use,默认的验证库是test,不是我们生产建议的.
    5. 从3.6 版本开始,不添加bindIp参数,默认不让远程登录,只能本地管理员登录。
    

    4.1 创建用户语法

    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 <name> -p <cleartext password>10.0.0.154/<验证库>
    

    4.2 创建管理员

    创建超级管理员:管理所有数据库(必须use admin再去创建)
    $ mongo
    use admin
    db.createUser(
    {
        user: "root",
        pwd: "root123",
        roles: [ { role: "root", db: "admin" } ]
    }
    )
    
    vim /mongodb/conf/mongo.conf  追加下面
    systemLog:
       destination: file
       path: "/mongodb/log/mongodb.log"
       logAppend: true
    storage:
       journal:
          enabled: true
       dbPath: "/mongodb/data/"
    processManagement:
       fork: true
    net:
       port: 27017
       bindIp: 10.0.0.154,127.0.0.1
    security:
      authorization: enabled
    
    systemctl restart mongod.service
    
    验证:
    mongo -uroot -proot123  admin
    mongo -uroot -proot123  10.0.0.154/admin
    
    或者
    mongo
    use admin
    db.auth('root','root123')
    查看当前用户
    use admin
    db.system.users.find().pretty()
    

    4.3 创建读写用户

    use app
    db.createUser(
        {
            user: "app01",
            pwd: "app01",
            roles: [ { role: "readWrite" , db: "app" } ]
        }
    )
    验证
    mongo  -uapp01 -papp01 10.0.0.154/app
    > use app
    switched to db app
    > db.myuser.insert({name:'app'})
    WriteResult({ "nInserted" : 1 })
    > db.myuser.find()
    { "_id" : ObjectId("604a18ea31bae3e7c35354a4"), "name" : "app" }
    > use rrr
    switched to db yyy
    > db.myuser.insert({name:'app'})
    WriteCommandError({
        "ok" : 0,
        "errmsg" : "not authorized on rrr to execute command { insert: \"myuser\", ordered: true, lsid: { id: UUID(\"9c843ae3-582a-41ea-aed2-0ec601a053f8\") }, $db: \"rrr\" }",
        "code" : 13,
        "codeName" : "Unauthorized"
    })
    

    4.4 删除用户

    mongo -uroot -proot123 10.0.0.154/admin 
    db.system.users.find().pretty() 查询用户验证库
    use app 进入验证库
    db.dropUser("app01") 
    
    1. 建用户要有验证库,管理员admin,普通用户是要管理的库
    2. 登录时,注意验证库
    mongo -uapp01 -papp01 10.0.0.154:27017/a
    3. 重点参数
    net:
       port: 27017
       bindIp: 10.0.0.154,127.0.0.1
    security:
       authorization: enabled
    

    5. 副本集 >=3个节点

    arbiter节点:主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务
    hidden节点:隐藏节点,不参与选主,也不对外提供服务。
    delay节点:延时节点,数据落后于主库一段时间,因为数据是延时的,也不应该提供服务或参与选主,所以通常会配合hidden(隐藏) 延时从库使用
    一般情况下会将delay+hidden一起配置使用
    

    5.1 副本集准备

    mkdir /mongodb/{28017,28018}/{conf,log,data} -p
    
    cat > /mongodb/28017/conf/mongo.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: $(ifconfig eth0|awk 'NR==2{print $2}'),127.0.0.1
      port: 28017
    replication:
      oplogSizeMB: 2048
      replSetName: my_repl
    EOF
    
    cat > /etc/systemd/system/mongod28017.service <<EOF
    [Unit]
    Description=mongodb 
    After=network.target remote-fs.target nss-lookup.target
    [Service]
    User=mongod
    Type=forking
    ExecStart=/mongodb/bin/mongod --config /mongodb/28017/conf/mongo.conf
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/mongodb/bin/mongod --config /mongodb/28017/conf/mongo.conf --shutdown
    PrivateTmp=true  
    [Install]
    WantedBy=multi-user.target
    EOF
    
    cat > /mongodb/28018/conf/mongo.conf <<EOF
    systemLog:
      destination: file
      path: /mongodb/28018/log/mongodb.log
      logAppend: true
    storage:
      journal:
        enabled: true
      dbPath: /mongodb/28018/data
      directoryPerDB: true
      #engine: wiredTiger
      wiredTiger:
        engineConfig:
          cacheSizeGB: 1
          directoryForIndexes: true
        collectionConfig:
          blockCompressor: zlib
        indexConfig:
          prefixCompression: true
    processManagement:
      fork: true
    net:
      bindIp: $(ifconfig eth0|awk 'NR==2{print $2}'),127.0.0.1
      port: 28018
    replication:
      oplogSizeMB: 2048
      replSetName: my_repl
    EOF
    
    cat > /etc/systemd/system/mongod28018.service <<EOF
    [Unit]
    Description=mongodb 
    After=network.target remote-fs.target nss-lookup.target
    [Service]
    User=mongod
    Type=forking
    ExecStart=/mongodb/bin/mongod --config /mongodb/28018/conf/mongo.conf
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/mongodb/bin/mongod --config /mongodb/28018/conf/mongo.conf --shutdown
    PrivateTmp=true  
    [Install]
    WantedBy=multi-user.target
    EOF
    
    chown -R mongod:mongod /mongodb
    systemctl daemon-reload
    systemctl start mongod28017.service
    systemctl start mongod28018.service
    
    配置介绍:
      #engine: wiredTiger 数据引擎
      wiredTiger:
        engineConfig:
          cacheSizeGB: 1 相当于mysql buff
          directoryForIndexes: true
    replication:
      oplogSizeMB: 2048  相当于mysql binlog  写入表中大小 默认是总磁盘的%5
      replSetName: my_repl  副本集名称 随意
    

    5.2 副本集配置

    1主2从,从库普通从库
    mongo --port 28017 admin
    config = {_id: 'my_repl', members: [
                              {_id: 0, host: '10.0.0.154:28017'},
                              {_id: 1, host: '10.0.0.154:28018'},
                              {_id: 2, host: '10.0.0.155:28017'}]
              }                   
    rs.initiate(config) 
    查询复制集状态
    rs.status();
    
    1主1从1 arbiterOnly 
    mongo -port 28017 admin
    config = {_id: 'my_repl', members: [
                              {_id: 0, host: '10.0.0.154:28017'},
                              {_id: 1, host: '10.0.0.154:28018'},
                              {_id: 2, host: '10.0.0.155:28017',"arbiterOnly":true}]
              }                
    rs.initiate(config) 
    
    rs.status();    //查看整体复制集状态
    rs.isMaster(); // 查看当前是否是主节点
    rs.conf();   //查看复制集配置信息
    rs.slaveOk() 改成 rs.secondaryOk() 从节点不需执行这个才能查看数据 
    

    5.3 副本集优先级调整 切换主从

    设置各个实例的优先权重,挑选自己想要的实例为主,只有primary可以更改权重配置
    conf = rs.config()          #获取副本集的配置,默认权重都是1
    conf.members[0].priority = 10   #索引号从0开始,每次递增1,类似数组
    conf.members[1].priority = 5
    conf.members[2].priority = 2
    rs.reconfig(conf)           #更新mongodb副本集的配置,优先权重最高的提升为primary,关闭启动后也为
    
    conf=rs.config()
    conf.members[0].priority=2
    conf.members[1].priority=5
    conf.members[2].priority=10
    rs.reconfig(conf)
    
    或者 
    --副本集角色切换(不要人为随便操作)
    admin> rs.stepDown()
    注:
    admin> rs.freeze(300) //锁定从,使其不会转变成主库
    freeze()和stepDown单位都是秒。
    

    5.4 副本集增加删除节点

    主节点操作PRIMARY: 必须  
    use admin
    rs.remove("ip:port"); // 删除一个节点 无法移除PRIMARY节点
    rs.add("ip:port"); // 新增从节点
    rs.addArb("ip:port"); // 新增仲裁节点
    
    use admin
    rs.remove("10.0.0.154:28018")
    rs.addArb('10.0.0.154:28018')
    rs.status(); 查看
    "stateStr" : "ARBITER",
    

    5.5 特殊从节点

    配置延时节点(一般延时节点也配置成hidden)
    cfg=rs.conf() 
    cfg.members[2].priority=0  #索引号从0开始,每次递增1,类似数组
    cfg.members[2].hidden=true
    cfg.members[2].slaveDelay=120
    rs.reconfig(cfg)    
    
    
    取消以上配置
    cfg=rs.conf() 
    cfg.members[2].priority=1
    cfg.members[2].hidden=false
    cfg.members[2].slaveDelay=0
    rs.reconfig(cfg)    
    配置成功后,通过以下命令查询配置后的属性
    rs.conf(); 
    
    查看副本节点(监控主从延时)
    admin> rs.printSlaveReplicationInfo()
    source: 192.168.1.22:27017
        syncedTo: Thu May 26 2016 10:28:56 GMT+0800 (CST)
        0 secs (0 hrs) behind the primary
    

    6. 分片集

    image.png
    角色 IP地址 shard sh1 shard sh2 configsvr router
    db01 10.0.0.154 38017 38018 38019 -
    db02 10.0.0.155 38017 38018 38019 -
    db03 10.0.0.156 38017 38018 38019 -
    db04 10.0.0.157 - - - 38020

    6.1 shard sh1 sh2 副本集

    mkdir /mongodb/{38017,38018,38019}/{conf,log,data} -p
    tar xf mongodb-linux-x86_64-rhel70-4.0.23.tgz
    cp -a mongodb-linux-x86_64-rhel70-4.0.23/bin/ /mongodb/
    useradd mongod -s /sbin/nologin
    
    cat >/etc/profile.d/mongod.sh <<EOF
    export PATH=\$PATH:/mongodb/bin
    EOF
    source /etc/profile.d/mongod.sh
    
    echo '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' >>/etc/rc.local
    chmod +x /etc/rc.d/rc.local
    
    echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled
    echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag 
    
    mkdir /mongodb/{38017,38018,38019}/{conf,log,data} -p
    cat > /mongodb/38017/conf/mongo.conf <<EOF
    systemLog:
      destination: file
      path: /mongodb/38017/log/mongodb.log
      logAppend: true
    storage:
      journal:
        enabled: true
      dbPath: /mongodb/38017/data
      directoryPerDB: true
      #engine: wiredTiger
      wiredTiger:
        engineConfig:
          cacheSizeGB: 1
          directoryForIndexes: true
        collectionConfig:
          blockCompressor: zlib
        indexConfig:
          prefixCompression: true
    processManagement:
      fork: true
    net:
      bindIp: $(ifconfig eth0|awk 'NR==2{print $2}'),127.0.0.1
      port: 38017
    replication:
      oplogSizeMB: 2048
      replSetName: sh1
    sharding:
      clusterRole: shardsvr
    EOF
    
    cat > /etc/systemd/system/mongod38017.service <<EOF
    [Unit]
    Description=mongodb 
    After=network.target remote-fs.target nss-lookup.target
    [Service]
    User=mongod
    Type=forking
    ExecStart=/mongodb/bin/mongod --config /mongodb/38017/conf/mongo.conf
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/mongodb/bin/mongod --config /mongodb/38017/conf/mongo.conf --shutdown
    PrivateTmp=true  
    [Install]
    WantedBy=multi-user.target
    EOF
    
    chown -R mongod:mongod /mongodb
    systemctl daemon-reload
    systemctl start mongod38017.service
    
    cat > /mongodb/38018/conf/mongo.conf <<EOF
    systemLog:
      destination: file
      path: /mongodb/38018/log/mongodb.log
      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
    processManagement:
      fork: true
    net:
      bindIp: $(ifconfig eth0|awk 'NR==2{print $2}'),127.0.0.1
      port: 38018
    replication:
      oplogSizeMB: 2048
      replSetName: sh2
    sharding:
      clusterRole: shardsvr
    EOF
    
    cat > /etc/systemd/system/mongod38018.service <<EOF
    [Unit]
    Description=mongodb 
    After=network.target remote-fs.target nss-lookup.target
    [Service]
    User=mongod
    Type=forking
    ExecStart=/mongodb/bin/mongod --config /mongodb/38018/conf/mongo.conf
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/mongodb/bin/mongod --config /mongodb/38018/conf/mongo.conf --shutdown
    PrivateTmp=true  
    [Install]
    WantedBy=multi-user.target
    EOF
    
    chown -R mongod:mongod /mongodb
    systemctl daemon-reload
    systemctl start mongod38018.service
    
    mongo --port 38017
    use  admin
    config = {_id: 'sh1', members: [
                              {_id: 0, host: '10.0.0.154:38017'},
                              {_id: 1, host: '10.0.0.155:38017'},
                              {_id: 2, host: '10.0.0.156:38017',"arbiterOnly":true}]
               }
    
    rs.initiate(config)
    ##arbiterOnly 也可以不是
    
    mongo --port 38018
    use  admin
    config = {_id: 'sh2', members: [
                              {_id: 0, host: '10.0.0.154:38018'},
                              {_id: 1, host: '10.0.0.155:38018'},
                              {_id: 2, host: '10.0.0.156:38018',"arbiterOnly":true}]
               }
    
    rs.initiate(config)
    

    6.2 config节点配置 不允许使用arbiterOnly节点

    cat > /mongodb/38019/conf/mongo.conf <<EOF
    systemLog:
      destination: file
      path: /mongodb/38019/log/mongodb.log
      logAppend: true
    storage:
      journal:
        enabled: true
      dbPath: /mongodb/38019/data
      directoryPerDB: true
      #engine: wiredTiger
      wiredTiger:
        engineConfig:
          cacheSizeGB: 1
          directoryForIndexes: true
        collectionConfig:
          blockCompressor: zlib
        indexConfig:
          prefixCompression: true
    processManagement:
      fork: true
    net:
      bindIp: $(ifconfig eth0|awk 'NR==2{print $2}'),127.0.0.1
      port: 38019
    replication:
      oplogSizeMB: 2048
      replSetName: configReplSet
    sharding:
      clusterRole: configsvr
    EOF
    
    cat > /etc/systemd/system/mongod38019.service <<EOF
    [Unit]
    Description=mongodb 
    After=network.target remote-fs.target nss-lookup.target
    [Service]
    User=mongod
    Type=forking
    ExecStart=/mongodb/bin/mongod --config /mongodb/38019/conf/mongo.conf
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/mongodb/bin/mongod --config /mongodb/38019/conf/mongo.conf --shutdown
    PrivateTmp=true  
    [Install]
    WantedBy=multi-user.target
    EOF
    
    chown -R mongod:mongod /mongodb
    systemctl daemon-reload
    systemctl start mongod38019.service
    
    mongo --port 38019
    use  admin
    config = {_id: 'configReplSet', members: [
                              {_id: 0, host: '10.0.0.154:38019'},
                              {_id: 1, host: '10.0.0.155:38019'},
                              {_id: 2, host: '10.0.0.156:38019'}]
               }
    
    rs.initiate(config)
    

    6.3 mongos节点配置 注意mongos启动

    mkdir /mongodb/38020/{conf,log,data} -p
    tar xf mongodb-linux-x86_64-rhel70-4.0.23.tgz
    cp -a mongodb-linux-x86_64-rhel70-4.0.23/bin/ /mongodb/
    useradd mongod -s /sbin/nologin
    
    cat >/etc/profile.d/mongod.sh <<EOF
    export PATH=\$PATH:/mongodb/bin
    EOF
    source /etc/profile.d/mongod.sh
    
    echo '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' >>/etc/rc.local
    chmod +x /etc/rc.d/rc.local
    
    echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled
    echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag 
    
    cat > /mongodb/38020/conf/mongos.conf <<EOF
    systemLog:
      destination: file
      path: /mongodb/38020/log/mongos.log
      logAppend: true
    net:
      bindIp: $(ifconfig eth0|awk 'NR==2{print $2}'),127.0.0.1
      port: 38020
    sharding:
      configDB: configReplSet/10.0.0.154:38019,10.0.0.155:38019,10.0.0.156:38019
    processManagement: 
      fork: true
    EOF
    cat > /etc/systemd/system/mongos38020.service <<EOF
    [Unit]
    Description=mongodb 
    After=network.target remote-fs.target nss-lookup.target
    [Service]
    User=mongod
    Type=forking
    ExecStart=/mongodb/bin/mongos --config /mongodb/38020/conf/mongos.conf
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/mongodb/bin/mongos --config /mongodb/38020/conf/mongos.conf --shutdown
    PrivateTmp=true  
    [Install]
    WantedBy=multi-user.target
    EOF
    chown -R mongod:mongod /mongodb
    systemctl daemon-reload
    systemctl start mongos38020.service
    
    mongo 10.0.0.157:38020/admin
    
    db.runCommand( { addshard : "sh1/10.0.0.154:38017,10.0.0.155:38017,10.0.0.156:38017",name:"shard1"} )
    db.runCommand( { addshard : "sh2/10.0.0.154:38018,10.0.0.155:38018,10.0.0.156:38018",name:"shard2"} )
    
    db.runCommand( { listshards : 1 } )
    sh.status();
    

    7 使用分片集群 range hash

    7.1 range分片配置与测试

    7.1.1 激活数据库分片功能

    mongo --port 38020 admin
    admin>  ( { enablesharding : "数据库名称" } )
    例如:
    admin> db.runCommand( { enablesharding : "ceshi" } )
    

    7.1.2 指定分片键对集合分片

    ### 创建索引
    use ceshi
    > db.vast.ensureIndex( { id: 1 } )
    ### 开启分片
    use admin
    > db.runCommand( { shardcollection : "ceshi.vast",key : {id: 1} } )
    

    7.1.3 集合分片验证

    admin> use ceshi
    ceshi> for(i=1;i<1000000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
    ceshi> db.vast.stats()
    

    7.1.3 验证结果

    use admin
    db.runCommand( { enablesharding : "xx" } )
    use xx
    db.yy.ensureIndex( { id: 1 } )
    use admin
    db.runCommand( { shardcollection : "xx.yy",key : {id: 1} } )
    use xx
    for(i=1;i<1000000;i++){ db.yy.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
    db.yy.stats()
    

    7.2 hash分片配置与测试

    对boy库下的vast大表进行hash
    创建哈希索引
    (1)对于boy开启分片功能
    mongo --port 38020 admin
    use admin
    admin> db.runCommand( { enablesharding : "boy" } )
    (2)对于boy库下的vast表建立hash索引
    use boy
    boy> db.vast.ensureIndex( { id: "hashed" } )
    (3)开启分片 
    use admin
    admin > sh.shardCollection( "boy.vast", { id: "hashed" } )
    (4)录入10w行数据测试
    use boy
    for(i=1;i<100000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
    (5)hash分片结果测试
    mongo --port 38017
    use boy
    db.vast.count();
    sh1:PRIMARY> db.vast.count()
    50393
    mongo --port 38018
    use boy
    db.vast.count();
    sh2:PRIMARY> db.vast.count()
    49606
    

    8. balancer操作

    https://docs.mongodb.com/manual/tutorial/manage-sharded-cluster-balancer/#schedule-the-balancing-window

    mongos的一个重要功能,自动巡查所有shard节点上的chunk的情况,自动做chunk迁移。
    什么时候工作?
    1、自动运行,会检测系统不繁忙的时候做迁移
    2、在做节点删除的时候,立即开始迁移工作
    3、balancer只能在预设定的时间窗口内运行
    
    有需要时可以关闭和开启blancer(备份的时候)
    mongos> sh.stopBalancer()
    mongos> sh.startBalancer()
    
    use config
    sh.setBalancerState( true )
    db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "3:00", stop : "5:00" } } }, true )
    
    sh.getBalancerWindow()
    sh.status()
    
    关于集合的balancer(了解下)
    关闭某个集合的balance
    sh.disableBalancing("students.grades")
    打开某个集合的balancer
    sh.enableBalancing("students.grades")
    确定某个集合的balance是开启或者关闭
    db.getSiblingDB("config").collections.findOne({_id : "students.grades"}).noBalance;
    

    9. mongodb 备份 恢复

    9.1 备份工具介绍

    9.1.1 备份工具介绍

    (1)**   mongoexport/mongoimport
    (2)***** mongodump/mongorestore
    

    9.1.2 备份工具区别

    应用场景总结:
    mongoexport/mongoimport:json csv 
    1、异构平台迁移  mysql  <---> mongodb
    2、同平台,跨大版本:mongodb 2  ----> mongodb 3
    mongodump/mongorestore
    日常备份恢复时使用.
    

    9.2 导出工具mongoexport

    use oldboy
    for(i=1;i<10000;i++){ db.log.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
    
    mongoexport具体用法如下所示:
    $ mongoexport --help  
    参数说明:
    -h:指明数据库宿主机的IP
    -u:指明数据库的用户名
    -p:指明数据库的密码
    -d:指明数据库的名字
    -c:指明collection的名字
    -f:指明要导出那些列
    -o:指明到要导出的文件名
    -q:指明导出数据的过滤条件
    --authenticationDatabase admin
    
    1.单表备份至json格式
    mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log -o /mongodb/log.json
    
    注:备份文件的名字可以自定义,默认导出了JSON格式的数据。
    
    2. 单表备份至csv格式
    如果我们需要导出CSV格式的数据,则需要使用----type=csv参数:
    
     mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log --type=csv -f id,name,age,date  -o /mongodb/log.csv
    

    9.3 导入工具mongoimport

    $ mongoimport --help
    参数说明:
    -h:指明数据库宿主机的IP
    -u:指明数据库的用户名
    -p:指明数据库的密码
    -d:指明数据库的名字
    -c:指明collection的名字
    -f:指明要导入那些列
    -j, --numInsertionWorkers=<number>  number of insert operations to run concurrently                                                  (defaults to 1)
    //并行
    数据恢复:
    1.恢复json格式表数据到log1
    mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log1 /mongodb/log.json
    2.恢复csv格式的文件到log2
    上面演示的是导入JSON格式的文件中的内容,如果要导入CSV格式文件中的内容,则需要通过--type参数指定导入格式,具体如下所示:
    [root@db01 mongodb]# head -n10 log.csv   csv备份中有一行数据
    id,name,age,date
    1,shenzheng,70,2021-03-15T08:18:31.722Z
    2,shenzheng,70,2021-03-15T08:18:32.539Z
    3,shenzheng,70,2021-03-15T08:18:32.541Z
    4,shenzheng,70,2021-03-15T08:18:32.541Z
    5,shenzheng,70,2021-03-15T08:18:32.542Z
    
    注意:
    (1)csv格式的文件头行,有列名字
    mongoimport   -uroot -proot123 --port 27017 --authenticationDatabase admin   -d oldboy -c log2 --type=csv --headerline --file  /mongodb/log.csv
    
    (2)csv格式的文件头行,没有列名字
    mongoimport   -uroot -proot123 --port 27017 --authenticationDatabase admin   -d oldboy -c log3 --type=csv -f id,name,age,date --file  /mongodb/log.csv
    --headerline:指明第一行是列名,不需要导入。
    

    9.4 案例 mysql数据导入mongodb中

    wget https://downloads.mysql.com/docs/world.sql.zip
    
    world数据库下city表进行导出,导入到mongodb
    
    (1)mysql开启安全路径
    vim /etc/my.cnf   --->添加以下配置
    secure-file-priv=/tmp
    
    --重启数据库生效
    /etc/init.d/mysqld restart
    
    (2)导出mysql的city表数据
    source /root/world.sql
    
    select * from world.city into outfile '/tmp/city1.csv' fields terminated by ',';
    
    (3)处理备份文件
    desc world.city
      ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
    | Name        | char(35) | NO   |     |         |                |
    | CountryCode | char(3)  | NO   | MUL |         |                |
    | District    | char(20) | NO   |     |         |                |
    | Population
    
    vim /tmp/city.csv   ----> 添加第一行列名信息
    
    ID,Name,CountryCode,District,Population
    
    (4)在mongodb中导入备份
    mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d world  -c city --type=csv -f ID,Name,CountryCode,District,Population --file  /tmp/city1.csv
    
    use world
    db.city.find({CountryCode:"CHN"});
    
    -------------
    world共100张表,全部迁移到mongodb
    
    select table_name ,group_concat(column_name) from columns where table_schema='world' group by table_name;
    
    select * from world.city into outfile '/tmp/world_city.csv' fields terminated by ',';
    
    select concat("select * from ",table_schema,".",table_name ," into outfile '/tmp/",table_schema,"_",table_name,".csv' fields terminated by ',';")
    from information_schema.tables where table_schema ='world';
    
    导入:
    提示,使用infomation_schema.columns + information_schema.tables
    
    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'; 
    

    9.5 mongodump和mongorestore

    mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘。
    但是存在的问题时使用mongodump产生的备份不一定是数据库的实时快照,如果我们在备份时对数据库进行了写入操作,
    则备份出来的文件可能不完全和Mongodb实时数据相等。另外在备份时可能会对其它客户端性能产生不利的影响。
    

    9.5.1 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
    
    全库备份
    mkdir /mongodb/backup
    mongodump -uroot -proot123 --port 27017 --authenticationDatabase admin -o /mongodb/backup
    [root@db01 ~]# ll /mongodb/backup
    总用量 0
    drwxr-xr-x 2 root root 128 3月  16 08:48 admin
    drwxr-xr-x 2 root root  53 3月  16 08:48 app
    drwxr-xr-x 2 root root 176 3月  16 08:48 oldboy
    drwxr-xr-x 2 root root  53 3月  16 08:48 shijiange
    drwxr-xr-x 2 root root  49 3月  16 08:48 world
    备份单库
    mongodump   -uroot -proot123 --port 27017 --authenticationDatabase admin -d world -o /mongodb/backup/
    备份单表集合
    mongodump   -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log -o /mongodb/backup/
    压缩备份
    mongodump   -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldguo -o /mongodb/backup/ --gzip
    mongodump   -uroot -proot123 --port 27017 --authenticationDatabase admin -o /mongodb/backup/ --gzip
    mongodump   -uroot -proot123 --port 27017 --authenticationDatabase admin -d app -c myuser -o /mongodb/backup/ --gzip
    [root@db01 ~]# ll /mongodb/backup/app/
    总用量 16
    -rw-r--r-- 1 root root  36 3月  16 08:48 myuser.bson
    -rw-r--r-- 1 root root  61 3月  16 08:52 myuser.bson.gz
    -rw-r--r-- 1 root root 124 3月  16 08:48 myuser.metadata.json
    -rw-r--r-- 1 root root 129 3月  16 08:52 myuser.metadata.json.gz
    bsondump myuser.bson 可以将bson转成json格式查看
    

    9.5.2 mongorestore的使用

    恢复单库
    mongorestore   -uroot -proot123 --port 27017 --authenticationDatabase admin -d world1  /mongodb/backup/world
    恢复单表
    mongorestore   -uroot -proot123 --port 27017 --authenticationDatabase admin -d world -c t1  --gzip  /mongodb/backup/app/myuser.bson.gz 
    drop表示恢复的时候把之前的集合drop掉(危险)
    mongorestore  -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy --drop  /mongodb/backup/oldboy
    

    10 mongodump、mongorestore高级应用 --oplog

    10.1 oplog介绍 副本集或者主从才有

    在replica set中oplog是一个定容集合(capped collection),它的默认大小是磁盘空间的5%(可以通过--oplogSizeMB参数修改).
    
    位于local库的db.oplog.rs
    其中记录的是整个mongod实例一段时间内数据库的所有变更(插入/更新/删除)操作。
    当空间用完时新记录自动覆盖最老的记录。
    其覆盖范围被称作oplog时间窗口。需要注意的是,因为oplog是一个定容集合,
    所以时间窗口能覆盖的范围会因为你单位时间内的更新次数不同而变化。
    想要查看当前的oplog时间窗口预计值,可以使用以下命令:
     use local 
     db.oplog.rs.find().pretty()
    "ts" : Timestamp(1553597844, 1),
    "op" : "n"
    "o"  :
    
    "i": insert
    "u": update
    "d": delete
    "c": db cmd
    
    my_repl:PRIMARY> rs.printReplicationInfo()
    configured oplog size:   2048MB   集合大小
    log length start to end: 40746secs (11.32hrs)  预计日志覆盖时间
    oplog first event time:  Tue Mar 16 2021 09:20:59 GMT+0800 (CST)
    oplog last event time:   Tue Mar 16 2021 20:40:05 GMT+0800 (CST)
    now:                     Tue Mar 16 2021 20:40:10 GMT+0800 (CST)
    集合大小的设置 根据备份周期设置 
    例如设置2048M 预计11.32小时重复覆盖日志 如果备份周期24H 设置是不合适的
    

    10.2 oplog企业级应用

    (1)实现热备,在备份时使用--oplog选项
    注:为了演示效果我们在备份过程,模拟数据插入
    (2)准备测试数据
    [mongod@db01 conf]$ mongo --port 28018
    my_repl:PRIMARY> use local
    my_repl:PRIMARY> db.oplog.rs.find({"op":"i"}).count()
    103
    
    use oldboy
    for(var i = 1 ;i < 100; i++) {
        db.foo.insert({a:i});
    }
    my_repl:PRIMARY> use local
    my_repl:PRIMARY> db.oplog.rs.find({"op":"i"}).pretty()
    202
    oplog 配合mongodump实现热备
    mongodump --port 28018 --oplog -o /mongodb/backup
    [root@db01 backup]# ll /mongodb/backup
    总用量 4
    drwxr-xr-x 2 root root  69 3月  16 20:50 admin
    drwxr-xr-x 2 root root  47 3月  16 20:50 oldboy
    -rw-r--r-- 1 root root 110 3月  16 20:50 oplog.bson
    作用介绍:--oplog 会记录备份过程中的数据变化。会以oplog.bson保存下来
    恢复
    mongorestore  --port 28018 --oplogReplay /mongodb/backup
    

    10.3 oplog高级应用

    背景:每天0点全备,oplog恢复窗口为48小时
    某天,上午10点world.city 业务表被误删除。
    恢复思路:
        0、停应用
        2、找测试库
        3、恢复昨天晚上全备
        4、截取全备之后到world.city误删除时间点的oplog,并恢复到测试库
        5、将误删除表导出,恢复到生产库
    
    恢复步骤:
    模拟故障环境:
    
    1、全备数据库
    模拟原始数据
    
    mongo --port 28018
    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表
    10:00时刻,误删除
    db.ci.drop()
    show tables;
    
    3、备份现有的oplog.rs表
    mongodump --port 28018 -d local -c oplog.rs  -o /mongodb/backup
    
    4、截取oplog并恢复到drop之前的位置
    更合理的方法:登陆到原数据库
    [mongod@db03 local]$ mongo --port 28018
    my_repl:PRIMARY> use local
    db.oplog.rs.find({op:"c"}).pretty();
    {
        "ts" : Timestamp(1615899485, 1),
        "t" : NumberLong(1),
        "h" : NumberLong("-6643941241438205217"),
        "v" : 2,
        "op" : "c",
        "ns" : "wo.$cmd",
        "ui" : UUID("37f2cb0a-fc60-482c-a358-d2214da0bfc2"),
        "wall" : ISODate("2021-03-16T12:58:05.706Z"),
        "o" : {
            "drop" : "ci"
        }
    }
    
    
    获取到oplog误删除时间点位置:
    "ts" : Timestamp(1615899485, 1)
    
     5、恢复备份+应用oplog
    [mongod@db03 backup]$ cd /mongodb/backup/local/
    [mongod@db03 local]$ ls
    oplog.rs.bson  oplog.rs.metadata.json
    [mongod@db03 local]$ cp oplog.rs.bson ../oplog.bson 
    rm -rf /mongodb/backup/local/
     
    mongorestore --port 28018  --oplogReplay --oplogLimit "1615899485:1"  --drop   /mongodb/backup/
    验证:
    my_repl:PRIMARY> show dbs;
    admin   0.000GB
    config  0.000GB
    local   0.000GB
    oldboy  0.000GB
    wo      0.000GB
    my_repl:PRIMARY> use wo;
    switched to db wo
    my_repl:PRIMARY> show tables;
    ci
    ci1
    ci2
    my_repl:PRIMARY> db.ci.count()
    19
    

    相关文章

      网友评论

          本文标题:mongodb

          本文链接:https://www.haomeiwen.com/subject/cmtzqltx.html