diff --git a/docs/depanare-spatiu-oracle.md b/docs/depanare-spatiu-oracle.md index e36b97c..dc77a2c 100644 --- a/docs/depanare-spatiu-oracle.md +++ b/docs/depanare-spatiu-oracle.md @@ -20,7 +20,19 @@ cu `diag_spatiu.ps1`; **email doar la prag depasit**, tacere completa altfel. Su `COMUN\docs\PACK_DIAG_SPATIU.pck`. Sectiunile informative (recyclebin, UNDO, TEMP, istoric statistici/scheduler, top segmente, audit -SYS, disc) se scriu doar cand exista deja o alerta — dau context, nu alerteaza singure. +SYS) se scriu doar cand exista deja o alerta — dau context, nu alerteaza singure. + +`co_2026_08_20_01_DIAG_SPATIU_PACK` (20.08.2026) inchide doua gauri prin care o baza blocata putea +sa nu alerteze niciodata: + +- **tablespace fara autoextend**: `dba_data_files.maxbytes` e 0, iar conditia `max_bytes > 0` il + scotea complet din verificare, oricat de plin ar fi fost. Acum plafonul e + `GREATEST(maxbytes, bytes)`, deci pentru un datafile fix maximul e chiar spatiul alocat. In log, + maximul 0 se scrie `fara autoextend`, nu `0MB`. +- **disc plin sub datafile autoextensibil**: tablespace-ul arata zeci de GB "poate creste", dar + autoextend-ul pica. Sectiunea `DISC` are prag propriu (`tnPragDiscMb`, implicit 2048 MB liberi) si + ruleaza mereu, prima; alerta ei deschide si sectiunile informative (`Verifica` o primeste prin + `tnAlerteInitiale`). Inainte rula doar daca exista deja o alerta, deci nu putea declansa una. `co_2026_08_06_08_DIAG_SPATIU_PACK` + `sys_2026_08_06_07_DIAG_SPATIU_GRANT3` (06.08.2026) scriu la top segmente si **tabela/coloana din care provine segmentul** (`DetaliuSegment`: `DBA_LOBS`, @@ -87,6 +99,15 @@ Emailurile ajung pe `marius.mutu@romfast.ro`, cate un expeditor per client - **ROA_CENTRAL** (`ORA-65114`, 02.08.2026): acelasi tipar, rezolvat prin curatenie tintita in loc de recreare PDB; SQL-uri gata scrise in acelasi repo (`docs/curatenie-spatiu-oracle.sql`). - **SIGMA** (03.08.2026): `SYSTEM` plafonat la 600 MB — vezi `depanare-pack-update.md`. +- **VADECO** (XE 11.2, 20.08.2026): actualizarea a picat cu `ORA-00604` + `ORA-01654: unable to + extend index SYS.I_IDL_CHAR1 in tablespace SYSTEM` la un `create package body` — eroarea n-are + legatura cu scriptul: `IDL_CHAR$` e locul unde Oracle scrie codul PL/SQL. `SYSTEM` era 600 MB + alocat cu `maxsize` tot 600 MB (autoextend pornit, dar la plafon), din care ~207 MB doar + `SOURCE$`/`IDL_*` si 41 MB `SYS.INFO`. Deblocare: `alter database datafile '...\SYSTEM.DBF' + autoextend on next 50m maxsize 2048m` (pe XE plafonul de 11 GB e pe date utilizator, nu pe + `SYSTEM`), apoi reluarea actualizarii si `sys_2026_08_08_02` pentru `SYS.INFO`. Jobul de + diagnostic n-ar fi ajutat: batch-ul murise inainte de `co_2026_08_03_02/03/04`, deci nu era + instalat. ## Capcane diff --git a/utile/context_watch.ps1 b/utile/context_watch.ps1 index 78e1745..ca75f82 100644 --- a/utile/context_watch.ps1 +++ b/utile/context_watch.ps1 @@ -4,13 +4,16 @@ # - ca hook (PostToolUse): primeste pe stdin JSON-ul hook-ului, cu transcript_path; # - manual: powershell -File context_watch.ps1 [-TranscriptPath ] [-Prag 250000] # Iese cu 2 si scrie pe stderr cand contextul depaseste pragul (asa ajunge mesajul la agent). +# -OSinguraData: emite o singura data per prag per sesiune (marcaj in %TEMP%). Necesar pe PostToolUse, +# altfel mesajul s-ar repeta la fiecare apel de tool si ar deveni zgomot ignorat. [CmdletBinding()] param( [string]$TranscriptPath, [int]$Prag = 250000, [int]$PragMax = 275000, [switch]$Intotdeauna, - [switch]$Stdout # UserPromptSubmit: mesajul se scrie pe stdout si se iese cu 0 + [switch]$Stdout, # UserPromptSubmit: mesajul se scrie pe stdout si se iese cu 0 + [switch]$OSinguraData # PostToolUse: o singura alerta per prag atins, nu la fiecare tool ) if (-not $TranscriptPath) { @@ -50,12 +53,30 @@ foreach ($camp in @('input_tokens', 'cache_creation_input_tokens', 'cache_read_i $k = [Math]::Round($total / 1000) $mesaj = '' +$nivel = '' if ($total -ge $PragMax) { - $mesaj = "CONTEXT ${k}k - peste limita de $([Math]::Round($PragMax/1000))k (regula 9): scrie handoff-ul in docs\progres.md si preda sesiunea acum." + $nivel = 'max' + $mesaj = "CONTEXT ${k}k - PESTE LIMITA de $([Math]::Round($PragMax/1000))k. REGULA ZERO, predare OBLIGATORIE ACUM: " + + "(1) opreste lucrul, nu incepe nimic nou, adu editarile in curs la o stare consistenta pe disc; " + + "(2) scrie handoff-ul PE DISC in docs\handoff_.md (nu doar in mesaj) - inventar livrabile cu fisier:linie, " + + "ce e terminat si ce nu, DACA write-back-ul e facut per fisier, comanda de rulare a testelor, ce s-a stabilit deja, " + + "ce e interzis, starea datelor de test, capcanele de mediu; " + + "(3) confirma in doua randuri ce ramane si ce e intr-o stare periculoasa; (4) preda unei sesiuni noi. " + + "'Mai am putin' nu e motiv de amanare." } elseif ($total -ge $Prag) { - $mesaj = "CONTEXT ${k}k - peste $([Math]::Round($Prag/1000))k (regula 9): actualizeaza docs\progres.md si pregateste predarea; deleaga la subagenti ce mai ai de citit/testat." + $nivel = 'avertisment' + $mesaj = "CONTEXT ${k}k - peste $([Math]::Round($Prag/1000))k. REGULA ZERO: incheie blocul curent, actualizeaza handoff-ul pe disc " + + "(docs\handoff_.md / docs\progres.md) si pregateste predarea. Deleaga la subagenti tot ce mai ai de citit sau de testat - " + + "nu citi loguri brute si nu diagnostica prin citire de cod in sesiunea asta." } if ($mesaj) { + if ($OSinguraData -and $nivel) { + # marcaj per sesiune+prag: transcriptul identifica sesiunea, deci si numele fisierului de marcaj + $cheie = [IO.Path]::GetFileNameWithoutExtension($TranscriptPath) + '_' + $nivel + $marcaj = Join-Path $env:TEMP "claude_ctxwatch_$cheie.flag" + if (Test-Path $marcaj) { exit 0 } + New-Item -ItemType File -Path $marcaj -Force | Out-Null + } if ($Stdout) { Write-Output $mesaj; exit 0 } [Console]::Error.WriteLine($mesaj) exit 2 diff --git a/utile/diag_spatiu.ps1 b/utile/diag_spatiu.ps1 index 1214391..835bd3a 100644 --- a/utile/diag_spatiu.ps1 +++ b/utile/diag_spatiu.ps1 @@ -174,21 +174,29 @@ with ts_free as ( sum(greatest(f.maxbytes - f.bytes, 0)) creste_bytes from dba_data_files f group by f.tablespace_name +), calc as ( + select a.tablespace_name, a.alocat_bytes, a.max_bytes, + nvl(tf.free_bytes,0) free_bytes, + nvl(tf.free_bytes,0) + a.creste_bytes creste_total_bytes, + greatest(a.max_bytes, a.alocat_bytes) limita_bytes + from agg a, ts_free tf + where a.tablespace_name = tf.tablespace_name(+) ) -select a.tablespace_name, - round(a.alocat_bytes/1048576) mb_alocat, - 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) < - greatest($PragTsMb * 1048576, a.max_bytes * $PragTsPct / 100) +select c.tablespace_name, + round(c.alocat_bytes/1048576) mb_alocat, + round(c.max_bytes/1048576) mb_max, + round(c.free_bytes/1048576) mb_liber, + round(c.creste_total_bytes/1048576) mb_poate_creste, + case when c.limita_bytes > 0 and c.creste_total_bytes < + case when c.limita_bytes <= $PragTsMb * 1048576 + then c.limita_bytes * $PragTsPct / 100 + else greatest($PragTsMb * 1048576, c.limita_bytes * $PragTsPct / 100) end 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; + from calc c + order by c.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" + ('Prag de atentie: sub ' + $PragTsMb + ' MB ramasi sau sub ' + $PragTsPct + '% din maximul tablespace-ului.') + "`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; pe cele cu maximul sub prag (UNDO, SYSTEM mic) doar procentul, iar la datafile fara autoextend maximul e chiar spatiul alocat.') + "`n`n" + $r2.Text) # tablespace-urile care au trecut pragul de atentie - top segmente acolo $r2m = Invoke-Sql -Sql @" @@ -196,16 +204,24 @@ set pagesize 0 linesize 100 trimspool on feedback off heading off with ts_free as ( select tablespace_name, sum(bytes) free_bytes from dba_free_space group by tablespace_name ), agg as ( - select f.tablespace_name, sum(f.maxbytes) max_bytes, sum(greatest(f.maxbytes - f.bytes, 0)) creste_bytes + select f.tablespace_name, sum(f.bytes) alocat_bytes, sum(f.maxbytes) max_bytes, + sum(greatest(f.maxbytes - f.bytes, 0)) creste_bytes from dba_data_files f group by f.tablespace_name +), calc as ( + select a.tablespace_name, + nvl(tf.free_bytes,0) + a.creste_bytes creste_total_bytes, + greatest(a.max_bytes, a.alocat_bytes) limita_bytes + from agg a, ts_free tf + where a.tablespace_name = tf.tablespace_name(+) ) -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) < - greatest($PragTsMb * 1048576, a.max_bytes * $PragTsPct / 100); +select 'TS_ATENTIE|' || c.tablespace_name + from calc c + where c.limita_bytes > 0 + and c.creste_total_bytes < + case when c.limita_bytes <= $PragTsMb * 1048576 + then c.limita_bytes * $PragTsPct / 100 + else greatest($PragTsMb * 1048576, c.limita_bytes * $PragTsPct / 100) end; 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_]+$' })