MongoDB 3.4兼容性变更说明

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

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

分片集群变更说明

明确成员角色

在 3.4分片集群中,所有分片节点的 mongod 实例必须通过以下方式显式声明其角色为 shardsvr

  • 配置文件:设置 sharding.clusterRole: shardsvr

  • 命令行参数:使用 --shardsvr 选项。

说明

shardsvr 角色的 mongod 实例默认端口为 27018。若需使用其他端口,需通过 net.port 配置项或 --port 参数指定。

兼容性限制

3.4版本 mongos 无法连接早于3.4版本的 mongod 实例。

移除的配置选项

MongoDB 3.4 从 mongos 中移除了以下配置选项:

  • 分片块大小配置:

    • 配置文件项 sharding.chunkSize

    • 命令行选项 --chunkSize

  • 自动分块拆分配置:

    • 配置文件项 sharding.autoSplit

    • 命令行选项 --noAutoSplit

停止支持SCCC配置服务器

MongoDB 3.4版本起,分片集群不再支持镜像模式(SCCC)的 mongod 实例作为配置服务器(该模式已在3.2版本标记为弃用)。

您必须将配置服务器(CSRS)部署为副本集。升级要求如下:

  • 若需将分片集群升级至3.4版本,配置服务器必须运行为副本集。

  • 若当前使用SCCC配置服务器,需先转换为副本集模式。

初始同步与重命名集合的兼容性问题

若在初始同步(initial sync)过程中对同步源(sync source)的集合执行重命名操作,初始同步进程将失败并重新启动,以避免潜在的数据损坏风险。具体介绍,请参见SERVER-26117

涉及集合重命名的操作包括:

  • renameCollection 命令:如 db.collection.renameCollection() 方法。

  • 聚合操作中的 $out 阶段:使用 db.collection.aggregate() 方法或 aggregate 命令时包含 $out 阶段。

  • MapReduce 的 out 选项:使用 db.collection.mapReduce() 方法或 mapReduce 命令时指定 out 选项。

  • convertToCapped 命令:将普通集合转换为固定集合(capped collection)。

3.2.11或更早版本升级至 3.4时,如果初始同步过程中遇到集合重命名操作,同步可能失败。

3.2.11及之前版本中,当遇到可能损坏数据的renameCollection操作时,初始同步过程将继续进行。具体介绍,请参见SERVER-4941

弃用的操作说明

group命令

MongoDB 3.4版本起,弃用group命令和mongo Shelldb.collection.group()方法,请改用db.collection.aggregate() 或db.collection.mapReduce()

聚合命令必须指定游标

MongoDB 3.6版本起,aggregate命令必须通过cursor选项返回游标,除非同时指定explain选项用于分析执行计划。

  • 要指示具有默认批大小的游标,请指定游标:{}

  • 要指示具有非默认批大小的游标,请使用cursor: { batchSize: <num> }

集合与索引规范

集合选项校验

MongoDB 3.4起,在 create 命令及 db.createCollection() 操作中,对集合选项的校验更为严格,您必须使用 createdb.createCollection() 支持的合法选项。

例如,以下操作因包含无效选项 cappedtypo 导致不再合法:

db.createCollection( "myCappedCollection", { cappedtypo: true, size: 5242880 } )

索引规范校验

MongoDB 3.4版本起,createIndexes 命令及 db.collection.createIndex() 方法在创建索引时执行更严格的校验(不适用于已有索引)。具体规则如下:

  • 索引键模式 key: value 中的 value 必须为以下值之一:

    说明

    数值 > 0

    升序索引(ascending)

    数值 < 0

    降序索引(descending)

    字符串

    特殊索引类型,仅允许:"text"、"2dsphere"、"2d"、"hashed"

    例如,以下操作将不再有效:

    db.collection.createIndex( { x: 0 } );
    db.collection.createIndex( { y: "text2d" } );
    db.collection.createIndex( { z: NaN } );
    db.collection.createIndex( { x: 1, unique: true } )
  • 3.4之前的版本会忽略无效的索引选项,而MongoDB 3.4版本起会直接报错。例如,以下操作将不再有效:

    db.collection.createIndex( { y: 1 }, { uniques2: true} );
    db.collection.createIndex( { z: 1 }, { expireAfterSec: 350 } )

