Tham nhũng không thể trộn DBCC CHECKDB: Chế độ xem được lập chỉ mục chứa các hàng không được tạo bởi định nghĩa chế độ xem


14

TL; DR: Tôi đã có một tham nhũng không thể sửa chữa trong một cái nhìn được lập chỉ mục. Đây là những thông tin chi tiết:


Đang chạy

DBCC CHECKDB([DbName]) WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS

trên một trong những cơ sở dữ liệu của tôi tạo ra lỗi sau:

Msg 8907, Cấp 16, Trạng thái 1, Dòng 1 Chỉ mục không gian, chỉ mục XML hoặc chế độ xem được lập chỉ mục 'ViewName' (ID đối tượng 784109934) chứa các hàng không được tạo bởi định nghĩa chế độ xem. Điều này không nhất thiết thể hiện vấn đề toàn vẹn với dữ liệu trong cơ sở dữ liệu này. (...)

CHECKDB đã tìm thấy 0 lỗi phân bổ và 1 lỗi nhất quán trong bảng 'ViewName'.

Repair_Vbuild là mức sửa chữa tối thiểu (...).

Tôi hiểu rằng thông báo này chỉ ra rằng dữ liệu được cụ thể hóa của chế độ xem được lập chỉ mục 'ViewName' không giống với những gì truy vấn cơ bản tạo ra. Tuy nhiên, việc xác minh dữ liệu theo cách thủ công không tạo ra bất kỳ sự khác biệt nào:

SELECT * FROM ViewName WITH (NOEXPAND)
EXCEPT
SELECT ...
from T1 WITH (FORCESCAN)
join T2 on ...

SELECT ...
from T1 WITH (FORCESCAN)
join T2 on ...
EXCEPT
SELECT * FROM ViewName WITH (NOEXPAND)

NOEXPANDđã được sử dụng để buộc sử dụng chỉ số (chỉ) trên ViewName. FORCESCANđã được sử dụng để ngăn chặn việc xem chỉ mục phù hợp xảy ra. Kế hoạch thực hiện xác nhận cả hai biện pháp để làm việc.

Không có hàng nào được trả về ở đây, có nghĩa là hai bảng giống hệt nhau. (Chỉ có các cột số nguyên và hướng dẫn, các bộ sưu tập không đi vào hoạt động).

Các lỗi không thể được cố định bằng cách tái tạo chỉ mục trên quan điểm hoặc bằng cách chạy DBCC CHECKDB REPAIR_ALLOW_DATA_LOSS. Lặp đi lặp lại các bản sửa lỗi cũng không giúp được gì. Tại sao DBCC CHECKDBbáo cáo lỗi này? Làm thế nào để thoát khỏi nó?

(Ngay cả khi xây dựng lại cố định, câu hỏi của tôi vẫn đứng vững - tại sao một lỗi được báo cáo mặc dù các truy vấn kiểm tra dữ liệu của tôi chạy thành công?)


Cập nhật: Lỗi đã được sửa trong một số bản phát hành. Tôi không còn có thể sao chép nó trong SQL Server 2014 SP2 CU 5. 2014 SP2 KB chứa bản sửa lỗi mà không có bài viết KB : Creating non-clustered index causes DBCC CheckDB With Extended_Logical_Checks to raise corruption error. Hai lỗi kết nối về điều này đã bị đóng:


1
Bạn có nói rằng bạn đã bỏ và tạo lại chỉ mục trên chế độ xem và DBCC CHECKDB vẫn báo cáo lỗi tương tự? Điều gì về việc bỏ chế độ xem và tạo nó từ đầu?
Aaron Bertrand

Từ BOL: Khắc phục sự cố lỗi DBCC trên Chế độ xem được lập chỉ mục If the indexed view does not contain an aggregate over values of type float or real and you receive errors 8907 or 8708, drop the index on the view and re-create it. Do not use ALTER INDEX REBUILD to try to remove the differences between the stored and the computed view, because ALTER INDEX REBUILD does not recalculate the view before rebuilding the index. Then run DBCC CHECKTABLE on the View to verify no differences remain.
Kin Shah

@Kin Tôi đã chỉnh sửa bình luận của bạn. Các [1]ký hiệu không hoạt động trong comment dấu xuống.
Aaron Bertrand

