本文介紹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 Shell的db.collection.group()方法,請改用db.collection.aggregate() 或db.collection.mapReduce()。
彙總命令必須指定遊標
自MongoDB 3.6版本起,aggregate命令必須通過cursor選項返回遊標,除非同時指定explain選項用於分析執行計畫。
要指示具有預設批大小的遊標,請指定遊標:
{}。要指示具有非預設批大小的遊標,請使用
cursor: { batchSize: <num> }。
集合與索引規範
集合選項校正
自MongoDB 3.4起,在 create 命令及 db.createCollection() 操作中,對集合選項的校正更為嚴格,您必須使用 create 或 db.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起,以下內建角色的許可權不再適用於 local 和 config 資料庫:
角色名稱 | 說明 |
readAnyDatabase | 若需授予對 local 資料庫的讀許可權,需在 admin 庫中建立使用者並顯式分配 local 庫的 read 角色。另可通過 clusterManager 或 clusterMonitor 角色訪問 config 和 local 庫。 |
readWriteAnyDatabase | 若需授予對 local 資料庫的讀寫權限,需在 admin 庫中建立使用者並顯式分配 local 庫的 readWrite 角色。 |
userAdminAnyDatabase | 無 |
dbAdminAnyDatabase | 若需授予對 local 資料庫的系統管理權限,需在 admin 庫中建立使用者並顯式分配 local 庫的 dbAdmin 角色。 |
以下內建角色新增了對 local 和 config 資料庫的許可權:
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)),必須將驅動程式升級至支援這些特性的版本。
單元素$in與upsert的行為變更
當 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 ] }