1 非正常關(guān)閉服務(wù)或關(guān)機(jī)后 mongod服務(wù)無法正常啟動(dòng)
在使用中發(fā)現(xiàn)mongodb 的服務(wù)很容易因?yàn)榉钦jP(guān)閉而啟動(dòng)不了,不過解決也很容易
刪除data目錄下的 *.lock文件,再運(yùn)行下 /mongodb_binpath/mongod -repair -f config文件路徑 再啟動(dòng)即可
也可以在/etc/init.d/mongod 服務(wù)啟動(dòng)的文件中加入 啟動(dòng)前刪除該文件 如下:
start() {
rm -f /usr/mongodb/data/master/mongod.lock
/usr/mongodb/bin/mongod --config /usr/mongodb/config/master.conf
}
2、server-side JavaScript execution is disabled
完整信息:JavaScript execution failed: group command failed: { "ok" : 0, "errmsg" : "server-side JavaScript execution is disabled" }
解決方法:mongod.conf 這個(gè)配置文件里 noscripting:false 如果true 就是禁止
3、 Decimal轉(zhuǎn)換成BsonValue值異常
BsonValue 暫不支持 Decimal類型,轉(zhuǎn)換前強(qiáng)制轉(zhuǎn)換類型,
if (type==typeof(Decimal))
{
return Convert.ToDouble(value);
}
如果用MongoDB,最好不要用decimal類型,否則在序列化的時(shí)候也有問題,可用double
4、MONGO Replica 頻繁插入大數(shù)據(jù)的問題
MONGO Replica 頻繁插入大數(shù)據(jù)的問題,當(dāng)在復(fù)制集中頻繁插入大數(shù)據(jù)時(shí)有可能出現(xiàn) “error RS102 too stale to catch up"出現(xiàn)這個(gè)錯(cuò)誤的原因是SECONDARY即副節(jié)點(diǎn)的復(fù)制速度跟不上了,當(dāng)需要批量頻繁向副本集中寫入數(shù)據(jù)時(shí)最好先移除副本節(jié)點(diǎn),待插入完后重新同步。
5 Mongo集群沒有primary但有secondary時(shí)連接不上且不能讀數(shù)據(jù)
#mongodb默認(rèn)是從主節(jié)點(diǎn)讀寫數(shù)據(jù)的,副本節(jié)點(diǎn)上不允許讀,需要設(shè)置副本節(jié)點(diǎn)可以讀。
shell
1 repset:SECONDARY> db.getMongo().setSlaveOk(); #要在primary上執(zhí)行
2 rs.slaveOk()
其他客戶端
從secondary 讀數(shù)據(jù)
如果應(yīng)用程序沒有設(shè)置相應(yīng)的ReadReference也可能不能進(jìn)行讀取操作
MongoClientSettings set = new MongoClientSettings();
ListMongoServerAddress> servers = new ListMongoServerAddress>();
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;
//設(shè)置副本集名稱
set.ReplicaSetName = "rs0";
//設(shè)置超時(shí)時(shí)間為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");
注:設(shè)置驅(qū)動(dòng)的ReadReference也可以通過MongoDB連接字符串配置:mongodb://example1.com,example2.com,example3.com/?readPreference=secondary。通過連接字符串指定的read preference是針對(duì)整個(gè)連接。
set.ReadPreference = new ReadPreference(ReadPreferenceMode.PrimaryPreferred);
將ReadPreferenceMode設(shè)置成Secondary或SecondaryPreferred
下面是其他網(wǎng)友的補(bǔ)充:
一、
1. addshard 遇到的錯(cuò)誤 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″ } 遇到這樣的錯(cuò)誤是由于某些服務(wù)啟動(dòng)在 localhost 地址。 經(jīng)過檢查發(fā)現(xiàn) route 啟動(dòng)時(shí),讀取 config 服務(wù)是讀取的 localhost 地址: ./mongos –port 40000 –configdb localhost:30000 –fork [...]
1. addshard 遇到的錯(cuò)誤
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″
}
遇到這樣的錯(cuò)誤是由于某些服務(wù)啟動(dòng)在 localhost 地址。
經(jīng)過檢查發(fā)現(xiàn) route 啟動(dòng)時(shí),讀取 config 服務(wù)是讀取的 localhost 地址:
./mongos –port 40000 –configdb localhost:30000 –fork –logpath /data/route/log/route.log –chunkSize 1
將 localhost 修改為 IP 地址,問題解決。
2. 為什么要同時(shí)有 config 和 route
一開始看到 config 和 route 的邏輯結(jié)構(gòu)有一點(diǎn)疑惑。既然一個(gè)數(shù)據(jù)庫查詢的過程是:
客戶端
|
route
|
config
|
Database
而 config 的作用就是告訴 route 應(yīng)該去哪一個(gè) Database 取數(shù)據(jù)。那么為什么不能直接由客戶端向 config 發(fā)起請(qǐng)求呢?這時(shí) route 的存在豈不是多余?
簡(jiǎn)單的思考之后,得出了以下結(jié)論:
在有多個(gè) route 和多個(gè) config 的情況下,route 與 route 之間是平行的存在,也就是說,一個(gè) route 并不知道另外一個(gè) route 的存在。但是一個(gè) route 知道所有 config 的存在。
那么當(dāng)要寫入數(shù)據(jù)時(shí),只要你是通過了 route,route 就會(huì)通知到所有的 config,那么每一個(gè) config 便會(huì)知道數(shù)據(jù)是如何分片的。
如果將 route 這層去掉,那么 config 與 config 之間并不知道彼此的存在??蛻舳说恼?qǐng)求很可能會(huì)只發(fā)向其中的一個(gè) config,那么也只有這一個(gè) config 知道最新的分片狀態(tài)。
這個(gè)答案其實(shí)經(jīng)不起太多的推敲,比如:
config 是可以從客戶端那里拿到所有 config 的列表的,一旦有了列表之后,config 就可以彼此相互通信了??梢越鉀Q數(shù)據(jù)同步的問題。
我還要看多一些文檔。
3. Replica Set 啟動(dòng)順序
在啟動(dòng)兩個(gè) rs 機(jī)器時(shí),我先啟動(dòng)了 second,后啟動(dòng)了 Primary。這是一臺(tái)機(jī)器上顯示自己為 second,另外一臺(tái)為 unreachable。而另外一臺(tái)機(jī)器顯示兩臺(tái)機(jī)器均在 second。
這個(gè)現(xiàn)象需要驗(yàn)證,是否 Replica Set 是有啟動(dòng)順序限制。
二、
昨天到今天一直在嘗試在同一臺(tái)機(jī)器上用多個(gè)IP地址來創(chuàng)建 Replica Set + Shard。 由于 MongoDB 官方用戶驗(yàn)證方面的文檔說的也不太細(xì)。所以走了一些回頭路。 下面整理一些常見的錯(cuò)誤,以及他們可能表達(dá)的意思。描述的順序是按照排錯(cuò)的邏輯: 1. route 啟動(dòng)的時(shí)候,連接 config 不可以以 localhost 為地址鏈接。不然會(huì)遇到以下錯(cuò)誤: “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 啟動(dòng)的時(shí)候不能加 –auth 選項(xiàng),不然會(huì)在log文件中遇到以下錯(cuò)誤: ERROR: [...]
昨天到今天一直在嘗試在同一臺(tái)機(jī)器上用多個(gè)IP地址來創(chuàng)建 Replica Set + Shard。
由于 MongoDB 官方用戶驗(yàn)證方面的文檔說的也不太細(xì)。所以走了一些回頭路。
下面整理一些常見的錯(cuò)誤,以及他們可能表達(dá)的意思。描述的順序是按照排錯(cuò)的邏輯:
1. route 啟動(dòng)的時(shí)候,連接 config 不可以以 localhost 為地址鏈接。不然會(huì)遇到以下錯(cuò)誤:
“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 啟動(dòng)的時(shí)候不能加 –auth 選項(xiàng),不然會(huì)在log文件中遇到以下錯(cuò)誤:
ERROR: config servers not in sync! not authorized, did you start with –keyFile?
此時(shí)進(jìn)程無法啟動(dòng)
3.在 route 和 config 準(zhǔn)備完畢后,通過 route 以遠(yuǎn)程 IP 為地址添加shard,則報(bào)錯(cuò):(有 –auth 參數(shù))
db.runCommand({addshard:'a1:28010′})
{
“ok” : 0,
“errmsg” : “failed listing a1:28010′s databases:{ errmsg: \”need to login\”, ok: 0.0 }”
}
4. 去掉 –auth 參數(shù),添加 shard,成功!
5. 依舊保留 –auth 參數(shù),添加用戶后,再添加shard。報(bào)錯(cuò):
“errmsg” : “couldn't connect to new shard DBClientBase::findN: transport error: a1:28010 query: { getlasterror: 1 }”
總結(jié):MongoDB 2.0 的認(rèn)證方式
1.Replica Set 之間通過 key 來相互認(rèn)證。
2.Route 與 Config 之間不存在認(rèn)證關(guān)系,Route 連接 Config 時(shí)不能以 localhost 連接。
3.單個(gè)Mongod進(jìn)程啟動(dòng)后,如果無 –auth 選項(xiàng)且無用戶,則必須通過 localhost 連接才能添加用戶和做其他操作。如果通過遠(yuǎn)程(非127.0.0.1的IP地址)連接,則必須要輸入用戶名、密碼。此時(shí)如果還無用戶存在,則無法連接。
4.添加 Shard 時(shí),mongod 不可以帶 –auth 參數(shù),不然會(huì)添加失敗。
三、
續(xù)上篇 筆記2 ,還是說一下關(guān)于 MongoDB 認(rèn)證的問題。 在 王文龍 所寫的 《MongoDB 實(shí)戰(zhàn)》 中,寫到: 創(chuàng)建主從 key 文件,用于標(biāo)識(shí)集群的私鑰的完整路徑,如果各個(gè)實(shí)例的 key file 內(nèi)容不一 致,程序?qū)⒉荒苷S谩?我誤以為 –keyFile 是各個(gè)節(jié)點(diǎn)之間的認(rèn)證方式。其實(shí)不是的。各個(gè)節(jié)點(diǎn)之間的確認(rèn)關(guān)系參數(shù)是 –replSet。只要此參數(shù)后面的內(nèi)容一致。Replica Set 就可以創(chuàng)建成功。 在官方文檔中提到: 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 其實(shí)包含了 auth 的作用。 [...]
續(xù)上篇 筆記2 ,還是說一下關(guān)于 MongoDB 認(rèn)證的問題。
在 王文龍 所寫的 《MongoDB 實(shí)戰(zhàn)》 中,寫到:
創(chuàng)建主從 key 文件,用于標(biāo)識(shí)集群的私鑰的完整路徑,如果各個(gè)實(shí)例的 key file 內(nèi)容不一 致,程序?qū)⒉荒苷S谩?/p>
我誤以為 –keyFile 是各個(gè)節(jié)點(diǎn)之間的認(rèn)證方式。其實(shí)不是的。各個(gè)節(jié)點(diǎn)之間的確認(rèn)關(guān)系參數(shù)是 –replSet。只要此參數(shù)后面的內(nèi)容一致。Replica Set 就可以創(chuàng)建成功。
在官方文檔中提到:
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 其實(shí)包含了 auth 的作用。
而當(dāng)你加了 –keyFile 參數(shù)后,如果你要添加 Shard,則會(huì)收到報(bào)錯(cuò):
need to login
這和加了 auth 的報(bào)錯(cuò)一致。
以前沒接觸過 MongoDB,直接從 2.0 使用,所以里面的有些細(xì)節(jié)可能還不理解??吹接腥苏f auth 是 2.0 的新功能。而之前只能用 keyFile 驗(yàn)證。還不太清楚 keyFile 下用戶登陸的一些細(xì)節(jié)。
MongoDB 常見問題處理
說明: 這里的問題是我在看MongoDB官網(wǎng)文章時(shí),從里面總結(jié)出來的。
mongod process "disappeared":
這個(gè)說的是mongodb進(jìn)行消失,可以理解為死掉等??梢詮南旅嬷姓覇栴}在
#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 默認(rèn)是7200
關(guān)于tomm many open files:
First:檢查以下幾項(xiàng):
lsof | grep mongod
lsof | grep mongod | grep TCP
lsof | grep mongod | grep data | wc
可以用:ulimit解決: ulimit -n X
High TCP Connection Count:
TCP Connection過大時(shí),可以檢查是不是client apps使用連接池問題
Mongod (hard) connection limit
這個(gè)連接數(shù)限制在20000,可以手動(dòng)調(diào)整大小
Data files count with very large databases
數(shù)據(jù)在T級(jí)以上時(shí),確定是否做了限制(手動(dòng)增加),再用repairdatabase時(shí),會(huì)同時(shí)有2 copies
No space left on device
這個(gè)時(shí)候reads仍然在進(jìn)行,要做的是first shutdown servers, then to delete some data and compact
Checking Siez of a collection(檢查集合)
>db.(collectionname).validate();
NUMA:
Linu,
Numa and MongoDB不能很好的一起工作。如果機(jī)器在numa硬件運(yùn)行的時(shí)候,需要把它關(guān)閉。一般出現(xiàn)大規(guī)模性能慢下來或一段時(shí)間cpu占用很高的system time ??梢詮娜罩局凶トUMA字。(我也翻譯不出這個(gè)NUMA是什么意思)
關(guān)閉的方法:
一:在啟動(dòng)mongoDB的時(shí)候:
numactl --interleave=all ${MONGODB_HOME}/bin/mongod --config conf/mongodb.conf
二:在不關(guān)閉mongoDB時(shí):
echo 0 > /proc/sys/vm/zone_reclaim_mod
案例:
https://www.jb51.net/article/109199.htm
或https://www.jb51.net/article/109198.htm
NFS:
官網(wǎng)不建意采用NFS系統(tǒng)文件運(yùn)行mongoDB,因?yàn)镹FS版本問題會(huì)導(dǎo)致性能很低或無法工作
SSD:
mongoDB在SSD(固態(tài)硬盤)運(yùn)行很快,但是比RAM低??梢杂胢ongoperf進(jìn)行硬盤性能狀態(tài)分析。
Virtualization:
mongoDB在虛擬化上運(yùn)行的很好,如OpenVZ 兼容EC2 ,VMWare也可以但是clone的時(shí)候會(huì)出現(xiàn)一些問題由其在a member of a replica set(一個(gè)復(fù)制節(jié)點(diǎn)上),要想可用的,需要journaling處在可用狀態(tài),再進(jìn)行clone。如果沒有的開啟journaling的時(shí)候,stop m ongod ,clone, and tehn restart
注意:在MongoDB中要用IP地址不要使用機(jī)器名或localhost,不然會(huì)出現(xiàn)鏈接不數(shù)據(jù)庫的。
Journal(日志):
日志的開啟:--journal ;關(guān)閉:--nojournal ,默認(rèn)時(shí)間是100ms
啟動(dòng)時(shí)會(huì)在數(shù)據(jù)目錄下創(chuàng)建一個(gè)journal地文件目錄,在受到毀壞時(shí),再啟動(dòng)mongoDB不需要再運(yùn)行repair,它會(huì)自動(dòng)恢復(fù)的。
可以通過運(yùn)行journalLatencyTest測(cè)試寫入磁盤的性能和同步性能。
>use admin
>db.runCommand("journalLatencyTest")
Backup with --journal 中journal是支持回滾恢復(fù)。
journaling的時(shí)候,stop m ongod ,clone, and tehn restart
注意:在MongoDB中要用IP地址不要使用機(jī)器名或localhost,不然會(huì)出現(xiàn)鏈接不數(shù)據(jù)庫的。
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
這是因?yàn)閮?nèi)存溢出導(dǎo)致mongodb進(jìn)程被剎死
情況二:
內(nèi)在沒有溢出,能過db..serverStatus()或mongostat查看內(nèi)存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是支持回滾恢復(fù)。
journaling的時(shí)候,stop m ongod ,clone, and tehn restart
注意:在MongoDB中要用IP地址不要使用機(jī)器名或localhost,不然會(huì)出現(xiàn)鏈接不數(shù)據(jù)庫的。
mongodb占用空間過大的原因,在官方的FAQ中,提到有如下幾個(gè)方面:
1、空間的預(yù)分配:為避免形成過多的硬盤碎片,mongodb每次空間不足時(shí)都會(huì)申請(qǐng)生成一大塊的硬盤空間,而且申請(qǐng)的量從64M、128M、256M那樣的指數(shù)遞增,直到2G為單個(gè)文件的最大體積。隨著數(shù)據(jù)量的增加,你可以在其數(shù)據(jù)目錄里看到這些整塊生成容量不斷遞增的文件。
2、字段名所占用的空間:為了保持每個(gè)記錄內(nèi)的結(jié)構(gòu)信息用于查詢,mongodb需要把每個(gè)字段的key-value都以BSON的形式存儲(chǔ),如果value域相對(duì)于key域并不大,比如存放數(shù)值型的數(shù)據(jù),則數(shù)據(jù)的overhead是最大的。一種減少空間占用的方法是把字段名盡量取短一些,這樣占用空間就小了,但這就要求在易讀性與空間占用上作為權(quán)衡了。我曾建議作者把字段名作個(gè)index,每個(gè)字段名用一個(gè)字節(jié)表示,這樣就不用擔(dān)心字段名取多長(zhǎng)了。但作者的擔(dān)憂也不無道理,這種索引方式需要每次查詢得到結(jié)果后把索引值跟原值作一個(gè)替換,再發(fā)送到客戶端,這個(gè)替換也是挺耗費(fèi)時(shí)間的?,F(xiàn)在的實(shí)現(xiàn)算是拿空間來換取時(shí)間吧。
3、刪除記錄不釋放空間:這很容易理解,為避免記錄刪除后的數(shù)據(jù)的大規(guī)模挪動(dòng),原記錄空間不刪除,只標(biāo)記“已刪除”即可,以后還可以重復(fù)利用。
RepairDatabase命令:
數(shù)據(jù)庫總會(huì)出現(xiàn)問題的,關(guān)于修復(fù)的方法如下:
運(yùn)行db.repairDatabase()來整理記錄,但這個(gè)過程會(huì)比較緩慢。
當(dāng)MongoDB做的是副本集群時(shí):可以直接把數(shù)據(jù)rm掉,然后再重新啟動(dòng)。
當(dāng)在不是primariy server上運(yùn)行時(shí),會(huì)得到一個(gè)"clone failed for wkgbc with error: query failed wkgbc.system.namespaces"
解決方法:為了修復(fù),需要restart server 不加--replSet選項(xiàng)并且要選用不同的端口
LINUX下找出哪個(gè)進(jìn)程造成的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
下面是從網(wǎng)上找的案例:
昨天我訪問mongodb的python程序開始出錯(cuò),經(jīng)常拋出AssertionError異常,經(jīng)查證只是master查詢異常,slave正常,可判斷為master的數(shù)據(jù)出了問題。
修復(fù)過程:
1、在master做db.repairDatabase(),不起作用; 這個(gè)時(shí)間很長(zhǎng)
2、停止slave的同步;
3、對(duì)slave作mongodump,備份數(shù)據(jù);
4、對(duì)master作mongostore,把備份數(shù)據(jù)恢復(fù),使用–drop參數(shù)可以先把原表刪除。
5、恢復(fù)slave的同步。
實(shí)例二:碎片整理-replSet架構(gòu)
1、rs.freeze(60) 在60s內(nèi)該機(jī)器無法成為primary
2、在primary機(jī)上進(jìn)行rs.stepDown([120]) 讓該機(jī)器成為從節(jié)點(diǎn)且在120s內(nèi)不會(huì)成為primary
3、在primary上 ,可以將data的數(shù)據(jù)刪掉 ,啟動(dòng)。數(shù)據(jù)會(huì)自動(dòng)兩步上去的。
您可能感興趣的文章:- Mongodb啟動(dòng)命令參數(shù)中文說明
- Mongodb 啟動(dòng)命令mongod參數(shù)說明(中文翻譯)
- 解析PHP中常見的mongodb查詢操作
- Mongodb常見錯(cuò)誤與解決方法小結(jié)(Mongodb中經(jīng)常出現(xiàn)的錯(cuò)誤)
- MongoDB使用小結(jié):一些不常見的經(jīng)驗(yàn)分享
- 關(guān)于Mongodb參數(shù)說明與常見錯(cuò)誤處理的總結(jié)