LATCH_EX Menunggu pada Sumberdaya METADATA_SEQUENCE_GENERATOR

11

Kami memiliki proses yang menghasilkan laporan inventaris. Di sisi klien, proses memisahkan sejumlah utas pekerja yang dapat dikonfigurasi untuk membangun sepotong data untuk laporan yang sesuai dengan satu penyimpanan dari banyak (berpotensi ribuan, biasanya lusinan). Setiap utas pekerja memanggil layanan web yang menjalankan prosedur tersimpan.

Proses basis data untuk memproses setiap chunk mengumpulkan banyak data ke dalam tabel #T Temporary. Pada akhir setiap potongan pemrosesan, data ditulis ke tabel permanen di tempdb. Akhirnya, pada akhir proses, satu utas di sisi klien meminta semua data dari tabel tempdb permanen.

Semakin banyak pengguna yang menjalankan laporan ini, semakin lambat hasilnya. Saya menganalisis aktivitas dalam database. Pada satu titik, saya melihat 35 permintaan terpisah semua diblokir pada satu titik dalam proses. Semua SPID ini memiliki urutan 50 ms menunggu jenis LATCH_EXsumber daya METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8). Satu SPID memiliki sumber ini, dan yang lainnya memblokir. Saya tidak menemukan apa pun tentang sumber daya tunggu ini di pencarian web.

Tabel di tempdb yang kami gunakan memang memiliki IDENTITY(1,1)kolom. Apakah SPID ini menunggu kolom IDENTITAS? Metode apa yang bisa kita gunakan untuk mengurangi atau menghilangkan pemblokiran?

Server adalah bagian dari sebuah cluster. Server menjalankan 64-bit SQL Server 2012 Standard Edition SP1 pada 64-bit Windows 2008 R2 Enterprise. Server memiliki 64 GB RAM dan 48 prosesor, tetapi database hanya dapat menggunakan 16 karena ini adalah edisi standar.

(Perhatikan bahwa saya tidak senang dengan desain menggunakan tabel permanen di tempdb untuk menampung semua data ini. Mengubah itu akan menjadi tantangan teknis dan politik yang menarik, tapi saya terbuka untuk saran.)

PEMBARUAN 4/23/2013

Kami telah membuka kasing dukungan dengan Microsoft. Saya akan terus memperbarui pertanyaan ini saat kami mempelajari lebih lanjut.

UPDATE 5/10/2013

Insinyur dukungan SQL Server setuju bahwa menunggu disebabkan oleh kolom IDENTITAS. Menghapus IDENTITAS menghilangkan menunggu. Kami tidak dapat menduplikasi masalah pada SQL 2008 R2; itu terjadi hanya pada SQL 2012.

Paul Williams
sumber
Apakah proses ini pada dasarnya menyalin data dari tabel #T Temporary ke tabel permanen, atau adakah logika transformasi tambahan yang terjadi pada langkah itu?
Jon Seigel
Pada langkah menunggu, itu menyalin catatan persediaan satu toko ke tabel permanen tanpa transformasi. Kita bisa beroperasi di dalam tabel permanen sepanjang waktu, tetapi saya pikir programmer memilih untuk menggunakan tabel #Tentara sebagai area penahan untuk mencegah pembaruan yang sering pada data dari mengkonversi ke kunci PAGE.
Paul Williams

Jawaban:

4

Dengan asumsi Anda dapat mengisolasi masalah ke generasi nilai identitas (coba hapus kolom itu sebagai ujian), apa yang saya sarankan adalah ini:

  1. Hapus IDENTITYproperti dari kolom di tabel final.
  2. Hasilkan nilai identitas di masing-masing tabel #T Temporary.
  3. Saat memuat tabel akhir, gabungkan pengidentifikasi numerik untuk toko tertentu dengan nilai identitas dari langkah 2.

Jadi, jika Anda memiliki id toko 3 dan 4, Anda akan mendapatkan nilai id akhir seperti ini:

3000000001
3000000002
3000000003
...
4000000001
4000000002
...

Atau sesuatu yang mirip dengan itu. Anda mendapatkan idenya.

Ini akan menghilangkan kebutuhan untuk membuat serial tentang IDENTITYgenerasi sambil mempertahankan keunikan dalam hasil akhir.

Atau, tergantung pada bagaimana prosesnya bekerja, masukkan nilai id akhir yang dihitung ke dalam tabel #Tentara. Kemudian Anda bisa membuat tampilan yang UNION ALLmenyatukan mereka, menghilangkan kebutuhan untuk menyalin data sama sekali.

