Taaskord . Tulevased DBA-d ei saa otse PROD serveritele juurde pÀÀseda, kuid saavad kasutada Jenkins töid piiratud hulga toimingute jaoks. DBA kÀivitab töö ja mÔne aja pÀrast saab ta e-kirja selle operatsiooni tÀitmise kohta. Vaadakem neid tulemusi kasutajale esitamise viise.

Plain Text
Alustame kÔige elementaarsemast. Esimene viis on nii lihtne, et sellest pole tegelikult mÔtet rÀÀkida (autor kasutab allpool FreeStyle töid):

sqlcmd midagi tÀidab, ja me esitame selle kasutajale. Ideaalne nÀiteks backup tööde jaoks:

Ărge unustage, et RDS all on backup/restore asĂŒnkroonne, seega tuleks seda oodata:
declare @rds table
(id int, task_type varchar(128), database_name sysname, pct int, duration int,
lifecycle varchar(128), taskinfo varchar(max) null,
upd datetime, cre datetime,
s3 varchar(256), ovr int, KMS varchar(256) null)
waitfor delay '00:00:20'
insert into @rds exec msdb.dbo.rds_task_status @db_name='{db}'
select @xid=max(id) from @rds
again:
waitfor delay '00:00:02'
delete from @rds
insert into @rds exec msdb.dbo.rds_task_status @db_name='{db}'
# {db} asendatakse powershelli abil andmebaasi nimega
select @stat=lifecycle,@info=taskinfo from @rds where id=@xid
if @stat not in ('ERROR','SUCCESS','CANCELLED') goto againTeine viis, CSV
Siin on kÔik samuti vÀga lihtne:

Kuid see meetod töötab ainult siis, kui CSV-s tagastatavad andmed on "lihtsad". Kui proovite sel viisil tagastada nĂ€iteks TOP N CPU mahukate pĂ€ringute loendi, siis CSV "laguneb", kuna pĂ€ringu tekst vĂ”ib sisaldada erinevaid sĂŒmboleid â komasid, jutumĂ€rke ja isegi reavahetusi. SeetĂ”ttu vajame midagi keerukamat.
Kaunid tabelid HTML-is
TÔin kohe vÀlja koodilÔigu
$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@
$Result = invoke-Sqlcmd -ConnectionString $jstr -Query "select * from DbInv" `
| Select-Object -Property * -ExcludeProperty "ItemArray", "RowError", "RowState", "Table", "HasErrors"
if ($Result -eq $null) { $cnt = 0; }
elseif ($Result.getType().FullName -eq "System.Management.Automation.PSCustomObject") { $cnt = 1; }
else { $cnt = $Result.Rows.Count; }
if ($cnt -gt 0) {
$body = "<h2>Minu tabel</h2>"
$Result | ConvertTo-HTML -Title "Rows" -Head $header -body $body `
| Out-File "res.log" -Append -Encoding UTF8
} else {
"<h3>Andmed puuduvad</h3>" | Out-File "res.log" -Append -Encoding UTF8
}Muide, pöörake tĂ€helepanu reale System.Management.Automation.PSCustomObject, see on maagiline; kui gridis on tĂ€pselt ĂŒks rida, siis tekkisid mingid probleemid. Lahendus on leitud internetist, erilist sĂŒvenemist tegemata. Tulemuseks on ligikaudu selline vormindatud vĂ€ljund:

