mongodb常见问题处理⽅法收集
1 ⾮正常关闭服务或关机后 mongod服务⽆法正常启动
在使⽤中发现mongodb 的服务很容易因为⾮正常关闭⽽启动不了,不过解决也很容易
删除data⽬录下的 *.lock⽂件,再运⾏下 /mongodb_binpath/mongod -repair -f config⽂件路径再启动即可
也可以在/etc/init.d/mongod 服务启动的⽂件中加⼊启动前删除该⽂件如下:
server error翻译start() {
rm -f /usr/mongodb/data/master/mongod.lock
/usr/mongodb/bin/mongod --config /usr/mongodb/f
}
2、server-side JavaScript execution is disabled
完整信息:JavaScript execution failed: group command failed: { "ok" : 0, "errmsg" : "server-side JavaScript execution is disabled" }
解决⽅法:f 这个配置⽂件⾥ noscripting:false 如果true 就是禁⽌
3、 Decimal转换成BsonValue值异常
BsonValue 暂不⽀持 Decimal类型,转换前强制转换类型,
if (type==typeof(Decimal))
{
return Convert.ToDouble(value);
}
如果⽤MongoDB,最好不要⽤decimal类型,否则在序列化的时候也有问题,可⽤double
4、MONGO Replica 频繁插⼊⼤数据的问题
MONGO Replica 频繁插⼊⼤数据的问题,当在复制集中频繁插⼊⼤数据时有可能出现 “error RS102 too stale to catch up"出现这个错误的原因是SECONDARY即副节点的复制速度跟不上了,当需要批量频繁向副本集中写⼊数据时最好先移除副本节点,待插⼊完后重新同步。
5 Mongo集没有primary但有secondary时连接不上且不能读数据
#mongodb默认是从主节点读写数据的,副本节点上不允许读,需要设置副本节点可以读。
shell
1 repset:SECONDARY> db.getMongo().setSlaveOk(); #要在primary上执⾏
2 rs.slaveOk()
其他客户端
从secondary 读数据
如果应⽤程序没有设置相应的ReadReference也可能不能进⾏读取操作
MongoClientSettings set = new MongoClientSettings();
List<MongoServerAddress> servers = new List<MongoServerAddress>();
servers.Add(new MongoServerAddress("192.168.129.129", 37017));
servers.Add(new MongoServerAddress("192.168.129.129", 37018));
servers.Add(new MongoServerAddress("192.168.129.129", 37019));
set.Servers = servers;
//设置副本集名称
set.ReplicaSetName = "rs0";
//设置超时时间为3秒
set.ConnectTimeout = new TimeSpan(0, 0, 0, 3, 0);
MongoClient client = new MongoClient(set);
MongoServer server = client.GetServer();
MongoDatabase db = server.GetDatabase("test");
MongoCollection coll = db.GetCollection("test");
注:设置驱动的ReadReference也可以通过MongoDB连接字符串配置:
mongodb://example1,example2,example3/?readPreference=secondary。通过连接字符串指定的read preference是针对整个连接。
set.ReadPreference = new ReadPreference(ReadPreferenceMode.PrimaryPreferred);
将ReadPreferenceMode设置成Secondary或SecondaryPreferred
下⾯是其他⽹友的补充:
⼀、
1. addshard 遇到的错误 db.runCommand({addshard:”17
2.16.5.104:20000″}) { “ok” : 0, “errmsg” : “can't use localhost as a shard since all shards need to communicate. either use all shards and configdbs in localhost or all in actual IPs host: 172.16.5.104:20
000 isLocalHost:0″ } 遇到这样的错误是由于某些服务启动在 localhost 地址。经过检查发现 route 启动时,读取 config 服务是读取的 localhost 地址: ./mongos –port 40000 –configdb localhost:30000 –fork [...]
1. addshard 遇到的错误
db.runCommand({addshard:”172.16.5.104:20000″})
{
“ok” : 0,
“errmsg” : “can't use localhost as a shard since all shards need to communicate. either use all shards and configdbs in localhost or all in actual IPs host: 172.16.5.104:20000 isLocalHost:0″
}
遇到这样的错误是由于某些服务启动在 localhost 地址。
经过检查发现 route 启动时,读取 config 服务是读取的 localhost 地址:
.
/mongos –port 40000 –configdb localhost:30000 –fork –logpath /data/route/log/route.log –chunkSize 1
将 localhost 修改为 IP 地址,问题解决。
2. 为什么要同时有 config 和 route
⼀开始看到 config 和 route 的逻辑结构有⼀点疑惑。既然⼀个数据库查询的过程是:
客户端
|
route
|
config
|
Database
⽽ config 的作⽤就是告诉 route 应该去哪⼀个 Database 取数据。那么为什么不能直接由客户端向 config 发起请求呢?这时route 的存在岂不是多余?
简单的思考之后,得出了以下结论:
在有多个 route 和多个 config 的情况下,route 与 route 之间是平⾏的存在,也就是说,⼀个 route 并不知道另外⼀个 route 的存在。但是⼀个 route 知道所有 config 的存在。
那么当要写⼊数据时,只要你是通过了 route,route 就会通知到所有的 config,那么每⼀个 config 便会知道数据是如何分⽚的。
如果将 route 这层去掉,那么 config 与 config 之间并不知道彼此的存在。客户端的请求很可能会只发向其中的⼀个 config,那么也只有这⼀个 config 知道最新的分⽚状态。
这个答案其实经不起太多的推敲,⽐如:
config 是可以从客户端那⾥拿到所有 config 的列表的,⼀旦有了列表之后,config 就可以彼此相互通信了。可以解决数据同步的问题。
我还要看多⼀些⽂档。
3. Replica Set 启动顺序
在启动两个 rs 机器时,我先启动了 second,后启动了 Primary。这是⼀台机器上显⽰⾃⼰为 second,另外⼀台为unreachable。⽽另外⼀台机器显⽰两台机器均在 second。
这个现象需要验证,是否 Replica Set 是有启动顺序限制。
⼆、
昨天到今天⼀直在尝试在同⼀台机器上⽤多个IP地址来创建 Replica Set + Shard。由于 MongoDB 官⽅⽤户验证⽅⾯的⽂档
说的也不太细。所以⾛了⼀些回头路。下⾯整理⼀些常见的错误,以及他们可能表达的意思。描述的顺序是按照排错的逻辑: 1. route 启动的时候,连接 config 不可以以 localhost 为地址链接。不然会遇到以下错误: “errmsg” : “can't use localhost as a shard since all shards need to communicate. either use all shards and configdbs in localhost or all in actual IPs host: 172.16.5.104:20000 isLocalHost:0″ 2. 如果不以 localhost 为地址链接,那么 config 启动的时候不能加 –auth 选项,不然会在log⽂件中遇到以下错误: ERROR: [...]
昨天到今天⼀直在尝试在同⼀台机器上⽤多个IP地址来创建 Replica Set + Shard。
由于 MongoDB 官⽅⽤户验证⽅⾯的⽂档说的也不太细。所以⾛了⼀些回头路。
下⾯整理⼀些常见的错误,以及他们可能表达的意思。描述的顺序是按照排错的逻辑:
1. route 启动的时候,连接 config 不可以以 localhost 为地址链接。不然会遇到以下错误:
“errmsg” : “can't use localhost as a shard since all shards need to communicate. either use all shards and configdbs in localhost or all in actual IPs host: 172.16.5.104:20000 isLocalHost:0″
2. 如果不以 localhost 为地址链接,那么 config 启动的时候不能加 –auth 选项,不然会在log⽂件中遇到以下错误:ERROR: config servers not in sync! not authorized, did you start with –keyFile?
此时进程⽆法启动
3.在 route 和 config 准备完毕后,通过 route 以远程 IP 为地址添加shard,则报错:(有 –auth 参数)
db.runCommand({addshard:'a1:28010′})
{
“ok” : 0,
“errmsg” : “failed listing a1:28010′s databases:{ errmsg: \”need to login\”, ok: 0.0 }”
}
4. 去掉 –auth 参数,添加 shard,成功!
5. 依旧保留 –auth 参数,添加⽤户后,再添加shard。报错:
“errmsg” : “couldn't connect to new shard DBClientBase::findN: transport error: a1:28010 query: { getlasterror: 1 }”
总结:MongoDB 2.0 的认证⽅式
1.Replica Set 之间通过 key 来相互认证。
2.Route 与 Config 之间不存在认证关系,Route 连接 Config 时不能以 localhost 连接。
3.单个Mongod进程启动后,如果⽆ –auth 选项且⽆⽤户,则必须通过 localhost 连接才能添加⽤户和做其他操作。如果通过远程(⾮127.0.0.1的IP地址)连接,则必须要输⼊⽤户名、密码。此时如果还⽆⽤户存在,则⽆法连接。
4.添加 Shard 时,mongod 不可以带 –auth 参数,不然会添加失败。
三、
续上篇笔记2 ,还是说⼀下关于 MongoDB 认证的问题。在王⽂龙所写的《MongoDB 实战》中,写到:创建主从 key ⽂件,⽤于标识集的私钥的完整路径,如果各个实例的 key file 内容不⼀致,程序将不能正常⽤。我误以为 –keyFile 是各个节点之间的认证⽅式。其实不是的。各个节点之间的确认关系参数是 –replSet。只要此参数后⾯的内容⼀致。Replica Set 就可以创建成功。在官⽅⽂档中提到: You do not need to use the –auth option, too (although there's no harm in doing so), –keyFile implies –auth. –auth does not imply –keyFile. 也就是说 keyFile 其实包含了 auth 的作⽤。 [...]
续上篇笔记2 ,还是说⼀下关于 MongoDB 认证的问题。
在王⽂龙所写的《MongoDB 实战》中,写到:
创建主从 key ⽂件,⽤于标识集的私钥的完整路径,如果各个实例的 key file 内容不⼀致,程序将不能正常⽤。
我误以为 –keyFile 是各个节点之间的认证⽅式。其实不是的。各个节点之间的确认关系参数是 –replSet。只要此参数后⾯的内容⼀致。Replica Set 就可以创建成功。
在官⽅⽂档中提到:
You do not need to use the –auth option, too (although there's no harm in doing so), –keyFile implies –auth. –auth does not imply –keyFile.
也就是说 keyFile 其实包含了 auth 的作⽤。
⽽当你加了 –keyFile 参数后,如果你要添加 Shard,则会收到报错:
need to login
这和加了 auth 的报错⼀致。
以前没接触过 MongoDB,直接从 2.0 使⽤,所以⾥⾯的有些细节可能还不理解。看到有⼈说 auth 是 2.0 的新功能。⽽之前只能⽤ keyFile 验证。还不太清楚 keyFile 下⽤户登陆的⼀些细节。
MongoDB 常见问题处理
说明:这⾥的问题是我在看MongoDB官⽹⽂章时,从⾥⾯总结出来的。
mongod process "disappeared":
这个说的是mongodb进⾏消失,可以理解为死掉等。可以从下⾯中问题在
#grep mongod /var/log/messages
#grep score /var/log/messages
Socket errors in sharded clusters and replica sets:
echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time 默认是7200
关于tomm many open files:
First:检查以下⼏项:
lsof | grep mongod
lsof | grep mongod | grep TCP
lsof | grep mongod | grep data | wc
可以⽤:ulimit解决: ulimit -n X
High TCP Connection Count:
TCP Connection过⼤时,可以检查是不是client apps使⽤连接池问题
Mongod (hard) connection limit
这个连接数限制在20000,可以⼿动调整⼤⼩
Data files count with very large databases
数据在T级以上时,确定是否做了限制(⼿动增加),再⽤repairdatabase时,会同时有2 copies
No space left on device
这个时候reads仍然在进⾏,要做的是first shutdown servers, then to delete some data and compact
Checking Siez of a collection(检查集合)
>db.(collectionname).validate();
NUMA:
Linu,
Numa and MongoDB不能很好的⼀起⼯作。如果机器在numa硬件运⾏的时候,需要把它关闭。⼀般出现⼤规模性能慢下来或⼀段时间cpu占⽤很⾼的system time 。可以从⽇志中抓取NUMA字。(我也翻译不出这个NUMA是什么意思)
关闭的⽅法:
⼀:在启动mongoDB的时候:
numactl --interleave=all ${MONGODB_HOME}/bin/mongod --config f
⼆:在不关闭mongoDB时:
echo 0 > /proc/sys/vm/zone_reclaim_mod
案例:
NFS:
官⽹不建意采⽤NFS系统⽂件运⾏mongoDB,因为NFS版本问题会导致性能很低或⽆法⼯作
SSD:
mongoDB在SSD(固态硬盘)运⾏很快,但是⽐RAM低。可以⽤mongoperf进⾏硬盘性能状态分析。Virtualization:
mongoDB在虚拟化上运⾏的很好,如OpenVZ 兼容EC2 ,VMWare也可以但是clone的时候会出现⼀些问题由其在a member of a replica set(⼀个复制节点上),要想可⽤的,需要journaling处在可⽤状态,再进⾏clone。如果没有的开启journaling的时候,stop m ongod ,clone, and tehn restart
注意:在MongoDB中要⽤IP地址不要使⽤机器名或localhost,不然会出现链接不数据库的。
Journal(⽇志):
⽇志的开启:--journal ;关闭:--nojournal ,默认时间是100ms
启动时会在数据⽬录下创建⼀个journal地⽂件⽬录,在受到毁坏时,再启动mongoDB不需要再运⾏repair,它会⾃动恢复的。
可以通过运⾏journalLatencyTest测试写⼊磁盘的性能和同步性能。
>use admin
>db.runCommand("journalLatencyTest")
Backup with --journal 中journal是⽀持回滚恢复。
journaling的时候,stop m ongod ,clone, and tehn restart
注意:在MongoDB中要⽤IP地址不要使⽤机器名或localhost,不然会出现链接不数据库的。
The Linux Out of Memory OOM Killer:
情况⼀:
Feb 13 04:33:23 hostm1 kernel: [279318.262555] mongod invoked oom-killer: gfp_mask=0x1201d2, order=0, oomkilladj=0这是因为内存溢出导致mongodb进程被刹死
情况⼆:
内在没有溢出,能过db..serverStatus()或mongostat查看内存virtualbytes - mappedbytes的界限
情况三:
ulimit的限制
t:minor-latin; mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family: Calibri;mso-hansi-theme-font:minor-latin'>中journal是⽀持回滚恢复。
journaling的时候,stop m ongod ,clone, and tehn restart
注意:在MongoDB中要⽤IP地址不要使⽤机器名或localhost,不然会出现链接不数据库的。
mongodb占⽤空间过⼤的原因,在官⽅的FAQ中,提到有如下⼏个⽅⾯:
1、空间的预分配:为避免形成过多的硬盘碎⽚,mongodb每次空间不⾜时都会申请⽣成⼀⼤块的硬盘空间,⽽且申请的量从64M、128M、256M那样的指数递增,直到2G为单个⽂件的最⼤体积。随着数据量的增加,你可以在其数据⽬录⾥看到这些整块⽣成容量不断递增的⽂件。
2、字段名所占⽤的空间:为了保持每个记录内的结构信息⽤于查询,mongodb需要把每个字段的key-value都以BSON 的形式存储,如果value域相对于key域并不⼤,⽐如存放数值型的数据,则数据的overhead是最⼤的。⼀种减少空间占⽤的⽅法是把字段名尽量取短⼀些,这样占⽤空间就⼩了,但这就要求在易读性与空间占⽤上作为权衡了。我曾建议作者把字段名作个index,每个字段名⽤⼀个字节表⽰,这样就不⽤担⼼字段名取多长了。但作者的担忧也不⽆道理,这种索引⽅式需要每次查询得到结果后把索引值跟原值作⼀个替换,再发送到客户端,这个替换也是挺耗费时间的。现在的实现算是拿空间来换取时间吧。
3、删除记录不释放空间:这很容易理解,为避免记录删除后的数据的⼤规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利⽤。
RepairDatabase命令:
数据库总会出现问题的,关于修复的⽅法如下:
运⾏db.repairDatabase()来整理记录,但这个过程会⽐较缓慢。
当MongoDB做的是副本集时:可以直接把数据rm掉,然后再重新启动。
当在不是primariy server上运⾏时,会得到⼀个"clone failed for wkgbc with error: query failed
wkgbc.system.namespaces"
解决⽅法:为了修复,需要restart server 不加--replSet选项并且要选⽤不同的端⼝
LINUX下出哪个进程造成的IO等待很⾼的⽅法:
可以判断是不是IO问题造成的:
#/etc/init.d/syslog stop
#echo 1 > /proc/sys/vm/block_dump
#dmesg |egrep "READ|WRITE|dirtied"|egrep -o '([a-zA-Z*])'|sort|uniq -c|sort -rn|head
下⾯是从⽹上的案例:
昨天我访问mongodb的python程序开始出错,经常抛出AssertionError异常,经查证只是master查询异常,slave正常,可判断为master的数据出了问题。
修复过程:
1、在master做db.repairDatabase(),不起作⽤;这个时间很长
2、停⽌slave的同步;
3、对slave作mongodump,备份数据;
4、对master作mongostore,把备份数据恢复,使⽤–drop参数可以先把原表删除。
5、恢复slave的同步。
实例⼆:碎⽚整理-replSet架构
1、rs.freeze(60) 在60s内该机器⽆法成为primary
2、在primary机上进⾏rs.stepDown([120]) 让该机器成为从节点且在120s内不会成为primary
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论