本文介绍MongoDB 4.2版本的兼容性变化。
如需查看MongoDB官网兼容性更新说明文档,请前往MongoDB官网下载。
移除MMAPv1存储引擎
MongoDB 4.2删除了对MMAPv1存储引擎的支持。
如果您在4.0版本使用了MMAPv1存储引擎,请在升级到4.2版本前将存储引擎更改为WiredTiger存储引擎。
MMAPv1特定配置选项
MongoDB删除了以下MMAPv1特定的配置选项:
删除的配置 | 删除的命令行 |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
从4.2版本开始,MongoDB将不再使用上述配置和命令。如果您使用了WiredTiger部署,请删除MMAPv1的配置选项。
MMAPv1特定参数
MongoDB删除了以下MMAPv1参数:
newCollectionsUsePowerOf2SizesreplIndexPrefetch
MMAPv1特定命令
MongoDB删除了MMAPv1特定的touch命令。
命令和方法的MMAPv1特定选项
MongoDB删除了MMAPv1的特定选项:
collMod命令的noPadding和usePowerOf2Sizes。collStats命令的verbose。create命令的flags。db.createCollection()命令的paddingFactor、paddingBytes和preservePadding。
MongoDB会忽略fsync命令中MMAPv1特定选项async。
删除或弃用的命令和方法
移除对group命令的支持
从4.2版本开始,MongoDB移除了group命令(该命令已于3.4版本弃用)及其mongo shell帮助函数db.collection.group()。
请改用带$group阶段的db.collection.aggregate()。
移除对eval命令的支持
从4.2版本开始,MongoDB移除了eval命令。eval命令已于3.0版本弃用。
mongo shell的帮助函数db.eval()和db.collection.copyTo()只能在连接到MongoDB 4.0及之前版本时运行。
移除对copydb和clone命令的支持
从4.2版本开始,MongoDB移除了copydb命令和clone命令。mongo shell的帮助函数db.copyDatabase()和db.cloneDatabase()只能在连接到MongoDB 4.0及之前版本时运行。
请改用mongodump和mongorestore(需配合mongorestore选项的--nsFrom和--nsTo参数使用)或使用驱动程序编写脚本。
例如,将test 数据库复制到同实例的 examples 数据库,您可以:
用于
mongodump将test数据库转储到归档文件mongodump-test-db。mongodump --archive="mongodump-test-db" --db=test使用
mongorestore搭配--nsFrom和--nsTo参数从存档中恢复。mongorestore --archive="mongodump-test-db" --nsFrom='test.*' --nsTo='examples.*'
您可以按需添加参数,例如 --uri、--host、--username 等。
您也可以不使用存档文件,通过 mongodump将test数据库连接到标准输出流,并通过管道传递到mongorestore。
mongodump --archive --db=test | mongorestore --archive --nsFrom='test.*' --nsTo='examples.*'移除对parallelCollectionScan命令的支持
从4.2版本开始,MongoDB移除了parallelCollectionScan命令。
移除maxScan选项
MongoDB移除了find命令和mongo shell帮助函数cursor.maxScan()中的maxScan选项。请改用find命令的maxTimeMS选项,或使用mongo shell中的cursor.maxTimeMS()。
移除对geoNear命令的支持
从4.2版本开始,MongoDB 移除了geoNear命令。请改用$geoNear聚合阶段。
对于$geoNear阶段,除了以下例外,选项与已移除的geoNear命令相似:
已移除的
geoNear命令的输出中包含名为dis的字段,其中包含距离信息。对于
$geoNear阶段,请在distanceField中指定距离字段名称。已移除的
geoNear命令接受includeLocs选项的布尔值以包含loc字段。对于
$geoNear阶段,请在includeLocs中指定位置字段名称。已移除的
geoNear命令返回结果中包含avgDistance和maxDistance。你可以使用聚合管道在
geoNear阶段之后使用group阶段来返回avgDistance和maxDistance。db.places.aggregate([ { $geoNear: { near: <...>, distanceField: "dis", includeLocs: "loc", spherical: true, ... } }, { $group: { _id: null, objectsLoaded: { $sum: 1 }, maxDistance: { $max: "$dis" }, avgDistance: { $avg: "$dis" } } } ])
移除对 repairDatabase 命令的支持
从4.2版本开始,MongoDB移除了repairDatabase命令、mongo shell帮助函数db.repairDatabase()、以及repairDatabase权限。
替代方法:
对mongod进行数据压缩,请使用
compact命令。对单节点实例进行索引重建,请使用
reIndex命令或其帮助函数db.collection.reIndex()。对单节点实例进行数据恢复,请使用
mongod --repair。
移除对getPrevError命令的支持
从4.2版本开始,MongoDB 移除了getPrevError命令及其mongo shell帮助函数db.getPrevError()。
弃用 cloneCollection 命令
MongoDB 弃用了cloneCollection命令及其mongo shell帮助函数db.cloneCollection()。
请改用mongoexport和mongoimport命令,或编写一个使用驱动的脚本。
弃用 PlanCache 命令
MongoDB弃用了以下内容:
PlanCache.getPlansByQuery()方法和planCacheListPlans命令。要获取某个查询模式的缓存查询计划,请改用
$planCacheStats聚合阶段。PlanCache.listQueryShapes()方法和planCacheListQueryShapes命令。要列出缓存的查询模式,请改用
$planCacheStats聚合阶段。
聚合操作(Aggregation)
$out 阶段限制
$out和视图
定义视图(view)的pipeline中不能包含$out阶段。如果您现有的视图包含$out阶段,则无法从该现有视图创建新视图。
对于包含$out阶段的现有视图,您可以选择删除并重新创建不包含$out阶段的视图,或使用新的pipeline替换视图定义,使其不包含$out阶段。
$out和$lookup
$lookup阶段的嵌套字段中不能包含$out阶段。
$out和Read Concern级别
$out阶段不能与Read Concern级别"linearizable"结合使用。
$out和Explain
如果聚合阶段包含$out阶段,则无法在executionStats模式或allPlansExecution模式下运行db.collection.explain()帮助函数(或explain命令)。
如果聚合阶段包含$out阶段,要查看executionStats或allPlansExecution信息,请在不包含out阶段的情况下运行explain,以便返回前面阶段的explain结果。
或者,您可以在包含$out阶段的聚合阶段中以queryPlanner模式运行explain。
$out 和 Majority Read Concern级别
从 MongoDB 4.2 开始,您可以在包含$out阶段的聚合操作中指定Read Concern级别为"majority"。
$geoNear移除了limit和num选项
从MongoDB 4.2开始,MongoDB删除了$geoNear的limit和num选项,以及100的默认limit限制。如需限制$geoNear的结果,请使用带有$limit阶段的$geoNear阶段。
例如,以下聚合示例在4.2版本中将不生效($geoNear包含了num选项)。
db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
distanceField: "distance",
num: 5, // Not supported in 4.2
spherical: true
}
}
])相反,您可以将聚合命令改写为以下格式。
db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
distanceField: "distance",
spherical: true
}
},
{ $limit: 5 }
])事务(Transactions)
从 MongoDB 4.2 开始,事务中的第一个操作不能是killCursors。
从 MongoDB 4.2 开始,事务中不能向capped collection写入数据。从capped collection读取数据仍支持在事务中进行。
从 MongoDB 4.2 开始,MongoDB移除了事务16 MB的总大小限制。在4.2版本中,MongoDB会创建尽可能多的oplog条目以包含事务中的所有写操作。在4.2之前的版本中,MongoDB会创建一个包含事务中所有写操作的单个条目,从而对事务施加16 MB的总大小限制。
变更流(Change Streams)
可用性
从MongoDB 4.2开始,您无需依赖对"majority"Read Concern级别支持,即可使用变更流。
在MongoDB 4.0及之前版本中,您只有在启用"majority"Read Concern级别支持(默认启用)时,才能使用变更流。
默认排序规则
从MongoDB 4.2开始,变更流使用简单的二进制比较,除非提供显式比较规则。在4.2之前的版本中,针对单个集合db.collection.watch()创建的变更流会继承该集合的默认比较规则。
恢复令牌修改
从MongoDB 4.2开始,如果变更流聚合管道修改了事件的_id字段,则会产生异常。
增加了接受连接所需的文件描述符
从MongoDB 4.2开始,mongod或mongos实例接受1个连接需要两个文件描述符。在MongoDB 4.2之前版本中,入站连接只需要一个文件描述符。
在从MongoDB 4.0升级到4.2之前,您可能需要增加open files 配置(ulimit -n)。
MongoDB工具
FIPS 模式
从4.2版本开始,MongoDB移除了以下程序的--sslFIPSMode选项:
mongodump
mongoexport
mongofiles
mongoimport
mongorestore
mongostat
mongotop。
上述程序在mongod和mongos实例中启用了FIPS模式时会使用符合FIPS标准的连接。
扩展 JSON v2
工具 | 说明 |
bsondump | 使用扩展JSON v2.0(规范模式)格式。 |
mongodump | 使用扩展JSON v2.0(规范模式)格式输出元数据。需要mongorestore版本4.2或更高版本,才能支持扩展JSON v2.0(规范模式或宽松模式)格式。 说明 通常情况下,应使用对应版本的mongodump和mongorestore。如需还原由特定版本mongodump创建的数据文件,应使用相应版本的mongorestore。 |
mongoexport | 默认生成扩展 JSON v2.0(宽松模式)输出。 如果指定 |
mongoimport | 默认期望导入的数据为扩展JSON v2.0(宽松或规范模式)。 如果指定 说明 通常情况下,mongoexport和mongoimport的版本应保持一致。如需导入由mongoexport创建的数据,应使用相应版本的mongoimport 。 |
查询选项
从 4.2 版本开始,mongodump和mongoexport的--query选项必须使用扩展JSON v2格式(宽松或严格模式),包括将字段名称和操作符用引号括起来,例如:
mongoexport -d=test -c=records -q='{ "a": { "$gte": 3 }, "date": { "$lt": { "$date": "2016-01-01T00:00:00.000Z" } } }' --out=exportdir/myRecords.json在4.2之前的版本中,查询选项使用扩展JSON v1格式,字段名称和操作符不需要用引号括起来:
mongoexport -d=test -c=records -q='{ a: { $gte: 3 }, date: { $lt: { "$date": "2016-01-01T00:00:00.000Z" } } }' --out=exportdir/myRecords.json副本集状态变更
Primary Step Down
从MongoDB 4.2开始,replSetStepDown(或通过replSetReconfig导致的下线)不再关闭所有客户端连接。但仍在处理中的写入会被终止。
在MongoDB 4.0及之前版本中,replSetStepDown在下线期间会关闭所有客户端连接。
回滚状态(ROLLBACK State)
从4.2版本开始,当成员进入ROLLBACK状态时,MongoDB会终止所有用户操作。
4.2 版本驱动程序默认启用可重试写入
MongoDB已于3.6版本支持可重试写入,但大多数MongoDB 3.6和4.0的官方驱动程序默认禁用此功能。对于这些驱动程序,可重试写入可以通过在连接字符串中指定retryWrites=true选项在连接级别启用。
MongoDB 4.2及以后的官方驱动程序默认启用可重试写入。升级到 4.2 版本驱动程序的应用程序,如果需要使用可重试写入,则无需指定retryWrites=true选项。如果需要禁用可重试写入,则必须在连接字符串中包含retryWrites=false选项。
local数据库不支持可重试写入。除非显式禁用可重试写入,否则使用升级到 4.2 版本的驱动程序在写入local数据库时会遇到写入错误。
一般变更
索引
对reIndex的限制
MongoDB对reIndex命令或db.collection.reIndex()函数添加了更严格的限制,禁止在mongos上运行reIndex和db.collection.reIndex()。
对db.collection.dropIndex()的限制
你不能使用db.collection.dropIndex()来删除所有非_id索引。请改用db.collection.dropIndexes()进行删除。
创建重复索引的错误信息
从4.2版本开始,如果您创建了一个索引,然后尝试使用另一个名称创建相同的索引,createIndexes命令以及mongo shell帮助函数db.collection.createIndex()和db.collection.createIndexes()会返回错误。
{
"ok" : 0,
"errmsg" : "Index with name: x_1 already exists with a different name",
"code" : 85,
"codeName" : "IndexOptionsConflict"
}如果在4.0和更早版本中执行此操作,MongoDB不会重新创建索引,但仍会返回一个包含以下内容的信息。
{
"numIndexesBefore" : 2,
"numIndexesAfter" : 2,
"note" : "all indexes already exist",
"ok" : 1
}PowerPC 上的哈希索引
对于哈希索引,MongoDB 4.2确保了在PowerPC上,浮点数 263的哈希值与其他平台一致。在4.2之前的版本中,PowerPC上浮点数263的哈希值与其他平台不一致。
尽管创建哈希索引时的字段不支持大于253的浮点数值,但客户端仍然可以插入索引字段的值为263的文档。
如果MongoDB 4.0分片集群在PowerPC上的分片键包含263的哈希值,在升级分片集群到4.2之前必须考虑额外因素。
min()/max()
从MongoDB 4.2开始,当您在db.collection.find()操作中指定min()/max()时,必须显式地指定与min()/max()对应的索引,除非find()查询是对_id字段的等值条件{ _id: }。
同理,在find命令中指定min/max时,也必须显式地指定min/max索引的提示。
在4.0和更早版本中,无论查询条件如何,您都可以选择是否显式地指定min()/max()索引。如果在4.0和更早版本中不显式指定提示,MongoDB会根据索引的边界选择索引;但如果存在多个在相同字段上但排序顺序不同的索引,选择索引可能会不明确。
CurrentOp
在报告"getmore"操作时,$currentOp聚合阶段、currentOp命令以及db.currentOp()现在将originatingCommand字段作为新cursor字段的子字段返回。在之前的版本中,originatingCommand是"getmore"文档中的顶级字段。
服务器状态
serverStatus和db.serverStatus返回的opcounters和opcountersRepl度量现在变为64位整数(即NumberLong)而不是32位整数(即NumberInt)。
日志记录
当记录到syslog时,消息文本的格式现在包含组件。例如:
... ACCESS [repl writer worker 5] Unsupported modification to roles collection ...在4.2之前版本中,syslog消息文本不包含组件。例如:
... [repl writer worker 1] Unsupported modification to roles collection ...从MongoDB 4.2开始,获取日志命令会截断任何包含超过1024个字符的事件。在4.2之前版本中,获取日志命令会在512个字符后截断。
从MongoDB 4.2开始,MongoDB记录调试日志级别。例如,如果日志级别为2,则MongoDB记录D2。
在4.2之前版本中,MongoDB日志消息仅支持指定D表示调试级别。
Wire Protocol
MongoDB不再支持OP_COMMAND和对应的OP_COMMANDREPLY网络协议。
killCursors变更
事务
从MongoDB 4.2开始,事务中的第一个操作不能是killCursors。
权限
从MongoDB 4.2开始,用户始终可以终止自己的游标,无论用户是否具有killCursors权限。因此,MongoDB 4.2及以后版本中的killCursors权限不再生效。
在MongoDB 3.6.3到MongoDB 4.0.x版本,用户需要killCursors权限才能在访问控制启用时终止自己的游标。
移除了 AsyncRequestsSenderUseBaton 参数
在 MongoDB 4.2及以后版本,MongoDB移除了AsyncRequestsSenderUseBaton参数,并始终启用该参数控制的性能增强。
更严格的 count 语法验证
从 4.2 版本开始,MongoDB实施了对count命令选项名称更严格的验证。如果指定未知的选项名称,命令会报错。
在4.2之前的版本中,MongoDB会忽略无效的选项名称。
因果一致性的会话
从MongoDB 4.2开始,以下命令不再支持指定afterClusterTime:
dbHash命令mapReduce命令validate命令
因此,这些操作无法与因果一致性的会话相关联。
移除了fastmodinsert指标
MongoDB 4.2 移除了已弃用的fastmodinsert指标,不再显示使用executionStats的Explain结果、查询分析器输出等位置。
Map-Reduce
从4.2版本开始,MongoDB弃用以下内容:
分片集群中使用
map-reduce创建新分片集合的功能,以及使用sharded选项进行map-reduce。要输出到分片集合,请先创建分片集合。MongoDB 4.2也弃用了替换现有分片集合的功能。Map-Reduce显式指定
nonAtomic: false选项。
Balencer状态和自动分割(Autosplit)
从MongoDB 4.2开始:
balancerStart命令和mongo shell帮助方法sh.startBalancer()和sh.setBalancerState(true)同时启用自动分割。如需禁用自动分割,可以使用
sh.disableAutoSplit()。balancerStop命令和mongo shell帮助方法sh.stopBalancer()和sh.setBalancerState(false)同时禁用自动分割。如需启用自动分割,可以使用
sh.enableAutoSplit()。
sh.enableBalancing(namespace)和sh.disableBalancing(namespace)方法不再影响自动分割。
锁诊断报告
从MongoDB 4.2开始,MongoDB报告ReplicationStateTransition锁的信息。
此外,MongoDB 4.2将ParallelBatchWriterMode锁信息与全局锁信息分开报告。4.2之前的版本会将ParallelBatchWriterMode锁信息包含在全局锁信息中。
有关报告锁信息的操作,请参见:
serverStatus命令和db.serverStatus()方法。$currentOp聚合管道阶段、currentOp命令、db.currentOp()方法。
对 findAndModify 的查询/排序/投影参数的验证
从MongoDB 4.2(包括 4.0.12+ 和 3.6.14+版本)开始,findAndModify命令及其关联的mongo shell方法在指定的查询、排序或投影参数不是文档时会报错。
在4.2之前的版本中,如果查询或排序参数不是文档,操作会将其视为空文档 {}。
dropDatabase 和 movePrimary
从 MongoDB 4.2开始:
如果您删除一个数据库并创建具有相同名称的新数据库,需要:
重启所有mongos实例和分片成员。
在读写该数据库之前,在所有mongos实例和分片成员上执行
flushRouterConfig命令。
如果您使用movePrimary命令移动非分片集合,需要:
重启所有mongos实例和分片成员。
在读写该集合之前,在所有mongos实例和分片成员上执行
flushRouterConfig命令。
这确保了mongos和分片成员刷新其元数据缓存。否则读取时可能会漏掉数据,写入时可能不会写入到正确的分片。如需恢复,请您手动干预。
在4.2之前的版本中,仅需重启mongos实例或在mongos实例上运行flushRouterConfig命令。
移除system.indexes和system.namespaces集合
从 4.2 版本开始,MongoDB移除了system.indexes和system.namespaces集合(已于3.0版本弃用)。
随着这些集合的移除,内置角色clusterManager、clusterMonitor、dbAdmin、read、restore等以及其他从这些角色继承的权限不再授予访问system.indexes和system.namespaces集合的权限。
降级 arbiter 需要清除数据目录
MongoDB 4.2 arbiter数据文件与MongoDB 4.0不兼容。从MongoDB 4.2降级到4.0需要先删除arbiter数据文件。使用MongoDB 4.2的数据文件来运行MongoDB 4.0的arbiter可能会产生错误。
分片集合和文档替换
从MongoDB 4.2开始:
替换文档的操作(如
replaceOne()或update()与替换文档配合使用)会首先尝试使用查询过滤器将文档目标定位到单个分片。如果无法通过查询过滤器定位到单个分片,则尝试使用替换文档定位。在4.2之前的版本中,这些操作仅尝试使用替换文档定位。MongoDB弃用了
save()方法,请改用insertOne()或replaceOne()方法。save()方法无法用于非_id分片的分片集合,否则会导致错误。对于带有
upsert: true的替换文档操作,分片集合上必须确保过滤器包含与分片键完全匹配的等式条件。
4.2 功能兼容性
4.2版本中的某些功能不仅需要4.2二进制文件,还需要功能兼容版本(fCV)设置为4.2。这些功能包括:
分布式事务。
移除了MongoDB 4.2及以上版本的索引键长限制。同时,
failIndexKeyTooLong参数对fCV设置为4.2及以上版本的MongoDB无效,仅适用于MongoDB 2.6-4.0版本。对MongoDB 4.2及以上版本,移除了索引名称长度限制。
新的唯一索引内部格式。此新格式适用于所有现有唯一索引以及新创建或重建的唯一索引。
从 MongoDB 4.2开始,用户无法再将
type:0作为exists:false的同义词使用。MongoDB 4.2新增了通配符索引,以支持用户查询自定义字段或集合中大量不同字段的工作负载。