Urutan menggunakan kembali

11

Saya memiliki urutan yang menghasilkan nomor pelacakan untuk objek di sistem saya. Sudah cukup lama bekerja dengan baik.

Minggu lalu kami perhatikan bahwa itu mulai menggunakan kembali nilai.

Apa yang tampaknya terjadi adalah bahwa pada titik yang berbeda di malam hari, itu akan mundur ke nilai seperti hari sebelumnya. Kemudian akan terus menghasilkan nilai dari titik itu.

Jadi misalnya saya bisa mendapatkan sesuatu seperti ini:

10112
10113
10114
10115
10116
10117
10118
10113
10114
10115
10116
...

Tampaknya tidak ada pola apa pun ketika itu terjadi, durasi antara penggunaan pertama dan penggunaan kedua (sesedikit 10 menit atau beberapa jam) atau berapa banyak yang digulung kembali (sesedikit 1 dan beberapa ratus).

Saya berpikir tentang menjalankan jejak (dan mungkin masih), tapi saya tidak berpikir objek urutan sedang dimodifikasi secara langsung. Alasan saya percaya ini adalah bahwa tanggal modifikasi berumur beberapa hari dan menunjuk ke waktu ketika kita secara manual menaikkan nilainya untuk mencoba dan menghilangkan duplikat. (Dan masalah telah terjadi beberapa kali sejak itu.)

Adakah yang tahu apa yang menyebabkan rollback berurutan dan menggunakan kembali nilai setiap malam?

UPDATE: Untuk menjawab beberapa pertanyaan di komentar:

  • @@Version:

    Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64) 19 Okt 2012 13:38:57

  • Buat Skrip:

    CREATE SEQUENCE [schemaName].[SequenceName] 
      AS [bigint]
      START WITH 410014104
      INCREMENT BY 1
      MINVALUE 410000000
      MAXVALUE 419999999
      CYCLE 
      CACHE 
    GO
  • Saya tidak memiliki Batasan Unik (tapi saya berencana untuk menggunakannya). Namun itu hanya akan membantu saya mengetahui kapan saya telah menggunakan kembali nilai. Bukan yang menyebabkan nilai-nilai diatur ulang. Saya menempatkan pekerjaan pada itu akan mendapatkan nilai baru setiap 5 menit dan simpan. Waktu dan lompatan nilai tidak mengikuti pola.

  • Saya telah memeriksa Log Kejadian untuk melihat apakah ada kesalahan. Satu-satunya pemikiran yang terjadi adalah ini: http://support.microsoft.com/kb/2793634 Kami menerapkan perbaikan hari ini. Saya tidak berpikir ini terkait, tetapi bisa jadi.
Gunung berapi
sumber
1
Mengapa tidak ada PK atau batasan unik pada kolom ini? Dengan itu, reuse ini akan tertangkap, dan Anda tidak perlu mencoba menebak dari mana asalnya, kecuali kode aplikasi Anda hanya menelan semua kesalahan ...
Aaron Bertrand
Bisakah Anda menunjukkan definisi urutan Anda? Dapatkah Anda juga memeriksa log kesalahan untuk melihat apakah ada peristiwa signifikan yang terjadi dalam semalam (mis. Failover, service restart, masalah memori, dll)?
Aaron Bertrand
2
Apa @@VERSION? Juga ada yang berubah tentang lingkungan? Ada item sambung yang melaporkan sesuatu yang serupa. OP di sana menganggap itu terkait dengan11.0.3000.0
Martin Smith
2
Nah, CYCLE pada dasarnya memberi tahu SQL Server bahwa Anda baik-baik saja dengan menggunakan kembali nilai-nilai. Saya sama sekali tidak tahu mengapa Anda mengalami masalah ini, dan tidak tahu bahwa Anda akan mengetahui sebabnya (berapa banyak waktu yang Anda habiskan untuk menyelidiki mengapa Anda mengalami ban kempes, sebelum Anda menggantinya?). Saya masih berpikir bahwa taruhan terbaik Anda adalah memiliki kendala di sana untuk mencegah duplikat, dan untuk mematikan caching dengan harapan mencegah penggunaan kembali.
Aaron Bertrand

Jawaban:

11

Pertama, jika Anda tidak ingin duplikat di kolom ini, sebutkan itu secara eksplisit .

ALTER TABLE dbo.whatever ADD CONSTRAINT uq_that_column UNIQUE (that_column);

(Atau Anda mungkin ingin menjadikannya sebagai kunci utama, atau mengubah indeks berkerumun, atau apa pun yang Anda ...)

Dalam kasus apa pun, meningkatkan kesalahan saat Anda membuat duplikat jauh lebih baik daripada hanya memasukkan duplikat secara membabi buta yang harus Anda tangani nanti.

Selanjutnya, pertimbangkan bahwa SEQUENCE hanyalah penghasil angka, dan secara default ia memiliki cache dengan nilai 50. Bergantung pada bagaimana transaksi Anda diatur, dan peristiwa kritis apa yang terjadi pada server, ada kemungkinan bahwa SQL Server dapat "lupa" bahwa itu menghasilkan nilai-nilai tertentu untuk Anda. Maaf tapi saya tidak tahu persis apa yang menjadi faktor kriteria dalam mereproduksi bug ini. Cara untuk mengatasi ini (sampai bug dipecahkan / dijelaskan ) adalah dengan mengubah urutan untuk digunakan NO CYCLEdan NO CACHE, misalnya:

ALTER SEQUENCE dbo.mysequence NO CYCLE NO CACHE; 

Catatan yang NO CACHEdapat mempengaruhi kinerja dan konkurensi, tetapi akan membantu menghilangkan kesenjangan, kehilangan blok dan, siapa tahu, mungkin masalah Anda juga.

Anda mungkin juga ingin memverifikasi bahwa Anda menggunakan paket layanan dan CU terbaru. Pada titik ini saya merekomendasikan SP1 dan CU10 dengan 3437 ; SP2 keluar tetapi masih ada masalah kritis di sana dengan pembangunan kembali online yang dapat memengaruhi Anda .

Aaron Bertrand
sumber
Yah, aku tidak bisa mendapatkannya kembali. Jadi jika NO CACHE akan memperbaikinya, maka itulah yang akan saya lakukan.
Vaccano
Saya pikir mungkin ada transaksi yang menyebabkan ini. Tetapi halaman Sequence di MSDN mengatakan "Nomor urutan dihasilkan di luar ruang lingkup transaksi saat ini. Mereka dikonsumsi apakah transaksi menggunakan nomor urutan dilakukan atau dibatalkan." Jadi saya membuang teori transaksi saya. Saya setuju pasti ada hal lain yang terjadi.
Vaccano
Ternyata pengaturan hanya dengan itu NO CYCLEsudah cukup. (Setidaknya itu tidak terjadi semalam.) Terima kasih atas bantuannya!
Vaccano
1
FIX: Objek urutan menghasilkan nilai urutan duplikat ketika SQL Server 2012 atau SQL Server 2014 berada di bawah tekanan memori Asumsikan bahwa Anda membuat objek urutan yang memiliki opsi CACHE diaktifkan di Microsoft SQL Server 2012 atau SQL Server 2014. Ketika instance berada di bawah tekanan memori , dan beberapa koneksi konkuren meminta nilai urutan dari objek urutan yang sama, nilai urutan duplikat dapat dihasilkan. Selain itu, kesalahan pelanggaran kunci unik atau primer (PK) terjadi ketika nilai urutan duplikat dimasukkan ke dalam tabel.
Andomar