本文介绍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参数:
newCollectionsUsePowerOf2Sizes
replIndexPrefetch
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新增了通配符索引,以支持用户查询自定义字段或集合中大量不同字段的工作负载。