Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Statistik Penantian Lutut :SOS_SCHEDULER_YIELD

Dalam posting saya sebelumnya, saya membahas LCK_M_XX, ASYNC_NETWORK_IO, dan OLEDB menunggu dan reaksi spontan terhadap mereka. Dalam posting ini saya akan melanjutkan dengan tema statistik menunggu dan membahas penantian SOS_SCHEDULER_YIELD.

Ketika SOS_SCHEDULER_YIELD adalah yang paling umum di server, penggunaan CPU yang tinggi dan berkelanjutan adalah hal yang biasa. Reaksi spontan di sini adalah server harus berada di bawah tekanan CPU, atau spinlock adalah masalahnya.

Kami membutuhkan sedikit latar belakang di sini untuk memahami dua reaksi ini.

Penjadwalan Thread

Penjadwalan utas di SQL Server dikelola oleh SQL Server itu sendiri, bukan oleh Windows (yaitu non-preemptive). Bagian SQL OS dari Storage Engine menyediakan fungsionalitas penjadwalan dan transisi utas dari berjalan di Prosesor (di mana status utas MENJALANKAN) menjadi di Daftar Pelayan menunggu sumber daya tersedia (status DITANGGUHKAN) menjadi di Runnable Antrian setelah sumber daya tersedia (status RUNNABLE) menunggu untuk mencapai puncak antrean dan kembali ke Prosesor lagi (kembali ke status MENJALANKAN). Saya telah menggunakan huruf kapital pada Prosesor, Daftar Pelayan, dan Antrian yang Dapat Dijalankan untuk mengidentifikasinya sebagai bagian dari penjadwal.

Setiap kali sebuah utas membutuhkan sumber daya yang tidak dapat segera diperolehnya, itu menjadi ditangguhkan dan menunggu di Daftar Pelayan untuk diberi tahu (diberi sinyal) bahwa sumber dayanya tersedia. Waktu yang dihabiskan di Waiter List adalah waktu tunggu sumber daya dan waktu yang dihabiskan di Runnable Queue adalah waktu tunggu sinyal. Bersama-sama mereka bergabung menjadi waktu tunggu keseluruhan. SQL OS melacak waktu tunggu dan waktu tunggu sinyal sehingga kita harus menghitung output dari sys.dm_os_wait_stats untuk mendapatkan waktu tunggu sumber daya (lihat skrip saya di sini).

Daftar Pelayan tidak berurutan (utas apa pun di dalamnya dapat diberi sinyal kapan saja dan pindah ke Antrian yang Dapat Dijalankan) dan Antrian yang Dapat Dijalankan adalah First-In-First-Out (FIFO) hampir 100% setiap saat. Satu-satunya pengecualian untuk Antrian yang Dapat Dijalankan adalah FIFO adalah di mana beberapa kelompok beban kerja Gubernur Sumber Daya telah dikonfigurasi dalam kumpulan sumber daya yang sama dan mereka memiliki prioritas yang berbeda relatif satu sama lain. Saya belum pernah melihat ini berhasil digunakan dalam produksi jadi saya tidak akan membahasnya lebih lanjut.

Ada alasan lain mengapa utas mungkin perlu dipindahkan dari Prosesor – ia menghabiskan kuantumnya. Kuantum utas dalam SQL OS diperbaiki pada 4 milidetik. Utas itu sendiri bertanggung jawab untuk menentukan bahwa kuantumnya telah habis (dengan memanggil rutinitas pembantu di SQL OS) dan secara sukarela menyerahkan prosesor (dikenal sebagai menghasilkan). Ketika ini terjadi, utas bergerak langsung ke bagian bawah Antrian yang Dapat Dijalankan, karena tidak ada yang menunggu. SQL OS harus mendaftarkan tipe tunggu untuk transisi ini dari Prosesor, dan mendaftarkan SOS_SCHEDULER_YIELD.

Perilaku ini sering disalahartikan sebagai tekanan CPU, tetapi sebenarnya tidak – hanya penggunaan CPU yang berkelanjutan. Tekanan CPU, dan mengenalinya, adalah topik lain untuk posting mendatang. Sejauh menyangkut postingan ini, selama waktu tunggu sinyal rata-rata rendah (0-0,1-0,2 md), cukup aman bahwa tekanan CPU tidak menjadi masalah.

Spinlock

Spinlock adalah primitif sinkronisasi tingkat sangat rendah yang digunakan untuk menyediakan akses thread-safe ke struktur data di SQL Server yang sangat panas (sangat fluktuatif dan diakses dan sangat sering diubah oleh banyak utas). Contoh struktur tersebut adalah daftar bebas buffer di setiap bagian kumpulan buffer dan array pembobotan proporsional-isi untuk file data dalam filegroup.

Ketika sebuah utas perlu memperoleh spinlock, ia melihat apakah spinlock itu gratis dan jika demikian segera memperolehnya (menggunakan primitif bahasa rakitan yang saling terkait seperti 'test bit clear and set'). Jika spinlock tidak dapat diperoleh, utas segera mencoba untuk mendapatkannya lagi, dan lagi, dan lagi, hingga seribu iterasi, hingga mundur (tidur sebentar). Ini tidak terdaftar sebagai jenis tunggu apa pun, karena utas hanya memanggil fungsi Windows sleep() , tetapi dapat membuat utas lain yang menunggu memiliki waktu tunggu sinyal yang besar (10-20 ms+) karena utas tidur tetap berada di prosesor hingga mendapatkan spinlock.

