Jalan buntu pada Hapus Pernyataan

11

Saya mendapatkan jalan buntu ketika Pekerjaan SQL Server berjalan. Kebuntuan terjadi pada pernyataan DELETE sederhana. Saya akan berpikir harus ada query SELECT / UPDATE yang berjalan untuk menyebabkan kebuntuan? Tapi sepertinya itu DELETE / DELETE deadlock ...

Apa yang saya cari adalah mengapa saya mendapatkan jalan buntu DELETE / DELETE. Ini (setahu saya) melewati parameter yang berbeda.

Ada ide? Terima kasih.

deadlock-list
2014-05-20 07:30:09.66 spid25s      deadlock victim=process409048
2014-05-20 07:30:09.66 spid25s       process-list
2014-05-20 07:30:09.66 spid25s        process id=process409048 taskpriority=0 logused=0 waitresource=PAGE: 12:1:7127294 waittime=4352 ownerId=629860973 transactionname=DELETE lasttranstarted=2014-05-20T07:30:05.307 XDES=0x397219620 lockMode=U schedulerid=5 kpid=3792 status=suspended spid=150 sbid=0 ecid=3 priority=0 trancount=0 lastbatchstarted=2014-05-20T07:30:05.307 lastbatchcompleted=2014-05-20T07:30:05.307 clientapp=QSQL25 hostname=MORRIS hostpid=1528 isolationlevel=read committed (2) xactid=629860973 currentdb=12 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
2014-05-20 07:30:09.66 spid25s         executionStack
2014-05-20 07:30:09.66 spid25s          frame procname=adhoc line=1 stmtstart=68 sqlhandle=0x020000000b887a18f75d0aa07c25a9b8630fca696aa0e5d2
2014-05-20 07:30:09.66 spid25s     DELETE FROM dbo.UserDetailsData WHERE        (Username = @P1) AND (UserDate = @P2)     
2014-05-20 07:30:09.66 spid25s          frame procname=unknown line=1 sqlhandle=0x000000000000000000000000000000000000000000000000
2014-05-20 07:30:09.66 spid25s     unknown     
2014-05-20 07:30:09.66 spid25s         inputbuf
2014-05-20 07:30:09.66 spid25s        process id=process432e08 taskpriority=0 logused=0 waitresource=PAGE: 12:1:7127916 waittime=2648 ownerId=629859744 transactionname=DELETE lasttranstarted=2014-05-20T07:30:04.833 XDES=0x4c3426b50 lockMode=U schedulerid=6 kpid=5988 status=suspended spid=146 sbid=0 ecid=3 priority=0 trancount=0 lastbatchstarted=2014-05-20T07:30:04.833 lastbatchcompleted=2014-05-20T07:30:04.820 clientapp=QSQL25 hostname=MORRIS hostpid=1528 isolationlevel=read committed (2) xactid=629859744 currentdb=12 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
2014-05-20 07:30:09.66 spid25s         executionStack
2014-05-20 07:30:09.66 spid25s          frame procname=adhoc line=1 stmtstart=68 sqlhandle=0x020000000b887a18f75d0aa07c25a9b8630fca696aa0e5d2
2014-05-20 07:30:09.66 spid25s     DELETE FROM dbo.UserDetailsData WHERE        (Username = @P1) AND (UserDate = @P2)     
2014-05-20 07:30:09.66 spid25s          frame procname=unknown line=1 sqlhandle=0x000000000000000000000000000000000000000000000000
2014-05-20 07:30:09.66 spid25s     unknown     
2014-05-20 07:30:09.66 spid25s         inputbuf
2014-05-20 07:30:09.66 spid25s        process id=process39ea562c8 taskpriority=0 logused=0 waitresource=PAGE: 12:1:7127916 waittime=4352 ownerId=629860973 transactionname=DELETE lasttranstarted=2014-05-20T07:30:05.307 XDES=0x13e0e4b50 lockMode=U schedulerid=2 kpid=7124 status=suspended spid=150 sbid=0 ecid=1 priority=0 trancount=0 lastbatchstarted=2014-05-20T07:30:05.307 lastbatchcompleted=2014-05-20T07:30:05.307 clientapp=QSQL25 hostname=MORRIS hostpid=1528 isolationlevel=read committed (2) xactid=629860973 currentdb=12 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
2014-05-20 07:30:09.66 spid25s         executionStack
2014-05-20 07:30:09.66 spid25s          frame procname=adhoc line=1 stmtstart=68 sqlhandle=0x020000000b887a18f75d0aa07c25a9b8630fca696aa0e5d2
K09
sumber
5
Tidak, jalan buntu dapat terjadi dalam skenario lain di luar SELECT / UPDATE. Yang Anda butuhkan hanyalah dua proses yang masing-masing membutuhkan sumber daya yang dimiliki oleh pihak lainnya. (1) Apakah pernyataan DELETE bagian dari transaksi yang lebih besar? (2) Bisakah Anda memposting kebuntuan XML di suatu tempat, bukan teks log kesalahan jelek?
Aaron Bertrand
Bisakah Anda memposting skema tabel dbo.UserDetailsDatatermasuk semua indeks? Juga, tahukah Anda jika pernyataan itu dipanggil dengan parameter yang sama? Mengingat bahwa keduanya memiliki nol log yang digunakan, saya bertanya-tanya apakah yang perlu Anda lakukan adalah membuat serial panggilan karena mereka saling menginjak.
Jon Seigel
Bagaimana saya mendapatkan XML? Mendapat kesalahan dari log kesalahan SQL Server. Pernyataan dipanggil dengan parameter berbeda. Kami baru-baru ini menambahkan sejumlah indeks yang difilter yang memfilter pada bidang UserDate.
K09
Tangkap acara grafik deadlock di Profiler. Kemudian, setelah Anda menangkapnya, klik kanan baris -> ekstrak data acara -> simpan sebagai .xdl di suatu tempat dan poskan isinya (ini adalah xml) di Pastebin (atau di tempat yang serupa).
Marian
1
Hai, XML diposting di sini ... semoga ini membantu! dl.dropboxusercontent.com/u/16953128/DeadlockTest.xdl
K09

