LATCH_EX chờ đợi trên tài nguyên METADATA_SEQUENCE_GENERATOR


11

Chúng tôi có một quy trình tạo ra một báo cáo hàng tồn kho. Về phía khách hàng, quá trình phân chia một số luồng công nhân có thể định cấu hình để xây dựng một khối dữ liệu cho báo cáo tương ứng với một cửa hàng trong số nhiều (có thể hàng ngàn, thường là hàng chục). Mỗi luồng công nhân gọi một dịch vụ web thực hiện một thủ tục được lưu trữ.

Quá trình cơ sở dữ liệu để xử lý mỗi khối tập hợp một loạt dữ liệu vào một bảng #T tạm thời. Vào cuối mỗi đoạn xử lý, dữ liệu được ghi vào một bảng cố định trong tempdb. Cuối cùng, khi kết thúc quá trình, một luồng ở phía máy khách yêu cầu tất cả dữ liệu từ bảng tempdb vĩnh viễn.

Càng nhiều người dùng chạy báo cáo này, nó càng chậm. Tôi đã phân tích các hoạt động trong cơ sở dữ liệu. Tại một thời điểm, tôi thấy 35 yêu cầu riêng biệt đều bị chặn tại một điểm trong quy trình. Tất cả các SPID này có thứ tự 50 ms chờ loại LATCH_EXtrên tài nguyên METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8). Một SPID có tài nguyên này và tất cả những cái khác đang chặn. Tôi không tìm thấy bất cứ điều gì về tài nguyên chờ này trên một tìm kiếm trên web.

Bảng trong tempdb mà chúng tôi đang sử dụng có một IDENTITY(1,1)cột. Có phải các SPID này đang chờ cột IDENTITY không? Những phương pháp nào chúng ta có thể sử dụng để giảm hoặc loại bỏ việc chặn?

Máy chủ là một phần của cụm. Máy chủ đang chạy 64-bit SQL Server 2012 Standard Edition SP1 trên Windows 2008 R2 Enterprise 64-bit. Máy chủ có 64 GB RAM và 48 bộ xử lý, nhưng cơ sở dữ liệu chỉ có thể sử dụng 16 vì đây là phiên bản tiêu chuẩn.

(Lưu ý rằng tôi không vui mừng khi thiết kế sử dụng bảng cố định trong tempdb để chứa tất cả dữ liệu này. Thay đổi đó sẽ là một thách thức kỹ thuật và chính trị thú vị, nhưng tôi sẵn sàng đề xuất.)

CẬP NHẬT 23/11/2013

Chúng tôi đã mở một trường hợp hỗ trợ với Microsoft. Tôi sẽ cập nhật câu hỏi này khi chúng tôi tìm hiểu thêm.

CẬP NHẬT 5/10/2013

Kỹ sư hỗ trợ SQL Server đồng ý rằng sự chờ đợi là do cột IDENTITY gây ra. Loại bỏ IDENTITY loại bỏ sự chờ đợi. Chúng tôi không thể sao chép vấn đề trên SQL 2008 R2; nó chỉ xảy ra trên SQL 2012.


Có phải quá trình cơ bản sao chép dữ liệu từ các bảng #T tạm thời sang bảng cố định hoặc có logic chuyển đổi bổ sung xảy ra trong bước đó không?
Jon Seigel

Ở bước chờ đợi, nó đang sao chép các bản ghi hàng tồn kho của một cửa hàng vào bảng cố định mà không cần chuyển đổi. Chúng ta có thể hoạt động bên trong bảng vĩnh viễn toàn bộ thời gian, nhưng tôi nghĩ rằng lập trình viên đã chọn sử dụng bảng #T tạm thời làm khu vực giữ để ngăn cập nhật thường xuyên dữ liệu chuyển thành khóa PAGE.
Paul Williams

Câu trả lời:


4

Giả sử bạn có thể tách biệt vấn đề với việc tạo các giá trị nhận dạng (thử xóa cột đó dưới dạng thử nghiệm), điều tôi muốn giới thiệu là:

  1. Loại bỏ IDENTITYtài sản khỏi cột trong bảng cuối cùng.
  2. Tạo các giá trị nhận dạng trong mỗi bảng #T tạm thời.
  3. Khi tải bảng cuối cùng, kết hợp một mã định danh số cho cửa hàng cụ thể với các giá trị nhận dạng từ bước 2.

Vì vậy, nếu bạn có id lưu trữ 3 và 4, bạn sẽ kết thúc với các giá trị id cuối cùng như thế này:

3000000001
3000000002
3000000003
...
4000000001
4000000002
...

Hoặc một cái gì đó tương tự như vậy. Bạn có được ý tưởng.

Điều này sẽ loại bỏ sự cần thiết phải tuần tự hóa trên IDENTITYthế hệ trong khi vẫn giữ được tính duy nhất trong kết quả cuối cùng.

Ngoài ra, tùy thuộc vào cách thức hoạt động của quy trình, hãy chèn các giá trị id được tính cuối cùng vào các bảng #T tạm thời. Sau đó, bạn có thể tạo một chế độ xem UNION ALLchúng cùng nhau, loại bỏ nhu cầu sao chép dữ liệu.