通用兼容性变更说明

  • 命名空间限制调整:自MongoDB 3.4起,数据库名称不再支持包含 $ 符号。

    说明

    升级至3.4前,必须删除所有名称包含 $ 的数据库。

  • 删除textSearchEnabled参数。MongoDB已于2.6版本默认启用文本搜索功能。

  • 移除mongosniff 工具:自MongoDB 3.4版本起,使用功能更强大的 mongoreplay 替代 mongosniff,支持更灵活的网络流量捕获与分析。

  • 聚合 $project 阶段行为变更:若 $project 阶段返回空文档(未保留或新增任何字段),将触发错误。

  • hint() 与稀疏索引的计数问题:当使用 hint() 强制指定稀疏索引(sparse index) 并执行全集合文档计数(即查询条件为空)时,稀疏索引可能导致计数结果不准确。

    db.collection.insert({ _id: 1, y: 1 } );
    db.collection.createIndex( { x: 1 }, { sparse: true } );
    
    db.collection.find().hint( { x: 1 } ).count();

    若要获得正确的计数,请不要在hint()中指定使用稀疏索引计数全集合文档。

    db.collection.find().count();
    
    db.collection.createIndex({ y: 1 });
    db.collection.find().hint({ y: 1 }).count();

    3.4之前的版本中,若使用稀疏索引会导致计数缺失,3.4之前的版本会忽略 hint() 强制索引的指定。

用户角色权限变更说明

MongoDB 3.4起,以下内置角色的权限不再适用于 localconfig 数据库:

角色名称

说明

readAnyDatabase

若需授予对 local 数据库的读权限,需在 admin 库中创建用户并显式分配 local 库的 read 角色。另可通过 clusterManager 或 clusterMonitor 角色访问 config 和 local 库。

readWriteAnyDatabase

若需授予对 local 数据库的读写权限,需在 admin 库中创建用户并显式分配 local 库的 readWrite 角色。

userAdminAnyDatabase

dbAdminAnyDatabase

若需授予对 local 数据库的管理权限,需在 admin 库中创建用户并显式分配 local 库的 dbAdmin 角色。

以下内置角色新增了对 localconfig 数据库的权限:

  • clusterManager

  • clusterMonitor

  • backup

  • restore

不向后兼容的功能说明

MongoDB 3.4 引入了以下特性,这些特性会持久化3.4之前的版本无法正确处理的数据,您需将 featureCompatibilityVersion 设为"3.4"方可启用:

  • 视图(Views)

  • 排序规则与大小写不敏感索引(Collation & Case-Insensitive Indexes)

  • 十进制类型(Decimal Type)

  • 索引版本 v2

    • 新增支持了排序规则与十进制数据类型。

    • 当 featureCompatibilityVersion 设为 "3.4" 时,新创建的索引默认版本为 v2;否则为 v1。

说明

启用这些不兼容特性会增加降级难度。

建议在升级后,允许部署在未启用这些功能的情况下运行,以确保降级的可能性最小。当您确信降级的可能性极小时,再启用这些功能。

featureCompatibilityVersion默认值如下:

  • 全新部署的3.4:"3.4"。

  • 3.2升级的部署:"3.2"(需手动设为"3.4")。

3.4之前的版本中,若数据库包含视图、排序规则定义或v2索引,3.4之前的版本MongoDB将无法启动;若存在十进制类型字段,针对这些文档的操作可能失败。

如需升级,您必须清除所有不兼容数据(如视图、v2索引、十进制字段)。

驱动兼容性变更说明

若要使用 MongoDB 3.4 引入的新功能(如十进制类型(Decimal Type)和排序规则(Collation)),必须将驱动程序升级至支持这些特性的版本。

单元素$inupsert的行为变更

upsert 操作未找到匹配文档时,会根据查询条件中的等式语句创建基础文档,再应用更新操作符。示例如下:

db.c.drop()
db.c.update( { a : 3, b: "foo" }, { $set : { c : 15 } }, { upsert : true } )
db.c.find()
{ "_id" : ObjectId("59c03009529946822d0afb8c"), "a" : 3, "b" : "foo", "c" : 15 }

3.4之前的版本中,单元素 $in 查询不会初始化字段:

db.c.drop()
db.c.update( { a : { $in : [1] } }, { $addToSet : { a : 2 } }, { upsert : true } )
db.c.find()
{ "_id" : ObjectId("58bdb00eb39e8f87607e9222"), "a" : [ 2 ] }

3.4及之后版本中,单元素 $in 视为等式条件:

  • 若查询条件中包含单元素 $in,字段会被初始化为标量值而非数组。

  • 上述示例的 $addToSet 操作将失败,因为无法对标量字段应用数组操作符。

解决方案:将 $in 表达式包裹在 $elemMatch 中,强制保持字段的数组类型。

db.c.drop()
db.c.update(
   { a : { $elemMatch : { $in : [ 2 ] } } },
   { $addToSet : { a: 3 } },
   { upsert: true } )
db.c.find()
{ "_id" : ObjectId("..."), "a" : [ 3 ] }