Jawaban:

14

Apa yang saya cari adalah mengapa saya mendapatkan jalan buntu DELETE / DELETE.

Tampaknya kebuntuan terjadi karena:

  1. spid 54 ecid 0memperoleh pembaruan ( U) kunci halaman aktifPAGE: 12:1:5147422
  2. spid 166 ecid 3meminta pembaruan ( U) kunci halaman pada halaman yang sama, dan diblokir
  3. spid 54 ecid 2meminta pembaruan ( U) kunci halaman pada halaman yang sama ...

Halaman sedang dibuat untuk kueri, dengan kunci pembaruan diperoleh oleh ecid 0. Itu adalah langkah 1 di atas. Di langkah 3, utas anak dari kueri paralel yang sama ( ecid 2) meminta kunci yang sama. Biasanya ini tidak akan menjadi masalah. SQL Server tahu ecid 0dan ecid 2merupakan utas dari proses induk yang sama. Sayangnya, langkah 2 menghalangi hal ini, dan kebuntuan terjadi.

Yang mengatakan, Anda seharusnya tidak terlalu peduli tentang mengapa kebuntuan terjadi, pertanyaan penting adalah bagaimana Anda menghindarinya. Jawabannya adalah untuk menyediakan jalur akses yang efisien untuk DELETE. Pernyataan perlu menemukan baris WHERE Username = @P1 AND UserDate = @P2, jadi Anda harus memiliki indeks yang dikunci pada kolom ini.

Dan tentu saja Anda memiliki indeks seperti itu. Pertanyaan sebenarnya adalah mengapa masalah Anda mulai terjadi setelah Anda menambahkan indeks yang difilter.

Jawabannya adalah informasi kolom tambahan diperlukan untuk menemukan baris indeks yang difilter untuk dihapus (dan untuk memeriksa predikatnya). Jika kueri menggunakan rencana eksekusi yang sempit / per baris , mesin eksekusi tidak dapat mengambil kolom tambahan di operator Penghapusan Indeks Berkelompok, seperti dalam rencana lebar / per-indeks.

Anda dapat menemukan detail lebih lanjut tentang itu, dan contoh yang berhasil di posting blog ini .

Dalam hal ini, informasi kolom harus berasal dari bagian rencana di sebelah kanan Penghapusan Indeks Berkelompok, sehingga pemindaian indeks berkerompak paralel digunakan, dan Anda mendapatkan kueri lambat dengan potensi jalan buntu yang tinggi.

Jawabannya adalah melakukan salah satu dari yang berikut:

  1. Hapus indeks yang difilter
  2. Tambahkan kunci indeks / sertakan / predikat kolom yang difilter ke indeks nama / tanggal yang ada
  3. Paksa rencana pembaruan yang luas (tidak ada cara yang didukung untuk melakukan ini)
  4. Jalankan kueri di bawah isolasi snapshot (bukan RCSI)

Opsi 2 akan menjadi preferensi kuat saya.

Opsi 4 (terima kasih Jack Douglas) memiliki keuntungan menghilangkan kebuntuan, dan seharusnya tidak menyebabkan "perbarui konflik", mengingat sifat perubahan yang terpisah-pisah, tetapi memang membutuhkan pengaktifan snapshot isolasi pada tingkat basis data, secara eksplisit mengubah tingkat isolasi, dan tidak akan memperbaiki masalah mendasar : Anda masih akan berakhir dengan pemindaian tabel paralel yang sia-sia, di mana pencarian indeks yang bagus adalah yang Anda inginkan.

Paul White 9
sumber