Membuat SQL Server dan PerfMon Friends

Di foto ada adegan dari komedi lama yang baik "Pesawat" - boomer mengingatnya.



Dia tidak di sini karena kebetulan. Namun bermanfaat nantinya.

Dba tidak suka perfmon


Ini tidak sama sekali karena antarmuka PerfMon tidak berubah dengan Windows NT 3.1 (?) Dan mengembalikan kehangatan dua per seribu. Ngomong-ngomong, mungkin seseorang tahu penjelasan untuk fakta aneh ini. Panel kontrol ditulis ulang beberapa kali dalam setahun. Bahkan kalkulator pun ditulis ulang. Tapi bukan perfMon.

DBA berpikir dengan kata-kata penutup. Ketika seorang dokter DBA yang baik tiba di server SQL yang sakit, ia membuka kopernya, dan di dalam koper ada sejumlah besar tempat yang melayani dengan setia. Dia mengambil yang terpendek dari memori. Terkadang DBA dapat melihat metrik PerfMon - disk fisik, atau Panjang Antrian Disk. Namun, DBA nyata akan mendapatkan metrik server SQL sendiri, bukan melalui PerfMon, tetapi dengan tambalan, misalnya, seperti ini:

select * from sys.dm_os_performance_counters 
  where object_name='SQLServer:Buffer Manager' 
    and counter_name like 'Page life expectancy%' 
	and instance_name=''

Saat perwakilan TI, bercerai dari lingkup DBA, tanyakan padanya, "metrik apa yang ingin Anda kumpulkan?" (well, ada semua jenis splunk, squared-up, dll.), maka DBA mulai memikirkan skrip, dan sisanya tentang metrik perfmon. Pada saat yang sama, sebagai aturan, mereka mencoba membuang semua metrik pada DBA. Ketika ini terjadi, gambar tidak berguna dalam kemacetannya. Dan kemudian klip video pendek dari film "Airplane" akan membantu saya .

Akibatnya, DBA menulis keri, yang menulis statistik setiap N menit ke beberapa piring dalam database DBAtasks. Apakah Anda mengenali diri sendiri?

Advokat Iblis (perfmon)


Namun demikian, penghitung perfmon adalah alat standar. Mereka dapat login, mengatur peringatan, tetapi yang paling penting, ada sejumlah besar sistem yang "menggabungkan" metrik-metrik ini dari banyak mesin menjadi repositori terpusat, memungkinkan Anda untuk menganalisis dan membangun grafik yang indah (dan tidak seperti perfmon).

Ternyata kita bisa berteman dengan dunia SQL dan dunia PerfMon!

Di bawah ini saya akan menunjukkan caranya.

Sekarang spesifik akan pergi


Sebagai contoh, kami akan menunjukkan cara mengekspor metrik yang SQL sendiri tidak terbitkan ke PerfMon. Misalnya, kueri di bawah ini:

select
  convert(numeric(10,2),round(((sum(version_store_reserved_page_count)*1.0)/128.00),2)),
  convert(numeric(10,2),round(((sum(user_object_reserved_page_count)*1.0)/128.00),2)),
  convert(numeric(10,2),round(((sum(internal_object_reserved_page_count)*1.0)/128.00),2))
from
  tempdb.sys.dm_db_file_space_usage;

