您好,登錄后才能下訂單哦!
如何進行mongodb數據庫的問題分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
MongoDB是一個介于關系數據庫和非關系數據庫之間的產品,是非關系數據庫當中功能最豐富,最像關系數據庫的。它的特點是高性能、易部署、易使用,存儲數據非常方便。公司在測試和生產環境使用了MONGODB數據庫,日常在使用MONGODB數據庫的過程中,遇到了一些問題,比較典型的三個問題現總結分享一下。
一、數據庫最大連接數問題
當你在后臺日志中,發現大量“connection refused because too many open connections: 819”信息時,一般跟你沒有設置合適的最大連接數值有關。
默認情況下,在LINUX系統中,MONGODB默認連接數為819,你可以適當調大這個值,但注意這個值不是無限大,最多可設置成20000, 參見MONGODB的官方說明。
我們可以在數據庫啟動時加--maxConns 10000參數來指定最大連接數
也可以修改mongodb.conf配置文件,在其中加一句maxConns = 10000保存退出后再啟動MONGODB就好了。
當然這個問題也跟ulimit限制有關, 可以手動修改ulimit -n 來改動open file 的數目.
如果想使open file的值永久生效的話,請在/etc/security/limits.conf中添加以下四行, 數目根據系統情況具體修改.
* soft nofile 102400 (*針對所有用戶)
* hard nofile 102400
root soft nofile 102400 (針對ROOT用戶)
root hard nofile 102400
然后在/etc/pam.d/login中添加
session required /lib64/security/pam_limits.so
....
reboot后即可永久生效.
環境變量
[root@localhost ~]# echo "PATH=$PATH:/app/mongodb/bin" >> /etc/profile
[root@localhost ~]# source /etc/profile
mongodb配置文件附例:
port=27017
dbpath=/backup/mongodbData
logpath=/app/mongodb/log/mongodb.log
logappend=true
directoryperdb=true
journal=true
fork=true
maxConns = 10000
二、虛擬內存限制問題
MongoDB主從配置后, 啟動時報錯“ERROR: mmap failed with out of memory”。 這是因為mongodb在設置為主從關系時,會創建“creating replication oplog of size: 944MB”,這個OPLOG日志應該是放在內存中的.
解決方法:
(1)設置oplog的大小,用參數--oplogSize來指定,不默認創建944M
(2)放開虛擬內存的限制(虛擬機默認設定512M ),編輯/etc/profile文件加入ulimit -v unlimited,使用source /etc/profile讓設置生效。
再執行主從的啟動命令就ok了
mongodb比較吃內存,也可以限制mongodb的內存使用量,操作如下
vi mongodb.conf
增加 ulimit -m 2560000 (約2.5G 內存)
需要注意的幾點:
1. MongoDB在32位操作系統出現“mmap failed with out of memory”錯誤,這是因為在32位平臺中MongoDB不允許數據庫文件(累計總和)超過2G,而64位平臺沒有這個限制。如果在64位平臺中也報這個錯,一般是虛擬內存不足所致。可以編輯/etc/profile文件加入ulimit -v unlimited,使用source /etc/profile讓設置生效或重啟生效。
2. oplog的大小和內存沒有太大關系,oplogSize相當于mysql數據庫的binlog,從庫復制的數據都是從oplog也就是local這個庫讀取的。
--oplopgSize,指定了slave同步時,更新日志保存的最大大小,最新版本的mongodb如果不指定參數的話默認是硬盤空間的5%,如果設置太小,slave同步和主庫相差遠超過了oplog的大小的話,有可能會數據不一致。
參看官方文檔說明:
http://www.mongodb.org/display/DOCS/Replication+Oplog+Length
3、使用mongoDB建議使用高性能sas硬盤,追求性能可以考慮使用raid10硬盤。
三、mongodb占用空間過大的問題
1、空間的預分配:為避免形成過多的硬盤碎片,mongodb每次空間不足時都會申請生成一大塊的硬盤空間,而且申請的量從64M、128M、256M那樣的指數遞增,直到2G為單個文件的最大體積。隨著數據量的增加,你可以在其數據目錄里看到這些整塊生成容量不斷遞增的文件。
2、字段名所占用的空間:為了保持每個記錄內的結構信息用于查詢,mongodb需要把每個字段的key-value都以BSON的形式存儲,如果value域相對于key域并不大,比如存放數值型的數據,則數據的overhead是最大的。一種減少空間占用的方法是把字段名盡量取短一些,這樣占用空間就小了,但這就要求在易讀性與空間占用上作權衡了。建議把字段名作個index,每個字段名用一個字節表示,這樣就不用擔心字段名取多長了。但這種索引方式需要每次查詢得到結果后把索引值跟原值作一個替換,再發送到客戶端,這個替換也是挺耗費時間的。
3、刪除記錄不釋放空間:這個很容易理解,為避免記錄刪除后的數據的大規模挪動,原記錄空間不刪除,只標記“已刪除”即可,以后還可以重復利用。
可以定期運行db.repairDatabase()來整理記錄釋放空間,但這個過程會比較緩慢。
補充:
1、mongodb客戶端連接服務端出現異常
一般是因為機器異常重啟或硬關機造成的,解決方法為:
①刪除mongod.lock文件后,重新啟動MongoDB即可。
rm -rf /data/mongodb/mongod.lock (此為mongodb數據存放的路徑)
②修復mongodb
mongod -repair -dbpath=/data/mongodb/data
2、mongodb的啟停
/opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.conf 啟動
/opt/mongodb/bin/mongo 停止
use admin
db.shutdownServer()
/opt/mongodb/bin/mongo 查看數據庫狀態
db.serverStatus()
操作補充:
以下是mongodb啟動時的常用參數說明:
--bind_ip 綁定IP,綁定后只能綁定的IP訪問服務
--dbpath 指定數據庫目錄
--port 指定數據庫端口,默認是27107
--logpath 指定日志存放目錄
--logappend 使用追加的方式寫日志
--pidfilepath 指定進程文件,不指定則不產生進程文件
--journal 啟用日志
--maxConns 最大的并發連接數,默認2000
--fork 將服務放到后臺運行
--notablescan 不允許表掃描
--syncdelay 數據寫入硬盤的時間(秒),0是不等待,直接寫入
shell操作數據庫:
1. 超級用戶相關:
1. #進入數據庫admin
use admin
2. #增加或修改用戶密碼
db.addUser('name','pwd')
3. #查看用戶列表
db.system.users.find()
4. #用戶認證
db.auth('name','pwd')
5. #刪除用戶
db.removeUser('name')
6. #查看所有用戶
show users
7. #查看所有數據庫
show dbs
8. #查看所有的collection
show collections
9. #查看各collection的狀態
db.printCollectionStats()
10. #查看主從復制狀態
db.printReplicationInfo()
11. #修復數據庫
db.repairDatabase()
12. #設置記錄profiling,0=off 1=slow 2=all
db.setProfilingLevel(1)
13. #查看profiling
show profile
14. #拷貝數據庫
db.copyDatabase('mail_addr','mail_addr_tmp')
15. #刪除collection
db.mail_addr.drop()
16. #刪除當前的數據庫
db.dropDatabase()
2. 增刪改 (其中下面的foo與user_addr為collection)
1. #存儲嵌套的對象
db.foo.save({'name':'ysz','address':{'city':'beijing','post':100096},'phone':[138,139]})
2. #存儲數組對象
db.user_addr.save({'Uid':'yushunzhi@sohu.com','Al':['test-1@sohu.com','test-2@sohu.com']})
3. #根據query條件修改,如果不存在則插入,允許修改多條記錄
db.foo.update({'yy':5},{'$set':{'xx':2}},upsert=true,multi=true)
4. #刪除yy=5的記錄
db.foo.remove({'yy':5})
5. #刪除所有的記錄
db.foo.remove()
3. 索引 (其中下面的foo與user_addr為collection)
1. #增加索引:1(ascending),-1(descending)
2. db.foo.ensureIndex({firstname: 1, lastname: 1}, {unique: true});
3. #索引子對象
4. db.user_addr.ensureIndex({'Al.Em': 1})
5. #查看索引信息
6. db.foo.getIndexes()
7. db.foo.getIndexKeys()
8. #根據索引名刪除索引
9. db.user_addr.dropIndex('Al.Em_1')
4. 查詢 (其中下面的foo與user_addr為collection)
1. #查找所有
2. db.foo.find()
3. #查找一條記錄
4. db.foo.findOne()
5. #根據條件檢索10條記錄
6. db.foo.find({'msg':'Hello 1'}).limit(10)
7. #sort排序
8. db.deliver_status.find({'From':'ixigua@sina.com'}).sort({'Dt',-1})
9. db.deliver_status.find().sort({'Ct':-1}).limit(1)
10. #count操作
11. db.user_addr.count()
12. #distinct操作,查詢指定列,去重復
13. db.foo.distinct('msg')
14. #”>=”操作
15. db.foo.find({"timestamp": {"$gte" : 2}})
16. #子對象的查找
17. db.foo.find({'address.city':'beijing'})
5. 管理 (其中下面的deliver_status為collection)
1. #查看collection數據的大小
2. db.deliver_status.dataSize()
3. #查看colleciont狀態
4. db.deliver_status.stats()
5. #查詢所有索引的大小
6. db.deliver_status.totalIndexSize()
看完上述內容,你們掌握如何進行mongodb數據庫的問題分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。