1.Linux下Mongodb安装和启动配置html
http://blog.csdn.net/yuwenruli/article/details/8529192vue
2.windows下mongodb安装和启动配置java
http://www.cnblogs.com/linjiqin/p/3192159.htmlnode
3.linux mongo启动 /关闭 linux
1.启动 git
./mongod --storageEngine mmapv1 --dbpath=/usr/gongbg/mongo_data/data --logpath=/usr/gongbg/mongo_data/logs --logappend --port=27017 --fork --auth
2.关闭 github
./mongo use admin db.shutdownServer()
3. 建立用户mongodb
具体步骤以下shell
a.首先用admin用户登录数据库
b.选择想建立用户的数据库
c.建立用户
use admin db.createUser( { "user" : "xxx", "pwd": "xxx", "roles" : [ { role: "clusterAdmin", db: "admin" }, { role: "readAnyDatabase", db: "admin" }, "readWrite" ] } ) use xxx(dbname) db.createUser({user:"baidubaike_",pwd:"baidubaike_123",roles:["readWrite"]})
各类权限解释
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
4.Failed global initialization: BadValue Invalid or no user locale set. Please ensure LANG and/or LC_* environment variables are set correctly
命令行输入 export LC_ALL=C 便可
5.Mongo VUE 能够和 MongoDB 链接,但是没法打开 collection
http://www.oschina.net/question/1995999_2148135
6.mongo文章
http://www.360doc.com/content/15/1010/15/1519870_504671696.shtml
0.官方文档
https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/
1. 包含省略号查询
{ title:/\\.{3}$/ }
2.是否包含
{ "hasfastPhoto": {"$exists": true} }
3.小于
{ "imgTxtUpdateFlag": { $lt: 7 } }
4.或者
{ "$or": [ { "hasfastPhoto": 1 }, { "imgTxtUpdateFlag": 7 } ] }
5.等于
{ url:'http://zhidao.baidu.com/question/1539766649154449027.html' }
6.#在mongovue下使用
{sort} {"insertTime" : -1}
7.and查询
{ "$and": [ { "insertTime": { "$gte": "2015-02-06 14:51:04", "$lte": "2015-02-06 14:52:03" } } ] }
8.like查询
① 普通like查询
{ "u": /.content.*/ }
② 忽略大小写
{ title:{ '$regex':'Vitamin', '$options':'i' } }
9.若是检索须要不区分大小写,咱们能够设置 $options 为 $i。
{ "u": {$regex: 'news.163.com', $options:'i'} }
10.not查询
{ "u": { $not: /.content.*/ } }
11.子文档like查询
{ "markingTagList": { "$elemMatch": { "appName": '政策', "currentTagsArray": '国办发' } } }
{ "similarList.title":/.*302*./ }
12.or查询
{ "$or": [ { "poemCon": /.①.*/ },{ "poemCon": /.②.*/ } ] }
13.and,or组合
{ "$and": [ { "$or": [ { "reported": {"$exists": false} }, { "reported": 0 } ] }, { "$or": [ { "hidden": {"$exists": false} }, { "hidden":1 } ] } ], "_id":1081 }
14.mongo分组查询(mongovue)
Group中 {"city" :true} Reduce中 Initial Value: {"count": 0} function Reduce(doc, out) { out.count += 1 } Finalize中 function Finalize(out) { return out; }
原生写法 db.getCollection('drugfuture').group({ key: { pageNo: true}, cond: { startTime:'2015-04-01',endTime:'2015-05-01' }, $reduce: function ( curr, result ) { result.total += 1; }, initial: { total : 0 } } )
对group后的数据进行过滤 db.yiMaiTongFinal2.aggregate( [ { $group: { _id : "$批准文号:", count : {$sum : 1}}}, {$match:{count:{$gt:1}}} ] )
多字段聚合(limit范围0~50) db.bysy_chufang_repeat_drug_disease.aggregate( [ { $group: { _id: { drugName: "$drugName", disease: "$disease" } ,count: { $sum: 1 } } },{ $sort: { count: -1 } } ,{ $limit : 50 } ])
15.查询系统中全部用户
db.system.users.find();
16.根据字段长度查询
db.getCollection('wechat_icd').find({$where:"this.code.length > 8"})
1.设置st字段为0
{ $set: { st: 0 } }
1.mongo删除字段
{ $unset:{"story":""} }
1.在建立的表中新增列与数据,右击表选择Insert document
mongodump --archive --db jinjing --host 127.0.0.1 --port 10088 | mongorestore --archive --host 182.92.202.151 --port 27017
http://www.runoob.com/mongodb/mongodb-mongodump-mongorerstore.html
mongodb 分片实战
http://www.cnblogs.com/magialmoon/archive/2013/04/10/3013121.html
pymongo使用示例
1.一次更新多条
db.collection.update({}, {'$set' : {'salary' : 10000}}, upsert=False, multi=True)
mongo导出
a>linux
./mongoexport --db baiduBaike --collection url --out /home/gongbg/url.json
b>windows
D:\java\MongoDB 2.6 Standard\bin>mongoexport.exe -d chat -c chat -q {"qudao":3},{"ques":1,"ans":1,"_id":0} --csv -f ques,ans -o temp.csv
官方文档
http://docs.mongoing.com/manual-zh/reference/program/mongoexport.html
The --journal option is the one causing the problem as that option is removed from Mongo 3.0.0
Remove the --journal option and it should work fine
http://www.cnblogs.com/yaoxing/p/mongodb-backup-rules.html (转)
dropDups选项为true时会删除集合的重复值,但如今报错了,通过查询dropDups不支持mongodb3版本了
用如下方法解决在重复数据的集合里创建惟一索引
1.首先把集合数据导出
./mongoexport --db baiduBaike --collection url --out /home/gongbg/url.json
2.删除集合数据
db.CollectedUrl.remove({})
3.在集合上建立惟一索引
db.CollectedUrl.ensureIndex({uri:1},{unique:true})
4.把导出数据再次导入集合中
./mongoimport --db baiduBaike --collection url --upsert /home/gongbg/url.json
注意要加上--upsert选项
--upsert insert or update objects that already exist
mongodb windows分片配置
http://www.cnblogs.com/huangxincheng/archive/2012/03/07/2383284.html
mongo linux 分片配置
mongod --fork --dbpath /home/gongbg/mongo_data/data/config --logpath /home/gongbg/mongo_data/log/config/config.log --port 10000 --storageEngine mmapv1 mongos --port 20000 --configdb 172.20.0.26:10000 --logpath /home/gongbg/mongo_data/log/mongos/mongos.log --fork mongod --dbpath /home/gongbg/mongo_data/data/shard/ --logpath /home/gongbg/mongo_data/log/shard/shard.log --fork --port 27019 --storageEngine mmapv1 ./mongod --storageEngine mmapv1 --dbpath=/home/gongbg/mongo_data/data/shard/ --logpath=/home/gongbg/mongo_data/log/shard/shard.log --logappend --port=27020 --fork mongo --port 20000 use admin db.runCommand({addshard:"172.20.0.26:27019" }) db.runCommand({addshard:"172.20.0.18:27020" }) db.runCommand( { enablesharding : "baiduBaike" } ) db.runCommand( { shardcollection : "baiduBaike.content", key : {url : 1} } ) db.printShardingStatus();
mongo错误(致使启动不了)
openExisting size 38273024 less than minimum file size expectation /home/gongbg/mongo_data/data/baiduBaike.13
把baiduBaike.13删掉就好 简单粗暴 不过不知道啥后果
--------------------------------------------------------------------------------------------------------------------------------------
最近一年忙碌于数据处理相关的工做,跟MongoDB打交道极多,如下为实践过程当中的Q&A,后续会不按期更新补充。
一、count统计结果错误
这是因为分布式集群正在迁移数据,它致使count结果值错误,须要使用aggregate pipeline来获得正确统计结果,例如:
db.collection.aggregate([{$group: {_id: null, count: {$sum: 1}}}])
引用:“On a sharded cluster, count can result in an inaccurate count if orphaned documents exist or if a chunk migration is in progress.”
参考:http://docs.mongodb.org/manual/reference/command/count/
二、从shell中更新/写入到文档的数字,会变为float类型
引用:“shell中的数字都被MongoDB看成是双精度数。这意味着若是你从数据库中得到的是一个32位整数,修改文档后,将文档存回数据库的时候,这个整数也就被换成了浮点数,即使保持这个整数原封不动也会这样的。”
参考:《MongoDB权威指南》初版
三、restore数据到新DB时,不要去先建索引
把bson数据文件restore到另外一个DB时,须要注意:不能先建立索引再restore数据,不然性能极差,mongorestore工具默认会在restore完数据时,根据dump出来的index信息建立索引,无须本身建立,若是是要更换索引,也应该在数据入库完以后再建立。
四、DB中的namespace数量太多致使没法建立新的collection
错误提示:error: hashtable namespace index max chain reached:1335,如何解决呢?
这是DB中的collection个数太多致使,在实践中以每一个collection 8KB计算(跟官方文档里说的不一样,可能跟index有关系),256MB能够支持36000个collection。db.system.namespaces.count() 命令能够统计当前DB内的collection数目,DB可支持collection数量是因为nssize参数指定的,它指定了dbname.ns磁盘文件的大小,也就指定了DB可支持的最大collection数目,ns为namespace缩写。默认nssize为16MB。
若是重启MongoD并修改了nssize参数,这新nssize只会对新加入的DB生效,对之前已经存在的DB不生效,若是你想对已经存在的DB采用新的nssize,必须在加大nssize重启以后新建DB,而后把旧DB的collection 复制到新DB中。
namespace限制相关文档:http://docs.mongodb.org/manual/reference/limits/#Number-of-Namespaces
五、moveChunk因旧数据未删除而失败
错误日志:”moveChunk failed to engage TO-shard in the data transfer: can't accept new chunks because there are still 1 deletes from previous migration“。
意思是说,当前正要去接受新chunk 的shard正在删除上一次数据迁移出的数据,不能接受新Chunk,因而本次迁移失败。这种log里显示的是warning,但有时候会发现shard的删除持续了十几天都没完成,查看日志,能够发现同一个chunk的删除在不断重复执行,重启全部没法接受新chunk的shard能够解决这个问题。
参考:
http://stackoverflow.com/questions/26640861/movechunk-failed-to-engage-to-shard-in-the-data-transfer-cant-accept-new-chunk
若是采用了balancer自动均衡,那么能够加上_waitForDelete参数,如:
{ "_id" : "balancer", "activeWindow" : { "start" : "12:00", "stop" : "19:30" }, "stopped" : false, "_waitForDelete" : true }
,这样就不会因delete堆积而致使后续migrate失败,固然,须要考虑到这里的阻塞是否会影响到程序正常运转,在实践中慎重采用使用waitForDelete,由于发现加上它以后迁移性能很是差,可能出现卡住十几个小时的状况,外界拿住了被迁移chunk的游标句柄,这时候删除不能执行,阻塞了后续其它迁移操做。
游标被打开而致使被迁移数据没法及时删除时的日志:
2015-03-07T10:21:20.118+0800 [RangeDeleter] rangeDeleter waiting for open cursors in: cswuyg_test.cswuyg_test, min: { _id: -6665031702664277348 }, max: { _id: -6651575076051867067 }, elapsedSecs: 6131244, cursors: [ 220477635588 ]
这可能会卡住几十小时,甚至一直卡住,影响后续的moveChunk操做,致使数据不均衡。
解决方法仍是:重启。
六、bson size不能超过16MB的限制
单个文档的BSON size不能超过16MB。find查询有时会遇到16MB的限制,譬如使用$in 查询的时候,in中的数组元素不能太多。对一些特殊的数据源作MapReduce,MapReduce中间会将数据组合为“KEY:[VALUE一、VALUE2]”这样的格式,当value特别多的时候,也可能会赶上16MB的限制。 限制无处不在,须要注意,”The issue is that the 16MB document limit applies to everything - documents you store, documents MapReduce tries to generate, documents aggregation tries to return, etc.
七、批量插入
批量插入能够减小数据往服务器的提交次数,提升性能,通常批量提交的BSON size不超过48MB,若是超过了,驱动程序自动修改成往mongos的屡次提交。
八、安全写入介绍及其沿革
关键字:acknowledge、write concern。
在2012年11月以前,MongoDB驱动、shell客户端默认是不安全写入,也就是fire-and-forget,动做发出以后,不关心是否真的写入成功,若是这时候出现了_id重复、非UTF8字符等异常,客户端不会知道。在2012年11月以后,默认为安全写入,安全级别至关于参数w=1,客户端能够知道写入操做是否成功。若是代码使用Mongo或者Collection来链接数据库,则说明它是默认不安全写入的legacy代码,安全写入已经把链接数据库修改成MongoClient接口。
安全写入能够分为三个级别,
第一级是默认的安全写入,确认数据写入到内存中就返回(w=N属于这一级);
第二级是Journal save,数据在写入到DB磁盘文件以前,MongoDB会先把操做写入到Journal文件,这一级指的是确认写入了Journal文件就返回;
第三级是fysnc,全部数据刷写到到DB磁盘文件才返回。
通常第一级就足够了,第二级是为了保证在机器异常断电的状况下也不会丢失数据。安全写入要付出性能的代码:不安全写入的性能大概是默认安全写入的3倍。使用fync参数则性能更差,通常不使用。
若是是副本集(replica set),其w=N参数,N表示安全写入到多少个副本集才返回。
参考:
http://docs.mongodb.org/manual/release-notes/drivers-write-concern/
http://docs.mongodb.org/manual/core/write-concern/
http://blog.mongodirector.com/understanding-durability-write-safety-in-mongodb/
http://whyjava.wordpress.com/2011/12/08/how-mongodb-different-write-concern-values-affect-performance-on-a-single-node/
九、善用索引——可能跟你觉得的不同
使用组合索引的时候,若是有两组索引,在限量查询的状况下,可能跟常规的认识不一样:
利用组合索引作的查询,在不一样数量级下会有不一样性能:
组合索引A: {"age": 1, "username": 1}
组合索引B: {"username": 1, "age": 1}
全量查询: db.user.find({"age": {"$gte": 21, "$lte": 30}}).sort({"username" :1}),使用索引A的性能优于索引B。
限量查询: db.user.find({"age": {"$gte": 21, "$lte": 30}}).sort({"username": 1}).limit(1000),使用索引B的性能优于索引A。
这两个查询在使用索引A的时候,是先根据age索引找到符合age的数据,而后再对这些结果作排序。使用索引B的时候,是遍历name,对应的数据判断age,而后获得的结果是name有序的。
优先使用sort key索引,在大多数应用上执行得很好。
参考:《MongoDB——The Definitive Guide 2nd Edition》page89
十、查询时索引位置的无顺序性
作find的时候,并不要求索引必定要在前面,
譬如:
db.test集合中对R有索引
db.test.find({R:"AA", "H": "BB"}).limit(100).explain()
db.test.find({"H":"BB", "R" : "AA"}).limit(100).explain()
这两个查找性能同样,它都会使用R索引。
十一、使用组合索引作shard key能够大幅度提升集群性能
“固定值+增量值” 两字段作组合索引能够有效的实现分布式集群中的分散多热点写入、读取。如下为读书笔记:
在单个MongoDB实例上,最高效的写入是顺序写入,而MongoDB集群则要求写入能随机,以便平均分散到多个MongoDB实例。因此最高效的写入是有多个局部热点:在多个MongoDB实例之间是分散写入,在实例内部是顺序写入。 要实现这一点,咱们采用组合索引。
例如:shardkey的第一部分是很粗糙的,可选集不多的字段,索引的第二部分是递增字段,当数据增长到必定程度时,会出现不少第一部分相同第二部分不一样的chunk,数据只会在最后一个chunk里写入数据,当第一部分不一样的chunk分散在多个shard上,就实现了多热点的写入。若是在一个shard上,不止一个chunk能够写入数据,那也就是说不止一个热点,当热点很是多的时候,也就等同于无热点的随机写入。当一个chunk分裂以后,只能有一个成为热点,另外一个不能再被写入,不然就会产生两个热点,再也不写入的chunk也就是死掉了,后续只会对它有读操做。
我在实践中除了书中讲到的组合键方式外,还加上了预分片策略,避免了早期数据增加过程当中的分片和数据迁移。另外还尽量的制造能利用局部性原理的数据写入,例如在数据写入以前先对数据排序,有大约30%左右的update性能提高。
预分片是这样子作的:根据组合shardkey信息先分裂好chunk,把这些空chunk移动到各个shard上,避免了后续自动分裂引发的数据迁移。
参考:《MongoDB——The Definitive Guide 2nd Edition》 page268
十二、怎么建索引更能提升查询性能?
在查询时,索引是否高效,要注意它的cardinality(cardinality越高表示该键可选择的值越多),在组合索引中,让cardinality高的放在前面。注意这里跟分布式环境选择shard key的不一样。如下为读书笔记:
index cardinality(索引散列程度),表示的是一个索引所对应到的值的多少,散列程度越低,则一个索引对应的值越多,索引效果越差:在使用索引时,高散列程度的索引能够更多的排除不符合条件的文档,让后续的比较在一个更小的集合中执行,这更高效。因此通常选择高散列程度的键作索引,或者在组合索引中,把高散列程度的键放在前面。
参考:《MongoDB——The Definitive Guide 2nd Edition》 page98
1三、非原地update,性能会不好
update文档时,若是新文档的空间占用大于旧文档加上它周围padding的空间,那么就会放弃原来的位置,把数据拷贝到新空间。
参考:《MongoDB——The Definitive Guide 2nd Edition》 page43
1四、没法在索引创建以后再去增长索引的过时时间
若是索引创建指定了过时时间,后续要update过时时间能够这样子:db.runCommand({"collMod":"a", index:{keyPattern:{"_":-1}, expireAfterSeconds: 60}})。
注意,经过collMod能修改过时时间的前提是:这个索引有过时时间,若是这个索引以前没有设置过时时间,那么没法update,只能删了索引,重建索引并指定过时时间。
参考:http://docs.mongodb.org/manual/tutorial/expire-data/
1五、_id索引没法删除
参考:《MongoDB——The Definitive Guide 2nd Edition》 page114
1六、paddingFactor是什么?
它是存储空间冗余系数,1.0表示没有冗余,1.5表示50%的冗余空间,有了冗余空间,可让后续引起size增长的操做更快(不会致使从新分配磁盘空间和文档迁移),通常是在1到4之间。能够经过db.collection.stats()看到collection的该值“paddingFactor”。
该值是MongoDB本身处理的,使用者没法设置paddingFactor。咱们能够在compact的时候对已经有的文档指定该值,但这个paddingFactor值不影响后续新插入的文档。
repairDatabase跟compact相似,也能移除冗余减小存储空间,但冗余空间少了会致使后续增长文档size的update操做变慢。
虽然咱们没法设置paddingFactor,可是可使用usePowerOf2Sizes保证分配的空间是2的倍数,这样也能够起到做用(MongoDB2.6版本起默认启用usePowerOf2Size)。
或者手动实现padding:在插入文档的时候先用默认字符占用一块空间,等到真实数据写入时,再unset掉它。
参考:
http://docs.mongodb.org/v2.4/core/record-padding/
http://docs.mongodb.org/v2.4/faq/developers/#faq-developers-manual-padding
1七、usePowerOf2Size是什么
这是为更有效的复用磁盘空间而设置的参数:分配的磁盘空间是2的倍数,若是超过了4MB,则是距离计算值最近的且大于它的完整MB数。
能够经过db.collections.stats()看到该值“userFlags”。
MongoDB2.6以后默认开启usePowerOf2Size参数
使用后的效果能够看这里的PPT:http://www.slideshare.net/mongodb/use-powerof2sizes-27300759
1八、aggregate pipeline 指定运算完成输出文档跟MapReduce相比有不足
(基于MongoDB2.6版本)MapReduce能够指定输出到特定的db.collection中,例如:out_put = bson.SON([("replace", "collection_name" ), ("db", "xx_db")])
aggregate pipeline只能指定collection名字,也就意味着数据只能写入到本db,同时结果不能写入到capped collection、shard collection中。
相比之下,aggregate pipeline限制是比较多的,若是咱们须要把结果放到某个DB下,则须要再作一次迁移:
db.runCommand({renameCollection:"sourcedb.mycol",to:"targetdb.mycol"})
可是!!上面的这条命令要求在admin下执行,且只能迁移往同shard下的DB,且被迁移的collection不能是shard的。
附错误码信息:
https://github.com/mongodb/mongo/blob/master/src/mongo/s/commands_public.cpp#L778
uassert(13140, "Don't recognize source or target DB", confFrom && confTo);
uassert(13138, "You can't rename a sharded collection", !confFrom->isSharded(fullnsFrom));
uassert(13139, "You can't rename to a sharded collection", !confTo->isSharded(fullnsTo));
uassert(13137, "Source and destination collections must be on same shard", shardFrom == shardTo);
参考:http://docs.mongodb.org/manual/reference/method/db.collection.mapReduce/#mapreduce-out-mtd
1九、杀掉MongoD进程的几种方式
1)进入到MongoD的命令行模式执行shutdown,
eg:
$ mongo --port 10001
> use admin
> db.shutdownServer()
2)1方式的简化:
eg:mongo admin --port 10001 --eval "db.shutdownServer()"
3)使用MongoD命令行关闭,须要指定db路径:
mongod --dbpath ./data/db --shutdown
20、集群的shard key慎重采用hash
若是你的日志是有日期属性的,那么shard key不要使用hash,不然删除过时日志时没法成块删除;在更新日志的时候,也不能利用局部性原理,查找、更新、插入数据都会所以而变慢。通常来讲,hash id应付小数据量时压力不大,但在数据量较大(热数据大于可用内存容量)时,CRUD性能极差,且会放大碎片对性能的影响:数据很是分散,当有过时日志被删除后,这些删除后的空间成为碎片,可能会由于磁盘预读策略被加载到内存中。另外,采用hash shard key还会浪费掉一个索引,浪费很多空间。
2一、副本数也不用太多
若是你的副本数量超过了12个(MongoDB3.0.0超过了50个),那么就要选择使用 master-slave ,但这样会失去故障自恢复功能,主节点故障时,须要手动去切换到无端障节点。
2二、mongos的config server配置信息中不要使用localhost、127.0.0.1
启动mongos时,config server的配置信息不得使用localhost、127.0.0.1,不然添加其它机器的shard时,会出现错误提示:
"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: xxxxx isLocalHost"
以新的config server启动mongos,也须要重启config server,不然会有错误提示:
“could not verify config servers were active and reachable before write”
若是改完后面又出现 “mongos specified a different config database string” 错误,那么还须要重启mongod,
修改了config server 几乎是要所有实例重启。另外,在配置replica set时也不得使用localhost、127.0.0.1。
参考:http://stackoverflow.com/questions/21226255/where-is-the-mongos-config-database-string-being-stored
2三、shard key的选择跟update性能紧密关联
分布式MongoDB,shard key的选择跟update性能,甚至是update可用性有很大关系,须要注意。
一、在对文档个别字段update时,若是query部分没有带上shard key,性能会不好,由于mongos须要把这条update语句派发给全部的shard 实例。
二、当update 的upsert参数为true时,query部分必须带上 shard key,不然语句执行出错,例子:
mongos> db.test.update({"_id":".7269993106A92327A89ABCD70D46AD5"}, {"$set":{"P": "aaa"}, "$setOnInsert":{"TEST":"a"}}, true)
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 61,
"errmsg" : "upsert { q: { _id: \".7269993106A92327A89ABCD70D46AD5\" }, u: { $set: { P: "aaa" }, $setOnInsert: { TEST: \"a\" } }, multi: false, upsert: true } does not contain shard key for pattern { _: 1.0, B: 1.0 }"
}
})
这是由于若是没有shard key,mongos既不能在全部shard实例上执行这条语句(可能会致使每一个shard都插入数据),也没法选择在某个shard上执行这条语句,因而出错了。
另外,须要特别注意,若是使用pymongo引擎,它不会告诉你出错了,只是函数调用陷入不返回,在shell下执行才能看到错误信息。
附:
如下英文部分来自:https://jira.mongodb.org/browse/SERVER-13010
It's actually not clear to me that this is something we can support - problem is this:
> db.coll.update({ _id : 1 }, { }, true);
> db.coll.find()
{ "_id" : ObjectId("53176700a2bc4d46c176f14a") }
Upserts generate new _ids in response to this operation, and therefore we can't actually target this correctly in a sharded environment. The shard on which we need to perform the query may not be the shard on which the new _id is placed.
意思是说,upsert产生了新的_id,_id就是shard key,可是若是query里没有shard key,它们不知道要到哪一个shard上执行这个命令,upsert产生的shard key可能并非执行这条命令的shard的。
另外,若是_id不是shard key咱们的例子也是不能成功的,由于没有shard key,这条upsert要在哪一个shard上执行呢?不能像普通update那样给全部的shard去作,不然可能致使插入多条。
参考:
https://jira.mongodb.org/browse/SERVER-13010
http://docs.mongodb.org/manual/core/sharding-shard-key/
http://stackoverflow.com/questions/17190246/which-of-the-following-statements-are-true-about-choosing-and-using-a-shard-key
2四、经过repairDatabase提升性能
从db.stats()中能够看到几个跟碎片相关的关键字段,dataSize,表示数据的大小,它包含了padding的空间;storageSize,表示这些数据存储占用的空间,包含了dataSize和被删除数据所占空间,能够认为storageSize/dataSize就是磁盘碎片比例,当删除、update文档比较多后,它会变大,考虑作repairDatabase,以减小碎片让数据更紧凑,在实践中,这对提升CURD性能极其有用。repairDatabase时须要注意:它是把数据拷贝到新的地方,而后再作处理,因此repair以前在DB目录所在磁盘须要预留一倍的空闲磁盘空间,若是你发现磁盘空间不足,能够中止服务,而后增长一块新磁盘,再执行实例级别的repair,并指定--repairpath为新磁盘路径,eg:mongod --dbpath /path/to/corrupt/data --repair --repairpath /media/external-hd/data/db,实例的数据会拷贝到/media/external-hd/data/db上作处理。
参考:《MongoDB——The Definitive Guide 2nd Edition》page325
2五、索引字段的长度不能大于1024字节
索引字段的长度不能大于1024字节,不然shell下会有插入错误提示:"errmsg" : "insertDocument :: caused by :: 17280 Btree::insert: key too large to index”。
使用pymongo的“continue_on_error”参数,不会发出错误提示,要注意。
参考: http://docs.mongodb.org/manual/reference/limits/#Index-Key-Limit
2六、修改索引的expireAfterSeconds以后,负载均衡失败
修改索引的expireAfterSeconds以后,负载均衡失败,出现错误提示“2015-06-05T09:59:49.056+0800 [migrateThread] warning: failed to create index before migrating data. idx: { v: 1, key: { _: -1 }, name: "__-1", ns: "cswuyg_test.cswuyg_test", expireAfterSeconds: 5227200 } error: IndexOptionsConflict Index with name: __-1 already exists with different options
检查发生moveChunk的两个shard,并无发现不一致,怀疑存在缓存,重启全部shard解决。
2七、config DB没法写入
因config DB没法修改,只可读,致使drop、enablesharding失败:
config server 相关日志:2015-06-11T16:51:19.078+0800 [replmaster] local.oplog.$main Assertion failure isOk() src/mongo/db/storage/extent.h 80
mongos 相关日志: [LockPinger] warning: pinging failed for distributed lock pinger 'xxx:1234/xxx:1235:1433993544:1804289383'. : : caused by :: isOk()
这是同事遇到的问题,不肯定是什么操做引发的。重启、configdb作repair均没法解决。
最后经过dump、restore解决:(1)把旧configdb dump出来;(2)restore到新的configure server;(3)mongos采用新的configure server;(4)重启所有mongod。\