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
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
@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)