Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Nếu bạn đang sử dụng các chế độ xem được lập chỉ mục và MERGE, vui lòng đọc phần này!

Fellow MVP Jamie Thomson gần đây đã chỉ ra rằng có một lỗi "kết quả sai" trong SQL Server có thể tự hiển thị khi các điều kiện sau là đúng:

  • Bạn có một chế độ xem được lập chỉ mục kết hợp ít nhất hai bảng;
  • các bảng đó bị ràng buộc theo một trong hai hướng bởi khóa ngoại một cột;
  • bạn thực hiện cập nhật cho (các) bảng cơ sở bằng MERGE bao gồm cả UPDATE và ( DELETE hoặc INSERT ) các hành động; và,
  • sau đó bạn đưa ra các truy vấn tham chiếu chỉ mục trên chế độ xem (có chủ ý hoặc không).

Rất tiếc, bài viết trong Cơ sở Kiến thức mô tả sự cố (KB # 2756471) khá thiếu chi tiết. Họ không cho bạn biết làm thế nào để tái tạo vấn đề, hoặc thậm chí cụ thể là những gì, bạn nên tìm kiếm để xem liệu điều này có ảnh hưởng đến bạn hay không; và họ thậm chí không đề cập đến MERGE (thực sự là cốt lõi của vấn đề, không phải NOEXPAND và không phải là một bản cập nhật đơn giản). Có một số chi tiết bổ sung trong mục Kết nối mang lại bản sửa lỗi; hy vọng bài viết trên KB sẽ được cập nhật với nhiều chi tiết hơn trong thời gian dài.

Trong thời gian chờ đợi, kết quả bạn có thể thấy là dữ liệu không chính xác - hay nói cách tốt hơn là dữ liệu cũ :Truy vấn có thể hiển thị cho bạn phiên bản cũ của (các) hàng được cập nhật! Tôi đã dành một vài phút để cố gắng tái tạo lại kịch bản này trong AdventureWorks, và đã thất bại thảm hại. Rất may, Paul White (blog | @SQL_Kiwi) đã viết một bài đăng xuất sắc mô tả tình huống và hiển thị bản tóm tắt đầy đủ của vấn đề.

Tôi không nghĩ mình có thể nhấn mạnh mức độ nghiêm trọng của việc này.

Chắc chắn hàng triệu khách hàng đang sử dụng chế độ xem được lập chỉ mục, nhiều người trong số họ đã di chuyển mã DML của họ để sử dụng MERGE và một số lượng lớn trong số đó có trên Phiên bản Doanh nghiệp (hoặc không nhưng đang sử dụng NOEXPAND gợi ý hoặc đang tham chiếu chỉ mục trực tiếp). Paul đã nhanh chóng chỉ ra rằng NOEXPAND không bắt buộc phải tái tạo sự cố trong Phiên bản Doanh nghiệp và cũng phát hiện ra nhiều chi tiết khác cần thiết để tái tạo lỗi.

Bài đăng này không nhằm mục đích ăn cắp bất kỳ lời sấm nào từ các bài đăng của Jamie hoặc Paul; chỉ là một nỗ lực để nhắc lại mối quan tâm và nâng cao nhận thức về vấn đề này. Nếu bạn có thói quen bỏ qua Cập nhật tích lũy, chọn chờ các Gói dịch vụ và có bất kỳ khả năng nào vấn đề này có thể ảnh hưởng đến bạn ngay bây giờ, bạn phải gánh chịu điều đó cho chính mình, chưa kể các bên liên quan và khách hàng của bạn. vấn đề này nghiêm túc.

Vậy bạn nên làm gì?

Chà, những gì bạn làm tiếp theo phụ thuộc vào phiên bản và phiên bản SQL Server bạn đang chạy và lỗi có thực sự ảnh hưởng đến bạn (hoặc có thể) hay không.

    SQL Server 2008 SP3
    SQL Server 2008 R2 SP1 / SP2
    SQL Server 2012 RTM / SP1

    Các tùy chọn của bạn nếu bạn đang sử dụng một trong các bản dựng này:

    1. Bạn nên cập nhật Bản cập nhật tích lũy mới nhất cho chi nhánh của mình:
      Branch Đã sửa trong CU Xây dựng Yêu cầu bản dựng tối thiểu
      để áp dụng bản cập nhật

      Bài viết KB
      (Tải xuống)
      2008 Gói dịch vụ 3 CU # 8 10.00.5828 10.00.5500 KB # 2771833
      2008 R2 Gói dịch vụ 1 CU # 10 10.50.2868 10.50.2500 KB # 2783135
      2008 R2 Gói dịch vụ 2 CU # 4 10.50.4270 10.00.4000 KB # 2777358
      RTM 2012 CU # 5 11.00.2395 11.00.2100 KB # 2777772
      2012 Gói dịch vụ 1 CU # 2 11.00.3339 11.00.3000 KB # 2790947

      Bảng 1:Các bản dựng có chứa bản sửa lỗi

    2. Nếu bạn không áp dụng bản sửa lỗi, thì bạn cần phải kiểm tra tất cả các tham chiếu đến dạng xem của mình để xác thực rằng chúng trả lại kết quả chính xác trong mọi trường hợp - kể cả sau khi bạn đã cập nhật bảng cơ sở bằng cách sử dụng MERGE . Nếu chúng không bị ảnh hưởng (hoặc bạn nghi ngờ rằng chúng có thể bị ảnh hưởng sau này), thì bạn nên xây dựng lại chỉ mục nhóm trên tất cả các chế độ xem bị ảnh hưởng (hoặc sửa (các) chế độ xem đã lập chỉ mục bằng cách sử dụng DBCC CHECKTABLE , như Paul đã mô tả trong bài đăng của mình) và ngừng sử dụng MERGE chống lại các bảng này cho đến khi bạn áp dụng bản sửa lỗi. Nếu bạn tiếp tục sử dụng MERGE dựa vào các bảng cơ sở, hãy chuẩn bị tiếp tục sửa chữa các khung nhìn để tránh sự cố.
    3. Cách khắc phục nhanh hơn là ngăn chế độ xem đã lập chỉ mục bị hỏng hoàn toàn không được sử dụng, bằng cách sử dụng bất kỳ phương pháp nào sau đây được yêu cầu:
      • áp dụng gợi ý truy vấn TÙY CHỌN (MỞ RỘNG XEM) cho tất cả các truy vấn có liên quan;
      • xóa mọi tham chiếu rõ ràng đến chỉ mục trên chế độ xem;
      • trong các phiên bản Chuẩn hoặc các phiên bản khác mà các chế độ xem được lập chỉ mục không được khớp tự động, hãy xóa tất cả các phiên bản của NOEXPAND .

      Nhưng điều này, tất nhiên, phần lớn sẽ đánh bại mục đích của chế độ xem được lập chỉ mục - cũng có thể chỉ làm giảm chỉ mục. Điều đó nói lên rằng, thông thường sẽ tốt hơn nếu bạn nhận được kết quả đúng từ từ, hơn là nhận được kết quả sai một cách nhanh chóng; vì vậy có lẽ điều đó không sao.

    SQL Server 2008 RTM / SP1 / SP2
    SQL Server 2008 R2 RTM

    Thật không may, bạn đang sử dụng một bản dựng không còn được hỗ trợ chính thống và không có khả năng sự cố này sẽ được khắc phục cho bạn (trừ khi bạn đang sử dụng hỗ trợ mở rộng và bạn gây ra nhiều tiếng ồn). Vì vậy, các tùy chọn của bạn bị giới hạn ở đây - di chuyển đến một nhánh được hỗ trợ theo bảng ở trên và áp dụng Cập nhật tích lũy hoặc chọn một trong các tùy chọn khác đã đề cập trước đây.

    SQL Server 2000
    SQL Server 2005

    Chà, tin xấu là bạn cũng đang sử dụng một bản dựng không còn được hỗ trợ nữa. Tin tốt là trong trường hợp cụ thể này, điều đó không thành vấn đề - bạn không thể sử dụng MERGE Dù sao, lỗi này không thể ảnh hưởng đến bạn.

Các vấn đề MERGE khác

Đáng buồn thay, đây không phải là lỗi đầu tiên mà chúng tôi đã thấy với MERGE , và nó có thể sẽ không phải là lần cuối cùng. Đây là lựa chọn nhanh về một tá MERGE lỗi vẫn được đánh dấu là hoạt động trên Connect:

  • # 773895:MERGE Báo cáo Không chính xác các Vi phạm Chính Duy nhất
  • # 766165:MERGE đánh giá chỉ mục được lọc trên mỗi hàng, không phải hoạt động đăng, điều này gây ra vi phạm chỉ mục đã lọc
  • # 723696:Nâng cấp MERGE cơ bản gây ra bế tắc
  • # 713699:Kiểm tra xác nhận hệ thống không thành công ("cxrowset.cpp":1528)
  • # 699055:Các kế hoạch truy vấn MERGE cho phép vi phạm ràng buộc FK và CHECK
  • # 685800:XÓA Tham số và MERGE Cho phép Vi phạm Ràng buộc Khoá ngoại
  • # 654746:hợp nhất trong SQL2008 SP2 vẫn gặp phải lỗi "Đang cố đặt giá trị của cột không thể NULL thành NULL"
  • # 635778:Các phần NOT MATCHED và MATCHED của câu lệnh SQL MERGE không được tối ưu hóa
  • # 633132:MERGE INTO VỚI NGUỒN ĐÃ LỌC không hoạt động đúng cách
  • # 596086:Lỗi câu lệnh MERGE khi INSERT / DELETE được sử dụng và lọc chỉ mục
  • # 583719:Câu lệnh MERGE xử lý không chính xác các cột được tính toán không thể null trong một số trường hợp
  • # 539084:MERGE Stmt:Điều kiện tìm kiếm trên cột không phải khóa và ORDER BY trong bảng mã nguồn ngắt hoàn toàn MERGE

Bây giờ, có thể có trường hợp một số lỗi này đã thực sự được sửa, nhưng trạng thái của chúng là sai vì vòng lặp quay lại Connect chưa bị đóng. Ngay cả khi đúng như vậy, nó không thể đúng cho tất cả chúng (và có thể cho những người khác mà tôi chưa phát hiện ra).

Ngoài ra, Dan Guzman đã chứng minh rằng MERGE không miễn nhiễm với các điều kiện chủng tộc và các vấn đề đồng thời khác. Giải pháp là sử dụng HOLDLOCK (hoặc mức độ cách ly cao hơn); tuy nhiên, có một quan niệm sai lầm phổ biến rằng MERGE là nguyên tử hoàn toàn và không dễ bị vấn đề này. Vì vậy, tôi sẽ tự hỏi lớn:có bao nhiêu MERGE các câu lệnh ngoài đó bao gồm HOLDLOCK (hoặc đang được thực thi dưới SERIALIZABLE )? Có bao nhiêu người đã được kiểm tra kỹ lưỡng về các vấn đề liên quan đến đồng thời?

Kết luận

Cá nhân tôi nghĩ rằng cú pháp là tuyệt vời (mặc dù khó học), nhưng mỗi khi một vấn đề xuất hiện, nó làm xói mòn niềm tin của tôi vào tính thực tiễn của việc thay thế DML hiện có bằng cấu trúc mới.

Với suy nghĩ đó, không phải là Chicken Little, nhưng tôi sẽ không cảm thấy thoải mái khi đề xuất bất kỳ ai sử dụng MERGE trừ khi họ thực hiện thử nghiệm cực kỳ toàn diện. Một số vấn đề này cũng xuất hiện với UPSERT tiêu chuẩn phương pháp luận, nhưng các vấn đề rõ ràng hơn ở đó. MERGE , chỉ thông qua bản chất tuyên bố duy nhất của nó, khiến bạn muốn tin vào ma thuật. Có thể một ngày nào đó nó sẽ chuyển giao, nhưng ngay bây giờ tôi biết rằng sẽ không thể cưa đôi một người nếu không có sự giúp đỡ nghiêm túc.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Giới thiệu về IRI Voracity (Quản lý dữ liệu tổng thể) [video]

  2. Cách sử dụng REPLACE trong SQL

  3. Xác định các vấn đề đặt hàng trong sự kiện mở rộng

  4. SQL Right Join

  5. Hội nghị thượng đỉnh MVP năm 2013:Đánh giá nhanh và xem trước