scripturi de diagnostic baza de date + script de livrare
- diag_actualizare.ps1: de ce s-a oprit actualizarea (UPD_ISTORIC, UPD_LOG, script_master.log prin UTL_FILE, versiuni per schema, spatiu tablespace, verdict) - diag_spatiu.ps1: spatiu Oracle la clienti (tablespace, audit, ADR, FRA, disc server) - livrare.ps1: git_sync + curatenie + verificari + commit/push - curatenie.ps1: sterge si docs\propuneri_*.md - docs: depanare-spatiu-oracle.md nou, depanare-pack-update.md completat cu cazul SIGMA Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014sNn6dmAimtyXkDU4frJrh
This commit is contained in:
@@ -5,6 +5,16 @@ Actualizarea automata a aplicatiilor si a bazei ruleaza din jobul `CONTAFIN_ORAC
|
||||
**UpdateScripts** (umple `UPD_DATABASE`) -> **UpdateDatabaseSqlPlus** (aplica scripturile pe scheme).
|
||||
O etapa esuata le opreste pe toate urmatoarele.
|
||||
|
||||
## Scriptul de diagnostic
|
||||
|
||||
`COMUN\utile\diag_actualizare.ps1 -Alias <ALIAS_TNS>` ruleaza tot lantul de mai jos si scoate un
|
||||
verdict (unde a ramas rularea, care e scriptul candidat, unde e eroarea). Strict read-only; `-Disc`
|
||||
adauga verificarea spatiului pe discurile serverului (singura parte care scrie ceva — un `.ps1`
|
||||
temporar in `DMPDIR`). Foloseste-l intai; sectiunile de mai jos explica ce citeste si de ce.
|
||||
|
||||
Cand cauza e spatiul (tablespace plin, audit/loguri Oracle care umplu discul), continua cu
|
||||
`depanare-spatiu-oracle.md` si `COMUN\utile\diag_spatiu.ps1`.
|
||||
|
||||
## Unde te uiti, in ordine
|
||||
|
||||
| Ce | Unde |
|
||||
@@ -52,6 +62,31 @@ Fisierul se poate citi si fara acces la desktopul serverului, prin `UTL_FILE` pe
|
||||
`DMPDIR` (`fopen(...,'R',32767)` + `get_line` in bucla; tine ultimele N linii intr-un tablou —
|
||||
partea utila e la sfarsit).
|
||||
|
||||
### Caz: nu orice esec de script e o problema de SQL (SIGMA, 03.08.2026)
|
||||
|
||||
`ff_2026_07_29_02_COMUN_TVA11.SQL` a picat pe `MARCU` cu `ORA-01653: unable to extend table
|
||||
SYS.INFO ... in tablespace SYSTEM` (din `SYS.PINFO`/`SYS.AUTH_PACK`, recursiv). Tablespace-ul
|
||||
`SYSTEM` era plin: autoextensibil, dar cu `maxbytes` atins la 600 MB, ~2 MB liberi. **Orice**
|
||||
script ar fi picat identic — `AUTH_PACK` scrie in `SYS.INFO` la fiecare conectare. Cand eroarea nu
|
||||
priveste obiectele scriptului, verifica intai spatiul.
|
||||
|
||||
Ce a contat, pentru data viitoare:
|
||||
|
||||
- **`maxbytes` mic nu e o limita XE.** Cele 11 GB ale XE sunt pe *date utilizator*; un plafon mic pe
|
||||
`SYSTEM.DBF` e o setare de instalare. Se ridica din `contafin_oracle` (are `ALTER DATABASE`):
|
||||
`alter database datafile '<cale>\SYSTEM.DBF' autoextend on next 50M maxsize 2000M;`
|
||||
- **Spatiul pe discul serverului se verifica fara RDP**, cu `sys.ExecuteScriptOS` (vezi mai jos) —
|
||||
`Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3"`, iesire in `DMPDIR`, citita cu `UTL_FILE`.
|
||||
Job asincron, dar raspunde in cateva secunde.
|
||||
- **`SYS.INFO` e tabel ROA, nu obiect de dictionar** (log de login scris de `PINFO`, ~7 randuri per
|
||||
conectare, +16-17k randuri/luna, nimic din baza nu-l citeste). Se poate goli, **dar numai ca
|
||||
`SYSDBA`**: privilegiile `ANY` (`DROP ANY TABLE`, `DELETE ANY TABLE`) nu se aplica pe obiectele
|
||||
din schema `SYS` cat timp `O7_DICTIONARY_ACCESSIBILITY=FALSE`, deci din `contafin_oracle` iese
|
||||
`ORA-01031`.
|
||||
- Restul lui `SYSTEM` era dictionar Oracle (`IDL_UB1$`, `SOURCE$`, `IDL_UB2$`, `ARGUMENT$` ~207 MB) —
|
||||
de neatins fara export/import. `AUD$`/`FGA_LOG$` erau goale. Recyclebin-ul si bloat-ul de scheduler
|
||||
stateau in `ROA`/`SYSAUX`, nu in `SYSTEM`.
|
||||
|
||||
## Descarcarea (UpdateApp)
|
||||
|
||||
Cu `server_info.POWERSHELLDOWNLOAD = '1'`, `PACK_UTILS.DownloadFileOS` scrie un `.ps1` cu `curl` in
|
||||
|
||||
55
docs/depanare-spatiu-oracle.md
Normal file
55
docs/depanare-spatiu-oracle.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Depanare spatiu Oracle la clienti
|
||||
|
||||
```powershell
|
||||
powershell -File COMUN\utile\diag_spatiu.ps1 -Alias <ALIAS_TNS> [-Disc] [-SysPassword <parola>] [-Top 30]
|
||||
```
|
||||
|
||||
Strict read-only in afara lui `-Disc` (singura parte care scrie: un `.ps1` temporar in `DMPDIR`,
|
||||
lansat cu `sys.ExecuteScriptOS` si sters la final). Actiunile de curatare sunt doar **sugerate**,
|
||||
niciodata executate. 8 sectiuni: conexiune/versiune (CDB-PDB), tablespace + top segmente, audit,
|
||||
alert log/trace/ADR, archivelog/FRA, disc server, alti mancatori de spatiu, verdict.
|
||||
|
||||
Pentru actualizarea blocata de spatiu, punctul de plecare e `depanare-pack-update.md`.
|
||||
|
||||
## Ce umple spatiul, in ordinea frecventei
|
||||
|
||||
- **Tablespace cu `maxbytes` atins** — nu "disc plin", ci un plafon pus la instalare. Pe XE limita
|
||||
de 11/12 GB e pe *date utilizator*, nu pe `SYSTEM`.
|
||||
- **`SYSAUX`** — SQL Tuning Sets (`wri$_sqlset_*`), AWR, audit policies active pe un PDB nou.
|
||||
- **Fisierele `.aud`** din `audit_file_dest` (`adump`) — zeci de mii, niciodata curatate; **nu se vad
|
||||
din SQL**, doar cu `-Disc`.
|
||||
- **Alert log / trace / incident** (`diagnostic_dest`) — se purja cu `adrci purge`.
|
||||
- **FRA plina cu `log_mode=ARCHIVELOG`** → `ORA-00257`/`ORA-19809`; baza se blocheaza brusc, fara
|
||||
eroare vizibila in aplicatie.
|
||||
- Recyclebin, `UNDO` umflat, istoric statistici/scheduler, `TEMP`.
|
||||
- **Tabele de log ale aplicatiei** care cresc nelimitat (tiparul `SYS.INFO` de pe SIGMA) — apar in
|
||||
raportul de top segmente, numele difera per client.
|
||||
|
||||
## Cazuri
|
||||
|
||||
- **Rompetrol Energy** (XE 21c): `ORA-12954`, limita de 12 GB pe `dba_data_files` atinsa. `SYSAUX`
|
||||
umflat la 7.8 GB din SQL Tuning Sets (~5 GB) + AWR + audit policies. `TRUNCATE wri$_sqlset_*` a
|
||||
eliberat segmentele, dar `RESIZE` a picat cu `ORA-03297` (`SYSAUX` nu se shrink pe XE 21c) →
|
||||
singura solutie a fost **recrearea PDB-ului**, 13.5 GB → 3 GB. Detalii:
|
||||
`E:\proiecte\ROMFASTSQL\proxmox\lxc108-oracle\clienti\oracle-xe-21c\` (`README.md`,
|
||||
`depanare-ora-12954-spatiu.md`).
|
||||
- **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`.
|
||||
|
||||
## Capcane
|
||||
|
||||
- **Privilegiile `ANY` nu se aplica pe obiectele din schema `SYS`** cat timp
|
||||
`O7_DICTIONARY_ACCESSIBILITY=FALSE` — orice curatare acolo cere `SYSDBA`.
|
||||
- **Parola `SYS` difera de la server la server.** `-SysPassword` e optional; diagnosticul de baza
|
||||
merge complet fara el, doar sectiunile SYSDBA se sar.
|
||||
- **Curatenia poate esua din lipsa de spatiu** (`DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL` a picat asa la
|
||||
Rompetrol): intai ridici plafonul, apoi cureti.
|
||||
- `RESIZE` pe datafile da `ORA-03297` daca extentele folosite nu sunt la coada fisierului — un
|
||||
`DELETE` fara `MOVE`/`SHRINK` nu recupereaza MB.
|
||||
- Dimensiunile reale ale fisierelor de pe disc nu se vad din SQL — `-Disc`, prin `ExecuteScriptOS`.
|
||||
- **`-Disc` merge doar pe servere Windows** (`ExecuteScriptOS` lanseaza PowerShell). Pe Linux
|
||||
expira curat dupa 60s, cu mesaj.
|
||||
- **`MAX_PDB_STORAGE` se citeste doar de pe un alias care tinteste radacina CDB.** De pe un
|
||||
serviciu de PDB (cazul obisnuit al aliasurilor din `tnsnames.ora`), `alter session set
|
||||
container=CDB$ROOT` da `ORA-01031` — e nevoie de un alias separat spre radacina.
|
||||
@@ -42,8 +42,8 @@ function Adauga($cale, $tipare, $recursiv, $director) {
|
||||
$docs = Join-Path $ProjectRoot 'docs'
|
||||
$teste = @((Join-Path $comun 'utile\Teste'), (Join-Path $ProjectRoot 'utile\Teste')) | Where-Object { Test-Path $_ }
|
||||
|
||||
# patch-uri de review, handoff-uri, planuri de runda
|
||||
Adauga $docs @('diff_runda*.patch', 'handoff*.md', 'plan_runda*.md', 'runda*.md') $false $false
|
||||
# patch-uri de review, handoff-uri, planuri de runda, propuneri implementate
|
||||
Adauga $docs @('diff_runda*.patch', 'handoff*.md', 'plan_runda*.md', 'runda*.md', 'propuneri_*.md') $false $false
|
||||
# backup-uri de runda si de cache text
|
||||
Adauga $ProjectRoot @('*.pre_runda*.bak') $true $false
|
||||
Adauga $CacheRoot @('*.pre_runda*.bak', '*.vc2.bak', '*.sc2.bak') $true $false
|
||||
|
||||
529
utile/diag_actualizare.ps1
Normal file
529
utile/diag_actualizare.ps1
Normal file
@@ -0,0 +1,529 @@
|
||||
# diag_actualizare.ps1 - depanare PACK_UPDATE (actualizare ROA) pe serverul unui client.
|
||||
# Urmareste pasii din COMUN\docs\depanare-pack-update.md: test conexiune, UPD_ISTORIC, UPD_LOG,
|
||||
# script_master.log/script_master2.log (UTL_FILE pe directorul Oracle DMPDIR), versiuni aplicate
|
||||
# pe fiecare schema, spatiu tablespace (detaliu + cat mai poate creste + top segmente pe cele
|
||||
# blocate), spatiu disc pe server (optional, -Disc), jobul UPDATEROA_ZILNIC.
|
||||
# STRICT READ-ONLY: doar select si UTL_FILE in mod 'R'. Nu apeleaza IncheiereActualizare, nu
|
||||
# relanseaza actualizarea, nu face DDL/DML. Comenzile de deblocare/marire sunt doar AFISATE ca
|
||||
# sugestie. Singura exceptie e -Disc: scrie un .ps1 temporar in DMPDIR pe server (prin
|
||||
# sys.ExecuteScriptOS) ca sa citeasca spatiul liber pe discuri, si il sterge la final.
|
||||
# Parola implicita (ROMFASTSOFT) e cea de dezvoltare, aceeasi folosita si pe serverele de client.
|
||||
#
|
||||
# Utilizare:
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_SIGMA
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_ROMCONSTRUCT -Tail 120
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_SIGMA -User contafin_oracle -Password ...
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_SIGMA -DoarLog # doar script_master.log
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_SIGMA -Disc # + spatiu liber pe discurile serverului
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$Alias,
|
||||
[string]$User = 'contafin_oracle',
|
||||
[string]$Password = 'ROMFASTSOFT',
|
||||
[int]$Tail = 60,
|
||||
[string]$SqlPlus = 'D:\ROA\instantclient_19_18\sqlplus.exe',
|
||||
[switch]$DoarLog,
|
||||
[switch]$Disc
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not (Test-Path $SqlPlus)) {
|
||||
Write-Output ('EROARE: nu gasesc sqlplus la ' + $SqlPlus)
|
||||
exit 1
|
||||
}
|
||||
|
||||
$env:TNS_ADMIN = Split-Path $SqlPlus -Parent
|
||||
$ConnStr = $User + '/' + $Password + '@' + $Alias
|
||||
|
||||
$TempDir = Join-Path $env:TEMP ('diag_actualizare_' + [guid]::NewGuid().ToString('N'))
|
||||
New-Item -ItemType Directory -Force -Path $TempDir | Out-Null
|
||||
|
||||
function Remove-TempDir {
|
||||
if (Test-Path $TempDir) { Remove-Item -LiteralPath $TempDir -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
|
||||
function Invoke-Sql {
|
||||
param([string]$Sql)
|
||||
$sqlFile = Join-Path $TempDir ('q_' + [guid]::NewGuid().ToString('N') + '.sql')
|
||||
[System.IO.File]::WriteAllText($sqlFile, $Sql, [System.Text.Encoding]::ASCII)
|
||||
try {
|
||||
$out = & $SqlPlus -L -S $ConnStr ('@' + $sqlFile) 2>&1
|
||||
$code = $LASTEXITCODE
|
||||
} catch {
|
||||
$out = 'EROARE lansare sqlplus: ' + $_.Exception.Message
|
||||
$code = -1
|
||||
}
|
||||
Remove-Item -LiteralPath $sqlFile -Force -ErrorAction SilentlyContinue
|
||||
[PSCustomObject]@{ Text = ($out -join "`n"); Code = $code }
|
||||
}
|
||||
|
||||
function Show-Section {
|
||||
param([string]$Title, [string]$Text)
|
||||
Write-Output ''
|
||||
Write-Output ('===== ' + $Title + ' =====')
|
||||
Write-Output $Text
|
||||
if ($Text -match 'ORA-00942|ORA-01031') {
|
||||
Write-Output '[AVERTISMENT] lipsesc probabil drepturi de acces (ORA-00942/ORA-01031) - pasul de mai sus poate fi incomplet cu acest utilizator.'
|
||||
}
|
||||
}
|
||||
|
||||
function Wait-RemoteFile {
|
||||
# asteapta aparitia unui fisier scris de sys.ExecuteScriptOS (asincron) - polling, nu instant
|
||||
param([string]$Directory, [string]$FileName, [int]$TimeoutSec = 60)
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
$r = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 100 trimspool on feedback off heading off
|
||||
select dbms_lob.fileexists(bfilename('$Directory','$FileName')) from dual;
|
||||
exit
|
||||
"@
|
||||
if ($r.Text -match '1') { return $true }
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
# ---------- 1. Test conexiune ----------
|
||||
Write-Output '===== 1. TEST CONEXIUNE ====='
|
||||
Write-Output ('Alias=' + $Alias + ' User=' + $User + ' TNS_ADMIN=' + $env:TNS_ADMIN)
|
||||
$r1 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'CONEXIUNE_OK' from dual;
|
||||
select 'VERSIUNE DB: ' || banner from v`$version where rownum = 1;
|
||||
select 'SCHEMA CONECTATA: ' || sys_context('userenv','session_user') || ' DB: ' || sys_context('userenv','db_name') from dual;
|
||||
exit
|
||||
"@
|
||||
Write-Output $r1.Text
|
||||
if ($r1.Code -ne 0 -or $r1.Text -notmatch 'CONEXIUNE_OK') {
|
||||
Write-Output ''
|
||||
Write-Output 'EROARE: conexiunea a esuat. Verifica:'
|
||||
Write-Output ' - tunelul SSH pe 1521 e deschis?'
|
||||
Write-Output (' - aliasul TNS ' + $Alias + ' exista in ' + $env:TNS_ADMIN + '\tnsnames.ora si tinteste 127.0.0.1?')
|
||||
Write-Output ' - user/parola corecte? (implicit contafin_oracle/ROMFASTSOFT)'
|
||||
Remove-TempDir
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ---------- 2. UPD_ISTORIC ----------
|
||||
if (-not $DoarLog) {
|
||||
$r2 = Invoke-Sql -Sql @"
|
||||
set pagesize 200 linesize 200 trimspool on feedback off
|
||||
column dataora_start format a19
|
||||
column dataora_end format a30
|
||||
column stare_text format a26
|
||||
select * from (
|
||||
select to_char(dataora_start,'yyyy-mm-dd hh24:mi:ss') dataora_start,
|
||||
nvl(to_char(dataora_end,'yyyy-mm-dd hh24:mi:ss'), '<<< NEINCHEIATA >>>') dataora_end,
|
||||
decode(stare, 0,'0-pornire', 1,'1-descarcare aplicatii', 2,'2-generare scripturi',
|
||||
3,'3-aplicare scripturi', 4,'4-incheiat', 'necunoscuta(' || stare || ')') stare_text
|
||||
from upd_istoric
|
||||
order by dataora_start desc
|
||||
) where rownum <= 10;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '2. UPD_ISTORIC (ultimele 10 rulari)' -Text $r2.Text
|
||||
|
||||
# ---------- 3. UPD_LOG (rularea curenta) ----------
|
||||
$r3 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off long 32000 longchunksize 32000
|
||||
select 'AVERTISMENT: UPD_LOG se goleste la fiecare rulare; erorile din etapa 3 (aplicare scripturi in SQL*Plus extern) NU ajung aici - vezi script_master.log mai jos.' from dual;
|
||||
select '-------------------------------------------' from dual;
|
||||
select 'SECV ' || secventa || ' SCHEMA=' || nvl(schema,'-') || ' SCRIPT=' || nvl(script,'-') ||
|
||||
' ' || to_char(dataora,'yyyy-mm-dd hh24:mi:ss') || chr(10) ||
|
||||
nvl(explicatie,'(fara explicatie)') || chr(10) || '-------------------------------------------'
|
||||
from upd_log
|
||||
where dataora_start = (select max(dataora_start) from upd_log)
|
||||
order by secventa;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '3. UPD_LOG (rularea curenta)' -Text $r3.Text
|
||||
}
|
||||
|
||||
# ---------- 4. script_master.log / script_master2.log (UTL_FILE pe DMPDIR) ----------
|
||||
foreach ($logFile in @('script_master.log', 'script_master2.log')) {
|
||||
$r4 = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
ln_n pls_integer := $Tail;
|
||||
la_buf dbms_sql.varchar2a;
|
||||
ln_idx pls_integer := 0;
|
||||
ln_cnt pls_integer := 0;
|
||||
lc_line varchar2(32767);
|
||||
lf utl_file.file_type;
|
||||
lc_path all_directories.directory_path%type;
|
||||
begin
|
||||
begin
|
||||
select directory_path into lc_path from all_directories where directory_name = 'DMPDIR';
|
||||
exception when no_data_found then lc_path := '(directorul Oracle DMPDIR nu exista)';
|
||||
end;
|
||||
dbms_output.put_line('Director DMPDIR -> ' || lc_path || ' fisier: $logFile');
|
||||
lf := utl_file.fopen('DMPDIR', '$logFile', 'R', 32767);
|
||||
begin
|
||||
loop
|
||||
utl_file.get_line(lf, lc_line, 32767);
|
||||
ln_idx := mod(ln_cnt, ln_n) + 1;
|
||||
la_buf(ln_idx) := lc_line;
|
||||
ln_cnt := ln_cnt + 1;
|
||||
end loop;
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
utl_file.fclose(lf);
|
||||
dbms_output.put_line('total linii citite: ' || ln_cnt || ' (ultimele ' || ln_n || ' afisate mai jos)');
|
||||
dbms_output.put_line('-------------------------------------------');
|
||||
if ln_cnt <= ln_n then
|
||||
for i in 1 .. ln_cnt loop dbms_output.put_line(la_buf(i)); end loop;
|
||||
else
|
||||
for i in 0 .. ln_n - 1 loop dbms_output.put_line(la_buf(mod(ln_cnt + i, ln_n) + 1)); end loop;
|
||||
end if;
|
||||
exception
|
||||
when others then
|
||||
if utl_file.is_open(lf) then utl_file.fclose(lf); end if;
|
||||
if sqlcode = -29280 then
|
||||
dbms_output.put_line('EROARE: directorul Oracle DMPDIR nu exista sau alias gresit (ORA-29280).');
|
||||
elsif sqlcode = -29283 then
|
||||
dbms_output.put_line('EROARE: fisierul $logFile nu exista in DMPDIR sau nu poate fi citit (ORA-29283). Normal daca actualizarea nu a ajuns inca la etapa 3, sau pentru script_master2.log daca rularea a picat inainte de pasii finali.');
|
||||
else
|
||||
dbms_output.put_line('EROARE: ' || sqlerrm);
|
||||
end if;
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title ('4. ' + $logFile) -Text $r4.Text
|
||||
}
|
||||
|
||||
if ($DoarLog) { Remove-TempDir; exit 0 }
|
||||
|
||||
# ---------- 5. Versiuni per schema ----------
|
||||
$rSchemas = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 200 trimspool on feedback off heading off
|
||||
select owner from all_tables where table_name = 'VERSIUNE' order by owner;
|
||||
exit
|
||||
"@
|
||||
$schemas = @($rSchemas.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ -match '^[A-Z_][A-Z0-9_]*$' })
|
||||
|
||||
if ($schemas.Count -eq 0) {
|
||||
Show-Section -Title '5. VERSIUNI PE SCHEMA' -Text ('Nu am gasit nicio schema cu tabela VERSIUNE (all_tables).' + "`n" + $rSchemas.Text)
|
||||
} else {
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
[void]$sb.AppendLine('set pagesize 0 linesize 250 trimspool on feedback off heading off')
|
||||
foreach ($sch in $schemas) {
|
||||
$prefix = if ($sch -eq 'CONTAFIN_ORACLE') { 'CO' } else { 'FF' }
|
||||
[void]$sb.AppendLine(@"
|
||||
select 'ULTIMA [$sch] ' || tip_script || ' data=' || to_char(data_script,'yyyy-mm-dd') || ' seq=' || seq_script
|
||||
from (select tip_script, data_script, seq_script from $sch.VERSIUNE order by data_script desc, seq_script desc)
|
||||
where rownum = 1;
|
||||
"@)
|
||||
[void]$sb.AppendLine(@"
|
||||
select 'CANDIDAT [$sch] ' || msg from (
|
||||
select msg, ord from (
|
||||
select script_name || ' (data=' || to_char(script_date,'yyyy-mm-dd') || ' seq=' || script_seq || ')' msg, 1 ord
|
||||
from (
|
||||
select d.script_name, d.script_date, d.script_seq
|
||||
from upd_database d,
|
||||
(select data_script mx_date, seq_script mx_seq from (
|
||||
select data_script, seq_script from $sch.VERSIUNE order by data_script desc, seq_script desc
|
||||
) where rownum = 1) w
|
||||
where d.script_name like '$prefix\_%' escape '\'
|
||||
and (d.script_date > w.mx_date or (d.script_date = w.mx_date and d.script_seq > w.mx_seq))
|
||||
order by d.script_date, d.script_seq
|
||||
) where rownum = 1
|
||||
union all
|
||||
select '(la zi - niciun script $prefix neaplicat gasit dupa ultima versiune)' msg, 2 ord from dual
|
||||
) order by ord
|
||||
) where rownum = 1;
|
||||
"@)
|
||||
}
|
||||
[void]$sb.AppendLine('exit')
|
||||
$r5 = Invoke-Sql -Sql $sb.ToString()
|
||||
Show-Section -Title '5. VERSIUNI PE SCHEMA (ultima aplicata / prima neaplicata - candidat)' -Text $r5.Text
|
||||
}
|
||||
|
||||
# ---------- 6. Spatiu tablespace: detaliu pe datafile + cat mai poate creste ----------
|
||||
$r6 = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column tablespace_name format a15
|
||||
column file_name format a55
|
||||
column autoext format a4
|
||||
select f.tablespace_name, f.file_name,
|
||||
round(f.bytes/1048576) mb_curent,
|
||||
round(f.maxbytes/1048576) mb_max,
|
||||
f.autoextensible autoext,
|
||||
round(f.increment_by * t.block_size / 1048576) mb_increment
|
||||
from dba_data_files f, dba_tablespaces t
|
||||
where f.tablespace_name = t.tablespace_name
|
||||
order by f.tablespace_name, f.file_name;
|
||||
column tablespace_name format a15
|
||||
column stare format a26
|
||||
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.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
|
||||
)
|
||||
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) < 1048576
|
||||
then 'ATENTIE: MAXBYTES ATINS' end stare
|
||||
from agg a, ts_free tf
|
||||
where a.tablespace_name = tf.tablespace_name(+)
|
||||
order by a.tablespace_name;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '6. 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" + $r6.Text)
|
||||
|
||||
# tablespace-urile cu maxbytes efectiv atins - identificate separat, pentru top segmente mai jos
|
||||
$r6m = Invoke-Sql -Sql @"
|
||||
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
|
||||
from dba_data_files f
|
||||
group by f.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) < 1048576;
|
||||
exit
|
||||
"@
|
||||
$tsProblema = @($r6m.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('TS_ATENTIE|') } | ForEach-Object { $_.Substring(11) } | Where-Object { $_ -match '^[A-Z0-9_]+$' })
|
||||
|
||||
if ($tsProblema.Count -gt 0) {
|
||||
$sbSeg = New-Object System.Text.StringBuilder
|
||||
[void]$sbSeg.AppendLine('set pagesize 0 linesize 250 trimspool on feedback off heading off')
|
||||
foreach ($ts in $tsProblema) {
|
||||
[void]$sbSeg.AppendLine("select 'Tablespace $ts - top 15 segmente:' from dual;")
|
||||
[void]$sbSeg.AppendLine(@"
|
||||
select rpad(owner,20) || rpad(segment_name,35) || rpad(segment_type,18) || round(bytes/1048576) || ' MB'
|
||||
from (select owner, segment_name, segment_type, bytes from dba_segments where tablespace_name = '$ts' order by bytes desc)
|
||||
where rownum <= 15;
|
||||
"@)
|
||||
if ($ts -eq 'SYSTEM') {
|
||||
[void]$sbSeg.AppendLine("select 'NOTA: privilegiile ANY (ex. DROP ANY TABLE/TRUNCATE ANY TABLE) nu se aplica pe obiecte din schema SYS cand O7_DICTIONARY_ACCESSIBILITY=FALSE - curatarea unui tabel din SYS cere conectare SYSDBA, nu contafin_oracle.' from dual;")
|
||||
}
|
||||
}
|
||||
[void]$sbSeg.AppendLine('exit')
|
||||
$r6s = Invoke-Sql -Sql $sbSeg.ToString()
|
||||
Write-Output ''
|
||||
Write-Output ('--- Top segmente pe tablespace-urile marcate ATENTIE (' + ($tsProblema -join ', ') + ') ---')
|
||||
Write-Output $r6s.Text
|
||||
}
|
||||
|
||||
# ---------- 7. Spatiu disc pe server (optional, scrie un .ps1 temporar in DMPDIR) ----------
|
||||
Write-Output ''
|
||||
Write-Output '===== 7. SPATIU DISC (server) ====='
|
||||
if (-not $Disc) {
|
||||
Write-Output 'Sarit implicit - ruleaza cu -Disc pentru spatiul liber pe discurile fizice ale serverului.'
|
||||
Write-Output 'Este singura parte a scriptului care NU e strict read-only: scrie un .ps1 temporar in DMPDIR (prin sys.ExecuteScriptOS) si il sterge la final.'
|
||||
} else {
|
||||
$rPaths = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 300 trimspool on feedback off heading off
|
||||
select 'DATAFILE_PATH|' || file_name from dba_data_files order by file_name;
|
||||
exit
|
||||
"@
|
||||
$datafilePaths = @($rPaths.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('DATAFILE_PATH|') } | ForEach-Object { $_.Substring(14) })
|
||||
|
||||
$psTemplate = @'
|
||||
$dOut = 'C:\DMPDIR\diag_disc_out.txt'
|
||||
Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object {
|
||||
$pct = 0
|
||||
if ($_.Size -gt 0) { $pct = [math]::Round($_.FreeSpace/$_.Size*100,1) }
|
||||
"DISC {0} {1} {2} {3}" -f $_.DeviceID, [math]::Round($_.Size/1GB,2), [math]::Round($_.FreeSpace/1GB,2), $pct
|
||||
} | Out-File -Encoding ascii $dOut
|
||||
__DATAFILES__
|
||||
'@
|
||||
$fileLines = foreach ($p in $datafilePaths) {
|
||||
$escaped = $p.Replace("'", "''")
|
||||
'Get-Item ''' + $escaped + ''' -ErrorAction SilentlyContinue | ForEach-Object { "FISIER {0} {1}" -f $_.FullName, $_.Length } | Out-File -Encoding ascii -Append $dOut'
|
||||
}
|
||||
$psScript = $psTemplate.Replace('__DATAFILES__', ([string]::Join("`n", $fileLines)))
|
||||
$psScriptSql = $psScript.Replace("'", "''")
|
||||
|
||||
$rLaunch = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
lcPS server_info.value%type;
|
||||
begin
|
||||
select value into lcPS from server_info where upper(name) = 'POWERSHELLPATH';
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_disc_out.txt'); exception when others then null; end;
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_disc.ps1'); exception when others then null; end;
|
||||
pack_utils_file.clob2fileX('$psScriptSql', 'DMPDIR', 'diag_disc.ps1');
|
||||
sys.ExecuteScriptOS(lcPS, 'C:\DMPDIR\diag_disc.ps1');
|
||||
dbms_output.put_line('Lansat pe server (' || lcPS || '), astept rezultatul...');
|
||||
exception when others then
|
||||
dbms_output.put_line('EROARE la lansare: ' || sqlerrm);
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Write-Output $rLaunch.Text
|
||||
|
||||
if ($rLaunch.Text -notmatch 'EROARE la lansare') {
|
||||
$gata = Wait-RemoteFile -Directory 'DMPDIR' -FileName 'diag_disc_out.txt' -TimeoutSec 60
|
||||
if (-not $gata) {
|
||||
Write-Output 'EROARE: rezultatul nu a aparut in 60s. Posibile cauze: server_info.POWERSHELLPATH gresit, politica de executie PowerShell blocheaza scriptul, sau sys.ExecuteScriptOS nu are drept de executie. Verifica manual C:\DMPDIR\diag_disc.ps1 pe server.'
|
||||
} else {
|
||||
$rRead = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
lf utl_file.file_type;
|
||||
lc_line varchar2(32767);
|
||||
begin
|
||||
lf := utl_file.fopen('DMPDIR','diag_disc_out.txt','R',32767);
|
||||
begin
|
||||
loop
|
||||
utl_file.get_line(lf, lc_line, 32767);
|
||||
dbms_output.put_line(lc_line);
|
||||
end loop;
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
utl_file.fclose(lf);
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_disc_out.txt'); exception when others then null; end;
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_disc.ps1'); exception when others then null; end;
|
||||
exception when others then
|
||||
dbms_output.put_line('EROARE citire: ' || sqlerrm);
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
$discLines = @()
|
||||
$fileLinesOut = @()
|
||||
foreach ($line in ($rRead.Text -split "`r?`n")) {
|
||||
if ($line -match '^DISC\s+(\S+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)') {
|
||||
$discLines += (' disc {0}: total {1} GB, liber {2} GB ({3}%)' -f $Matches[1], $Matches[2], $Matches[3], $Matches[4])
|
||||
} elseif ($line -match '^FISIER\s+(\S+)\s+(\d+)') {
|
||||
$mb = [math]::Round(([double]$Matches[2]) / 1048576, 1)
|
||||
$fileLinesOut += (' {0}: {1} MB pe disc' -f $Matches[1], $mb)
|
||||
} elseif ($line -match '\S') {
|
||||
$discLines += (' ' + $line)
|
||||
}
|
||||
}
|
||||
Write-Output 'Discuri fixe:'
|
||||
Write-Output ($discLines -join "`n")
|
||||
Write-Output 'Dimensiune reala pe disc a datafile-urilor:'
|
||||
Write-Output ($fileLinesOut -join "`n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ---------- 8. Job UPDATEROA_ZILNIC ----------
|
||||
$r8 = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column log_date format a20
|
||||
column additional_info format a90 word_wrapped
|
||||
select * from (
|
||||
select to_char(log_date,'yyyy-mm-dd hh24:mi:ss') log_date, status, additional_info
|
||||
from dba_scheduler_job_run_details
|
||||
where job_name = 'UPDATEROA_ZILNIC'
|
||||
order by log_date desc
|
||||
) where rownum <= 10;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '8. JOB UPDATEROA_ZILNIC (ultimele 10 rulari)' -Text ('AVERTISMENT: additional_info e frecvent falsa - la orice esec se apeleaza EmailLog, iar daca SMTP-ul e picat ridica ORA-20000 care masca eroarea reala. Cauza adevarata e in UPD_LOG / script_master.log de mai sus.' + "`n`n" + $r8.Text)
|
||||
|
||||
# ---------- 9. Verdict ----------
|
||||
$r9 = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
ln_stare upd_istoric.stare%type;
|
||||
ld_end upd_istoric.dataora_end%type;
|
||||
ld_start upd_istoric.dataora_start%type;
|
||||
lc_stare_text varchar2(50);
|
||||
lc_line varchar2(32767);
|
||||
lf utl_file.file_type;
|
||||
lc_errs varchar2(4000);
|
||||
ln_errcnt pls_integer := 0;
|
||||
lb_spatiu boolean := false;
|
||||
lc_tspatiu varchar2(100);
|
||||
lc_match varchar2(200);
|
||||
lc_datafile varchar2(400);
|
||||
begin
|
||||
select stare, dataora_end, dataora_start into ln_stare, ld_end, ld_start
|
||||
from (select stare, dataora_end, dataora_start from upd_istoric order by dataora_start desc)
|
||||
where rownum = 1;
|
||||
|
||||
lc_stare_text := case ln_stare
|
||||
when 0 then '0-pornire' when 1 then '1-descarcare aplicatii' when 2 then '2-generare scripturi'
|
||||
when 3 then '3-aplicare scripturi' when 4 then '4-incheiat cu succes'
|
||||
else 'necunoscuta(' || ln_stare || ')' end;
|
||||
|
||||
dbms_output.put_line('Ultima rulare: ' || to_char(ld_start,'yyyy-mm-dd hh24:mi:ss') || ' stare=' || lc_stare_text ||
|
||||
case when ld_end is null then ' <<< NEINCHEIATA >>>' else ' incheiata ' || to_char(ld_end,'yyyy-mm-dd hh24:mi:ss') end);
|
||||
|
||||
if ld_end is null and ln_stare = 3 then
|
||||
dbms_output.put_line('Rularea a ramas la aplicarea scripturilor (etapa 3, SQL*Plus extern). Cauza reala e in script_master.log, NU in UPD_LOG.');
|
||||
elsif ld_end is null then
|
||||
dbms_output.put_line('Rularea nu s-a incheiat (stare ' || lc_stare_text || ').');
|
||||
else
|
||||
dbms_output.put_line('Ultima rulare s-a incheiat normal.');
|
||||
end if;
|
||||
|
||||
begin
|
||||
lf := utl_file.fopen('DMPDIR', 'script_master.log', 'R', 32767);
|
||||
begin
|
||||
loop
|
||||
utl_file.get_line(lf, lc_line, 32767);
|
||||
if instr(lc_line,'ORA-06512') = 0 and (instr(upper(lc_line), 'ORA-') > 0 or instr(lc_line, 'ERROR') > 0) then
|
||||
ln_errcnt := ln_errcnt + 1;
|
||||
lc_errs := lc_errs || chr(10) || lc_line;
|
||||
if regexp_like(lc_line, 'ORA-016[0-9][0-9]|ORA-30036') then
|
||||
lb_spatiu := true;
|
||||
lc_match := regexp_substr(upper(lc_line), 'TABLESPACE [A-Z0-9_]+', 1, 1);
|
||||
if lc_match is not null then lc_tspatiu := ltrim(substr(lc_match, 11)); end if;
|
||||
end if;
|
||||
end if;
|
||||
end loop;
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
utl_file.fclose(lf);
|
||||
exception when others then
|
||||
if utl_file.is_open(lf) then utl_file.fclose(lf); end if;
|
||||
end;
|
||||
|
||||
if ln_errcnt > 0 then
|
||||
dbms_output.put_line('script_master.log contine erori (' || ln_errcnt || '):' || lc_errs);
|
||||
else
|
||||
dbms_output.put_line('Nu s-a gasit "ORA-"/"ERROR" in script_master.log.');
|
||||
end if;
|
||||
|
||||
if lb_spatiu then
|
||||
dbms_output.put_line('=== PROBLEMA DE SPATIU, NU DE SQL === tablespace implicat: ' || nvl(lc_tspatiu,'necunoscut'));
|
||||
if lc_tspatiu is not null then
|
||||
begin
|
||||
select file_name into lc_datafile
|
||||
from (select file_name from dba_data_files where tablespace_name = lc_tspatiu order by file_name)
|
||||
where rownum = 1;
|
||||
dbms_output.put_line('Sugestie (NU se executa automat): ALTER DATABASE DATAFILE ''' || lc_datafile ||
|
||||
''' AUTOEXTEND ON NEXT 50M MAXSIZE <valoare mai mare>;');
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
end if;
|
||||
dbms_output.put_line('Pe XE limita de 11GB e pe datele utilizator, nu pe SYSTEM - un maxbytes mic pe SYSTEM (sau alt tablespace de sistem) e o setare de instalare, se poate mari.');
|
||||
end if;
|
||||
|
||||
dbms_output.put_line('Vezi sectiunea 4 pentru context complet in log, sectiunea 5 pentru scriptul candidat per schema, sectiunea 6 pentru spatiul pe tablespace/segmente.');
|
||||
dbms_output.put_line('Daca rularea a ramas blocata (stare < 4 de peste o ora) si problema de mai sus e reparata, deblocarea (NU se executa automat de acest script):');
|
||||
dbms_output.put_line(' exec contafin_oracle.pack_update.IncheiereActualizare;');
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '9. VERDICT' -Text $r9.Text
|
||||
if ($r9.Text -match 'PROBLEMA DE SPATIU' -and -not $Disc) {
|
||||
Write-Output 'Sugestie: reruleaza cu -Disc pentru spatiul liber pe discurile fizice ale serverului (poate lipsi spatiu pe disc pentru crestere, nu doar maxbytes).'
|
||||
}
|
||||
|
||||
Remove-TempDir
|
||||
exit 0
|
||||
621
utile/diag_spatiu.ps1
Normal file
621
utile/diag_spatiu.ps1
Normal file
@@ -0,0 +1,621 @@
|
||||
# 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
|
||||
# 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
|
||||
# din verdict sunt doar AFISATE ca sugestie, niciodata executate (niciun purge/truncate/alter).
|
||||
# Singura scriere e sub -Disc: un .ps1 temporar in DMPDIR pe server (prin sys.ExecuteScriptOS),
|
||||
# sters la final cu verificare.
|
||||
# -SysPassword e optional, fara valoare implicita, nesalvat nicaieri (parola SYS difera per
|
||||
# server). Sectiunile care o cer (MAX_PDB_STORAGE din CDB$ROOT, audit intern sys.aud$/fga_log$,
|
||||
# recyclebin la nivel de baza) se sar curat, cu mesaj, daca nu e data - diagnosticul de baza
|
||||
# merge complet fara ea.
|
||||
#
|
||||
# Utilizare:
|
||||
# powershell -File COMUN\utile\diag_spatiu.ps1 -Alias ROA_SIGMA
|
||||
# powershell -File COMUN\utile\diag_spatiu.ps1 -Alias ROA_SIGMA -Disc
|
||||
# powershell -File COMUN\utile\diag_spatiu.ps1 -Alias ROA_SIGMA -SysPassword ...
|
||||
# powershell -File COMUN\utile\diag_spatiu.ps1 -Alias ROA_SIGMA -Top 30 -Disc
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$Alias,
|
||||
[string]$User = 'contafin_oracle',
|
||||
[string]$Password = 'ROMFASTSOFT',
|
||||
[string]$SysPassword,
|
||||
[string]$SqlPlus = 'D:\ROA\instantclient_19_18\sqlplus.exe',
|
||||
[switch]$Disc,
|
||||
[int]$Top = 20
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not (Test-Path $SqlPlus)) {
|
||||
Write-Output ('EROARE: nu gasesc sqlplus la ' + $SqlPlus)
|
||||
exit 1
|
||||
}
|
||||
|
||||
$env:TNS_ADMIN = Split-Path $SqlPlus -Parent
|
||||
$ConnStr = $User + '/' + $Password + '@' + $Alias
|
||||
$ConnStrSys = if ($SysPassword) { 'sys/' + $SysPassword + '@' + $Alias + ' as sysdba' } else { $null }
|
||||
|
||||
$TempDir = Join-Path $env:TEMP ('diag_spatiu_' + [guid]::NewGuid().ToString('N'))
|
||||
New-Item -ItemType Directory -Force -Path $TempDir | Out-Null
|
||||
|
||||
function Remove-TempDir {
|
||||
if (Test-Path $TempDir) { Remove-Item -LiteralPath $TempDir -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
|
||||
function Invoke-SqlAs {
|
||||
param([string]$Sql, [string]$Connect)
|
||||
$sqlFile = Join-Path $TempDir ('q_' + [guid]::NewGuid().ToString('N') + '.sql')
|
||||
[System.IO.File]::WriteAllText($sqlFile, $Sql, [System.Text.Encoding]::ASCII)
|
||||
try {
|
||||
$out = & $SqlPlus -L -S $Connect ('@' + $sqlFile) 2>&1
|
||||
$code = $LASTEXITCODE
|
||||
} catch {
|
||||
$out = 'EROARE lansare sqlplus: ' + $_.Exception.Message
|
||||
$code = -1
|
||||
}
|
||||
Remove-Item -LiteralPath $sqlFile -Force -ErrorAction SilentlyContinue
|
||||
[PSCustomObject]@{ Text = ($out -join "`n"); Code = $code }
|
||||
}
|
||||
|
||||
function Invoke-Sql {
|
||||
param([string]$Sql)
|
||||
Invoke-SqlAs -Sql $Sql -Connect $ConnStr
|
||||
}
|
||||
|
||||
function Invoke-SqlSys {
|
||||
# ruleaza doar daca -SysPassword a fost dat; altfel intoarce $null (apelantul trebuie sa verifice)
|
||||
param([string]$Sql)
|
||||
if (-not $ConnStrSys) { return $null }
|
||||
Invoke-SqlAs -Sql $Sql -Connect $ConnStrSys
|
||||
}
|
||||
|
||||
function Show-Section {
|
||||
param([string]$Title, [string]$Text)
|
||||
Write-Output ''
|
||||
Write-Output ('===== ' + $Title + ' =====')
|
||||
Write-Output $Text
|
||||
if ($Text -match 'ORA-00942|ORA-01031') {
|
||||
Write-Output '[AVERTISMENT] lipsesc probabil drepturi de acces (ORA-00942/ORA-01031) - pasul de mai sus poate fi incomplet cu acest utilizator.'
|
||||
}
|
||||
}
|
||||
|
||||
function Wait-RemoteFile {
|
||||
# asteapta aparitia unui fisier scris de sys.ExecuteScriptOS (asincron) - polling, nu instant
|
||||
param([string]$Directory, [string]$FileName, [int]$TimeoutSec = 60)
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
$r = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 100 trimspool on feedback off heading off
|
||||
select dbms_lob.fileexists(bfilename('$Directory','$FileName')) from dual;
|
||||
exit
|
||||
"@
|
||||
if ($r.Text -match '1') { return $true }
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
# ---------- 1. Test conexiune + versiune + CDB/PDB ----------
|
||||
Write-Output '===== 1. TEST CONEXIUNE ====='
|
||||
Write-Output ('Alias=' + $Alias + ' User=' + $User + ' TNS_ADMIN=' + $env:TNS_ADMIN)
|
||||
$r1 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'CONEXIUNE_OK' from dual;
|
||||
select 'VERSIUNE DB: ' || banner from v`$version where rownum = 1;
|
||||
select 'SCHEMA CONECTATA: ' || sys_context('userenv','session_user') || ' DB: ' || sys_context('userenv','db_name') from dual;
|
||||
exit
|
||||
"@
|
||||
Write-Output $r1.Text
|
||||
if ($r1.Code -ne 0 -or $r1.Text -notmatch 'CONEXIUNE_OK') {
|
||||
Write-Output ''
|
||||
Write-Output 'EROARE: conexiunea a esuat. Verifica:'
|
||||
Write-Output ' - tunelul SSH pe 1521 e deschis?'
|
||||
Write-Output (' - aliasul TNS ' + $Alias + ' exista in ' + $env:TNS_ADMIN + '\tnsnames.ora si tinteste 127.0.0.1?')
|
||||
Write-Output ' - user/parola corecte? (implicit contafin_oracle/ROMFASTSOFT)'
|
||||
Remove-TempDir
|
||||
exit 1
|
||||
}
|
||||
|
||||
$verMajor = 0
|
||||
if ($r1.Text -match 'Release\s+(\d+)\.') { $verMajor = [int]$Matches[1] }
|
||||
elseif ($r1.Text -match 'Database\s+(\d+)[gc]\b') { $verMajor = [int]$Matches[1] }
|
||||
if ($verMajor -eq 0) {
|
||||
Write-Output '[AVERTISMENT] nu am putut determina versiunea majora din banner - presupun 11 (fara facilitati 12c+).'
|
||||
$verMajor = 11
|
||||
}
|
||||
$ver12plus = ($verMajor -ge 12)
|
||||
$ver11plus = ($verMajor -ge 11)
|
||||
Write-Output ('Versiune majora detectata: ' + $verMajor + ' (CDB/PDB si unified_audit_trail: ' + $(if ($ver12plus) {'da'} else {'nu, sarite mai jos'}) + ')')
|
||||
|
||||
if ($ver12plus) {
|
||||
$rCdb = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 200 trimspool on feedback off heading off
|
||||
select 'CDB=' || cdb from v`$database;
|
||||
select 'CONTAINER ' || con_id || ' ' || name || ' ' || open_mode from v`$containers order by con_id;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '1b. CDB/PDB' -Text $rCdb.Text
|
||||
} else {
|
||||
Write-Output ''
|
||||
Write-Output '===== 1b. CDB/PDB ====='
|
||||
Write-Output 'Sarit - baza sub versiunea 12c (CDB/PDB nu se aplica pe 10.2/11g).'
|
||||
}
|
||||
|
||||
# ---------- 2. Tablespace / datafile ----------
|
||||
$r2 = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column tablespace_name format a15
|
||||
column file_name format a55
|
||||
column autoext format a4
|
||||
select f.tablespace_name, f.file_name,
|
||||
round(f.bytes/1048576) mb_curent,
|
||||
round(f.maxbytes/1048576) mb_max,
|
||||
f.autoextensible autoext,
|
||||
round(f.increment_by * t.block_size / 1048576) mb_increment
|
||||
from dba_data_files f, dba_tablespaces t
|
||||
where f.tablespace_name = t.tablespace_name
|
||||
order by f.tablespace_name, f.file_name;
|
||||
column tablespace_name format a15
|
||||
column stare format a26
|
||||
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.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
|
||||
)
|
||||
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) < 1048576
|
||||
then 'ATENTIE: MAXBYTES ATINS' 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)
|
||||
|
||||
# tablespace-urile cu maxbytes efectiv atins - top segmente acolo
|
||||
$r2m = Invoke-Sql -Sql @"
|
||||
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
|
||||
from dba_data_files f
|
||||
group by f.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) < 1048576;
|
||||
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_]+$' })
|
||||
|
||||
if ($tsProblema.Count -gt 0) {
|
||||
$sbSeg = New-Object System.Text.StringBuilder
|
||||
[void]$sbSeg.AppendLine('set pagesize 0 linesize 250 trimspool on feedback off heading off')
|
||||
foreach ($ts in $tsProblema) {
|
||||
[void]$sbSeg.AppendLine("select 'Tablespace $ts - top $Top segmente:' from dual;")
|
||||
[void]$sbSeg.AppendLine(@"
|
||||
select rpad(owner,20) || rpad(segment_name,35) || rpad(segment_type,18) || round(bytes/1048576) || ' MB'
|
||||
from (select owner, segment_name, segment_type, bytes from dba_segments where tablespace_name = '$ts' order by bytes desc)
|
||||
where rownum <= $Top;
|
||||
"@)
|
||||
if ($ts -eq 'SYSTEM') {
|
||||
[void]$sbSeg.AppendLine("select 'NOTA: privilegiile ANY (ex. DROP ANY TABLE/TRUNCATE ANY TABLE) nu se aplica pe obiecte din schema SYS cand O7_DICTIONARY_ACCESSIBILITY=FALSE - curatarea unui tabel din SYS cere conectare SYSDBA, nu contafin_oracle.' from dual;")
|
||||
}
|
||||
}
|
||||
[void]$sbSeg.AppendLine('exit')
|
||||
$r2s = Invoke-Sql -Sql $sbSeg.ToString()
|
||||
Write-Output ''
|
||||
Write-Output ('--- Top segmente pe tablespace-urile marcate ATENTIE (' + ($tsProblema -join ', ') + ') ---')
|
||||
Write-Output $r2s.Text
|
||||
}
|
||||
|
||||
# MAX_PDB_STORAGE - doar daca CDB si -SysPassword dat
|
||||
Write-Output ''
|
||||
Write-Output '===== 2b. MAX_PDB_STORAGE (CDB$ROOT) ====='
|
||||
if (-not $ver12plus) {
|
||||
Write-Output 'Sarit - baza sub versiunea 12c, nu are CDB/PDB.'
|
||||
} elseif (-not $ConnStrSys) {
|
||||
Write-Output 'Sarit - necesita -SysPassword (conectare SYSDBA + alter session set container=CDB$ROOT; contafin_oracle nu vede limita din PDB).'
|
||||
} else {
|
||||
$rPdb = Invoke-SqlSys -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
begin
|
||||
execute immediate 'alter session set container = CDB`$ROOT';
|
||||
for r in (select con_id, name, open_mode from v`$pdbs order by con_id) loop
|
||||
dbms_output.put_line('PDB con_id=' || r.con_id || ' name=' || r.name || ' open_mode=' || r.open_mode);
|
||||
end loop;
|
||||
begin
|
||||
for r in (select p.con_id, p.name, round(nvl(c.max_size,0)/1048576) mb_max
|
||||
from v`$pdbs p, v`$containers c
|
||||
where p.con_id = c.con_id(+)
|
||||
order by p.con_id) loop
|
||||
dbms_output.put_line(' ' || r.name || ' MAX_PDB_STORAGE(MB)=' || case when r.mb_max = 0 then 'nelimitat/necunoscut' else to_char(r.mb_max) end);
|
||||
end loop;
|
||||
exception when others then
|
||||
dbms_output.put_line('MAX_PDB_STORAGE: interogare v`$containers.max_size esuata (' || sqlerrm || ').');
|
||||
dbms_output.put_line('Verifica manual: ALTER PLUGGABLE DATABASE <pdb> STORAGE; sau interogheaza dba_pdbs/v`$pdbs direct pe server.');
|
||||
end;
|
||||
exception
|
||||
when others then
|
||||
if sqlcode = -1031 then
|
||||
dbms_output.put_line('EROARE la comutarea pe CDB`$ROOT: ORA-01031 (privilegii insuficiente). Aliasul TNS dat tinteste probabil un serviciu de PDB (ex. XEPDB1), nu serviciul radacina al CDB - de pe un serviciu de PDB, SYSDBA nu poate comuta pe CDB`$ROOT. Necesita un alias/serviciu separat care tinteste radacina (de obicei numele instantei, nu al PDB-ului).');
|
||||
else
|
||||
dbms_output.put_line('EROARE la comutarea pe CDB`$ROOT: ' || sqlerrm);
|
||||
end if;
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Write-Output $rPdb.Text
|
||||
}
|
||||
|
||||
# ---------- 3. Audit Oracle ----------
|
||||
$r3 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'AUD`$ (contafin_oracle): ' || count(*) from sys.aud`$;
|
||||
select 'FGA_LOG`$ (contafin_oracle): ' || count(*) from sys.fga_log`$;
|
||||
select 'audit_file_dest = ' || value from v`$parameter where name = 'audit_file_dest';
|
||||
select 'audit_trail = ' || value from v`$parameter where name = 'audit_trail';
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '3. AUDIT ORACLE (tabele, din contafin_oracle)' -Text $r3.Text
|
||||
|
||||
if ($ver12plus) {
|
||||
$r3u = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'unified_audit_trail: ' || count(*) || ' randuri' from unified_audit_trail;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '3b. UNIFIED AUDIT TRAIL' -Text $r3u.Text
|
||||
} else {
|
||||
Write-Output ''
|
||||
Write-Output '===== 3b. UNIFIED AUDIT TRAIL ====='
|
||||
Write-Output 'Sarit - baza sub versiunea 12c, nu are unified auditing.'
|
||||
}
|
||||
|
||||
if (-not $ConnStrSys) {
|
||||
Write-Output ''
|
||||
Write-Output '===== 3c. AUDIT INTERN (SYSDBA) ====='
|
||||
Write-Output 'Sarit - necesita -SysPassword. sys.aud$/fga_log$ sunt obiecte SYS: privilegiile ANY nu se aplica pe ele (O7_DICTIONARY_ACCESSIBILITY=FALSE), deci contafin_oracle poate primi ORA-01031 mai sus chiar daca are rol DBA.'
|
||||
} else {
|
||||
$r3s = Invoke-SqlSys -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'AUD`$ (sysdba): ' || count(*) from sys.aud`$;
|
||||
select 'FGA_LOG`$ (sysdba): ' || count(*) from sys.fga_log`$;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '3c. AUDIT INTERN (rezultat garantat, conectat SYSDBA)' -Text $r3s.Text
|
||||
}
|
||||
Write-Output 'Fisierele fizice .aud din audit_file_dest (numar + MB reale): vezi sectiunea 6 (-Disc).'
|
||||
Write-Output 'Curatare (doar sugestie, niciodata executata automat): oprire viitoare = alter system set audit_trail=NONE scope=spfile (cere restart instanta); golire sys.aud$/fga_log$ = DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL sau delete direct, ambele SYSDBA; fisierele .aud se pot sterge direct de pe disc (independente de dictionar).'
|
||||
|
||||
# ---------- 4. Alert log / trace / ADR ----------
|
||||
Write-Output ''
|
||||
Write-Output '===== 4. ALERT LOG / TRACE / ADR (cai) ====='
|
||||
$diagPaths = @()
|
||||
if ($ver11plus) {
|
||||
$r4 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 300 trimspool on feedback off heading off
|
||||
select 'DIAG|' || name || '|' || value from v`$diag_info where name in ('Diag Trace','Diag Alert','Diag Incident','Diag Cdump');
|
||||
exit
|
||||
"@
|
||||
Write-Output $r4.Text
|
||||
$diagPaths = @($r4.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('DIAG|') } | ForEach-Object {
|
||||
$parts = $_.Substring(5) -split '\|', 2
|
||||
[PSCustomObject]@{ Label = ('DIAG_' + ($parts[0] -replace '[^A-Za-z0-9]','_')).ToUpper(); Path = $parts[1] }
|
||||
})
|
||||
} else {
|
||||
$r4 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 300 trimspool on feedback off heading off
|
||||
select 'DIAG|BACKGROUND|' || value from v`$parameter where name = 'background_dump_dest';
|
||||
select 'DIAG|USER|' || value from v`$parameter where name = 'user_dump_dest';
|
||||
select 'DIAG|CORE|' || value from v`$parameter where name = 'core_dump_dest';
|
||||
exit
|
||||
"@
|
||||
Write-Output '(baza sub 11g - fara ADR/diagnostic_dest, foloseste background_dump_dest/user_dump_dest/core_dump_dest)'
|
||||
Write-Output $r4.Text
|
||||
$diagPaths = @($r4.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('DIAG|') } | ForEach-Object {
|
||||
$parts = $_.Substring(5) -split '\|', 2
|
||||
[PSCustomObject]@{ Label = ('DIAG_' + $parts[0]); Path = $parts[1] }
|
||||
})
|
||||
}
|
||||
Write-Output 'Marimea reala a acestor foldere (alert log, trace, incident, cdump): vezi sectiunea 6 (-Disc) - SQL nu vede sistemul de fisiere.'
|
||||
Write-Output 'Curatare (doar sugestie): adrci exec="set homepath <path>; purge -age <minute> -type ALERT/INCIDENT/TRACE" rulat ca proces extern (prin ExecuteScriptOS) - purjeaza doar diagnostic vechi, nu afecteaza baza.'
|
||||
|
||||
# ---------- 5. Archivelog / Fast Recovery Area ----------
|
||||
$r5 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'log_mode = ' || log_mode from v`$database;
|
||||
select 'db_recovery_file_dest = ' || nvl(value,'(neconfigurat)') from v`$parameter where name = 'db_recovery_file_dest';
|
||||
select 'db_recovery_file_dest_size(MB) = ' || round(to_number(value)/1048576) from v`$parameter where name = 'db_recovery_file_dest_size';
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '5. ARCHIVELOG / FAST RECOVERY AREA' -Text $r5.Text
|
||||
|
||||
$r5b = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column name format a60
|
||||
select round(space_limit/1048576) mb_limita, round(space_used/1048576) mb_folosit,
|
||||
round(space_reclaimable/1048576) mb_recuperabil, number_of_files
|
||||
from v`$recovery_file_dest;
|
||||
column file_type format a20
|
||||
select file_type, percent_space_used, percent_space_reclaimable, number_of_files
|
||||
from v`$flash_recovery_area_usage
|
||||
order by percent_space_used desc;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '5b. FRA - utilizare pe tip de fisier' -Text $r5b.Text
|
||||
|
||||
# linie separata, fara ambiguitate de coloane, doar pentru pragul de alarma (nu pentru afisare)
|
||||
$r5c = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 100 trimspool on feedback off heading off
|
||||
select 'FRAPCT|' || round(space_used*100/nullif(space_limit,0),1) from v`$recovery_file_dest;
|
||||
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 ($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 '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).'
|
||||
}
|
||||
|
||||
# ---------- 6. Spatiu pe discurile serverului (optional, scrie un .ps1 temporar in DMPDIR) ----------
|
||||
Write-Output ''
|
||||
Write-Output '===== 6. SPATIU DISC (server) ====='
|
||||
if (-not $Disc) {
|
||||
Write-Output 'Sarit implicit - ruleaza cu -Disc pentru spatiul liber pe discurile fizice si marimea reala a folderelor oradata/audit/diag/DMPDIR/FRA.'
|
||||
Write-Output 'Este singura parte a scriptului care NU e strict read-only: scrie un .ps1 temporar in DMPDIR (prin sys.ExecuteScriptOS) si il sterge la final.'
|
||||
} else {
|
||||
$rFolders = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 300 trimspool on feedback off heading off
|
||||
select 'ORADATA|' || substr(file_name,1,instr(file_name,'\',-1)-1)
|
||||
from (select distinct substr(file_name,1,instr(file_name,'\',-1)-1) file_name from dba_data_files);
|
||||
select 'AUDITDIR|' || value from v`$parameter where name = 'audit_file_dest';
|
||||
select 'DMPDIR|' || directory_path from all_directories where directory_name = 'DMPDIR';
|
||||
select 'FRADIR|' || value from v`$parameter where name = 'db_recovery_file_dest' and value is not null;
|
||||
exit
|
||||
"@
|
||||
$folders = New-Object System.Collections.ArrayList
|
||||
$seen = New-Object 'System.Collections.Generic.HashSet[string]' ([StringComparer]::OrdinalIgnoreCase)
|
||||
foreach ($line in ($rFolders.Text -split "`r?`n")) {
|
||||
$line = $line.Trim()
|
||||
foreach ($prefix in @('ORADATA','AUDITDIR','DMPDIR','FRADIR')) {
|
||||
if ($line.StartsWith($prefix + '|')) {
|
||||
$p = $line.Substring($prefix.Length + 1).Trim()
|
||||
if ($p -and $seen.Add($prefix + '::' + $p.ToUpper())) {
|
||||
[void]$folders.Add([PSCustomObject]@{ Label = $prefix; Path = $p })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($dp in $diagPaths) {
|
||||
if ($dp.Path -and $seen.Add($dp.Label + '::' + $dp.Path.ToUpper())) {
|
||||
[void]$folders.Add($dp)
|
||||
}
|
||||
}
|
||||
|
||||
$psTemplate = @'
|
||||
$dOut = 'C:\DMPDIR\diag_spatiu_out.txt'
|
||||
Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object {
|
||||
$pct = 0
|
||||
if ($_.Size -gt 0) { $pct = [math]::Round($_.FreeSpace/$_.Size*100,1) }
|
||||
"DISC {0} {1} {2} {3}" -f $_.DeviceID, [math]::Round($_.Size/1GB,2), [math]::Round($_.FreeSpace/1GB,2), $pct
|
||||
} | Out-File -Encoding ascii $dOut
|
||||
__FOLDERS__
|
||||
'@
|
||||
$folderLines = foreach ($f in $folders) {
|
||||
$escaped = $f.Path.Replace("'", "''")
|
||||
$lbl = $f.Label
|
||||
@"
|
||||
if (Test-Path -LiteralPath '$escaped') {
|
||||
`$items = Get-ChildItem -LiteralPath '$escaped' -Recurse -File -ErrorAction SilentlyContinue
|
||||
`$cnt = @(`$items).Count
|
||||
`$sum = (`$items | Measure-Object -Property Length -Sum).Sum
|
||||
if (-not `$sum) { `$sum = 0 }
|
||||
"FOLDER $lbl|$escaped|{0}|{1}" -f `$cnt, [math]::Round(`$sum/1MB,1) | Out-File -Encoding ascii -Append `$dOut
|
||||
`$aud = @(`$items | Where-Object { `$_.Extension -ieq '.aud' })
|
||||
if (`$aud.Count -gt 0) {
|
||||
`$audSum = (`$aud | Measure-Object -Property Length -Sum).Sum
|
||||
"AUDFILES $lbl|{0}|{1}" -f `$aud.Count, [math]::Round(`$audSum/1MB,1) | Out-File -Encoding ascii -Append `$dOut
|
||||
}
|
||||
} else {
|
||||
"FOLDER $lbl|$escaped|MISSING" | Out-File -Encoding ascii -Append `$dOut
|
||||
}
|
||||
"@
|
||||
}
|
||||
$psScript = $psTemplate.Replace('__FOLDERS__', ([string]::Join("`n", $folderLines)))
|
||||
$psScriptSql = $psScript.Replace("'", "''")
|
||||
|
||||
$rLaunch = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
lcPS server_info.value%type;
|
||||
begin
|
||||
select value into lcPS from server_info where upper(name) = 'POWERSHELLPATH';
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu_out.txt'); exception when others then null; end;
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu.ps1'); exception when others then null; end;
|
||||
pack_utils_file.clob2fileX('$psScriptSql', 'DMPDIR', 'diag_spatiu.ps1');
|
||||
sys.ExecuteScriptOS(lcPS, 'C:\DMPDIR\diag_spatiu.ps1');
|
||||
dbms_output.put_line('Lansat pe server (' || lcPS || '), astept rezultatul...');
|
||||
exception when others then
|
||||
dbms_output.put_line('EROARE la lansare: ' || sqlerrm);
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Write-Output $rLaunch.Text
|
||||
|
||||
if ($rLaunch.Text -notmatch 'EROARE la lansare') {
|
||||
$gata = Wait-RemoteFile -Directory 'DMPDIR' -FileName 'diag_spatiu_out.txt' -TimeoutSec 60
|
||||
if (-not $gata) {
|
||||
Write-Output 'EROARE: rezultatul nu a aparut in 60s. Posibile cauze: server_info.POWERSHELLPATH gresit, politica de executie PowerShell blocheaza scriptul, sys.ExecuteScriptOS nu are drept de executie, sau serverul nu e Windows (DMPDIR pe cale Linux - mecanismul ExecuteScriptOS e specific Windows/PowerShell). Verifica manual C:\DMPDIR\diag_spatiu.ps1 pe server.'
|
||||
Invoke-Sql -Sql @"
|
||||
set feedback off
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu.ps1'); exception when others then null; end;
|
||||
/
|
||||
exit
|
||||
"@ | Out-Null
|
||||
Write-Output 'Curatare: am incercat oricum stergerea diag_spatiu.ps1 din DMPDIR (best-effort, fara confirmare de succes daca serverul nu a raspuns).'
|
||||
} else {
|
||||
$rRead = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
lf utl_file.file_type;
|
||||
lc_line varchar2(32767);
|
||||
begin
|
||||
lf := utl_file.fopen('DMPDIR','diag_spatiu_out.txt','R',32767);
|
||||
begin
|
||||
loop
|
||||
utl_file.get_line(lf, lc_line, 32767);
|
||||
dbms_output.put_line(lc_line);
|
||||
end loop;
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
utl_file.fclose(lf);
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu_out.txt'); exception when others then null; end;
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu.ps1'); exception when others then null; end;
|
||||
exception when others then
|
||||
dbms_output.put_line('EROARE citire: ' || sqlerrm);
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
$discLines = @()
|
||||
$folderLinesOut = @()
|
||||
foreach ($line in ($rRead.Text -split "`r?`n")) {
|
||||
if ($line -match '^DISC\s+(\S+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)') {
|
||||
$discLines += (' disc {0}: total {1} GB, liber {2} GB ({3}%)' -f $Matches[1], $Matches[2], $Matches[3], $Matches[4])
|
||||
} elseif ($line -match '^FOLDER\s+(\S+)\|(.+)\|MISSING\s*$') {
|
||||
$folderLinesOut += (' {0} ({1}): nu exista pe server' -f $Matches[1], $Matches[2])
|
||||
} elseif ($line -match '^FOLDER\s+(\S+)\|(.+)\|(\d+)\|([\d.]+)\s*$') {
|
||||
$folderLinesOut += (' {0} ({1}): {2} fisiere, {3} MB' -f $Matches[1], $Matches[2], $Matches[3], $Matches[4])
|
||||
} elseif ($line -match '^AUDFILES\s+(\S+)\|(\d+)\|([\d.]+)\s*$') {
|
||||
$folderLinesOut += (' din care .aud: {0} fisiere, {1} MB' -f $Matches[2], $Matches[3])
|
||||
} elseif ($line -match '\S') {
|
||||
$discLines += (' ' + $line)
|
||||
}
|
||||
}
|
||||
Write-Output 'Discuri fixe:'
|
||||
Write-Output ($discLines -join "`n")
|
||||
Write-Output 'Foldere (oradata / audit / diag / DMPDIR / FRA):'
|
||||
Write-Output ($folderLinesOut -join "`n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ---------- 7. Alti mancatori de spatiu ----------
|
||||
Write-Output ''
|
||||
Write-Output '===== 7. ALTI MANCATORI DE SPATIU ====='
|
||||
|
||||
$r7a = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'user_recyclebin (schema ' || sys_context('userenv','session_user') || '): ' || count(*) || ' obiecte, ' ||
|
||||
round(sum(space)*8192/1048576) || ' MB (aprox, space in blocuri)'
|
||||
from user_recyclebin;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7a. RECYCLEBIN (schema conectata)' -Text $r7a.Text
|
||||
|
||||
if ($ConnStrSys) {
|
||||
$r7as = Invoke-SqlSys -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'dba_recyclebin (toata baza): ' || count(*) || ' obiecte, ' ||
|
||||
round(sum(space)*8192/1048576) || ' MB (aprox)'
|
||||
from dba_recyclebin;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7a-bis. RECYCLEBIN (toata baza, SYSDBA)' -Text $r7as.Text
|
||||
} else {
|
||||
Write-Output 'RECYCLEBIN la nivel de baza (dba_recyclebin): sarit - necesita -SysPassword.'
|
||||
}
|
||||
|
||||
$r7b = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'UNDO tablespace = ' || value from v`$parameter where name = 'undo_tablespace';
|
||||
select 'UNDO alocat(MB) = ' || round(sum(bytes)/1048576)
|
||||
from dba_data_files
|
||||
where tablespace_name = (select value from v`$parameter where name = 'undo_tablespace');
|
||||
select 'tranzactii active = ' || count(*) from v`$transaction;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7b. UNDO' -Text ($r7b.Text + "`nResize UNDO poate da ORA-03297 daca extenturile nu au expirat inca - de incercat doar dupa ce activitatea scade, niciodata automat.")
|
||||
|
||||
$r7c = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'dba_tab_stats_history: ' || count(*) || ' randuri, cel mai vechi = ' || to_char(min(stats_update_time),'yyyy-mm-dd')
|
||||
from dba_tab_stats_history;
|
||||
select 'dba_scheduler_job_run_details: ' || count(*) || ' randuri, cel mai vechi = ' || to_char(min(log_date),'yyyy-mm-dd')
|
||||
from dba_scheduler_job_run_details;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7c. ISTORIC STATISTICI / SCHEDULER' -Text ($r7c.Text + "`nCuratare (doar sugestie): DBMS_STATS.PURGE_STATS(<data>); DBMS_SCHEDULER.PURGE_LOG(log_history => <zile>).")
|
||||
|
||||
$r7d = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column tablespace_name format a20
|
||||
select tablespace_name, round(sum(bytes)/1048576) mb_alocat from dba_temp_files group by tablespace_name;
|
||||
column tablespace_name format a20
|
||||
select tablespace_name, round(sum(bytes_used)/1048576) mb_folosit, round(sum(bytes_free)/1048576) mb_liber
|
||||
from v`$temp_space_header group by tablespace_name;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7d. TEMP (alocat vs folosit)' -Text $r7d.Text
|
||||
|
||||
$r7e = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column owner format a20
|
||||
column segment_name format a35
|
||||
column segment_type format a18
|
||||
column tablespace_name format a15
|
||||
select * from (
|
||||
select owner, segment_name, segment_type, tablespace_name, round(bytes/1048576) mb
|
||||
from dba_segments
|
||||
order by bytes desc
|
||||
) where rownum <= $Top;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title ('7e. TOP ' + $Top + ' SEGMENTE DIN TOATA BAZA (generic, fara nume hardcodate)') -Text $r7e.Text
|
||||
|
||||
# ---------- 8. Verdict ----------
|
||||
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.')
|
||||
} else {
|
||||
Write-Output 'Niciun tablespace la limita de maxbytes gasit (sectiunea 2).'
|
||||
}
|
||||
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 '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) {
|
||||
Write-Output 'Fara -SysPassword: sectiunile 2b (MAX_PDB_STORAGE), 3c (audit intern sys.aud$/fga_log$) si 7a-bis (dba_recyclebin) au fost sarite - ruleaza cu -SysPassword daca ai parola SYS a acestui client pentru imaginea completa.'
|
||||
}
|
||||
if (-not $Disc) {
|
||||
Write-Output 'Fara -Disc: marimile reale pe disc (audit_file_dest, alert/trace/ADR, oradata, FRA, discuri fizice) nu au fost masurate - ruleaza cu -Disc pentru ele.'
|
||||
}
|
||||
|
||||
Remove-TempDir
|
||||
exit 0
|
||||
231
utile/livrare.ps1
Normal file
231
utile/livrare.ps1
Normal file
@@ -0,0 +1,231 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Lantul complet de dinaintea si din timpul unui commit: sync text VFP, curatenie,
|
||||
verificari de livrare, stare repo-uri, commit + push.
|
||||
|
||||
.DESCRIPTION
|
||||
1. git_sync.ps1 -ProjectRoot <root> - reimprospateaza .vc2/.sc2 din arbore.
|
||||
Iesire nenula -> opreste tot (nu se comite cu text nesincronizat). Se sare cu -FaraSync.
|
||||
2. curatenie.ps1 -ProjectRoot <root> - sterge artefactele de lucru (neurmarite de git).
|
||||
3. Verificari de livrare (avertismente, neblocante): changelog neatins, fisiere de runda
|
||||
ramase, binare VFP fara perechea text in modificari.
|
||||
4. Stare repo proiect si repo COMUN (separat, partajat de toate aplicatiile ROA):
|
||||
git status --short + git diff --stat.
|
||||
5. Commit + push. Proiectul implicit; COMUN doar cu -Comun explicit (altfel doar raportat).
|
||||
Niciodata push --force. Comite pe ramura curenta, nu creeaza alta.
|
||||
6. -DryRun: ruleaza pasii 1-4 (curatenia in -DryRun) si se opreste inainte de commit.
|
||||
|
||||
.PARAMETER ProjectRoot
|
||||
Radacina proiectului (implicit dedus, ca la curatenie.ps1 - doua nivele deasupra acestui script).
|
||||
|
||||
.PARAMETER Mesaj
|
||||
Mesajul de commit. Obligatoriu la o rulare reala (fara -DryRun).
|
||||
|
||||
.PARAMETER Comun
|
||||
Comite si impinge si repo-ul COMUN (implicit doar proiectul).
|
||||
|
||||
.PARAMETER FaraSync
|
||||
Sare peste git_sync.ps1 (util cand nu s-a atins niciun binar VFP).
|
||||
|
||||
.PARAMETER FaraPush
|
||||
Doar commit local, fara push.
|
||||
|
||||
.PARAMETER DryRun
|
||||
Nu modifica nimic - arata ce s-ar comite si unde.
|
||||
|
||||
.EXAMPLE
|
||||
powershell -File COMUN\utile\livrare.ps1 -DryRun
|
||||
|
||||
.EXAMPLE
|
||||
powershell -File COMUN\utile\livrare.ps1 -Mesaj "achizitie import: rebindare ControlSource"
|
||||
|
||||
.EXAMPLE
|
||||
powershell -File COMUN\utile\livrare.ps1 -Mesaj "conventie noua in COMUN" -Comun
|
||||
|
||||
.EXAMPLE
|
||||
powershell -File COMUN\utile\livrare.ps1 -Mesaj "doar .prg, fara binare" -FaraSync -FaraPush
|
||||
#>
|
||||
param(
|
||||
[string]$ProjectRoot,
|
||||
[string]$Mesaj,
|
||||
[switch]$Comun,
|
||||
[switch]$FaraSync,
|
||||
[switch]$FaraPush,
|
||||
[switch]$DryRun
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not $ProjectRoot) { $ProjectRoot = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent }
|
||||
$comunPath = Join-Path $ProjectRoot 'COMUN'
|
||||
$gitSync = 'D:\ROA\UTIL\foxbin2prg\git_sync.ps1'
|
||||
$curatenie = Join-Path $PSScriptRoot 'curatenie.ps1'
|
||||
|
||||
if (-not $DryRun -and -not $Mesaj) {
|
||||
Write-Output 'livrare: -Mesaj este obligatoriu (sau ruleaza cu -DryRun)'
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Output ('livrare: ProjectRoot=' + $ProjectRoot)
|
||||
|
||||
# --- pas 1: git_sync ---
|
||||
if ($FaraSync) {
|
||||
Write-Output '[1] git_sync: sarit (-FaraSync)'
|
||||
} else {
|
||||
if (-not (Test-Path $gitSync)) {
|
||||
Write-Output ('[1] git_sync: NU s-a gasit ' + $gitSync)
|
||||
exit 2
|
||||
}
|
||||
& powershell -ExecutionPolicy Bypass -File $gitSync -ProjectRoot $ProjectRoot
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Output ('[1] git_sync: ESUAT (cod ' + $LASTEXITCODE + ') - opresc tot, nu se comite')
|
||||
exit 2
|
||||
}
|
||||
Write-Output '[1] git_sync: OK'
|
||||
}
|
||||
|
||||
# --- pas 2: curatenie ---
|
||||
$curArgs = @('-ProjectRoot', $ProjectRoot)
|
||||
if ($DryRun) { $curArgs += '-DryRun' }
|
||||
Write-Output '[2] curatenie:'
|
||||
& powershell -ExecutionPolicy Bypass -File $curatenie @curArgs | ForEach-Object { Write-Output (' ' + $_) }
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Output ('[2] curatenie: cod neasteptat ' + $LASTEXITCODE + ' (continui)')
|
||||
}
|
||||
|
||||
# --- fisiere modificate per repo (dupa curatenie) ---
|
||||
function Get-ChangedFiles($repoPath) {
|
||||
if (-not (Test-Path (Join-Path $repoPath '.git'))) { return @() }
|
||||
$rezultat = New-Object System.Collections.ArrayList
|
||||
foreach ($linie in (& git -C $repoPath status --porcelain --untracked-files=all)) {
|
||||
if (-not $linie) { continue }
|
||||
$cale = $linie.Substring(3)
|
||||
if ($cale -match ' -> ') { $cale = ($cale -split ' -> ')[1] }
|
||||
$cale = $cale.Trim('"')
|
||||
[void]$rezultat.Add($cale)
|
||||
}
|
||||
return $rezultat
|
||||
}
|
||||
|
||||
$modifProiect = Get-ChangedFiles $ProjectRoot
|
||||
$modifComun = Get-ChangedFiles $comunPath
|
||||
|
||||
# --- pas 3: verificari de livrare (avertismente, neblocante) ---
|
||||
$avertismente = New-Object System.Collections.ArrayList
|
||||
|
||||
function Verifica-Livrare($modif, $repoPath, $eticheta) {
|
||||
$codExt = @('.prg', '.vc2', '.sc2', '.ps1')
|
||||
$areCod = $modif | Where-Object { $ext = [System.IO.Path]::GetExtension($_).ToLower(); $codExt -contains $ext }
|
||||
$areChangelog = $modif | Where-Object { $_ -match 'changelog.*\.txt$' }
|
||||
if ($areCod -and -not $areChangelog -and $eticheta -eq 'proiect') {
|
||||
[void]$script:avertismente.Add('changelog neatins (' + $eticheta + ') desi s-a modificat cod')
|
||||
}
|
||||
|
||||
foreach ($f in $modif) {
|
||||
$ext = [System.IO.Path]::GetExtension($f).ToLower()
|
||||
if ($ext -eq '.vcx') { $pereche = [System.IO.Path]::ChangeExtension($f, '.vc2') }
|
||||
elseif ($ext -eq '.scx') { $pereche = [System.IO.Path]::ChangeExtension($f, '.sc2') }
|
||||
else { continue }
|
||||
if ($modif -notcontains $pereche) {
|
||||
[void]$script:avertismente.Add('binar fara text sincronizat in modificari (' + $eticheta + '): ' + $f)
|
||||
}
|
||||
}
|
||||
|
||||
$docsPath = Join-Path $repoPath 'docs'
|
||||
if (Test-Path $docsPath) {
|
||||
$ramase = Get-ChildItem -Path $docsPath -Include @('propuneri_*.md', 'handoff*.md', 'runda*.md') -Recurse -ErrorAction SilentlyContinue
|
||||
foreach ($r in $ramase) {
|
||||
[void]$script:avertismente.Add('fisier de runda ramas (' + $eticheta + '): docs\' + $r.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Verifica-Livrare $modifProiect $ProjectRoot 'proiect'
|
||||
Verifica-Livrare $modifComun $comunPath 'COMUN'
|
||||
|
||||
Write-Output '[3] verificari de livrare:'
|
||||
if ($avertismente.Count -eq 0) {
|
||||
Write-Output ' fara avertismente'
|
||||
} else {
|
||||
foreach ($a in $avertismente) { Write-Output (' ATENTIE: ' + $a) }
|
||||
}
|
||||
|
||||
# --- pas 4: stare repo-uri ---
|
||||
Write-Output '[4] stare repo proiect:'
|
||||
& git -C $ProjectRoot status --short | ForEach-Object { Write-Output (' ' + $_) }
|
||||
& git -C $ProjectRoot diff --stat HEAD | ForEach-Object { Write-Output (' ' + $_) }
|
||||
|
||||
Write-Output '[4] stare repo COMUN:'
|
||||
if (Test-Path (Join-Path $comunPath '.git')) {
|
||||
& git -C $comunPath status --short | ForEach-Object { Write-Output (' ' + $_) }
|
||||
& git -C $comunPath diff --stat HEAD | ForEach-Object { Write-Output (' ' + $_) }
|
||||
} else {
|
||||
Write-Output ' (fara repo git in COMUN)'
|
||||
}
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Output '[5] commit/push: sarit (-DryRun)'
|
||||
if ($modifProiect.Count -gt 0) {
|
||||
Write-Output (' ar comite in proiect (' + $modifProiect.Count + ' fisiere)')
|
||||
} else {
|
||||
Write-Output ' proiect: nimic de comis'
|
||||
}
|
||||
if ($modifComun.Count -gt 0) {
|
||||
if ($Comun) {
|
||||
Write-Output (' ar comite in COMUN (' + $modifComun.Count + ' fisiere)')
|
||||
} else {
|
||||
Write-Output (' COMUN are ' + $modifComun.Count + ' fisiere necomise - nu se comite fara -Comun')
|
||||
}
|
||||
} else {
|
||||
Write-Output ' COMUN: nimic de comis'
|
||||
}
|
||||
exit 0
|
||||
}
|
||||
|
||||
# --- pas 5: commit + push ---
|
||||
$exitCode = 0
|
||||
|
||||
function Comite-Si-Impinge($repoPath, $eticheta, $faraPush) {
|
||||
# mesajele folosesc Write-Host (nu Write-Output): functia e apelata cu rezultatul
|
||||
# capturat intr-o variabila, iar Write-Output ar ajunge in valoarea returnata.
|
||||
if (-not (Test-Path (Join-Path $repoPath '.git'))) {
|
||||
Write-Host ('[5] ' + $eticheta + ': fara repo git, sarit')
|
||||
return 0
|
||||
}
|
||||
& git -C $repoPath add -A
|
||||
& git -C $repoPath diff --cached --quiet
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host ('[5] ' + $eticheta + ': nimic de comis')
|
||||
return 0
|
||||
}
|
||||
$ramura = (& git -C $repoPath rev-parse --abbrev-ref HEAD)
|
||||
& git -C $repoPath commit -m $Mesaj | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host ('[5] ' + $eticheta + ': COMMIT ESUAT pe ramura ' + $ramura)
|
||||
return 1
|
||||
}
|
||||
Write-Host ('[5] ' + $eticheta + ': commit OK pe ramura ' + $ramura)
|
||||
if ($faraPush) {
|
||||
Write-Host ('[5] ' + $eticheta + ': push sarit (-FaraPush)')
|
||||
return 0
|
||||
}
|
||||
& git -C $repoPath push
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host ('[5] ' + $eticheta + ': PUSH ESUAT')
|
||||
return 1
|
||||
}
|
||||
Write-Host ('[5] ' + $eticheta + ': push OK')
|
||||
return 0
|
||||
}
|
||||
|
||||
$exitCode += (Comite-Si-Impinge $ProjectRoot 'proiect' $FaraPush)
|
||||
|
||||
if ($Comun) {
|
||||
$exitCode += (Comite-Si-Impinge $comunPath 'COMUN' $FaraPush)
|
||||
} elseif ($modifComun.Count -gt 0) {
|
||||
Write-Output ('[5] COMUN: ' + $modifComun.Count + ' fisiere necomise - nu se comite fara -Comun')
|
||||
}
|
||||
|
||||
if ($exitCode -gt 0) { exit 3 }
|
||||
Write-Output 'livrare: OK'
|
||||
exit 0
|
||||
Reference in New Issue
Block a user