Penyebab proses menjadi korban kebuntuan

105

Saya memiliki proses dengan Select yang membutuhkan waktu lama untuk menyelesaikannya, dengan urutan 5 hingga 10 menit.
Saat ini saya tidak menggunakan NOLOCK sebagai petunjuk untuk mesin database MS SQL.
Pada saat yang sama kami memiliki proses lain yang melakukan pembaruan dan memasukkan ke dalam database yang sama dan tabel yang sama.
Proses pertama telah dimulai, baru-baru ini diakhiri dengan pesan sebelum waktunya

SQLEXCEPTION: Transaksi menemui jalan buntu pada sumber daya kunci dengan proses lain dan telah dipilih sebagai korban kebuntuan.

Proses pertama ini berjalan di situs lain dalam kondisi yang sama tetapi dengan database yang lebih kecil dan dengan demikian pernyataan pemilihan yang dimaksud membutuhkan waktu yang lebih singkat (sekitar 30 detik atau lebih). Di situs lain ini, saya tidak mendapatkan pesan kebuntuan di situs lain tersebut. Saya juga tidak mendapatkan pesan ini di situs yang pada awalnya mengalami masalah, tetapi, saya berasumsi, karena database telah berkembang, saya yakin saya pasti telah melewati beberapa ambang batas. Inilah pertanyaan saya:

  1. Mungkinkah waktu yang diperlukan untuk mengeksekusi transaksi membuat proses terkait lebih mungkin ditandai sebagai korban jalan buntu.
  2. Jika saya menjalankan pemilihan dengan petunjuk NOLOCK, apakah ini akan menghilangkan masalah?
  3. Saya menduga bahwa bidang datetime yang diperiksa sebagai bagian dari klausa WHERE dalam pernyataan pilih menyebabkan waktu pencarian yang lambat. Dapatkah saya membuat indeks berdasarkan bidang ini? Apakah itu dianjurkan?
Elliott
sumber
Sebagian jawaban untuk poin 1: Jangan rancukan jalan buntu dengan batas waktu. Jika Anda mengalami timeout maka waktu yang diperlukan untuk menyelesaikan satu transaksi mungkin bertanggung jawab atas abending lainnya. Selain itu, akan berguna untuk mengetahui resource apa yang Anda buntu (apakah itu indeks atau tabel?).
NealB
1
TETAPKAN DEADLOCK_PRIORITY HIGH ALTER DATABASE dbname SET MULTI_USER;
gstackoverflow

Jawaban:

128

T1: Mungkinkah waktu yang diperlukan untuk mengeksekusi transaksi membuat proses terkait lebih mungkin ditandai sebagai korban jalan buntu.

Tidak. SELECT menjadi korban karena hanya membaca data, oleh karena itu transaksi memiliki biaya yang lebih rendah terkait dengannya sehingga dipilih sebagai korban:

Secara default, Mesin Database memilih sebagai korban kebuntuan sesi yang menjalankan transaksi yang paling murah untuk dibatalkan . Alternatifnya, pengguna dapat menentukan prioritas sesi dalam situasi kebuntuan menggunakan SET DEADLOCK_PRIORITYpernyataan tersebut. DEADLOCK_PRIORITY dapat disetel ke LOW, NORMAL, atau HIGH, atau alternatifnya dapat disetel ke nilai integer apa pun dalam rentang (-10 hingga 10).

Q2. Jika saya menjalankan pemilihan dengan petunjuk NOLOCK, apakah ini akan menghilangkan masalah?

Tidak. Karena beberapa alasan:

P3. Saya menduga bahwa bidang datetime yang diperiksa sebagai bagian dari klausa WHERE dalam pernyataan pilih menyebabkan waktu pencarian yang lambat. Dapatkah saya membuat indeks berdasarkan bidang ini? Apakah itu dianjurkan?

Mungkin. Penyebab kebuntuan hampir kemungkinan besar adalah database yang diindeks dengan buruk. Kueri 10 menit dapat diterima dalam kondisi yang begitu sempit, sehingga saya 100% yakin dalam kasus Anda tidak dapat diterima.

Dengan keyakinan 99% saya menyatakan bahwa kebuntuan Anda disebabkan oleh pemindaian tabel besar yang bertentangan dengan pembaruan. Mulailah dengan menangkap grafik kebuntuan untuk menganalisis penyebabnya. Anda kemungkinan besar harus mengoptimalkan skema database Anda. Sebelum Anda melakukan modifikasi apa pun, baca topik Mendesain Indeks dan sub-artikel ini.

Remus Rusanu
sumber
Terima kasih atas jawaban menyeluruh Anda. Saya rasa saya masih punya satu pertanyaan. Mengapa saya mendapatkan situasi kebuntuan hanya di satu lingkungan dan bukan di lingkungan lain. Padahal software nya sama. Jawaban Anda menunjukkan bahwa lamanya waktu untuk menjalankan kueri Pilih tidak membuat perbedaan dan fakta bahwa kueri Pilih itu sendiri yang menyebabkan proses gagal. Namun, mengapa hanya jika kueri pemilihan membutuhkan waktu lama untuk dieksekusi?
Elliott
4
Panjangnya query tidak membuat perbedaan dalam memilih korban jalan buntu . Itu membuat perbedaan dalam menyebabkan kebuntuan setidaknya oleh dua faktor: 1) probabilitas sederhana. Semakin lama kueri, semakin besar kemungkinan untuk tumpang tindih dengan pembaruan bersamaan dan mengalami kebuntuan. 2) tabel yang lebih besar dapat menggunakan rencana kueri yang sama sekali berbeda, yang rentan terhadap kebuntuan.
Remus Rusanu
12

Berikut adalah bagaimana masalah kebuntuan ini benar-benar terjadi dan bagaimana itu sebenarnya diselesaikan. Ini adalah database yang cukup aktif dengan 130 ribu transaksi yang terjadi setiap hari. Indeks dalam tabel di database ini awalnya berkerumun. Klien meminta kami untuk membuat indeks menjadi nonclustered. Segera setelah kami melakukannya, kebuntuan dimulai. Saat kami menetapkan kembali indeks sebagai berkerumun, kebuntuan berhenti.

Elliott
sumber
34
Adakah yang bisa menjelaskan mengapa? (Solusi ajaib tidak terlalu membantu)
OGrandeDiEnne
1
Orang ini menjelaskannya di postingannya: mssqltips.com/sqlservertip/2517/…
siga0984
6

Jawabannya di sini patut dicoba, tetapi Anda juga harus meninjau kode Anda. Secara khusus, baca jawaban Polyfun di sini: Bagaimana cara menghilangkan kebuntuan di aplikasi SQL Server 2005 dan C #?

Ini menjelaskan masalah konkurensi, dan bagaimana penggunaan "with (updlock)" dalam kueri Anda dapat memperbaiki situasi deadlock Anda - bergantung pada apa yang sebenarnya dilakukan kode Anda. Jika kode Anda mengikuti pola ini, kemungkinan besar ini adalah perbaikan yang lebih baik, sebelum beralih ke bacaan kotor, dll.

Peter Barton
sumber