Hướng dẫn mongodb write conflict - mongodb viết xung đột

Trên trang này

  • MongoDB sử dụng loại khóa nào?
  • Làm thế nào hạt là khóa trong MongoDB?
  • Làm cách nào để thấy trạng thái của khóa trên các trường hợp của tôi? instances?
  • Một hoạt động đọc hoặc viết có bao giờ mang lại khóa không?
  • Khóa nào được thực hiện bởi một số hoạt động khách hàng chung?
  • Những lệnh quản trị nào khóa cơ sở dữ liệu?
  • Lệnh hành chính nào khóa bộ sưu tập?
  • Liệu một hoạt động MongoDB có bao giờ khóa nhiều hơn một cơ sở dữ liệu không?
  • Làm thế nào để Sharding ảnh hưởng đến sự đồng thời?
  • Làm thế nào để đồng thời ảnh hưởng đến một bản sao đặt chính?
  • Làm thế nào để đồng thời ảnh hưởng đến thứ hai?
  • MongoDB có hỗ trợ giao dịch không?
  • MongoDB bảo đảm những gì mà MongoDB cung cấp?
  • Hoạt động đọc không khóa là gì?

MongoDB cho phép nhiều máy khách đọc và viết cùng một dữ liệu. Để đảm bảo tính nhất quán, MongoDB sử dụng kiểm soát khóa và kiểm soát đồng thời để ngăn khách hàng sửa đổi cùng một dữ liệu. Viết vào một tài liệu duy nhất xảy ra đầy đủ hoặc hoàn toàn và khách hàng luôn thấy dữ liệu nhất quán.

MongoDB sử dụng khóa đa lỗ [1] cho phép các hoạt động khóa ở cấp độ toàn cầu, cơ sở dữ liệu hoặc thu thập và cho phép các công cụ lưu trữ riêng lẻ thực hiện kiểm soát đồng thời của riêng họ dưới cấp độ thu thập (ví dụ: ở cấp độ tài liệu trong Wiredtiger) .

MongoDB sử dụng các khóa của người đọc cho phép người đọc đồng thời chia sẻ quyền truy cập vào một tài nguyên, chẳng hạn như cơ sở dữ liệu hoặc bộ sưu tập.

Ngoài chế độ khóa được chia sẻ để đọc và chế độ khóa độc quyền (x) cho các hoạt động ghi, các chế độ chia sẻ ý định (IS) và ý định (ix) cho thấy ý định đọc hoặc viết tài nguyên bằng cách sử dụng khóa chi tiết tốt hơn . Khi khóa ở một mức độ chi tiết nhất định, tất cả các cấp cao hơn đều bị khóa bằng cách sử dụng khóa ý định.

Ví dụ: khi khóa bộ sưu tập để viết (sử dụng chế độ X), cả khóa cơ sở dữ liệu tương ứng và khóa toàn cầu phải được khóa ở chế độ INSTENT EXCLUST (IX). Một cơ sở dữ liệu duy nhất có thể đồng thời bị khóa ở chế độ IS và IX, nhưng khóa độc quyền (x) không thể cùng tồn tại với bất kỳ chế độ nào khác và khóa được chia sẻ chỉ có thể cùng tồn tại với khóa được chia sẻ (IS).

Khóa là công bằng, với các yêu cầu khóa cho các lần đọc và ghi được xếp hàng theo thứ tự. Tuy nhiên, để tối ưu hóa thông lượng, khi một yêu cầu khóa được cấp, tất cả các yêu cầu khóa tương thích khác được cấp cùng một lúc, có khả năng phát hành khóa trước khi yêu cầu khóa mâu thuẫn được thực hiện. Ví dụ, hãy xem xét một tình huống mà khóa X vừa được phát hành và hàng đợi xung đột có chứa các khóa này:

Là → là → x → x → s → là

Trong lần đầu tiên đến, đặt hàng đầu tiên (FIFO), chỉ có hai chế độ đầu tiên được cấp. Thay vào đó, MongoDB thực sự sẽ cấp tất cả các chế độ là và S, và một khi tất cả đều thoát ra, nó sẽ cấp X, ngay cả khi các yêu cầu mới hoặc S đã được xếp hàng trong thời gian đó. Vì một khoản trợ cấp sẽ luôn di chuyển tất cả các yêu cầu khác trước trong hàng đợi, không có bất kỳ yêu cầu nào của bất kỳ yêu cầu nào.

Trong đầu ra db.serverStatus()db.currentOp(), các chế độ khóa được biểu diễn như sau:

