Cara Mencegah Kebuntuan Kolom yang Dipartisi di SELECT

10

Saya memiliki tiga tabel Clustered Columnstore Index (CCI) di SQL Server 2016. Semua CCI ini berada dalam skema partisi yang sama, berdasarkan pada Tenant ID. Akhir-akhir ini, dan tidak konsisten, saya mendapatkan kebuntuan pada pernyataan pilih sederhana dari bergabung ke tabel ini. Contoh permintaan yang deadlock:

SELECT  TOP 33 r.tenantid
FROM    Table_r r
        INNER JOIN Table_cm cm ON r.MyKey=cm.MyKey 
        INNER JOIN Table_pe pe ON r.MyKey=pe.MyKey 
WHERE   r.TenantId = 69
        AND pe.TenantId = 69
        AND cm.TenantId = 69

Pesan eror:

Transaksi (ID Proses 56) menemui jalan buntu pada sumber daya objek yang dapat ditunggu secara umum dengan proses lain dan telah dipilih sebagai korban kebuntuan. Jalankan kembali transaksi.

Petunjuk:

  • Jika kueri menggunakan indeks lain selain CCI itu tidak menemui jalan buntu.
  • Jika saya menghapus dua dari tiga filter tenantid, itu tidak menemui jalan buntu.
  • Jika saya memilih 32 teratas atau lebih rendah itu tidak menemui jalan buntu.
  • Jika saya menambahkan OPSI (MAXDOP 1) itu tidak menemui jalan buntu.
  • Saya dapat merepro ini di replika PROD orak, PROD READ-ONLY Secondary, dan PROD sendiri.
  • Saya tidak bisa mengulangi perilaku ini dalam DEV atau INT.
  • Itu masih kebuntuan jika saya menambahkan DENGAN (NOLOCK) ke semua 3 tabel bergabung
  • Kebuntuan itu sendiri. Ini akan menemui jalan buntu ketika tidak ada proses aktif lainnya.
  • Rencana permintaan tanpa paralelisme tidak menemui jalan buntu

Jalan buntu xml di sini

Versi PROD kami:

Microsoft SQL Server 2016 (SP2-CU5) (KB4475776) - 13.0.5264.1 (X64) 10 Jan 2019 18:51:38 Hak cipta (c) Microsoft Corporation Enterprise Edition (64-bit) pada Windows Server 2012 R2 Standar 6.3 (Build 9600) :) (Hypervisor)

Bagaimana cara mencegah kebuntuan pada kueri ini?

Cyndi Baker
sumber

Jawaban:

8

Karena Anda menggunakan SQL Server 2016, perlu disebutkan bahwa setidaknya ada satu perbaikan bug publik untuk kebuntuan paralel yang melibatkan indeks columnstore:

PERBAIKI: Kebuntuan terjadi ketika Anda menjalankan kueri paralel pada indeks columnstore berkerumun di SQL Server 2016 dan 2017

(terima kasih kepada Denis Rubashkin untuk memberikan tautan pada awalnya)

Ini dirilis sebagai bagian dari SP1 CU7. Jika Anda tidak sanggup dengan CU itu, Anda harus mencobanya. Perbaikan ini juga akan dimasukkan dalam SP2 (salah satu CU).

Secara umum, dua pendekatan untuk memperbaiki kebuntuan paralelisme intra-kueri:

  • hindari paralelisme (dengan menyetel kueri agar tidak paralel, menggunakan MAXDOPpetunjuk, dll.) - ini tercakup dalam jawaban lain oleh Thomas Costers
  • menerapkan pemutakhiran paket layanan / kumulatif terbaru untuk SQL Server
Josh Darnell
sumber
2

Sudahkah Anda memeriksa blog berikut di Intra-Query Parallel Thread Deadlocks

Sumber SyncPointdaya menunjukkan penggunaan acara pertukaran jika saya tidak salah.
Melihat peserta kebuntuan Anda, Anda dapat melihat bahwa mereka semua berasal dari spid (55) dan batch (0) yang sama, tetapi menggunakan utas yang berbeda. Ini menunjukkan bahwa mereka semua adalah bagian dari kueri paralel yang sama dan dikonfirmasi oleh fakta bahwa Anda tidak menerima deadlock setiap kali Anda menjalankan kueri MAXDOP 1. Dalam kasus Kebuntuan Utas Paralel Paralel Intra-Kueri, utas satu kueri akan berakhir menemui jalan buntu menunggu objek sinkronisasi, SyncPoints dalam kasing Anda.

Terakhir kali ketika saya menyaksikan perilaku semacam ini, saya dapat lebih mengoptimalkan kueri dan dengan demikian mencegah kueri dari menggunakan rencana eksekusi paralel. Saya menduga Anda melakukan hal yang sama dengan membatasi hasil yang Anda set menjadi 32 catatan atau dengan menggunakan indeks yang berbeda.
Opsi lain adalah menambahkan MAXDOP 1ke permintaan Anda, meskipun bukan penggemar opsi ini.

Tapi sebelum mengutak-atik dua opsi itu, periksa dulu apakah Anda menggunakan SP / CU terbaru.

Thomas Costers
sumber