Cảm ơn bạn đã phản hồi. Tôi đồng ý nếu đó là vấn đề, sử dụng một số khóa được sản xuất (hoặc không có khóa nào) có thể khắc phục nó. Chúng tôi đã mở một trường hợp với Microsoft liên quan đến vấn đề này. Tôi sẽ đăng kết quả ở đây và chấp nhận câu trả lời của bạn nếu họ đồng ý rằng đó là vấn đề.
Paul Williams

@Paul: Xin vui lòng cho tôi biết; Tôi chỉ tò mò thôi. Giống như bạn, tôi không thể tìm thấy bất cứ điều gì trên web về chốt này, nhưng chắc chắn hợp lý rằng đó là tuần tự hóa danh tính / trình tự. Cho dù đó có phải là nút cổ chai khó nói hay không, mặc dù với hơn 30 chủ đề cạnh tranh giá trị, có vẻ như có khả năng. Bạn cũng có thể thử sao chép từ mỗi bảng #T tạm thời (thay vì song song) để xem điều đó có giúp ích không.
Jon Seigel

2
Kỹ sư SQL Server đồng ý rằng nó có thể là IDENTITYcột. Chúng tôi đã lấy nó ra khỏi chỉ mục được nhóm rộng và loại bỏ hoàn toàn cột. Nó không cần thiết. Sau đó, những chờ đợi LATCH_EX này đã biến mất. Chúng tôi không thể nhân đôi sự chờ đợi trên SQL 2008 R2. Sự cố chỉ xảy ra trên SQL Server 2012.
Paul Williams

@Paul: Cảm ơn đã theo dõi. Rất thú vị. Tôi đoán rằng mã tạo ra IDENTITYcác giá trị đã được viết lại để sử dụng công cụ tạo chuỗi mới mới vào năm 2012. Vào <2012, bạn có thể thấy một loại chốt khác, mặc dù nếu không có vấn đề hoàn hảo, thì có vẻ như đã có một hồi quy trong mã. Trong mọi trường hợp, loại bỏ IDENTITYcột là điều an toàn nhất.
Jon Seigel

Thay vì danh tính, bạn có thể thử sử dụng 'SEQUENCE' (tính năng mới trong SQL 2012)
Bogdan Maxim

7

(Cập nhật tháng 2 năm 2019)

Đây là một bài viết cũ, nói rằng cuối cùng tôi đã thuyết phục được Microsoft rằng thực tế điều này xảy ra thực sự là một khiếm khuyết.

Cập nhật: MS đã xác nhận lỗi và gán cho nó lỗi # 12628722.

Tôi đã thấy bài đăng này vào tháng 11 năm 2018 vừa qua khi chúng tôi bắt đầu chịu đựng nhiều điều tương tự sau khi chúng tôi nâng cấp từ Sql Server 2005 lên Sql Server 2017. Một bảng 3,3 triệu được sử dụng để mất 10 giây để chèn hàng loạt đột nhiên bắt đầu mất 10 giây phút trên bàn với Identitycột.

Hóa ra có hai vấn đề đằng sau điều này:

  1. Microsoft đã thay đổi hành vi trong Sql Server 2014 để buộc các phần chèn hàng loạt chạy song song - trong các phiên bản trước, phần chèn hàng loạt đã được cung cấp một gói nối tiếp.
  2. Sau khi chạy song song trên hộp 32 lõi của chúng tôi, động cơ đã dành nhiều thời gian hơn với các lõi khóa với nhau hơn là thực sự làm việc.

Mất tôi 4 tuần nhưng chỉ sau kỳ nghỉ tôi nhận được một món quà muộn từ ông già Noel - xác nhận rằng vấn đề thực sự là một khiếm khuyết.

Có một vài cách giải quyết có thể có mà chúng tôi đã tìm thấy cho đến khi điều này được khắc phục:

  1. Sử dụng Option (MaxDop 1)trong truy vấn để biến khối chèn trở lại thành một kế hoạch nối tiếp.
  2. Che dấu cột Danh tính bằng cách đúc nó (ví dụ Select Cast(MyIdentityColumn As Integer) As MyIdentityColumn)
    • điều này ngăn tài sản nhận dạng khỏi bị sao chép khi sử dụng SELECT...INTO
  3. Xóa cột danh tính như mô tả ở trên.
  4. Thay đổi chế độ tương thích cơ sở dữ liệu thành Sql Server 2012 hoặc thấp hơn để thiết lập lại gói được tuần tự hóa.

Cập nhật: Bản sửa lỗi MS sẽ triển khai sẽ đưa các loại Chèn này trở lại sử dụng gói Serialized . Điều này được lên kế hoạch cho Sql Server 2017 CU14 (không có tin tức nào về các phiên bản khác của Sql Server - xin lỗi!). Khi được triển khai, Cờ Trace 9492 sẽ cần được bật, ở cấp độ máy chủ hoặc thông qua DBCC TraceOn .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.