Chế độ khóa

Sự mô tả

R

Đại diện cho khóa (s) được chia sẻ.

W

Đại diện cho khóa độc quyền (x).

r

Đại diện cho ý định chia sẻ (IS) khóa.

w

Đại diện cho khóa dành riêng (ix).

Đối với hầu hết các hoạt động đọc và viết, Wiredtiger sử dụng kiểm soát đồng thời lạc quan. Wiredtiger chỉ sử dụng khóa ý định ở cấp độ toàn cầu, cơ sở dữ liệu và thu thập. Khi công cụ lưu trữ phát hiện xung đột giữa hai hoạt động, người ta sẽ phát sinh xung đột ghi khiến MongoDB thử lại hoạt động đó một cách minh bạch.

Một số hoạt động toàn cầu, thường là các hoạt động sống ngắn liên quan đến nhiều cơ sở dữ liệu, vẫn yêu cầu khóa "toàn bộ trường hợp" toàn cầu. Một số hoạt động khác, chẳng hạn như collMod, vẫn yêu cầu khóa cơ sở dữ liệu độc quyền.

Để báo cáo về thông tin sử dụng khóa trên khóa, hãy sử dụng bất kỳ phương pháp nào trong số này:

  • db.serverStatus()

  • db.currentOp()

  • db.serverStatus()0

  • db.serverStatus()1 và/hoặc, and/or

  • Trình quản lý đám mây MongoDB hoặc Trình quản lý OPS, một giải pháp tại chỗ có sẵn trong MongoDB Enterprise AdvancedMongoDB Cloud Manager or Ops Manager, an on-premise solution available in MongoDB Enterprise Advanced

Cụ thể, tài liệu db.serverStatus()2 trong đầu ra của ServerStatus hoặc trường db.serverStatus()2 trong báo cáo hoạt động hiện tại cung cấp cái nhìn sâu sắc về loại khóa và số lượng tranh chấp khóa trong phiên bản db.serverStatus()4 của bạn.

Trong đầu ra db.serverStatus()db.currentOp(), các chế độ khóa được biểu diễn như sau:

Chế độ khóa

Sự mô tả

R

Đại diện cho khóa (s) được chia sẻ.

W

Đại diện cho khóa độc quyền (x).

r

Đại diện cho ý định chia sẻ (IS) khóa.

w

Đại diện cho khóa dành riêng (ix).

Đối với hầu hết các hoạt động đọc và viết, Wiredtiger sử dụng kiểm soát đồng thời lạc quan. Wiredtiger chỉ sử dụng khóa ý định ở cấp độ toàn cầu, cơ sở dữ liệu và thu thập. Khi công cụ lưu trữ phát hiện xung đột giữa hai hoạt động, người ta sẽ phát sinh xung đột ghi khiến MongoDB thử lại hoạt động đó một cách minh bạch.

Một số hoạt động toàn cầu, thường là các hoạt động sống ngắn liên quan đến nhiều cơ sở dữ liệu, vẫn yêu cầu khóa "toàn bộ trường hợp" toàn cầu. Một số hoạt động khác, chẳng hạn như collMod, vẫn yêu cầu khóa cơ sở dữ liệu độc quyền.

Để báo cáo về thông tin sử dụng khóa trên khóa, hãy sử dụng bất kỳ phương pháp nào trong số này:

Đối với các công cụ lưu trữ hỗ trợ kiểm soát đồng thời cấp tài liệu, chẳng hạn như Wiredtiger, việc mang lại là không cần thiết khi truy cập lưu trữ như các khóa ý định, được giữ ở cấp độ toàn cầu, cơ sở dữ liệu và thu thập, không chặn các độc giả và nhà văn khác. Tuy nhiên, các hoạt động sẽ định kỳ năng suất, chẳng hạn như:

  • Để tránh các giao dịch lưu trữ tồn tại lâu vì những điều này có khả năng yêu cầu chứa một lượng lớn dữ liệu trong bộ nhớ;

  • Để phục vụ như là điểm gián đoạn để bạn có thể giết các hoạt động chạy dài;

  • Để cho phép các hoạt động yêu cầu quyền truy cập độc quyền vào một bộ sưu tập như giảm chỉ mục/thu thập và sáng tạo.

Bảng sau liệt kê một số hoạt động và các loại khóa họ sử dụng cho các công cụ lưu trữ khóa cấp tài liệu:

Hoạt động

Cơ sở dữ liệu

Bộ sưu tập