mengembalikan jumlah ruang tempdb yang digunakan oleh versi store (untuk snapshot), objek pengguna (tab #tab dan ##) dan mengurutkan / ruang penyimpanan sementara. Mari buat metrik untuk mereka (18+, tim tidak memiliki dokumen)

dbcc addinstance ('SQLServer:User Settable', 'TempDB version store KB')
dbcc addinstance ('SQLServer:User Settable', 'TempDB user store KB')
dbcc addinstance ('SQLServer:User Settable', 'TempDB sort store KB')

Ini akan membuat tiga metrik dalam SQLServer -> UserSettable -> Query. Metriknya adalah bilangan bulat - int (bukan bigint). Selain itu, maknanya diartikan apa adanya. Artinya, jika Anda membutuhkan delta dari nilai sebelumnya, maka ini adalah urusan Anda. Namun dalam kasus ini, kita hanya perlu memberikan nilai ke metrik:

declare @TEMPDBver int, @TEMPDBuser int, @TEMPDBsort int
select

@TEMPDBver = convert(numeric(10,2),round(((sum(version_store_reserved_page_count) *1.0)/128.00),2)),
@TEMPDBuser = convert(numeric(10,2),round(((sum(user_object_reserved_page_count) *1.0)/128.00),2)),
@TEMPDBsort = convert(numeric(10,2),round(((sum(internal_object_reserved_page_count) *1.0)/128.00),2))
from tempdb.sys.dm_db_file_space_usage;

if @TEMPDBver is not null    
  dbcc setinstance ('SQLServer:User Settable', 'Query', 
    'TempDB version store KB', @TEMPDBver)
if @TEMPDBuser is not null   
  dbcc setinstance ('SQLServer:User Settable', 'Query', 
   'TempDB user store KB', @TEMPDBuser)
if @TEMPDBsort is not null   
  dbcc setinstance ('SQLServer:User Settable', 'Query', 
    'TempDB sort store KB', @TEMPDBsort)

Sebenarnya itu saja. Sekarang panggil saja kode ini secara teratur dan semuanya akan berfungsi.

Penghitung Delta


Sekarang mari kita membuat penghitung delta. Ini akan menjadi batas waktu penguncian dalam ms.

dbcc addinstance ('SQLServer:User Settable', 'LOCK ms per s')

Di sini Anda dapat mengajukan keberatan kepada saya bahwa metrik semacam itu sudah ada:

select * from sys.dm_os_performance_counters 
  where counter_name like 'Lock Wait Time (ms)%' 
    and instance_name='_Total'
    and object_name='SQLServer:Locks'

Tetapi metrik ini akhirnya konsisten. Seperti yang Anda ingat, jika proton tidak stabil, maka setiap basis data di alam semesta pada akhirnya konsisten. Artinya, jika Anda membuat kunci dan melihat nilai metrik ini, maka itu tidak akan tumbuh! Dan hanya pada akhir kunci nilainya akan melonjak tajam selama waktu tunggu penuh. Pada grafik, alih-alih 'dataran tinggi' yang diharapkan, Anda akan mendapatkan puncak yang tajam, yang juga merusak skala Anda di sepanjang sumbu Y.

Masalah yang sama adalah dengan kvery:

select sum(wait_time_ms) 
  from sys.dm_os_wait_stats 
  where wait_type like 'LCK_%'

Oleh karena itu, kita harus menambahkan waktu yang sekarang ke waktu kunci 'selesai':

declare @NEWlock bigint
select @NEWlock=sum(wait_time_ms) 
  from sys.dm_os_wait_stats 
  where wait_type like 'LCK_%' -- finished waits
select @NEWlock=@NEWlock+isnull(sum(waittime),0) 
  from master.dbo.sysprocesses 
  where blocked>0 and lastwaittype like 'LCK_%' -- waits in progress

Pertanyaan ini sudah memberikan dataran tinggi yang benar pada grafik.

Sekarang kita perlu mempertimbangkan delta dari nilai sebelumnya. Ada dua cara:

  • Desain proses sebagai pekerjaan yang sering disebut (katakanlah, sekali per menit). Buat label untuk menyimpan nilai sebelumnya. Bahkan, sering kali buruk untuk menyebut pekerjaan (overhead + kompetisi untuk riwayat pelaksanaan Pekerjaan), dan Anda dapat melakukannya tanpa plat tambahan:
  • Buat proses yang berjalan dalam satu lingkaran tanpa akhir dengan menunggu. Proses mengingat nilai sebelumnya dalam variabel. Kami akan memproses proses tersebut sebagai pekerjaan dengan dua jadwal: saat mulai dan satu jam sekali (jika pekerjaan jatuh, maka akan dimulai kembali)

Dalam kasus kedua, sangat mungkin untuk melakukan siklus setiap lima detik atau bahkan lebih sering. Jadi, kita dapat:

declare @OLDlock bigint, @NEWlock bigint
declare @lock int, @seconds int = 5 -- must match WAITFOR
loop:
  set @OLDlock=@NEWlock -- shift new to old
  select @NEWlock=sum(wait_time_ms) 
    from sys.dm_os_wait_stats 
	where wait_type like 'LCK_%' -- finished waits
  select @NEWlock=@NEWlock+isnull(sum(waittime),0) 
    from master.dbo.sysprocesses 
	where blocked>0 and lastwaittype like 'LCK_%' -- waits in progress
  set @lock=(@NEWlock-@OLDlock)/@seconds -- this is delta
  if @lock is not null    
    dbcc setinstance ('SQLServer:User Settable', 'Query', 
	  'LOCK ms per s', @lock)
  waitfor delay '00:00:05' 
goto loop

Harap dicatat bahwa pertama kali Anda menjalankan loop DBCC, itu akan dilewati (yang benar), karena @OLDlock (dan mengunci) akan menjadi nol.

All Articles