Jon Seigel
sumber
Terima kasih atas tanggapannya. Saya setuju jika itu masalahnya, menggunakan beberapa kunci buatan (atau tanpa kunci sama sekali) dapat memperbaikinya. Kami telah membuka kasing dengan Microsoft terkait masalah ini. Saya akan memposting hasilnya di sini dan menerima jawaban Anda jika mereka setuju itu masalahnya.
Paul Williams
@ Paul: Tolong beri tahu saya; Saya juga ingin tahu. Seperti Anda, saya tidak dapat menemukan apa pun di web tentang kait ini, tetapi tentu masuk akal bahwa itu adalah serialisasi identitas / urutan. Apakah itu hambatannya sulit untuk dikatakan, meskipun dengan 30+ utas bersaing untuk mendapatkan nilai, tampaknya itu mungkin. Anda juga dapat mencoba menyalin dari setiap tabel #Tentara secara seri (alih-alih secara paralel) untuk melihat apakah itu membantu.
Jon Seigel
2
Insinyur SQL Server setuju itu mungkin IDENTITYkolom. Kami melepasnya dari indeks cluster yang sudah luas dan menghapus kolom seluruhnya. Itu tidak perlu. Setelah itu, menunggu LATCH_EX ini hilang. Kami tidak bisa menduplikasi menunggu di SQL 2008 R2. Masalah ini terjadi hanya pada SQL Server 2012.
Paul Williams
@ Paul: Terima kasih telah menindaklanjuti. Sangat menarik. Saya menduga bahwa kode yang menghasilkan IDENTITYnilai ditulis ulang untuk menggunakan hal-hal generasi urutan baru yang baru pada tahun 2012. Pada <2012, Anda dapat melihat jenis kait yang berbeda, meskipun jika tidak ada masalah perf, maka sepertinya ada regresi dalam kode. Bagaimanapun, menghapus IDENTITYkolom adalah hal yang paling aman.
Jon Seigel
Alih-alih identitas Anda bisa mencoba menggunakan 'SEQUENCE' (yang baru dalam SQL 2012)
Bogdan Maxim
7

(Diperbarui Februari 2019)

Ini adalah posting lama, yang mengatakan bahwa saya akhirnya berhasil meyakinkan Microsoft bahwa fakta yang terjadi memang cacat.

Pembaruan: MS Mengonfirmasi kerusakan dan menetapkannya sebagai bug # of 12628722.

Saya telah melihat posting ini pada November 2018 yang lalu ketika kita mulai menderita hal yang sama setelah kita meningkatkan dari Sql Server 2005 ke Sql Server 2017. Tabel 3,3 juta baris yang digunakan untuk mengambil 10 detik untuk memasukkan massal tiba-tiba mulai mengambil 10 menit pada tabel dengan Identitykolom.

Ternyata ada dua masalah di balik ini:

  1. Microsoft mengubah perilaku di Sql Server 2014 untuk memaksa Sisipan Massal untuk berjalan paralel - dalam versi sebelumnya Sisipan Massal diberi rencana Serialized.
  2. Setelah berjalan paralel pada 32 core box kami, mesin menghabiskan lebih banyak waktu dengan core saling mengunci daripada benar-benar melakukan pekerjaan.

Butuh waktu 4 minggu tetapi setelah liburan saya mendapat hadiah terlambat dari Santa - konfirmasi bahwa masalah itu memang cacat.

Ada beberapa kemungkinan penyelesaian yang kami temukan sampai ini diperbaiki:

  1. Gunakan Option (MaxDop 1)dalam kueri untuk mengubah sisipan massal kembali menjadi paket bersambung.
  2. Tutupi kolom Identity dengan melemparkannya (mis. Select Cast(MyIdentityColumn As Integer) As MyIdentityColumn)
    • ini mencegah properti identitas disalin saat menggunakan SELECT...INTO
  3. Hapus kolom identitas seperti dijelaskan di atas.
  4. Ubah mode kompatibilitas database ke Sql Server 2012 atau lebih rendah untuk membangun kembali paket serial.

Pembaruan: Perbaikan yang akan diterapkan MS adalah mengembalikan jenis Sisipan ini kembali menggunakan Serialized rencana. Ini direncanakan untuk Sql Server 2017 CU14 (tidak ada berita tentang versi lain dari Sql Server - maaf!). Ketika diimplementasikan, Trace Flag 9492 perlu dinyalakan, baik di tingkat server, atau via DBCC TraceOn .

Rachel Ambler
sumber