Phát hành một truy vấn

r (ý định chia sẻ)

r (ý định chia sẻ)

Chèn dữ liệu

w (ý định độc quyền)

w (ý định độc quyền)

Xóa dữ liệu

w (ý định độc quyền)

w (ý định độc quyền)

Xóa dữ liệu

w (ý định độc quyền)

w (ý định độc quyền)

Xóa dữ liệu

r (ý định chia sẻ)

r (ý định chia sẻ)

Chèn dữ liệu

w (ý định độc quyền)

Xóa dữ liệu

w (ý định độc quyền)

w (ý định độc quyền)

Xóa dữ liệu

r (ý định chia sẻ)

Chèn dữ liệu

Map-reduce

w (ý định độc quyền)

Xóa dữ liệu

Cập nhật dữ liệu

Thực hiện tập hợp

  • Tạo một chỉ mục (tiền cảnh)

  • W (độc quyền)

  • Tạo một chỉ mục (nền)

  • Danh sách bộ sưu tập

Đã thay đổi trong phiên bản 4.0.

W (độc quyền) và R (chia sẻ)

w (ý định độc quyền) và r (ý định chia sẻ)

Một số lệnh quản trị có thể khóa cơ sở dữ liệu trong khoảng thời gian dài. Đối với việc triển khai cơ sở dữ liệu lớn, bạn có thể xem xét việc thực hiện trường hợp db.serverStatus()4 ngoại tuyến để khách hàng không bị ảnh hưởng. Ví dụ: nếu db.serverStatus()4 là một phần của bộ bản sao, hãy thực hiện ngoại tuyến db.serverStatus()4 và cho các thành viên khác của các yêu cầu quy trình đặt bản sao trong khi bảo trì được thực hiện.

Các hoạt động quản trị này yêu cầu khóa độc quyền ở cấp cơ sở dữ liệu trong thời gian dài:

Lệnh W3

Lệnh collMod

Lệnh W5

Lệnh collMod

Lệnh W5

Lệnh W6

Ngoài ra, lệnh W7 và phương thức shell W8 tương ứng thực hiện các khóa sau tùy thuộc vào phiên bản MongoDB:

Yêu cầu

MongoDB 4.2.2 trở lên

MongoDB 4.2.0 - 4.2.1

MongoDB 4.0.x và trước đó

  • W7 Lệnh cơ sở dữ liệu

  • Nếu đổi tên một bộ sưu tập trong cùng một cơ sở dữ liệu, lệnh W7 sẽ khóa (W) độc quyền trên các bộ sưu tập nguồn và mục tiêu.

    Nếu không gian tên đích nằm trong cơ sở dữ liệu khác như bộ sưu tập nguồn, lệnh W7 sẽ khóa (W) độc quyền trên cơ sở dữ liệu đích khi đổi tên bộ sưu tập trên cơ sở dữ liệu và chặn các hoạt động khác trên cơ sở dữ liệu đó cho đến khi hoàn thành.

Nếu không gian tên đích nằm trong một cơ sở dữ liệu khác như bộ sưu tập nguồn, lệnh W7 sẽ khóa độc quyền toàn cầu (W) khi đổi tên bộ sưu tập trên cơ sở dữ liệu và chặn các hoạt động khác cho đến khi hoàn thành.