Tôi đã tạo lại mọi thứ. Tôi cũng để DBCC CHECKDB REPAIR_ALLOW_DATA_LOSS chạy. Nó nói nó xây dựng lại khung nhìn, nhưng sau đó nó báo lỗi tương tự.
usr

Bạn có thể hiển thị định nghĩa chế độ xem (nếu quá dài ở đây sau đó trong một pastebin)?
Aaron Bertrand

Câu trả lời:


14

Bộ xử lý truy vấn có thể tạo ra một kế hoạch thực hiện không hợp lệ cho truy vấn (chính xác) do DBCC tạo ra để kiểm tra xem chỉ mục xem có tạo ra các hàng giống như truy vấn của chế độ xem bên dưới không.

Kế hoạch được tạo bởi bộ xử lý truy vấn xử lý không chính xác NULLscho ImageObjectIDcột. Nó không chính xác lý do mà truy vấn xem từ chối NULLscho cột này, khi nó không. Nghĩ rằng NULLsbị loại trừ, nó có thể khớp với chỉ mục không được lọc trên Usersbảng mà bộ lọc trên ImageObjectID IS NOT NULL.

Bằng cách tạo ra một gói sử dụng chỉ mục được lọc này, nó đảm bảo rằng các hàng có NULLin ImageObjectIDkhông gặp phải. Các hàng này được trả về (chính xác) từ chỉ mục xem, vì vậy nó xuất hiện có tham nhũng khi không có.

Định nghĩa xem là:

SELECT
    dbo.Universities.ID AS Universities_ID, 
    dbo.Users.ImageObjectID AS Users_ImageObjectID
FROM dbo.Universities
JOIN dbo.Users
    ON dbo.Universities.AdminUserID = dbo.Users.ID

Các ONso sánh bình đẳng khoản giữa AdminUserIDIDRejects NULLstrong các cột, nhưng không phải từ ImageObjectIDcột.

Một phần của truy vấn được tạo DBCC là:

SELECT [Universities_ID], [Users_ImageObjectID], 0 as 'SOURCE'
FROM [dbo].[mv_Universities_Users_ID] tOuter WITH (NOEXPAND) 
WHERE NOT EXISTS
( 
    SELECT 1 
    FROM   [dbo].[mv_Universities_Users_ID] tInner
    WHERE 
    (
        (
            (
                [tInner].[Universities_ID] = [tOuter].[Universities_ID]
            ) 
            OR 
            (
                [tInner].[Universities_ID] IS NULL
                AND [tOuter].[Universities_ID] IS NULL
            )
        )
        AND
        (
            (
                [tInner].[Users_ImageObjectID] = [tOuter].[Users_ImageObjectID]
            ) 
            OR 
            (
                [tInner].[Users_ImageObjectID] IS NULL 
                AND [tOuter].[Users_ImageObjectID] IS NULL
            )
        )
    )
)
OPTION (EXPAND VIEWS);

Đây là mã chung để so sánh các giá trị theo NULLkiểu nhận biết. Nó chắc chắn dài dòng, nhưng logic là tốt.

Lỗi trong lý luận của bộ xử lý truy vấn có nghĩa là một kế hoạch truy vấn sử dụng không đúng chỉ mục được lọc có thể được tạo ra, như trong đoạn kế hoạch ví dụ dưới đây:

Kế hoạch sai lầm

Truy vấn DBCC có một đường dẫn mã khác thông qua bộ xử lý truy vấn từ các truy vấn của người dùng. Đường dẫn mã này chứa lỗi. Khi một kế hoạch sử dụng chỉ mục được lọc được tạo, nó không thể được sử dụng với USE PLANgợi ý để buộc hình dạng kế hoạch đó có cùng văn bản truy vấn được gửi từ kết nối cơ sở dữ liệu người dùng.

Đường dẫn mã trình tối ưu hóa chính (đối với các truy vấn của người dùng) không chứa lỗi này, do đó, nó đặc trưng cho các truy vấn nội bộ giống như các truy vấn được tạo bởi DBCC.


Tôi có thể thấy kế hoạch bị lỗi trong sự kiện SQL Profiler Showplan XML. Tôi sẽ đánh dấu đây là câu trả lời.; Tại sao DBCC xây dựng truy vấn theo cách khác với bộ xử lý truy vấn thông thường?; Tôi sẽ thêm một liên kết đến câu trả lời này vào mục kết nối.
usr

