3

I have a T-SQL code that delta-copies data from the source table (SrcTable) to the destination table (DestTable). The data is inserted into the source table by multiple sessions and copied to the destination table by a SQL Server Agent job. Here's the snippet which inserts the batch into the destination table:


...

WITH cte
AS (SELECT st.SrcTable_ID,
           st.SrcTable_CreatedDateTime
    FROM SrcTable st WITH (READCOMMITTEDLOCK, INDEX(PK_SrcTable))
    WHERE st.SrcTable_ID
    BETWEEN @FromID AND @ToID)
INSERT DestTable
(
    DestTable_SrcTableID
)
SELECT cte.SrcTable_ID
FROM cte;

...

both tables are partitioned on CreatedDateTime column which default to SYSUTCDATETIME


CREATE TABLE [dbo].[SrcTable](
    [SrcTable_ID] [BIGINT] IDENTITY(1,1) NOT NULL,
    [SrcTable_CreatedDateTime] [DATETIME2](3) NOT NULL,
 CONSTRAINT [PK_SrcTable] PRIMARY KEY CLUSTERED 
(
    [SrcTable_ID] ASC,
    [SrcTable_CreatedDateTime] ASC
) ON [ps_Daily]([SrcTable_CreatedDateTime])
) ON [ps_Daily]([SrcTable_CreatedDateTime])
GO

CREATE TABLE [dbo].[DestTable](
    [DestTable_ID] [BIGINT] IDENTITY(1,1) NOT NULL,
    [DestTable_CreatedDateTime] [DATETIME2](3) NOT NULL,
    [DestTable_SrcTableID] [BIGINT] NOT NULL,
 CONSTRAINT [PK_DestTable] PRIMARY KEY CLUSTERED 
(
    [DestTable_ID] ASC,
    [DestTable_CreatedDateTime] ASC
) ON [ps_Daily]([DestTable_CreatedDateTime])
) ON [ps_Daily]([DestTable_CreatedDateTime])
GO

This code has been running for years copying millions of records a day with no issues. Recently it started missing a single row every couple of weeks.

Here's an example of such a batch with @FromID=2140 and @ToID=2566 and one missing row (2140)

SELECT * FROM dbo.SrcTable st
LEFT JOIN dbo.DestTable dt ON st.SrcTable_ID=dt.DestTable_SrcTableID
WHERE st.SrcTable_ID BETWEEN 2140 AND 2566
ORDER BY st.SrcTable_ID ASC 

the result set of the LEFT JOIN

The only plausible explanation that I can think of is that the allocation of identity values (SrcTable_ID) happens outside of the transaction which inserts into the source table (which I learned from an excellent answer by Paul White on the related question, but judging by the time stamps in both tables this scenario seems highly unlikely.

The question is:

How likely is it that the missing row was invisible to the SELECT statement because its' identity was allocated outside of the inserting transaction and before the lock was acquired, given the fact that the next row in the batch (2141) was inserted into the source table a couple of seconds later but was successfully picked up?

We're running on Microsoft SQL Server 2019 (RTM-CU16) (KB5011644) - 15.0.4223.1 (X64)

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.