Trước MongoDB 4.2, lệnh W7 sẽ khóa (W) độc quyền trên cơ sở dữ liệu khi đổi tên trong cùng một cơ sở dữ liệu.

  • r5 Phương pháp trợ giúp Shell

  • Nếu đổi tên một bộ sưu tập trong cùng một cơ sở dữ liệu, phương thức r5 sẽ khóa (W) độc quyền trên các bộ sưu tập nguồn và mục tiêu.

  • (hành vi tương tự như MongoDB 4.2.2 trở lên)

  • Trước MongoDB 4.2, phương thức r5 sẽ khóa (W) độc quyền trên cơ sở dữ liệu khi đổi tên trong cùng một cơ sở dữ liệu.

  • Các hoạt động quản trị này khóa cơ sở dữ liệu nhưng chỉ giữ khóa trong một thời gian rất ngắn:

    • Lệnh r8 và phương thức shell r9 tương ứng

    • Lệnh w0 và phương thức shell w1 tương ứng

      • MongoDB 4.2.2 và sau đó, thao tác sẽ khóa (W) độc quyền trên cơ sở dữ liệu đích khi đổi tên bộ sưu tập trên cơ sở dữ liệu và chặn các hoạt động khác trên cơ sở dữ liệu đó cho đến khi hoàn thành.

      • MongoDB 4.2.1 và trước đó, hoạt động sẽ có khóa độc quyền toàn cầu (W) khi đổi tên một bộ sưu tập trên cơ sở dữ liệu và chặn các hoạt động khác cho đến khi hoàn thành.

  • Lệnh collMod8 và phương thức shell collMod9 tương ứng thực hiện các khóa sau, tùy thuộc vào phiên bản:

    • Đối với MongoDB 4.2.2 và sau đó, các hoạt động này có được khóa độc quyền (W) trên bộ sưu tập và chặn các hoạt động khác trên bộ sưu tập cho đến khi hoàn thành.

    • Đối với MongoDB 4.0.0 đến 4.2.1, các hoạt động này có khóa độc quyền toàn cầu (W) và chặn các hoạt động khác cho đến khi hoàn thành.

  • Lệnh db.serverStatus()0 có các khóa sau, tùy thuộc vào phiên bản:

    • Đối với MongoDB 4.2.2 và sau đó, thao tác này sẽ khóa (W) độc quyền trên bộ sưu tập db.serverStatus()1 và chặn các hoạt động khác trên bộ sưu tập cho đến khi hoàn thành.

    • Đối với MongoDB 4.2.1 và sớm hơn, hoạt động này có khóa độc quyền toàn cầu (W) và chặn các hoạt động khác cho đến khi nó kết thúc.

Trước MongoDB 4.2, các hoạt động này đã khóa độc quyền trên cơ sở dữ liệu, chặn tất cả các hoạt động trên cơ sở dữ liệu và các bộ sưu tập của nó cho đến khi hoạt động hoàn tất.

Các hoạt động MongoDB này có thể có được và giữ khóa trên nhiều cơ sở dữ liệu:

Hoạt động

Hành vi

db.serverStatus()2

Hoạt động này có được khóa độc quyền toàn cầu (W) và chặn các hoạt động khác cho đến khi hoàn thành.

collMod8

collMod9

Đã thay đổi trong phiên bản 4.2.

Đối với MongoDB 4.0.0 đến 4.2.1, các hoạt động này có khóa độc quyền toàn cầu (W) và chặn các hoạt động khác cho đến khi hoàn thành.

Lệnh db.serverStatus()0 có các khóa sau, tùy thuộc vào phiên bản:

Đối với MongoDB 4.2.2 và sau đó, thao tác này sẽ khóa (W) độc quyền trên bộ sưu tập db.serverStatus()1 và chặn các hoạt động khác trên bộ sưu tập cho đến khi hoàn thành.

W7

Đã thay đổi trong phiên bản 4.2.

Bắt đầu từ MongoDB 4.2.2, các hoạt động này chỉ có khóa thu thập (W) độc quyền thay vì khóa độc quyền toàn cầu.

Trước MongoDB 4.0, các hoạt động này đã có được khóa cơ sở dữ liệu độc quyền (W).

db.serverStatus()0

Đã thay đổi trong phiên bản 4.2.

Bắt đầu từ MongoDB 4.2.2, các hoạt động này chỉ có khóa thu thập (W) độc quyền thay vì khóa độc quyền toàn cầu.

Trước MongoDB 4.0, các hoạt động này đã có được khóa cơ sở dữ liệu độc quyền (W).

Đối với MongoDB 4.2.1 và sớm hơn, hoạt động này có được khóa độc quyền toàn cầu (W) khi đổi tên bộ sưu tập giữa cơ sở dữ liệu và chặn các hoạt động khác cho đến khi hoàn thành.

Bắt đầu từ MongoDB 4.2.2, thao tác này chỉ có được khóa độc quyền (W) trên cơ sở dữ liệu đích, khóa được chia sẻ (r) có ý định trên cơ sở dữ liệu nguồn và khóa được chia sẻ trên bộ sưu tập nguồn thay vì độc quyền toàn cầu Khóa.locks. The operations on one db.serverStatus()4 instance do not block the operations on any others.

Đối với MongoDB 4.2.1 và sớm hơn, hoạt động này có được khóa độc quyền toàn cầu (W) và chặn các hoạt động khác cho đến khi hoàn thành.

Bắt đầu từ MongoDB 4.2.2, thao tác này chỉ có được khóa độc quyền (W) trên bộ sưu tập db.serverStatus()1 thay vì khóa độc quyền toàn cầu.

