Kami telah menemukan kesalahan aneh ini tiga kali selama beberapa hari terakhir, setelah bebas dari kesalahan selama 8 minggu, dan saya bingung.
Ini adalah pesan kesalahan:
Executing the query "EXEC dbo.MergeTransactions" failed with the following error: "Cannot insert duplicate key row in object 'sales.Transactions' with unique index 'NCI_Transactions_ClientID_TransactionDate'. The duplicate key value is (1001, 2018-12-14 19:16:29.00, 304050920).".
Indeks yang kami miliki tidak unik. Jika Anda perhatikan, nilai kunci duplikat dalam pesan kesalahan bahkan tidak sejalan dengan indeks. Hal yang aneh adalah jika saya menjalankan kembali proc, itu berhasil.
Ini adalah tautan terbaru yang bisa saya temukan yang memiliki masalah, tetapi saya tidak melihat solusinya.
Beberapa hal tentang skenario saya:
- Proc sedang memperbarui TransactionID (bagian dari kunci utama) - Saya pikir ini yang menyebabkan kesalahan tetapi tidak tahu mengapa? Kami akan menghapus logika itu.
- Ubah pelacakan diaktifkan di atas meja
- Melakukan transaksi tanpa komitmen
Ada 45 bidang untuk setiap tabel, saya terutama mencantumkan yang digunakan dalam indeks. Saya memperbarui TransactionID (kunci berkerumun) dalam pernyataan pembaruan (tidak perlu). Aneh bahwa kami belum memiliki masalah selama berbulan-bulan sampai minggu lalu. Dan itu hanya terjadi secara sporadis melalui SSIS.
Meja
USE [DB]
GO
/****** Object: Table [sales].[Transactions] Script Date: 5/29/2019 1:37:49 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[sales].[Transactions]') AND type in (N'U'))
BEGIN
CREATE TABLE [sales].[Transactions]
(
[TransactionID] [bigint] NOT NULL,
[ClientID] [int] NOT NULL,
[TransactionDate] [datetime2](2) NOT NULL,
/* snip*/
[BusinessUserID] [varchar](150) NOT NULL,
[BusinessTransactionID] [varchar](150) NOT NULL,
[InsertDate] [datetime2](2) NOT NULL,
[UpdateDate] [datetime2](2) NOT NULL,
CONSTRAINT [PK_Transactions_TransactionID] PRIMARY KEY CLUSTERED
(
[TransactionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=PAGE) ON [DB_Data]
) ON [DB_Data]
END
GO
USE [DB]
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[sales].[Transactions]') AND name = N'NCI_Transactions_ClientID_TransactionDate')
begin
CREATE NONCLUSTERED INDEX [NCI_Transactions_ClientID_TransactionDate] ON [sales].[Transactions]
(
[ClientID] ASC,
[TransactionDate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION = PAGE) ON [DB_Data]
END
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[sales].[DF_Transactions_Units]') AND type = 'D')
BEGIN
ALTER TABLE [sales].[Transactions] ADD CONSTRAINT [DF_Transactions_Units] DEFAULT ((0)) FOR [Units]
END
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[sales].[DF_Transactions_ISOCurrencyCode]') AND type = 'D')
BEGIN
ALTER TABLE [sales].[Transactions] ADD CONSTRAINT [DF_Transactions_ISOCurrencyCode] DEFAULT ('USD') FOR [ISOCurrencyCode]
END
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[sales].[DF_Transactions_InsertDate]') AND type = 'D')
BEGIN
ALTER TABLE [sales].[Transactions] ADD CONSTRAINT [DF_Transactions_InsertDate] DEFAULT (sysdatetime()) FOR [InsertDate]
END
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[sales].[DF_Transactions_UpdateDate]') AND type = 'D')
BEGIN
ALTER TABLE [sales].[Transactions] ADD CONSTRAINT [DF_Transactions_UpdateDate] DEFAULT (sysdatetime()) FOR [UpdateDate]
END
GO
meja sementara
same columns as the mgdata. including the relevant fields. Also has a non-unique clustered index
(
[BusinessTransactionID] [varchar](150) NULL,
[BusinessUserID] [varchar](150) NULL,
[PostalCode] [varchar](25) NULL,
[TransactionDate] [datetime2](2) NULL,
[Units] [int] NOT NULL,
[StartDate] [datetime2](2) NULL,
[EndDate] [datetime2](2) NULL,
[TransactionID] [bigint] NULL,
[ClientID] [int] NULL,
)
CREATE CLUSTERED INDEX ##workingTransactionsMG_idx ON #workingTransactions (TransactionID)
It is populated in batches (500k rows at a time), something like this
IF OBJECT_ID(N'tempdb.dbo.#workingTransactions') IS NOT NULL DROP TABLE #workingTransactions;
select fields
into #workingTransactions
from import.Transactions
where importrowid between two number ranges -- pseudocode
Kunci utama
CONSTRAINT [PK_Transactions_TransactionID] PRIMARY KEY CLUSTERED
(
[TransactionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=PAGE) ON [Data]
) ON [Data]
Indeks tidak berkerumun
CREATE NONCLUSTERED INDEX [NCI_Transactions_ClientID_TransactionDate] ON [sales].[Transactions]
(
[ClientID] ASC,
[TransactionDate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION = PAGE)
contoh pernyataan pembaruan
-- updates every field
update t
set
t.transactionid = s.transactionid,
t.[CityCode]=s.[CityCode],
t.TransactionDate=s.[TransactionDate],
t.[ClientID]=s.[ClientID],
t.[PackageMonths] = s.[PackageMonths],
t.UpdateDate = @UpdateDate
FROM #workingTransactions s
JOIN [DB].[sales].[Transactions] t
ON s.[TransactionID] = t.[TransactionID]
WHERE CAST(HASHBYTES('SHA2_256 ',CONCAT( S.[BusinessTransactionID],'|',S.[BusinessUserID],'|', etc)
<> CAST(HASHBYTES('SHA2_256 ',CONCAT( T.[BusinessTransactionID],'|',T.[BusinessUserID],'|', etc)
Pertanyaan saya adalah, apa yang terjadi di bawah tenda? Dan apa solusinya? Untuk referensi, tautan di atas menyebutkan ini:
Pada titik ini, saya punya beberapa teori:
- Bug yang berkaitan dengan tekanan memori atau rencana pembaruan paralel besar, tetapi saya akan mengharapkan jenis kesalahan yang berbeda dan sejauh ini saya tidak dapat menghubungkan sumber daya yang rendah akan kerangka waktu dari kesalahan yang terisolasi dan sporadis ini.
- Bug dalam pernyataan atau data UPDATE menyebabkan pelanggaran duplikat yang sebenarnya pada kunci utama, tetapi beberapa bug SQL Server tidak jelas mengakibatkan dan pesan kesalahan yang mengutip nama indeks yang salah.
- Bacaan kotor yang dihasilkan dari isolasi yang tidak terikat baca menyebabkan pembaruan paralel besar untuk memasukkan ganda. Tetapi pengembang ETL mengklaim default read berkomitmen digunakan, dan sulit untuk menentukan dengan tepat tingkat isolasi apa yang sebenarnya digunakan saat runtime.
Saya menduga bahwa jika saya mengubah rencana eksekusi sebagai solusi, mungkin MAXDOP (1) mengisyaratkan atau menggunakan flag jejak sesi untuk menonaktifkan operasi spool, kesalahan hanya akan hilang, tetapi tidak jelas bagaimana ini akan mempengaruhi kinerja
Versi: kapan
Microsoft SQL Server 2017 (RTM-CU13) (KB4466404) - 14.0.3048.4 (X64) 30 Nov 2018 12:57:58 Hak cipta (C) 2017 Microsoft Corporation Enterprise Edition (64-bit) pada Windows Server 2016 Standard 10.0 (Build 14393 :)