全部产品
Search
文档中心

ApsaraDB RDS:Apa yang harus saya lakukan jika terjadi deadlock pada instance ApsaraDB RDS for SQL Server?

更新时间:Jul 06, 2025

Deskripsi masalah

Deadlock dapat terjadi ketika aplikasi sering membaca atau menulis data ke tabel atau sumber daya pada instance ApsaraDB RDS for SQL Server. Saat deadlock terjadi, instance RDS menghentikan salah satu transaksi dan mengirimkan pesan kesalahan kepada klien yang memulai transaksi tersebut. Pesan kesalahan yang dikirim mirip dengan berikut:

Pesan Kesalahan: Msg 1205, Level 13, State 47, Line 1Transaksi (Process ID 53) mengalami deadlock pada sumber daya kunci bersama dengan proses lain dan telah dipilih sebagai korban deadlock. Jalankan ulang transaksi.

Solusi

  1. Hubungkan ke instance RDS dari klien. Untuk informasi lebih lanjut, lihat Hubungkan ke instance ApsaraDB RDS for SQL Server.

  2. Pantau tampilan terkait.

    1. Jalankan pernyataan SQL berikut untuk memantau tampilan SYS.SYSPROCESSES secara berkala:

      WHILE 1 = 1
      BEGIN
      SELECT * FROM SYS.SYSPROCESSES WHERE BLOCKED <> 0;
      WAITFOR DELAY '[$Time]';
      END;
      Catatan

      [$Time] menentukan interval pemantauan. Dalam contoh ini, digunakan nilai 00:00:01.

      Gambar berikut menunjukkan contoh keluaran:

      image

      Catatan

      Dalam keluaran, kolom blocked menunjukkan ID sesi yang memblokir sesi saat ini, sedangkan kolom waitresource menunjukkan sumber daya yang ditunggu oleh sesi yang diblokir. Pada contoh ini, sesi 53 dan sesi 56 saling memblokir, menyebabkan deadlock. spid menunjukkan ID sesi.

    2. Jalankan pernyataan SQL berikut untuk memantau tampilan sys.dm_tran_locks dan sys.dm_os_waiting_tasks secara berkala:

      while 1=1
          Begin
          SELECT
          db.name DBName,
          tl.request_session_id,
          wt.blocking_session_id,
          OBJECT_NAME(p.OBJECT_ID) BlockedObjectName,
          tl.resource_type,
          h1.TEXT AS RequestingText,
          h2.TEXT AS BlockingText,
          tl.request_mode
          FROM sys.dm_tran_locks AS tl
          INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
          INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
          INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
          INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
          INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
          CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
          CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
          waitfor delay '[$Time]'
          End

      Gambar berikut menunjukkan contoh keluaran:

      image

      Tabel berikut menjelaskan parameter respons:

      Parameter

      Deskripsi

      DBName

      Nama database yang sesi yang diblokir mencoba akses.

      request_session_id

      ID sesi dalam permintaan saat ini. Sesi tersebut adalah sesi yang diblokir.

      blocking_session_id

      ID sesi pemblokiran.

      BlockedObjectName

      Objek yang dikelola oleh sesi yang diblokir.

      resource_type

      Jenis sumber daya yang sesi tunggu.

      RequestingText

      Pernyataan yang dieksekusi dalam sesi. Pernyataan tersebut adalah pernyataan yang diblokir.

      BlockingText

      Pernyataan yang dieksekusi dalam sesi pemblokiran.

      request_mode

      Mode kunci yang diminta oleh sesi.

    3. Jika instance RDS Anda menggunakan SQL Server 2012, Anda juga dapat menggunakan SQL Server Profiler untuk memantau deadlock dan menghasilkan grafik deadlock.

      image

      Gambar berikut menunjukkan grafik deadlock:

      image

Saran optimasi

Anda dapat melakukan langkah-langkah berikut untuk optimasi:

  • Hentikan sesi pemblokiran untuk menyelesaikan masalah pemblokiran.

  • Periksa apakah ada transaksi yang belum dikomit dalam waktu lama. Jika ada, segera komit transaksi tersebut.

  • Jika kueri diblokir karena kunci bersama dan aplikasi Anda mengizinkan dirty read, gunakan petunjuk kueri WITH (NOLOCK). Sebagai contoh, jalankan pernyataan SELECT * FROM table WITH (NOLOCK);. Dengan cara ini, kueri tidak akan mengajukan permohonan kunci untuk mencegah masalah deadlock.

  • Periksa logika aplikasi untuk memastikan akses ke sumber daya dilakukan secara berurutan.

Referensi

Anda dapat melihat deadlock dari instance RDS di Konsol ApsaraDB RDS. Untuk informasi lebih lanjut, lihat Lihat statistik deadlock.