2
@usr DBCC thực hiện tất cả các loại điều không thể có được từ kết nối người dùng. Tôi tưởng tượng nó hoạt động theo cách này bởi vì nó phải, nhưng bạn phải yêu cầu một người như Paul Randal có được chi tiết thực sự về điều đó. Anh ấy có thể không được tự do để nói, tất nhiên. Tôi biết rằng có rất nhiều thứ bên ngoài DBCC thậm chí còn làm những điều kỳ lạ hơn; một số thậm chí xây dựng một kế hoạch thực hiện mà không cần thông qua trình tối ưu hóa!
Paul White phục hồi Monica

6

Điều tra sâu hơn cho thấy đây là một lỗi trong DBCC CHECKDB. Một lỗi Microsoft Connect đã được mở: Lỗi DBCC CHECKDB không thể sửa được (đó cũng là một lỗi dương tính và khác lạ) . May mắn thay, tôi đã có thể tạo ra một repro để lỗi có thể được tìm thấy và sửa chữa.

Lỗi có thể được ẩn bằng cách chơi với lược đồ cơ sở dữ liệu. Xóa một chỉ mục được lọc không liên quan hoặc xóa bộ lọc, sẽ che giấu lỗi. Để biết chi tiết xin vui lòng xem các mục kết nối.

Mục kết nối cũng chứa truy vấn nội bộ mà DBCC CHECKDB sử dụng để xác thực nội dung xem. Nó trả về không có kết quả, cho thấy đây là một lỗi.

Các lỗi đã được sửa trong một số bản phát hành. Tôi không còn có thể sao chép nó trong SQL Server 2014 SP2 CU 5.


Rất nhiều dữ liệu (sản xuất) là cần thiết để tái tạo lỗi (đó là bằng chứng nữa cho thấy sự thay đổi kế hoạch có thể là nguyên nhân). Tôi không thoải mái khi phát hành dữ liệu mặc dù tôi có thể xóa tất cả trừ hai cột từ mỗi bảng. Vấn đề bạn liên kết để yêu cầu gây ra tham nhũng trong chế độ xem. Tôi đã tạo lại khung nhìn để không tham nhũng do DML có thể là nguyên nhân.; Bạn có biết bất cứ điều gì có thể gây ra một kế hoạch khác nếu truy vấn đang được chạy trong DBCC CHECKDB thay vì trong một cửa sổ truy vấn thông thường không?
usr

Một cơ sở dữ liệu ẩn danh vừa được tải lên. Dưới đây là tập lệnh xây dựng lại tất cả các chỉ mục và tạo lại chế độ xem: pastebin.com/jPEALeEw (hữu ích để đặt lại mọi thứ và đảm bảo cấu trúc vật lý ổn). Các tập lệnh hữu ích khác: pastebin.com/KxNSwm2J Các tập lệnh nên chạy và vấn đề sẽ được xử lý lại ngay lập tức.
usr

Gương của bak: mega.co.nz/...
usr

Ngày 11.0.3349 với -T272,4199,3604. 4199 cho phép sửa bộ xử lý truy vấn. Tôi vừa xóa TF đó; Có lẽ chúng ta cần phải tạo ra kế hoạch truy vấn đúng. Bây giờ tôi đã đặt RAM 1GB và khởi động lại phiên bản (là 8GB). Điều đó đã thay đổi một trong hai liên kết hợp nhất mà tôi đang thấy với NLJ. Vẫn còn repros.; Để thử một số biến thể của gói, tôi đã thêm và xóa các hàng: pastebin.com/y972Sx4d Lỗi dường như kích hoạt iff Tôi nhận được một phép nối hợp nhất hoặc hàm băm trong phần "bên trái chống bán tham gia" của truy vấn. Hãy thử điều này: thêm 100k hàng cho Người dùng. Điều này đáng tin cậy cho một tham gia băm (song song) cho tôi.
usr

Tôi vừa tải lên "plan.zip" vào mục kết nối có chứa các gói thực thi khác nhau cho truy vấn DBCC CHECKDB. Với số lượng hàng khác nhau trong các trường đại học, tôi có thể tạo ra ít nhất ba kế hoạch khác nhau. Chỉ với vòng lặp tham gia kế hoạch, vấn đề không xảy ra. Với sự hợp nhất và băm tham gia, lỗi là có thể tái tạo.
usr
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.