diff --git a/utile/diag_spatiu.ps1 b/utile/diag_spatiu.ps1 index ea4a5ea..1214391 100644 --- a/utile/diag_spatiu.ps1 +++ b/utile/diag_spatiu.ps1 @@ -1,6 +1,7 @@ # diag_spatiu.ps1 - diagnostic de spatiu pe serverul Oracle al unui client ROA. # Raspunde "cat spatiu mai am si ce ocupa unde": tablespace/datafile (cat mai poate creste), -# audit Oracle (tabele + fisiere .aud), alert log/trace/ADR, archivelog/FRA, spatiu pe discurile +# plafonul de date al editiei XE, audit Oracle (tabele + fisiere .aud), alert log/trace/ADR, +# archivelog/FRA, spatiu pe discurile # fizice ale serverului, si alti mancatori de spatiu (recyclebin, UNDO, istoric statistici/ # scheduler, TEMP, top segmente generic - fara nume de tabele ROA hardcodate). # STRICT READ-ONLY pe baza: doar select/agregate si UTL_FILE in mod 'R'. Actiunile de curatare @@ -29,6 +30,12 @@ param( $ErrorActionPreference = 'Stop' +# praguri de alerta, aceleasi ca in PACK_DIAG_SPATIU (jobul zilnic de la clienti): tablespace-ul +# intra in atentie sub pragul absolut SAU sub procentul din maximul lui, ca sa existe timp de reactie +$PragTsMb = 2048 +$PragTsPct = 15 +$PragFraPct = 75 + if (-not (Test-Path $SqlPlus)) { Write-Output ('EROARE: nu gasesc sqlplus la ' + $SqlPlus) exit 1 @@ -173,16 +180,17 @@ select a.tablespace_name, round(a.max_bytes/1048576) mb_max, round(nvl(tf.free_bytes,0)/1048576) mb_liber, round((nvl(tf.free_bytes,0) + a.creste_bytes)/1048576) mb_poate_creste, - case when a.max_bytes > 0 and (nvl(tf.free_bytes,0) + a.creste_bytes) < 1048576 - then 'ATENTIE: MAXBYTES ATINS' end stare + case when a.max_bytes > 0 and (nvl(tf.free_bytes,0) + a.creste_bytes) < + greatest($PragTsMb * 1048576, a.max_bytes * $PragTsPct / 100) + then 'ATENTIE: APROAPE FARA LOC' end stare from agg a, ts_free tf where a.tablespace_name = tf.tablespace_name(+) order by a.tablespace_name; exit "@ -Show-Section -Title '2. SPATIU TABLESPACE (detaliu pe datafile + cat mai poate creste)' -Text ('mb_poate_creste = liber curent + (maxbytes - alocat) - spatiul real disponibil inainte de ORA-01653, nu doar liberul de acum.' + "`n`n" + $r2.Text) +Show-Section -Title '2. SPATIU TABLESPACE (detaliu pe datafile + cat mai poate creste)' -Text ('mb_poate_creste = liber curent + (maxbytes - alocat) - spatiul real disponibil inainte de ORA-01653, nu doar liberul de acum.' + "`n" + ('Prag de atentie: sub ' + $PragTsMb + ' MB ramasi sau sub ' + $PragTsPct + '% din maximul tablespace-ului.') + "`n`n" + $r2.Text) -# tablespace-urile cu maxbytes efectiv atins - top segmente acolo +# tablespace-urile care au trecut pragul de atentie - top segmente acolo $r2m = Invoke-Sql -Sql @" set pagesize 0 linesize 100 trimspool on feedback off heading off with ts_free as ( @@ -196,7 +204,8 @@ select 'TS_ATENTIE|' || a.tablespace_name from agg a, ts_free tf where a.tablespace_name = tf.tablespace_name(+) and a.max_bytes > 0 - and (nvl(tf.free_bytes,0) + a.creste_bytes) < 1048576; + and (nvl(tf.free_bytes,0) + a.creste_bytes) < + greatest($PragTsMb * 1048576, a.max_bytes * $PragTsPct / 100); exit "@ $tsProblema = @($r2m.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('TS_ATENTIE|') } | ForEach-Object { $_.Substring(11) } | Where-Object { $_ -match '^[A-Z0-9_]+$' }) @@ -263,6 +272,45 @@ exit Write-Output $rPdb.Text } +# ---------- 2c. Plafonul de date al editiei XE ---------- +# limita editiei, independenta de maxbytes-ul tablespace-urilor: extinderea poate fi refuzata cu +# ORA-12952 desi tablespace-ul mai are loc +Write-Output '' +Write-Output '===== 2c. PLAFON DE DATE XE =====' +$xeCritic = $false +if ($r1.Text -notmatch 'Express Edition') { + Write-Output 'Sarit - editia nu e Express Edition, nu exista plafon de date pe editie.' +} else { + $xePlafonGb = if ($verMajor -le 10) { 4 } elseif ($verMajor -eq 11) { 11 } else { 12 } + $rXe = Invoke-Sql -Sql @" +set pagesize 0 linesize 200 trimspool on feedback off heading off +select 'XEFOLOSIT|' || round(nvl(sum(f.bytes),0)/1048576, 2) + from dba_data_files f + where f.tablespace_name not in ('SYSTEM','SYSAUX') + and f.tablespace_name not in (select t.tablespace_name from dba_tablespaces t + where t.contents in ('UNDO','TEMPORARY')); +exit +"@ + $xeFolositMb = $null + foreach ($line in ($rXe.Text -split "`r?`n")) { + if ($line.Trim() -match '^XEFOLOSIT\|([\d.]+)$') { $xeFolositMb = [double]$Matches[1] } + } + if ($null -eq $xeFolositMb) { + Write-Output 'Nu am putut masura datele de utilizator (dba_data_files) - vezi erorile de mai sus.' + Write-Output $rXe.Text + } else { + $xePlafonMb = $xePlafonGb * 1024 + $xeLiberMb = $xePlafonMb - $xeFolositMb + $xePragMb = [math]::Max($PragTsMb, $xePlafonMb * $PragTsPct / 100) + $xeCritic = ($xeLiberMb -lt $xePragMb) + Write-Output ('Editie Express, plafon de date ' + $xePlafonGb + ' GB (masurat pe dba_data_files, fara SYSTEM/SYSAUX/UNDO/TEMP).') + Write-Output (' folosit = ' + [math]::Round($xeFolositMb/1024, 2) + ' GB liber pana la plafon = ' + [math]::Round($xeLiberMb, 0) + ' MB') + if ($xeCritic) { + Write-Output ('[ATENTIE] sub pragul de ' + [math]::Round($xePragMb, 0) + ' MB. Cand plafonul e atins, baza refuza extinderea cu ORA-12952 si nu se mai poate face nimic din baza - elibereaza date sau treci pe alta editie.') + } + } +} + # ---------- 3. Audit Oracle ---------- $r3 = Invoke-Sql -Sql @" set pagesize 0 linesize 250 trimspool on feedback off heading off @@ -369,12 +417,12 @@ exit $fraCritic = $false foreach ($line in ($r5c.Text -split "`r?`n")) { if ($line.Trim() -match '^FRAPCT\|([\d.]+)$') { - if ([double]$Matches[1] -ge 80) { $fraCritic = $true } + if ([double]$Matches[1] -ge $PragFraPct) { $fraCritic = $true } } } if ($fraCritic) { Write-Output '' - Write-Output '[ATENTIE] FRA peste 80% pe cel putin un tip de fisier. Daca log_mode=ARCHIVELOG si FRA se umple complet, baza se blocheaza pe scriere (ORA-19809/ORA-00257).' + Write-Output ('[ATENTIE] FRA peste ' + $PragFraPct + '% din spatiul alocat. Daca log_mode=ARCHIVELOG si FRA se umple complet, baza se blocheaza pe scriere (ORA-19809/ORA-00257).') Write-Output 'Ce se poate face fara backup: marire db_recovery_file_dest_size (daca discul are loc) - imediat, fara pierdere.' Write-Output 'Ce NU se face fara backup real: sterge archivelog-uri neaplicate-la-backup ar rupe recuperarea (RMAN DELETE ARCHIVELOG ... BACKED UP 1 TIMES TO DISK, doar daca exista backup real configurat).' } @@ -602,12 +650,15 @@ Show-Section -Title ('7e. TOP ' + $Top + ' SEGMENTE DIN TOATA BAZA (generic, far Write-Output '' Write-Output '===== 8. VERDICT =====' if ($tsProblema.Count -gt 0) { - Write-Output ('Tablespace-uri la limita (maxbytes atins): ' + ($tsProblema -join ', ') + '. Vezi sectiunea 2 pentru top segmente acolo - candidatii de curatare/crestere maxbytes sunt acolo.') + Write-Output ('Tablespace-uri aproape fara loc: ' + ($tsProblema -join ', ') + '. Vezi sectiunea 2 pentru top segmente acolo - candidatii de curatare/crestere maxbytes sunt acolo.') } else { - Write-Output 'Niciun tablespace la limita de maxbytes gasit (sectiunea 2).' + Write-Output ('Niciun tablespace sub pragul de atentie (' + $PragTsMb + ' MB sau ' + $PragTsPct + '% din maxim, sectiunea 2).') +} +if ($xeCritic) { + Write-Output ('Plafonul de date al editiei XE e aproape atins (sectiunea 2c) - la ORA-12952 nu se mai poate face nimic din baza. Prioritate maxima: eliberare de date sau trecere pe alta editie.') } if ($fraCritic) { - Write-Output 'FRA peste 80% pe cel putin un tip de fisier (sectiunea 5b) - risc de blocaj pe scriere daca log_mode=ARCHIVELOG. Prioritate: verifica arhivarea/backup-ul inainte sa se umple complet.' + Write-Output ('FRA peste ' + $PragFraPct + '% din spatiul alocat (sectiunea 5b) - risc de blocaj pe scriere daca log_mode=ARCHIVELOG. Prioritate: verifica arhivarea/backup-ul inainte sa se umple complet.') } Write-Output 'Ordine tipica de curatare (cea mai sigura primul): fisiere .aud vechi din audit_file_dest (sters direct pe disc, fara privilegii DB) -> adrci purge pe alert/trace/incident vechi -> istoric statistici/scheduler (DBMS_STATS.PURGE_STATS / DBMS_SCHEDULER.PURGE_LOG) -> recyclebin -> resize UNDO dupa ce scade activitatea -> curatare SYS.aud$/fga_log$ sau alte tabele interne (cere SYSDBA) -> ca ultima solutie, recreare PDB (export/import).' if (-not $ConnStrSys) {