Joonistame graafikud
TĂ€helepanu: allpool on veider kood!
On olemas naljakas pĂ€ring SQL serveris, mis kuvab CPU viimase N minuti jooksul â selgub, et kapten Major mĂ€letab kĂ”ike! Proovige seda pĂ€ringut:
MÀÀrake @ts_now bigint = (SELECT cpu_ticks/(cpu_ticks/ms_ticks)
FROM sys.dm_os_sys_info WITH (NOLOCK));
SELECT TOP(256)
DATEADD(ms, -1 * (@ts_now - [timestamp]), GETDATE()) AS [EventTime],
SQLProcessUtilization AS [SQLCPU],
100 - SystemIdle - SQLProcessUtilization AS [OtherCPU]
FROM (SELECT record.value('(./Record/@id)[1]', 'int') AS record_id,
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int')
AS [SystemIdle],
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int')
AS [SQLProcessUtilization], [timestamp]
FROM (SELECT [timestamp], CONVERT(xml, record) AS [record]
FROM sys.dm_os_ring_buffers WITH (NOLOCK)
WHERE ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR'
AND record LIKE N'%%') AS x) AS y
ORDER BY 1 DESC OPTION (RECOMPILE);NĂŒĂŒd, kasutades sellist vormindamist (muutuja $Fragment)
<table style="width: 100%"><tbody><tr style="background-color: white; height: 2pt;">
<td style="width: SQLCPU%; background-color: green;"></td>
<td style="width: OtherCPU%; background-color: blue;"></td>
<td style="width: REST%; background-color: #C0C0C0;"></td></tr></tbody>
</table>Saame koostada kirja sisu:
$Result = invoke-Sqlcmd -ConnectionString $connstr -Query $Query `
| Select-Object -Property * -ExcludeProperty `
"ItemArray", "RowError", "RowState", "Table", "HasErrors"
if ($Result.HasRows) {
foreach($item in $Result)
{
$time = $itemEventTime
$sqlcpu = $item.SQLCPU
$other = $itemOtherCPU
$rest = 100 - $sqlcpu - $other
$f = $fragment -replace "SQLCPU", $sqlcpu
$f = $f -replace "OtherCPU", $other
$f = $f -replace "REST", $rest
$f | Out-File "res.log" -Append -Encoding UTF8
}Mis nÀeb vÀlja jÀrgmine:

Jah, hĂ€rra teab tĂ”eliselt, mis on lustakus! Huvitav, et see kood sisaldab: Powershell (millel see on kirjutatud), SQL, Xquery, HTML. Kahju, et HTML-le ei saa lisada Javascripti (kuna see on e-kirja jaoks), kuid Python-koodi lihvimine (mida saab kasutada SQL-is) on igaĂŒhe kohustus!
SQL profiler trace vÀljund
On selge, et trace 'ei pÀÀse' CSV-sse, kuna TextData vĂ€li. Kuid trace'i esitamine gridina kirjas on samuti kummaline â mitte ainult suuruse tĂ”ttu, vaid ka seetĂ”ttu, et neid andmeid kasutatakse sageli edasise analĂŒĂŒsi jaoks. SeetĂ”ttu teeme jĂ€rgmist: kutsume esile invoke-SqlCmd mingi skripti, mille sisu teeb
select
SPID, EventClass, TextData,
Duration, Reads, Writes, CPU,
StartTime, EndTime, DatabaseName, HostName,
ApplicationName, LoginName
from ::fn_trace_gettable ( @filename , default ) Edasi, sĂ”braga serveril, kergesti kĂ€tte saadaval DBA-le, on olemas Traces andmebaas tĂŒhi vorm, tabeliga Model, mis on valmis vĂ”tma kĂ”ik nimetatud veerud. Me kopeerime selle mudeli uude tabelisse unikaalse nimega:
$dt = Get-Date -format "yyyyMMdd"
$tm = Get-Date -format "hhmmss"
$tableName = $srv + "_" + $dt + "_" + $tm
$copytab = "select * into " + $tableName + " from Model"
invoke-SqlCmd -ConnectionString $tstr -Query $copytab Ja nĂŒĂŒd saame me sinna salvestada meie trace'i abil Data.SqlClient.SqlBulkCopy â nĂ€ide sellest olen juba varem toonud. Jah, oleks hea teha masking konstante TextData-s:
# mask data
foreach ($Row in $Result)
{
$v = $Row["TextData"]
$v = $v -replace "'([^']{2,})'", "'str'" -replace "[0-9][0-9]+", '999'
$Row["TextData"] = $v
}
Asendame numbrid, mis on pikemad kui ĂŒhe tegelasega, 999-ga, ja stringid, mis on pikemad kui ĂŒks tegelane, asendame 'str'-iga. Numbrid vahemikus 0 kuni 9 kasutatakse sageli lipukestena ja me ei puutu neid, samuti tĂŒhjad ja ĂŒhesuguste pikkustega stringid â nende seas on sageli 'Y', 'N' jne.
Lisame vÀrve meie ellu (tÔsiselt 18+)
Tabelites tahame sageli esile tĂ”sta rakke, mis vajavad tĂ€helepanu. NĂ€iteks FAILS, kĂ”rge fragmentatsiooni tase jne. Muidugi saab seda teha ka puhta SQL-iga, genereerides HTML-i PRINT-i kaudu, ja Jenkinsis mÀÀrata failitĂŒĂŒbiks HTML:
deklareeri @body varchar(max), @chunk varchar(max)
määratle @body='<font face="Lucida Console" size="3">'
määra @body=@body+'<b>Serveri nimi: '+@@servername+'</b><br>'
määra @body=@body+'<br><br>'
määra @body=@body+'<table><tr><th>Töö</th><th>Viimane käivitamine</th><th>Keskmine kestus, sek</th><th>Viimane käivitamine, sek</th><th>Viimane olek</th></tr>'
print @body
DECLARE tab CURSOR FOR SELECT '<tr><td>'+name+'</td><td>'+
ViimaneKäivitamine+'</td><td>'+
convert(varchar,KeskmineKestus)+'</td><td>'+
convert(varchar,ViimaneKestus)+'</td><td>'+
case when ViimaneOlek<>'Õnnestus' then '<font color="red">' else '' end+
ViimaneOlek+
case when ViimaneOlek<>'Õnnestus' then '</font>' else '' end+
+'</td><td>'
from #j2
OPEN tab;
FETCH NEXT FROM tab into @chunk
WHILE @@FETCH_STATUS = 0
BEGIN
print @chunk
FETCH NEXT FROM tab into @chunk;
END
CLOSE tab;
DEALLOCATE tab;
print '</table>'
Miks ma kirjutasin sellise koodi?

Aga on ilusam lahendus. ConvertTo-HTML ei anna meile rakke vĂ€rvata, kuid saame seda teha hilisema protsessina. NĂ€iteks tahame esile tĂ”sta rakke, mille fragmentatsiooni tase on ĂŒle 80 ja 90. Lisame stiilid:
.SQLmarkup-red { color: red; background-color: yellow; }
.SQLmarkup-yellow { color: black; background-color: #FFFFE0; }
.SQLmarkup-default { color: black; background-color: white; }KĂŒsimuses lisame vale veeru otse enne veergu, mida tahame vĂ€rvida. Veeru nimi peab olema SQLmarkup-midagi:
case
when ps.avg_fragmentation_in_percent>=90.0 then 'SQLmarkup-red'
when ps.avg_fragmentation_in_percent>=80.0 then 'SQLmarkup-yellow'
else 'SQLmarkup-default'
end as [SQLmarkup-1],
ps.avg_fragmentation_in_percent, NĂŒĂŒd, pĂ€rast Powershelli loodud HTML-i saamist, eemaldame pealkirjast vale veeru ja toome andmete kehas vÀÀrtuse veerust stiili. See toimub kĂ”igest kahe asendusega:
$html = $html `
-asenda "<th>SQLmarkup[^<]*</th>", "" `
-asenda "<td>SQLmarkup-(.+?)</td><td>",'<td class="SQLmarkup-$1">'
Tulemus:

Ei ole tÔsi, et see vÀrvigraafika mulle meenutab

Allikas: habr.com