Mengapa saya berbicara tentang spinlock? Karena mereka juga dapat menjadi penyebab penggunaan CPU yang tinggi, dan ada kesalahpahaman bahwa spinlock adalah penyebab SOS_SCHEDULER_YIELD menunggu. Mereka tidak.

Penyebab SOS_SCHEDULER_YIELD

Jadi, ada satu penyebab SOS_SCHEDULER_YIELD:thread yang menghabiskan kuantum penjadwalannya dan instance yang sangat berulang dapat menyebabkan SOS_SCHEDULER_YIELD menjadi penantian paling umum bersama dengan penggunaan CPU yang tinggi.

Anda tidak akan melihat SOS_SCHEDULER_YIELD menunggu muncul di output dari sys.dm_os_waiting_tasks, karena utasnya tidak menunggu. Anda dapat melihat kueri mana yang menghasilkan SOS_SCHEDULER_YIELD menunggu dengan menanyakan sys.dm_exec_requests dan memfilter pada kolom last_wait_type.

Ini juga berarti bahwa ketika Anda melihat SOS_SCHEDULER_YIELD dalam keluaran sys.dm_os_wait_stats, tunggu sumber daya akan menjadi nol, karena tidak benar-benar menunggu. Namun ingat bahwa setiap 'menunggu' ini sama dengan 4 mdtk waktu CPU yang diperoleh untuk kueri.

Satu-satunya cara untuk membuktikan apa yang menyebabkan SOS_SCHEDULER_YIELD menunggu adalah dengan menangkap tumpukan panggilan SQL Server saat jenis menunggu itu terjadi, menggunakan Peristiwa yang Diperpanjang dan simbol debug dari Microsoft. Saya memiliki postingan blog yang menjelaskan dan menunjukkan cara melakukan investigasi tersebut, dan ada buku putih yang bagus tentang spinlocks dan investigasi spinlock yang layak dibaca jika Anda tertarik dengan kedalaman internal tersebut.

Untuk kasus kelelahan kuantum, itu bukan akar masalahnya. Ini adalah gejala lebih lanjut. Sekarang kita perlu mempertimbangkan mengapa utas mungkin menghabiskan kuantumnya berulang kali.

Sebuah utas hanya dapat menghabiskan kuantumnya ketika dapat terus memproses kode SQL Server selama 4 ms tanpa memerlukan sumber daya yang dimiliki utas lain – tidak perlu menunggu kunci, kait halaman, halaman file data untuk dibaca dari disk, alokasi memori, pertumbuhan file, logging , atau berbagai sumber daya lain yang mungkin dibutuhkan oleh sebuah utas.

Bagian paling umum dari kode di mana kelelahan kuantum dapat terjadi dan mengumpulkan sejumlah besar SOS_SCHEDULER_YIELD menunggu adalah memindai indeks/tabel di mana semua halaman file data yang diperlukan berada di memori dan tidak ada pertentangan untuk akses ke halaman tersebut, dan itulah yang Saya mendorong Anda untuk mencari dalam rencana kueri ketika Anda melihat SOS_SCHEDULER_YIELD sebagai jenis menunggu teratas – pemindaian indeks/tabel yang besar dan/atau berulang.

Ini tidak berarti saya mengatakan bahwa pemindaian besar itu buruk, karena bisa jadi cara paling efisien untuk memproses beban kerja Anda adalah melalui pemindaian. Namun, jika SOS_SCHEDULER_YIELD menunggu baru dan tidak biasa, dan disebabkan oleh pemindaian besar, Anda harus menyelidiki mengapa rencana kueri menggunakan pemindaian. Mungkin seseorang menjatuhkan indeks nonclustered kritis, atau statistik kedaluwarsa sehingga rencana kueri yang salah dipilih, atau mungkin nilai parameter yang tidak biasa diteruskan ke prosedur tersimpan dan rencana kueri meminta pemindaian, atau perubahan kode terjadi tanpa mendukung penambahan indeks.

Ringkasan

Sama seperti jenis menunggu lainnya, memahami dengan tepat apa yang dimaksud dengan SOS_SCHEDULER_YIELD adalah kunci untuk memahami cara memecahkan masalah, dan apakah perilaku tersebut diharapkan karena beban kerja yang sedang diproses.

Sejauh menyangkut statistik tunggu umum, Anda dapat menemukan informasi lebih lanjut tentang menggunakannya untuk pemecahan masalah kinerja di:

  • Seri posting blog SQLskills saya, dimulai dengan statistik Tunggu, atau tolong beri tahu saya di bagian mana yang sakit
  • Perpustakaan Jenis Tunggu dan Kelas Latch Saya di sini
  • Kursus pelatihan online Pluralsight saya SQL Server:Pemecahan Masalah Kinerja Menggunakan Statistik Tunggu
  • Penasihat Kinerja SQL Sentry

Dalam artikel berikutnya dalam seri ini, saya akan membahas tipe menunggu lain yang merupakan penyebab umum reaksi spontan. Sampai saat itu, selamat memecahkan masalah!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mencegah Serangan Injeksi SQL Dengan Python

  2. Menghapus file jejak dengan ADRCI

  3. Memahami Sistem Output Input Hadoop

  4. Membuat dan Menyebarkan Beberapa Versi Basis Data melalui Cuplikan Skema

  5. Operator SQL EXISTS untuk Pemula