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. 分片集
角色 | 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操作
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