Profesional database secara rutin dihadapkan dengan masalah performa database seperti pengindeksan yang tidak tepat dan kode yang ditulis dengan buruk dalam instance SQL produksi. Misalkan Anda memperbarui transaksi dan SQL Server melaporkan pesan kebuntuan berikut. Untuk DBA yang baru memulai, ini mungkin mengejutkan.
Dalam artikel ini, kita akan menjelajahi kebuntuan SQL Server dan cara terbaik untuk menghindarinya.
Apa itu kebuntuan SQL Server?
SQL Server adalah database yang sangat transaksional. Misalnya, Anda mendukung database untuk portal belanja online tempat Anda menerima pesanan baru dari pelanggan sepanjang waktu. Beberapa pengguna kemungkinan melakukan aktivitas yang sama pada waktu yang sama. Dalam hal ini, database Anda harus mengikuti properti Atomicity, Consistency, Isolation, Durability (ACID) agar konsisten, andal, dan melindungi integritas data.
Gambar di bawah menjelaskan properti ACID dalam database relasional.
Untuk mengikuti properti ACID, SQL Server menggunakan mekanisme penguncian, batasan, dan pencatatan di depan. Berbagai jenis kunci meliputi:kunci eksklusif (X), kunci bersama (S), kunci pembaruan (U), kunci maksud (I), kunci skema (SCH) dan kunci pembaruan massal (BU). Kunci ini dapat diperoleh pada tingkat kunci, tabel, baris, halaman, dan basis data.
Misalkan Anda memiliki dua pengguna, John dan Peter yang terhubung ke database pelanggan.
- John ingin memperbarui catatan pelanggan yang memiliki [nomor pelanggan] 1.
- Pada saat yang sama, Peter ingin mengambil nilai untuk pelanggan yang memiliki [customerid] 1.
Dalam hal ini, SQL Server menggunakan kunci berikut untuk John dan Peter.
Kunci untuk John
- Dibutuhkan kunci intent eksklusif (IX) pada tabel pelanggan dan halaman yang berisi catatan.
- Selanjutnya diperlukan kunci (X) eksklusif pada baris yang ingin diperbarui oleh John. Ini mencegah pengguna lain memodifikasi data baris sampai proses A melepaskan kuncinya.
Kunci untuk Peter
- Ini memperoleh kunci maksud bersama (IS) di tabel pelanggan dan halaman yang berisi catatan sesuai klausa where.
- Ini mencoba mengambil kunci bersama untuk membaca baris. Baris ini sudah memiliki kunci eksklusif untuk John.
Dalam hal ini, Peter harus menunggu sampai John menyelesaikan pekerjaannya dan melepaskan kunci eksklusif. Situasi ini dikenal sebagai pemblokiran.
Sekarang, misalkan dalam skenario lain, John dan Peter memiliki kunci berikut.
- John memiliki kunci eksklusif di meja pelanggan untuk id pelanggan 1.
- Peter memiliki kunci eksklusif di meja pesanan untuk id pelanggan 1.
- John memerlukan kunci eksklusif pada tabel pesanan untuk menyelesaikan transaksinya. Peter sudah memiliki kunci eksklusif di meja pesanan.
- Peter membutuhkan kunci eksklusif di meja pelanggan untuk menyelesaikan transaksinya. John sudah memiliki kunci eksklusif di meja pelanggan.
Dalam hal ini, tidak satu pun dari transaksi dapat dilanjutkan karena setiap transaksi memerlukan sumber daya yang dimiliki oleh transaksi lainnya. Situasi ini dikenal sebagai kebuntuan SQL Server.
Mekanisme pemantauan kebuntuan SQL Server
SQL Server memonitor situasi kebuntuan secara berkala menggunakan thread monitor kebuntuan. Ini memeriksa proses yang terlibat dalam kebuntuan dan mengidentifikasi apakah suatu sesi telah menjadi korban kebuntuan. Ini menggunakan mekanisme internal untuk mengidentifikasi proses korban kebuntuan. Secara default, transaksi dengan jumlah sumber daya paling sedikit yang diperlukan untuk rollback dianggap sebagai korban.
SQL Server membunuh sesi korban sehingga sesi lain dapat memperoleh kunci yang diperlukan untuk menyelesaikan transaksinya. Secara default, SQL Server memeriksa situasi kebuntuan setiap 5 detik menggunakan monitor kebuntuan. Jika mendeteksi kebuntuan, mungkin mengurangi frekuensi dari 5 detik menjadi 100 milidetik tergantung pada terjadinya kebuntuan. Sekali lagi, utas pemantauan akan diatur ulang menjadi 5 detik jika kebuntuan yang sering tidak terjadi.
Setelah SQL Server menghentikan proses sebagai korban kebuntuan, Anda akan menerima pesan berikut. Dalam sesi ini, proses ID 69 menjadi korban kebuntuan.
Dampak penggunaan pernyataan prioritas kebuntuan SQL Server
Secara default, SQL Server menandai transaksi dengan rollback paling murah sebagai korban kebuntuan. Pengguna dapat mengatur prioritas kebuntuan dalam transaksi menggunakan pernyataan DEADLOCK_PRIORITY.
SET DEADLOCK_PRIORITY
Ini menggunakan argumen berikut:
- Rendah:Setara dengan prioritas kebuntuan -5
- Normal:Ini adalah prioritas kebuntuan default 0
- Tinggi:Ini adalah prioritas kebuntuan tertinggi 5.
Kami juga dapat mengatur nilai numerik untuk prioritas kebuntuan dari -10 hingga 10 (total 21 nilai).
Mari kita lihat beberapa contoh pernyataan prioritas kebuntuan.
Contoh 1:
Sesi 1 dengan prioritas kebuntuan:Normal (0)> Sesi 2 dengan prioritas kebuntuan:Rendah (-5)
Korban Kebuntuan: Sesi 2
Contoh 2:
Sesi 1 dengan prioritas kebuntuan:Normal (0)
Korban Kebuntuan: Sesi 1
Contoh 3
Sesi 1 dengan prioritas kebuntuan:-3> Sesi 2 dengan prioritas kebuntuan:-7
Contoh 4:
Sesi 1 dengan prioritas kebuntuan:-5
Korban Kebuntuan: Sesi 1
Grafik kebuntuan adalah representasi visual dari proses kebuntuan, kuncinya dan korban kebuntuan. Kami dapat mengaktifkan tanda pelacakan 1204 dan 1222 untuk menangkap informasi detail kebuntuan dalam format XML dan grafis. Kami dapat menggunakan acara diperpanjang system_health default untuk mendapatkan detail kebuntuan. Cara cepat dan mudah untuk menginterpretasikan kebuntuan adalah melalui grafik kebuntuan. Mari simulasikan kondisi kebuntuan dan lihat grafik kebuntuan yang sesuai.
Untuk demonstrasi ini, kami membuat tabel Pelanggan dan Pesanan dan menyisipkan beberapa catatan sampel.
Kemudian, kami membuka jendela kueri baru dan mengaktifkan tanda pelacakan secara global.
DBCC traceon(1222,-1)
Setelah kami mengaktifkan tanda deadlock trace, kami memulai dua sesi dan mengeksekusi kueri dalam urutan di bawah ini:
Dalam contoh ini, SQL Server memilih korban kebuntuan (ID sesi 65) dan mematikan transaksi. Mari ambil grafik kebuntuan dari sesi acara diperpanjang system_health.
Kueri ini memberi kita XML kebuntuan yang membutuhkan DBA berpengalaman untuk menginterpretasikan informasi.
Kami menyimpan XML kebuntuan ini menggunakan ekstensi .XDL dan ketika kami membuka file XDL di SSMS, kami mendapatkan grafik kebuntuan yang ditunjukkan di bawah ini.
Grafik kebuntuan ini memberikan informasi berikut:
Ini mewakili korban kebuntuan dengan mencoret oval di grafik kebuntuan.
Anda dapat menangkap informasi kebuntuan SQL Server dengan cara berikut:
1) Kebuntuan pencarian bookmark
Pencarian bookmark adalah kebuntuan yang umum ditemukan di SQL Server. Itu terjadi karena konflik antara pernyataan pilih dan pernyataan DML (masukkan, perbarui, dan hapus). Biasanya, SQL Server memilih pernyataan pilih sebagai korban kebuntuan karena tidak menyebabkan perubahan data dan rollback cepat. Untuk menghindari pencarian bookmark, Anda dapat menggunakan indeks penutup. Anda juga dapat menggunakan petunjuk kueri NOLOCK dalam pernyataan pilih, tetapi petunjuk tersebut membaca data yang tidak dikomit.
2) Kebuntuan pemindaian jarak
Terkadang, kami menggunakan tingkat isolasi SERIALIZABLE di tingkat server atau tingkat sesi. Ini adalah tingkat isolasi terbatas untuk kontrol konkurensi dan dapat membuat kunci pemindaian rentang alih-alih kunci tingkat halaman atau baris. Dalam tingkat isolasi SERIALIZABLE, pengguna tidak dapat membaca data jika diubah tetapi menunggu untuk dilakukan dalam suatu transaksi. Demikian pula, jika suatu transaksi membaca data, transaksi lain tidak dapat mengubahnya. Ini memberikan konkurensi terendah sehingga kita harus menggunakan tingkat isolasi ini dalam persyaratan aplikasi tertentu.
3) Kebuntuan kendala bertingkat
SQL Server menggunakan hubungan induk-anak di antara tabel menggunakan batasan kunci asing. Dalam skenario ini, jika kami memperbarui atau menghapus rekaman dari tabel induk, diperlukan kunci yang diperlukan pada tabel anak untuk mencegah rekaman yatim piatu. Untuk menghilangkan kebuntuan ini, Anda harus selalu mengubah data dalam tabel anak terlebih dahulu diikuti oleh data induk. Anda juga dapat bekerja secara langsung dengan tabel induk menggunakan opsi DELETE CASCADE atau UPDATE CASCADE. Anda juga harus membuat indeks yang sesuai pada kolom kunci asing.
4) Kebuntuan paralelisme intra-kueri
Setelah pengguna mengirimkan kueri ke mesin kueri SQL, pengoptimal kueri akan membuat rencana eksekusi yang dioptimalkan. Itu dapat mengeksekusi kueri dalam urutan serial atau paralel tergantung pada biaya kueri, derajat paralelisme maksimum (MAXDOP) dan ambang batas biaya untuk paralelisme.
Dalam mode paralelisme, SQL Server menetapkan beberapa utas. Terkadang untuk kueri besar dalam mode paralelisme, utas ini mulai saling memblokir. Akhirnya, itu berubah menjadi kebuntuan. Dalam hal ini, Anda perlu meninjau rencana eksekusi dan MAXDOP serta ambang biaya Anda untuk konfigurasi paralelisme. Anda juga dapat menentukan MAXDOP pada tingkat sesi untuk memecahkan masalah skenario kebuntuan.
5) Membalikkan kebuntuan urutan objek
Dalam jenis kebuntuan ini, beberapa transaksi mengakses objek dalam urutan yang berbeda di T-SQL. Ini menyebabkan pemblokiran di antara sumber daya untuk setiap sesi dan mengubahnya menjadi kebuntuan. Anda selalu ingin mengakses objek dalam urutan logis sehingga tidak mengarah ke situasi kebuntuan.
Deadlock adalah mekanisme alami di SQL Server untuk menghindari sesi menahan kunci dan menunggu sumber daya lainnya. Anda harus menangkap kueri kebuntuan dan mengoptimalkannya sehingga tidak bertentangan satu sama lain. Sangat penting untuk menangkap kunci untuk jangka pendek dan melepaskannya, sehingga kueri lain dapat menggunakannya secara efektif.
Kebuntuan SQL Server terjadi, dan sementara SQL Server menangani situasi kebuntuan secara internal, Anda harus mencoba meminimalkannya bila memungkinkan. Beberapa cara terbaik untuk menghilangkan kebuntuan adalah dengan membuat indeks, menerapkan perubahan kode aplikasi, atau memeriksa sumber daya secara cermat dalam grafik kebuntuan. Untuk tips selengkapnya tentang cara menghindari kebuntuan SQL, lihat postingan kami:Menghindari kebuntuan SQL dengan penyetelan kueri.Deadlock SQL Server menggunakan grafik deadlock
CREATE TABLE Customer
(ID INT IDENTITY(1,1), CustomerName VARCHAR(20))
GO
CREATE TABLE Orders
(OrderID INT IDENTITY(1,1), ProductName VARCHAR(50))
GO
INSERT INTO Customer(CustomerName) VALUES ('Rajendra')
Go 100
S INSERT INTO Orders(ProductName) VALUES ('Laptop')
Go 100
SELECT XEvent.query('(event/data/value/deadlock)[1]') AS DeadlockGraph
FROM (
SELECT XEvent.query('.') AS XEvent
FROM (
SELECT CAST(target_data AS XML) AS TargetData
FROM sys.dm_xe_session_targets st
INNER JOIN sys.dm_xe_sessions s
ON s.address = st.event_session_address
WHERE s.NAME = ‘system_health’
AND st.target_name = ‘ring_buffer’
) AS Data
CROSS APPLY TargetData.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]
') AS XEventData(XEvent)
) AS source;
5 jenis kebuntuan di SQL Server
Cara yang berguna untuk menghindari dan meminimalkan kebuntuan SQL Server
Pertimbangan kebuntuan SQL Server