MongoDB安装部署及操作
目录
安装服务套路
MongoDB安装部署及操作
安装
yum install libcurl openssl -y
mkdir /opt/mongo_cluster/ -p
mkdir /data/soft -p
cd /data/soft/
#wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.13.tgz
tar zxvf mongodb-linux-x86_64-3.6.13.tgz -C /opt/mongo_cluster/
cd /opt/mongo_cluster/ && ln -s mongodb-linux-x86_64-3.6.13 mongodb
mkdir /opt/mongo_cluster/mongo_27017/{conf,logs,pid} -p
mkdir /data/mongo_cluster/mongo_27017 -p
配置启动:
cat > /opt/mongo_cluster/mongo_27017/conf/mongodb.conf << EOF
systemLog:
destination: file
logAppend: true
path: /opt/mongo_cluster/mongo_27017/logs/mongodb.log
storage:
journal:
enabled: true
dbPath: /data/mongo_cluster/mongo_27017
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
pidFilePath: /opt/mongo_cluster/mongo_27017/pid/mongod.pid
net:
port: 27017
bindIp: 127.0.0.1,10.0.0.51
EOF
2.启动命令
cd /opt/mongo_cluster/
mongodb/bin/mongod -f mongo_27017/conf/mongodb.conf
3.检查
ps -ef|grep mongo
netstat -lntup|grep 27017
4.登录
mongodb/bin/mongo db01:27017
5.关闭
mongodb/bin/mongod -f mongo_27017/conf/monogdb.conf --shutdown
6 警告解决:
优化警告
#解决大内存页警告
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
-----------------
vim /etc/init.d/disable-transparent-hugepages
#!/bin/bash
### BEGIN INIT INFO
# Provides: disable-transparent-hugepages
# Required-Start: $local_fs
# Required-Stop:
# X-Start-Before: mongod mongodb-mms-automation-agent
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Disable Linux transparent huge pages
# Description: Disable Linux transparent huge pages, to improve
# database performance.
### END INIT INFO
case $1 in
start)
if [ -d /sys/kernel/mm/transparent_hugepage ]; then
thp_path=/sys/kernel/mm/transparent_hugepage
elif [ -d /sys/kernel/mm/redhat_transparent_hugepage ]; then
thp_path=/sys/kernel/mm/redhat_transparent_hugepage
else
return 0
fi
echo 'never' > ${thp_path}/enabled
echo 'never' > ${thp_path}/defrag
re='^[0-1]+$'
if [[ $(cat ${thp_path}/khugepaged/defrag) =~ $re ]]
then
# RHEL 7
echo 0 > ${thp_path}/khugepaged/defrag
else
# RHEL 6
echo 'no' > ${thp_path}/khugepaged/defrag
fi
unset re
unset thp_path
;;
esac
------------------
chmod 755 /etc/init.d/disable-transparent-hugepages
chkconfig --add disable-transparent-hugepages
#普通用户启动
/opt/mongo_cluster/mongodb/bin/mongod -f /opt/mongo_cluster/mongo_27017/conf/mongodb.conf --shutdown
> useradd mongo
> echo '123456'|passwd --stdin mongo
chown -R mongato:mongo /opt/mongo_cluster
chown -R mongo:mongo /data/mongo_cluster
su - mongo
vim .bashrc
export PATH=/opt/mongo_cluster/mongodb/bin:$PATH
source .bashrc
mongod -f /opt/mongo_cluster/mongo_27017/conf/mongodb.conf
mongo
基础命令
> show databases
admin 0.000GB
config 0.000GB
local 0.000GB
>
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
>
> db
test
> use local
switched to db local
>
> db
local
> show tables
startup_log
### 插入数据
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.insert({"name":"yazhang","age":28,"ad":"北京市朝阳区"})
db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区"})
db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区","sex":"boy"})
##### 批量插入多条数据
db.inventory.insertMany( [
{ "item": "journal", "qty": 25, "size": { "h": 14, "w": 21, "uom": "cm" }, "status": "A" },
{ "item": "notebook", "qty": 50, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "A" },
{ "item": "paper", "qty": 100, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "D" },
{ "item": "planner", "qty": 75, "size": { "h": 22.85, "w": 30, "uom": "cm" }, "status": "D" },
{ "item": "postcard", "qty": 45, "size": { "h": 10, "w": 15.25, "uom": "cm" }, "status": "A" }
]);
##### 查询数据
db.test.find() #查询test表下所有数据
db.test.findOne() #查询一条数据
db.inventory.find() #查询表下所有数据
db.inventory.findOne() #查询一条数据
###### 条件查询
db.inventory.find({"status":"D"})
db.inventory.find({"size.uom":"cm"})
db.inventory.find({"size.uom":"cm","qty":{$lt: 50}})
db.inventory.find({"status":"A","qty":{$lt:50}})
db.inventory.find(
{
"size.uom":"cm", c# 查询
"qty": #条件
{
$lt:50 #小于50
}
}
)
# 且语句
> db.inventory.find({"size.h":{$gt:11},"qty":{$lt:50}})
{ "_id" : ObjectId("5d232ffb441afa799e27dd0f"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }
> db.inventory.find({"size.h":{$gt:11},"qty":{$lt:100}})
{ "_id" : ObjectId("5d232ffb441afa799e27dd0f"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }
{ "_id" : ObjectId("5d232ffb441afa799e27dd12"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }
# 或语句
db.inventory.find({$or:[{"status":"A"},{"status":"D"}]})
db.inventory.find( {
$and : [
{ $or : [ { "status" : "D" }, {"qty":{$lt: 50}} },
{ $or : [ { "status" : "A" }, {"qty":{$lt: 50} } ] }
]})
myCursor = db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
})
# 更新 修改
更新前的内容
db.inventory.find({ "item" : "paper" })
{ "_id" : ObjectId("5d22be4e0e03689b676725dc"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }
更新语句
db.inventory.updateOne(
{ "item" : "paper" },
{
$set: { "size.uom" : "cm", "status" : "P" },
$currentDate: { "lastModified": true }
}
)
更新后的内容
db.inventory.find( { "item" : "paper" } )
{ "_id" : ObjectId("5d22be4e0e03689b676725dc"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-07-08T07:06:00.748Z")}
更新多条
db.inventory.updateMany(
{ "qty" : { $lt: 50 } },
{
$set: { "size.uom" : "cm", "status": "P" },
$currentDate : { "lastModified": true }
}
)
db.inventory.updateOne(
{ "qty" : { $lt: 50 } },
{
$set: { "size.uom" : "cm", "status": "P" },
$currentDate : { "lastModified": true }
}
)
db.inventory.updateMany(
{ "qty" : { $lt: 50 } },
{
$set: { "size.uom" : "cm", "status": "P" },
$currentDate : { "lastModified": true }
}
)
db.inventory.updateOne(
{"item":"journal"},
{$set:
{"size.h":"100"},
$currentDate:{"lastModified":true}
}
)
删除内容
db.inventory.find( {"status" : "D"})
db.inventory.deleteOne(
{"status" : "D"}
)
删除匹配到的内容
db.inventory.find( {"status" : "P"})
db.inventory.deleteMany(
{"status" : "P"}
)
mongo分析工具
mongotop #另一窗口查看数据库正在工作的语句
mongostat #另一窗口查看数据库正在工作的语句
#实验语句
for(i=0;i<100000;i++){db.log.insert({"uid":i,"name":"mongodb","age":6})}
用户授权认证
use admin
db.createUser(
{
user: "admin",
pwd: "123456",
roles:[ { role: "root", db:"admin"}]}
)
--------------role里的角色可以选:
Built-In Roles(内置角色):
.1. 数据库用户角色:read、readWrite;
.2. 数据库管理角色:dbAdmin、dbOwner、userAdmin;
.3. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
.4. 备份恢复角色:backup、restore;
.5. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
.6. 超级用户角色:root
// 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
.7. 内部角色:__system
具体角色:
Read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
backup,retore:在进行备份、恢复时可以单独指定的角色,在db.createUser()方法中roles里面的db必须写成是admin库,要不然会 报错
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限,
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
root:只在admin数据库中可用。超级账号,超级权限
修改配置文件
vim /opt/mongo_cluster/mongo_27017/conf/mongodb.conf
# 添加
security:
authorization: enabled
重启服务
mongod -f /opt/mongo_cluster/mongo_27017/conf/mongodb.conf --shutdown
mongod -f /opt/mongo_cluster/mongo_27017/conf/mongodb.conf
登录
mongo
show dbs
mongo -uadmin -p
show dbs
用户
1.使用admin用户登录
mongo -uadmin -p
show dbs
2.切换到test库,并创建一个用户赋予不同库的不同角色
use test
db.createUser(
{
user: "myTester",
pwd: "xyz123",
roles: [ { role: "readWrite", db: "test" },
{ role: "read", db: "test2" } ]
}
)
3.在test库下插入测试数据
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.test.insert({"name":"yazhang","age":28,"ad":"北京市朝阳区"})
db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区"})
4.在test2库下插入测试数据
use test2
db.test2.insert({"name":"zhangya","age":27,"ad":"北京市昌平区"})
db.test2.insert({"name":"zhangya","age":27,"ad":"北京市昌平区"})
db.test2.insert({"name":"yazhang","age":28,"ad":"北京市昌平区"})
5.使用myTester用户登录到test验证库
mongo -umyTester -pxyz123 db01:27017/test
show dbs
db
6.切换到test库,测试能否读写
use test
db.test.insert({"name":"58NB","age":27,"ad":"北京市朝阳区"})
db.test.find()
7.切换到test2库,测试能否读写
use test2
db.test2.insert({"name":"58NB","age":27,"ad":"北京市昌平区"})
db.test2.find()
多实例
Mongo用户下
su - mongo
副本集配置
1.创建配置文件目录
mkdir -p /opt/mongo_cluster/mongo_2801{7,8,9}/{conf,logs,pid}
2.修改副本集配置文件
cat >/opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf <<EOF
systemLog:
destination: file
logAppend: true
path: /opt/mongo_cluster/mongo_28017/logs/mongodb.log
storage:
journal:
enabled: true
dbPath: /data/mongo_cluster/mongo_28017
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 0.5
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
pidFilePath: /opt/mongo_cluster/mongo_28017/pid/mongod.pid
net:
port: 28017
bindIp: 127.0.0.1,10.0.0.51
replication:
oplogSizeMB: 1024
replSetName: dba58
EOF
3.复制配置文件到其他目录
cp /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf /opt/mongo_cluster/mongo_28018/conf/mongo_28018.conf
cp /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf /opt/mongo_cluster/mongo_28019/conf/mongo_28019.conf
4.修改配置文件里的端口
sed -i 's#28017#28018#g' /opt/mongo_cluster/mongo_28018/conf/mongo_28018.conf
sed -i 's#28017#28019#g' /opt/mongo_cluster/mongo_28019/conf/mongo_28019.conf
5.创建数据目录
mkdir /data/mongo_cluster/mongo_2801{7,8,9}
6.启动多实例
mongod -f /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf
mongod -f /opt/mongo_cluster/mongo_28018/conf/mongo_28018.conf
mongod -f /opt/mongo_cluster/mongo_28019/conf/mongo_28019.conf
7.初始化副本集
config = {
_id : "dba58",
members : [
{_id : 0, host : "db01:28017"},
{_id : 1, host : "db01:28018"},
{_id : 2, host : "db01:28019"},
] }
rs.initiate(config)
8.查看副本集状态
rs.status()
# 主
db.inventory.insertMany( [
{ "item": "journal", "qty": 25, "size": { "h": 14, "w": 21, "uom": "cm" }, "status": "A" },
{ "item": "notebook", "qty": 50, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "A" },
{ "item": "paper", "qty": 100, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "D" },
{ "item": "planner", "qty": 75, "size": { "h": 22.85, "w": 30, "uom": "cm" }, "status": "D" },
{ "item": "postcard", "qty": 45, "size": { "h": 10, "w": 15.25, "uom": "cm" }, "status": "A" }
]);
# 从
8.查看副本集状态
rs.status()
##### 报错
临时解决
rs.slaveOk();
永久解决
echo "rs.slaveOk();" >> .mongorc.js
权重调整+主库降级
1.查看配置信息
rs.conf()
2.配置权重
config = rs.conf()
config.members[2].priority=100
3.重新导入配置信息
rs.reconfig(config)
4.主库降级,发起重新选举
rs.stepDown()
5.恢复成默认权重
config = rs.conf()
config.members[2].priority=1
rs.reconfig(config)
rs.stepDown()
增加节点
1.安装配置启动新节点
mkdir /opt/mongo_cluster/mongo_28010/{conf,logs,pid} -p
mkdir /data/mongo_cluster/mongo_28010
cp /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf /opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf
sed -i 's#28017#28010#g' /opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf
mongod -f /opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf
mongo db01:28010
2.主库执行添加新节点操作
use admin
rs.add("db01:28010")
删除旧节点
1.主库操作,删除旧节点
mongo db01:28017
rs.remove("db01:28010")
2.节点下线
mongod -f /opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf --shutdown
添加仲裁节点
1.清空28010节点的数据
rm -rf /data/mongo_cluster/mongo_28010/*
2.重新启动
mongod -f /opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf
3.检查
mongo db01:28010
4.主库操作
mongo db01:28017
rs.addArb("db01:28010")
5.查看节点状态
mongo db01:28010
备份恢复
导出
mongoexport --port 28017 -d dba -c inventory -o /backup/log.json
mongoexport --port 28017 -d dba -c inventory --type=csv -f item,qty,size,status -o /backup/log.csv
导入
mongoimport --port 28017 -d oldboy -c inventory /backup/log.json
导入CSV
mongoimport --port 28017 -d dba58 -c log2 --type=csv --headerline -f item,qty,size,status --file /backup/log.csv
mysql导出csv
select * from world.city into outfile '/tmp/city1.csv' fields terminated by ',';
导入csv
mongoimport --port 28017 -d world -c city --type=csv -f ID,Name,CountryCode,District,Population --file /tmp/city1.csv
全备
mongodump --port 28017 -o /data/backup
只备一个库
mongodump --port 28017 -d world -o /data/backup
恢复:
mongorestore --port 28017 -d world1 /data/backup/world/
恢复之前先删除
mongorestore --port 28017 -d world1 /data/backup/world/ --drop
db.oplog.rs.find({"op":"i","ns" : "oldboy.foo"}).pretty()
{
"ts" : Timestamp(1562586945, 1),
"t" : NumberLong(6),
"h" : NumberLong("-3385388396708106697"),
"v" : 2,
"op" : "c",
"ns" : "wo.$cmd",
"ui" : UUID("f8a551a8-bde0-4456-a2bc-3c449da7864d"),
"wall" : ISODate("2019-07-08T11:55:45.409Z"),
"o" : {
"drop" : "ci"
}
}
mongorestore --port 28017 --oplogReplay --oplogLimit "1562586945:1" --drop /data/backup/
报错总结
报错记录1
> db.test.insert({"name":"yazhangya","age":27,"ad":"北京市朝阳区"})
WriteResult({
"writeError" : {
"code" : 13,
"errmsg" : "not authorized on test2 to execute command { insert: \"test\", ordered: true, lsid: { id: UUID(\"01431e12-5d4a-47a9-8ac4-657ab08fda7c\") }, $db: \"test2\" }"
}
})
问题原因:
当前登录的用户对这个库没有写入权限
报错记录2
dba58:SECONDARY> show tables
2019-07-08T17:50:44.576+0800 E QUERY [thread1] Error: listCollections failed: {
"operationTime" : Timestamp(1562579435, 1),
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk",
"$clusterTime" : {
"clusterTime" : Timestamp(1562579435, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
} :
解决方法:
临时解决
rs.slaveOk();
永久解决
echo "rs.slaveOk();" >> .mongorc.js
db.inventory.deleteOne( {"item" : "journal"})
报错记录3
从库执行命令
db.inventory.deleteOne( {"item" : "journal"})
2019-07-08T18:03:45.247+0800 E QUERY [thread1] WriteCommandError: not master :
WriteCommandError({
"operationTime" : Timestamp(1562580215, 1),
"ok" : 0,
"errmsg" : "not master",
"code" : 10107,
"codeName" : "NotMaster",
"$clusterTime" : {
"clusterTime" : Timestamp(1562580215, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
})
问题原因:
从库不能执行增删改命令
报错记录4
2019-07-08T18:58:31.608+0800 I NETWORK [thread1] trying reconnect to db01:28010 (10.0.0.51) failed
2019-07-08T18:58:31.609+0800 I NETWORK [thread1] reconnect db01:28010 (10.0.0.51) ok
dba58:OTHER>
dba58:OTHER>
问题原因:
不在集群内或者被集群移除了
菜鸟9528号,请求开炮。