Sharding cải thiện sự đồng thời bằng cách phân phối các bộ sưu tập qua nhiều trường hợp db.serverStatus()4, cho phép các máy chủ Shard (cụ thể là các quy trình db.serverStatus()9) để chạy đồng thời với các trường hợp db.serverStatus()4 xuôi dòng.

Trong một cụm mảnh vỡ, các khóa áp dụng cho mỗi mảnh riêng lẻ, không phải cho toàn bộ cụm; tức là mỗi ví dụ db.serverStatus()4 độc lập với các trường hợp khác trong cụm bị che khuất và sử dụng khóa riêng của nó. Các hoạt động trên một trường hợp db.serverStatus()4 không chặn các hoạt động trên bất kỳ hoạt động nào khác.

Với các bộ bản sao, khi MongoDB viết cho một bộ sưu tập trên chính, MongoDB cũng viết vào oplog của chính, một bộ sưu tập đặc biệt trong cơ sở dữ liệu db.currentOp()3. Do đó, MongoDB phải khóa cả cơ sở dữ liệu của bộ sưu tập và cơ sở dữ liệu db.currentOp()3. db.serverStatus()4 phải khóa cả hai cơ sở dữ liệu cùng một lúc để giữ cho cơ sở dữ liệu nhất quán và đảm bảo rằng các hoạt động ghi, ngay cả khi sao chép, tất cả đều là hoạt động.

Tuy nhiên, đối với các tình huống yêu cầu tính nguyên tử của việc đọc và ghi vào nhiều tài liệu (trong một hoặc nhiều bộ sưu tập), MongoDB hỗ trợ các giao dịch đa tài liệu:

  • Trong phiên bản 4.0, MongoDB hỗ trợ các giao dịch đa tài liệu trên các bộ bản sao., MongoDB supports multi-document transactions on replica sets.

  • Trong phiên bản 4.2, MongoDB giới thiệu các giao dịch phân tán, bổ sung hỗ trợ cho các giao dịch đa tài liệu trên các cụm chia nhỏ và kết hợp hỗ trợ hiện có cho các giao dịch đa tài liệu trên các bộ bản sao., MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets.

    Để biết chi tiết về các giao dịch trong MongoDB, hãy xem trang Giao dịch.

Quan trọng

Trong hầu hết các trường hợp, giao dịch đa tài liệu phát sinh chi phí hiệu suất lớn hơn so với ghi tài liệu đơn lẻ và sự sẵn có của các giao dịch đa tài liệu không nên là một sự thay thế cho thiết kế lược đồ hiệu quả. Đối với nhiều kịch bản, mô hình dữ liệu được chuẩn hóa (tài liệu và mảng nhúng) sẽ tiếp tục tối ưu cho các trường hợp dữ liệu và sử dụng của bạn. Đó là, đối với nhiều kịch bản, mô hình hóa dữ liệu của bạn một cách thích hợp sẽ giảm thiểu nhu cầu cho các giao dịch đa tài liệu.

Để biết các cân nhắc sử dụng giao dịch bổ sung (như giới hạn thời gian chạy và giới hạn kích thước oplog), xem thêm các cân nhắc sản xuất.

Tùy thuộc vào mối quan tâm đọc, khách hàng có thể thấy kết quả ghi trước khi viết là bền. Để kiểm soát xem việc đọc dữ liệu có thể được quay lại hay không, khách hàng có thể sử dụng tùy chọn db.currentOp()6.

Mới trong phiên bản 5.0.

Hoạt động đọc không khóa chạy ngay lập tức: nó không bị chặn khi một thao tác khác có khóa ghi độc quyền (x) trên bộ sưu tập.

Bắt đầu từ MongoDB 5.0, các hoạt động đọc sau đây không bị chặn khi một thao tác khác giữ khóa ghi độc quyền (x) trên bộ sưu tập:

  • db.currentOp()7

  • db.currentOp()8

  • db.currentOp()9

  • db.serverStatus()00

  • db.serverStatus()01

  • db.serverStatus()02

  • db.serverStatus()03

Khi viết vào một bộ sưu tập, db.serverStatus()01 và db.serverStatus()00 giữ khóa dành riêng cho ý định (IX). Do đó, nếu khóa X độc quyền đã được giữ trên một bộ sưu tập, các hoạt động ghi db.serverStatus()01 và db.serverStatus()00 bị chặn.

Để biết thông tin, xem:

  • Đọc sự cô lập, nhất quán và suy ngẫm

  • Tính nguyên tử và giao dịch

  • Đọc mối quan tâm