Мониторинг блокировок MSSQL SERVER на PowerShell

Административные скрипты MS SQL > Мониторинг блокировок MSSQL SERVER на PowerShell
10.09.2014 15:33:22


Наиболее часто встречающиеся слова в статье:

[ListView] [Windows] [SubItems] [Columns] [new-object] [New-Object] [TextBoxResult] [PanelView] [PanelButton] [controls]


Статья:

#Строка коннекции к БД (в данном случае с Windows-авторизацией)
$ConnectionString="Data Source='(local)';Integrated Security=SSPI;"

#Ниже СКЛ-авторизация (для примера)
#Data Source='(local)';User='Login';password='Password';")

#Основной запрос к Серверу БД, для получения списка процессов
$Query=
"
select
spid,
blocked,
db_name(dbid) db,
cmd,
status,
hostname,
program_name,
loginame,
waittime, cpu, physical_io, MemUsage,
isnull((select text from sys.dm_exec_sql_text(sql_handle)),'') sql
from master.dbo.sysprocesses
--where blocked!=0
order by spid
"

#Создаём коннекцию
$SQLConnection = new-object System.Data.SqlClient.SqlConnection($ConnectionString)
#Идентификатор сессии, изначально=0
$spid=0

#Функция для заполнения таблицы
function GetProcesses
{
$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($Query, $SQLConnection)
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet);
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$reader=$SQLCommand.ExecuteReader()

$ListView.Items.Clear()
while ($reader.Read())
{
$item=new-object Windows.Forms.ListViewItem
$item.Text=$reader[0]
[void]$item.SubItems.Add($reader[1])
[void]$item.SubItems.Add($reader[2])
[void]$item.SubItems.Add($reader[3])
[void]$item.SubItems.Add($reader[4])
[void]$item.SubItems.Add($reader[5])
[void]$item.SubItems.Add($reader[6])
[void]$item.SubItems.Add($reader[7])
[void]$item.SubItems.Add($reader[8])
[void]$item.SubItems.Add($reader[9])
[void]$item.SubItems.Add($reader[10])
[void]$item.SubItems.Add($reader[11])
[void]$item.SubItems.Add($reader[12])
#Подкрашиваем красным строки у которых blocked<>0
if ($reader[1] -ne 0)
{ $item.ForeColor="Red"}
[void]$ListView.Items.Add($item)
}

$SQLConnection.Close()
$ListView.Refresh()
#Время последнего считывания данных из БД потаймеру
$Time.Text="Last Update: $((Get-Date).ToString())"
}

#Функция удаления сессии
function KillProcess ($id)
{
$QueryKill="kill $id"

$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($QueryKill, $SQLConnection)
$SQLCommand.ExecuteNonQuery()
$SQLConnection.Close()
}

[void][reflection.assembly]::LoadWithPartialName("System.Data.Sql")
[void][reflection.assembly]::LoadWithPartialName("System.Data.SqlClient")
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$timer = new-object Windows.Forms.Timer
#Значение (в мс), через которое автоматически обновляется таблица (в данном случае раз в 10 секунд)
$timer.Interval=10000

#Создаём форму
$form = new-object Windows.Forms.Form
$form.Text = "SQL Server Locks"
$form.WindowState="Maximized"
$form.startposition = "CenterScreen"
$form.autosize = 0

#add a PanelLocs
$PanelLocks = new-object Windows.Forms.Panel
$PanelLocks.Location = New-Object System.Drawing.Size(0,0)
$PanelLocks.Dock="Fill"

#add a PanelView
$PanelView = new-object Windows.Forms.Panel
$PanelView.Location = New-Object System.Drawing.Size(0,200)
$PanelView.Height=100
$PanelView.Dock="Bottom"

#add a Scroll
$Scroll = new-object Windows.Forms.Splitter
$Scroll.Location = New-Object System.Drawing.Size(0,190)
$Scroll.Dock="Bottom"

#add a PanelButton
$PanelButton = new-object Windows.Forms.Panel
$PanelButton.Location = New-Object System.Drawing.Size(0,0)
$PanelButton.Width=100
$PanelButton.BorderStyle="Fixed3D"
$PanelButton.Dock="Right"

# add a TextBoxResult
$TextBoxResult = new-object Windows.Forms.TextBox
$TextBoxResult.Location = New-Object System.Drawing.Size(0,0)
$TextBoxResult.Multiline="true"
$TextBoxResult.Dock="Fill"
$TextBoxResult.ScrollBars="Vertical"

#add a button
$button = new-object Windows.Forms.button
$button.Location = New-Object System.Drawing.Size(5,5)
$button.text = "Kill"
$button.width = 90
#Удаляем сессию по нажатию на кнопку "Kill"
$button.add_click({
KillProcess $spid
GetProcesses
})

# add a TreeView
$ListView = new-object Windows.Forms.ListView
$ListView.Location = New-Object System.Drawing.Size(0,0)
$ListView.Dock="Fill"
$ListView.FullRowSelect="True"
$ListView.View="Details"
$ListView.Columns.Add("SPID", 50)
$ListView.Columns.Add("Blocked", 50)
$ListView.Columns.Add("DB", 60)
$ListView.Columns.Add("CMD", 100)
$ListView.Columns.Add("Status", 80)
$ListView.Columns.Add("HostName", 80)
$ListView.Columns.Add("ProgramName", 120)
$ListView.Columns.Add("LoginName", 100)
$ListView.Columns.Add("WaitTime", 80)
$ListView.Columns.Add("CPU", 80)
$ListView.Columns.Add("Physical IO", 80)
$ListView.Columns.Add("MemUsage", 80)
$ListView.Columns.Add("SQL", 200)

#Выводим текст запроса в выбранной сессии в таблице
$ListView.Add_ItemSelectionChanged({
$TextBoxResult.Clear()
$TextBoxResult.Text=$this.items[$_.itemindex].SubItems[12].Text
$spid=$this.items[$_.itemindex].Text
}
)

#add a statusStrip
$statusStrip = new-object System.Windows.Forms.StatusStrip
$Time = new-object System.Windows.Forms.ToolStripStatusLabel
$Time.Text="Last Update: "
[void]$statusStrip.Items.add($Time)

#По таймеру обновляем табличку
$timer.add_Tick({GetProcesses})
$timer.Start()

$form.controls.add($scroll)
$form.controls.add($PanelView)
$PanelView.controls.add($PanelButton)
$PanelView.controls.add($TextBoxResult)
$PanelButton.controls.add($button)
$form.controls.add($PanelLocks)
$PanelLocks.controls.add($ListView)
$form.controls.add($statusStrip)

GetProcesses
$form.Add_Shown({$form.Activate()})
$form.ShowDialog()