MongoDB 4.2兼容性更新说明

本文介绍MongoDB 4.2版本的兼容性变化。

如需查看MongoDB官网兼容性更新说明文档,请前往MongoDB官网下载

移除MMAPv1存储引擎

MongoDB 4.2删除了对MMAPv1存储引擎的支持。

如果您在4.0版本使用了MMAPv1存储引擎,请在升级到4.2版本前将存储引擎更改为WiredTiger存储引擎。

MMAPv1特定配置选项

MongoDB删除了以下MMAPv1特定的配置选项:

删除的配置

删除的命令行

storage.mmapv1.journal.commitIntervalMs

storage.mmapv1.journal.debugFlags

mongod --journalOptions

storage.mmapv1.nsSize

mongod --nssize

storage.mmapv1.preallocDataFiles

mongod --noprealloc

storage.mmapv1.quota.enforced

mongod --quota

storage.mmapv1.quota.maxFilesPerDB

mongod --quotaFiles

storage.mmapv1.smallFiles

mongod --smallfiles

storage.repairPath

mongod --repairpath

replication.secondaryIndexPrefetch

mongod --replIndexPrefetch

说明

4.2版本开始,MongoDB将不再使用上述配置和命令。如果您使用了WiredTiger部署,请删除MMAPv1的配置选项。

MMAPv1特定参数

MongoDB删除了以下MMAPv1参数:

  • newCollectionsUsePowerOf2Sizes

  • replIndexPrefetch

MMAPv1特定命令

MongoDB删除了MMAPv1特定的touch命令。

命令和方法的MMAPv1特定选项

MongoDB删除了MMAPv1的特定选项:

  • collMod命令的noPaddingusePowerOf2Sizes

  • collStats命令的verbose

  • create命令的flags

  • db.createCollection()命令的paddingFactorpaddingBytespreservePadding

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及之前版本时运行。

移除对copydbclone命令的支持

4.2版本开始,MongoDB移除了copydb命令和clone命令。mongo shell的帮助函数db.copyDatabase()db.cloneDatabase()只能在连接到MongoDB 4.0及之前版本时运行。

请改用mongodumpmongorestore(需配合mongorestore选项的--nsFrom--nsTo参数使用)或使用驱动程序编写脚本。

例如,将test 数据库复制到同实例的 examples 数据库,您可以:

  1. 用于mongodumptest数据库转储到归档文件mongodump-test-db

    mongodump --archive="mongodump-test-db" --db=test
  2. 使用mongorestore搭配--nsFrom--nsTo参数从存档中恢复。

    mongorestore --archive="mongodump-test-db" --nsFrom='test.*' --nsTo='examples.*'
说明

您可以按需添加参数,例如 --uri--host--username 等。

您也可以不使用存档文件,通过 mongodumptest数据库连接到标准输出流,并通过管道传递到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命令返回结果中包含avgDistancemaxDistance

    你可以使用聚合管道在geoNear阶段之后使用group阶段来返回avgDistancemaxDistance

    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()

请改用mongoexportmongoimport命令,或编写一个使用驱动的脚本。

弃用 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阶段。

$outRead Concern级别

$out阶段不能与Read Concern级别"linearizable"结合使用。

$outExplain

如果聚合阶段包含$out阶段,则无法在executionStats模式或allPlansExecution模式下运行db.collection.explain()帮助函数(或explain命令)。

如果聚合阶段包含$out阶段,要查看executionStatsallPlansExecution信息,请在不包含out阶段的情况下运行explain,以便返回前面阶段的explain结果。

或者,您可以在包含$out阶段的聚合阶段中以queryPlanner模式运行explain

$out 和 Majority Read Concern级别

从 MongoDB 4.2 开始,您可以在包含$out阶段的聚合操作中指定Read Concern级别为"majority"

$geoNear移除了limitnum选项

MongoDB 4.2开始,MongoDB删除了$geoNearlimitnum选项,以及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开始,mongodmongos实例接受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。

上述程序在mongodmongos实例中启用了FIPS模式时会使用符合FIPS标准的连接。

扩展 JSON v2

工具

说明

bsondump

使用扩展JSON v2.0(规范模式)格式。

mongodump

使用扩展JSON v2.0(规范模式)格式输出元数据。需要mongorestore版本4.2或更高版本,才能支持扩展JSON v2.0(规范模式或宽松模式)格式。

说明

通常情况下,应使用对应版本的mongodumpmongorestore。如需还原由特定版本mongodump创建的数据文件,应使用相应版本的mongorestore。

mongoexport

默认生成扩展 JSON v2.0(宽松模式)输出。

如果指定--jsonFormatcanonical,则mongoexport生成扩展JSON v2.0(规范模式)输出。

mongoimport

默认期望导入的数据为扩展JSON v2.0(宽松或规范模式)。

如果指定--legacy选项, mongoimport可以识别扩展JSON v1.0格式的数据。

说明

通常情况下,mongoexportmongoimport的版本应保持一致。如需导入由mongoexport创建的数据,应使用相应版本的mongoimport 。

查询选项

从 4.2 版本开始,mongodumpmongoexport--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.64.0的官方驱动程序默认禁用此功能。对于这些驱动程序,可重试写入可以通过在连接字符串中指定retryWrites=true选项在连接级别启用。

MongoDB 4.2及以后的官方驱动程序默认启用可重试写入。升级到 4.2 版本驱动程序的应用程序,如果需要使用可重试写入,则无需指定retryWrites=true选项。如果需要禁用可重试写入,则必须在连接字符串中包含retryWrites=false选项。

说明

local数据库不支持可重试写入。除非显式禁用可重试写入,否则使用升级到 4.2 版本的驱动程序在写入local数据库时会遇到写入错误。

一般变更

索引

reIndex的限制

MongoDBreIndex命令或db.collection.reIndex()函数添加了更严格的限制,禁止在mongos上运行reIndexdb.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"文档中的顶级字段。

服务器状态

serverStatusdb.serverStatus返回的opcountersopcountersRepl度量现在变为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.3MongoDB 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指标,不再显示使用executionStatsExplain结果、查询分析器输出等位置。

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.2ParallelBatchWriterMode锁信息与全局锁信息分开报告。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.indexessystem.namespaces集合

从 4.2 版本开始,MongoDB移除了system.indexessystem.namespaces集合(已于3.0版本弃用)。

随着这些集合的移除,内置角色clusterManagerclusterMonitordbAdminreadrestore等以及其他从这些角色继承的权限不再授予访问system.indexessystem.namespaces集合的权限。

降级 arbiter 需要清除数据目录

MongoDB 4.2 arbiter数据文件与MongoDB 4.0不兼容。从MongoDB 4.2降级到4.0需要先删除arbiter数据文件。使用MongoDB 4.2的数据文件来运行MongoDB 4.0arbiter可能会产生错误。

分片集合和文档替换

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