MongoDB Sharding 請勿複用已刪除的 namespace

SERVER-17397: Dropping a Database or Collection in a Sharded Cluster may not fully succeed 是 MongoDB 里老大難的問題,庫或集合刪除操做若是沒有徹底執行成功,再新建相同名字的集合,可能致使讀到老版本數據的問題。mongodb

集合分片原理

MongoDB sharding 分片原理參考 MongoDB Sharded cluster架構原理數據庫

總的來講,當用戶對集合執行開啓分片以後,集合分片的元數據會保存在 config server 的 config 集合裏架構

  • config.collections 記錄集合分片的元數據,根據哪一個 shardKey 分片,集合是否已經被刪除等元數據
  • config.chunks,記錄各個 chunk(shardKey的某一段範圍)對應的 shard 信息,用於路由請求
  • 各個 shard 裏存儲集合實際的數據

刪除分片集合流程

  1. 刪除全部 shard 裏的對應的數據
  2. 刪除 config.chunks 這個集合相關的chunk信息
  3. 修改 config.collections,標記集合已經刪除

注:3.2+都是按上述流程操做,刪除 Database 過程相似,還須要再額外操做 config.databases 集合,但本質上存在的問題相似阿里雲

上述動做須要操做 config server 以及 全部的 shard,若是中間有步驟失敗(一些很老的版本,並非按照上述步驟執行,並且執行過程當中可能沒有嚴格檢查返回的錯誤碼,即便返回成功實際上內部可能執行失敗),最終致使集合的部分數據仍然殘留,沒有徹底清理乾淨。url

若是這個集合名字從新被使用,再次調用 shardCollection 產生新的分片元數據,可能致使spa

  1. 在 shard 上的一些殘留數據可能被讀取到,而這些數據實際上應該被刪除了
  2. mongos 沒有成功更新路由信息,最終可能出現多個 mongos 看到的數據視圖也不一致,有的 mongos 能讀到數據,有的讀不到(經過 `flushRouterConfig 命令能夠強制刷新路由信息可解決)

解決方案

MongoDB sharding 刪除集合/數據庫涉及到多個節點進行操做,這些動做沒法作到原子性,可能致使一個集合最終處於某種中間狀態;複用該集合可能致使一寫數據一致性問題。code

  1. 使用 MongoDB 3.2+ 以上版本,大部分case,只要沒有異常,刪除集合動做都能正常完成的,複用集合名字問題通常問題也不大,但沒法徹底避免問題。
  2. 建議 Sharding 環境下,namespace 名字一旦被刪除,不要再次複用
  3. 在須要複用 Namespace 的狀況下,若是要確保不會有數據問題,每次能夠按 drop collection workaround 確保相關數據被正確清理,而且路由信息被更新。

搶阿里雲新用戶專屬優惠權益,致電95187-1 !
server



本文做者:張友東

閱讀原文blog

本文爲雲棲社區原創內容,未經容許不得轉載。路由

相關文章
相關標籤/搜索