Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Anatomi kebuntuan SQL Server dan cara terbaik untuk menghindarinya

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

Deadlock SQL Server menggunakan grafik deadlock

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.

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

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:

  • Sesi pertama memulai transaksi untuk memperbarui tabel pelanggan untuk ID pelanggan 1.
  • Sesi kedua memulai transaksi untuk memperbarui tabel pesanan untuk ID pesanan 10.
  • Sesi pertama mencoba memperbarui tabel pesanan untuk ID pesanan yang sama 10. Sesi kedua sudah mengunci baris ini. Sesi 1 diblokir karena penguncian dilakukan oleh sesi 2.
  • Sekarang, untuk sesi 2, kami ingin memperbarui tabel pelanggan untuk ID pelanggan 1. Ini menghasilkan situasi kebuntuan di mana kedua sesi ID 63 dan ID 65 tidak dapat berkembang.

Dalam contoh ini, SQL Server memilih korban kebuntuan (ID sesi 65) dan mematikan transaksi. Mari ambil grafik kebuntuan dari sesi acara diperpanjang system_health.

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;

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:

  • Node proses:  Di oval, Anda mendapatkan informasi terkait proses.
  • Node sumber daya:  Node sumber daya (kotak persegi) memberikan informasi tentang objek yang terlibat dalam transaksi bersama dengan kunci. Dalam contoh ini, ini menunjukkan kunci RID karena kami tidak memiliki indeks untuk kedua tabel.
  • Tepi:  Sebuah tepi menghubungkan node proses dan node sumber daya. Ini menunjukkan pemilik sumber daya dan meminta mode kunci.

Ini mewakili korban kebuntuan dengan mencoret oval di grafik kebuntuan.

Anda dapat menangkap informasi kebuntuan SQL Server dengan cara berikut:

  • Profil SQL Server
  • Acara yang diperluas SQL Server
  • Log kesalahan SQL Server
  • Jejak default di SQL Server

5 jenis kebuntuan di SQL Server

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.

Cara yang berguna untuk menghindari dan meminimalkan kebuntuan SQL Server

  • Cobalah untuk menjaga agar transaksi tetap singkat; ini akan menghindari menahan kunci dalam transaksi untuk jangka waktu yang lama.
  • Mengakses objek dengan cara logis yang sama dalam beberapa transaksi.
  • Buat indeks penutup untuk mengurangi kemungkinan kebuntuan.
  • Buat indeks agar cocok dengan kolom kunci asing. Dengan cara ini, Anda dapat menghilangkan kebuntuan karena integritas referensial berjenjang.
  • Tetapkan prioritas kebuntuan menggunakan variabel sesi SET DEADLOCK_PRIORITY. Jika Anda menetapkan prioritas kebuntuan, SQL Server mematikan sesi dengan prioritas kebuntuan terendah.
  • Gunakan penanganan kesalahan menggunakan blok try-catch. Anda dapat menjebak kesalahan kebuntuan dan menjalankan kembali transaksi jika ada korban kebuntuan.
  • Ubah tingkat isolasi ke READ COMMITTED SNAPSHOT ISOLATION atau SNAPSHOT ISOLATION. Ini mengubah mekanisme penguncian SQL Server. Meskipun demikian, Anda harus berhati-hati dalam mengubah tingkat isolasi, karena dapat berdampak negatif pada kueri lainnya.

Pertimbangan kebuntuan SQL Server

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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. @@IDENTITY, SCOPE_IDENTITY(), OUTPUT dan metode lain untuk mengambil identitas terakhir

  2. Dapatkan Bahasa yang Saat Ini Digunakan di SQL Server

  3. Cara Mendaftar semua Batasan Default dengan Kolom di Database SQL Server - Tutorial SQL Server / TSQL Bagian 92

  4. Cara mendapatkan Daftar Kendala Pemeriksaan Diaktifkan / Dinonaktifkan di Database SQL Server - Tutorial SQL Server / TSQL Bagian 86

  5. Cara Mengonversi String ke Tanggal/Waktu di SQL Server menggunakan PARSE()