Sql-server – Physical only checkdb is failing, but full one is completed successfully

dbcc-checkdbsql serversql-server-2017

I am executing checkdb with physical_only option and it fails with multiple errors like below:

Msg 8965, Level 16, State 1, Line 1
Table error: Object ID 1557580587,
index ID 1, partition ID 72057594088456192, alloc unit ID
72057594177454080 (type In-row data). The off-row data node at page
(1:13282192), slot 3, text ID 6370769698816 is referenced by page
(0:0), slot 0, but was not seen in the scan.
Msg 8965, Level 16, State
1, Line 1

Table error: Object ID 1557580587, index ID 1, partition ID
72057594088456192, alloc unit ID 72057594177454080 (type In-row data).
The off-row data node at page (1:13282192), slot 5, text ID
6370769764352 is referenced by page (0:0), slot 0, but was not seen in
the scan.
CHECKDB found 0 allocation errors and 5255 consistency
errors in table 'TableX'
(object ID
1557580587).
CHECKDB found 0 allocation errors and 5255 consistency
errors in database 'DatabaseX'
. repair_allow_data_loss is the minimum
repair level for the errors found by DBCC CHECKDB (DWH_LAND).

However full checkdb is successfull:

CHECKDB found 0 allocation errors and 0 consistency errors in database
'DatabaseX'.
DBCC execution completed. If DBCC printed error messages,
contact your system administrator.

TableX has around 200 000 rows and has clustered columnstore index on it.

We are using following version of SQL Server:

Microsoft SQL Server 2017 (RTM-CU13) (KB4466404) – 14.0.3048.4

Should I be worried?

Best Answer

Yes, this a defect in SQL Server 2017 up to CU14. There was a similar issue with nonclustered columnstore indexes in SQL Server 2016.

It's detailed in this video: CHECKDB Bug With SQL Server 2017 And ColumnStore Indexes

A more portable repro of the issue is this:

SELECT *, CONVERT(NVARCHAR(MAX), m.text + m.text + m.text + m.text + m.text) AS texty
INTO dbo.corrupt
FROM sys.messages AS m;

CREATE CLUSTERED COLUMNSTORE INDEX cx_corrupt ON dbo.corrupt;

DBCC CHECKDB WITH PHYSICAL_ONLY;

DROP TABLE dbo.corrupt;