Fisierul era per proiect; acum e in COMUN, partajat de toate aplicatiile ROA. Ramane neversionat in git (docs/local/ adaugat in .gitignore-ul COMUN), exista doar in SVN. Parola SYS e generica, nu difera de la server la server. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014sNn6dmAimtyXkDU4frJrh
177 lines
10 KiB
Markdown
177 lines
10 KiB
Markdown
# Depanare actualizare ROA (CONTAFIN_ORACLE.PACK_UPDATE)
|
|
|
|
Actualizarea automata a aplicatiilor si a bazei ruleaza din jobul `CONTAFIN_ORACLE.UPDATEROA_ZILNIC`
|
|
-> `PACK_UPDATE.UpdateROA`, in 3 etape secventiale: **UpdateApp** (descarca arhivele programelor) ->
|
|
**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 |
|
|
|---|---|
|
|
| pana unde a ajuns fiecare rulare | `UPD_ISTORIC` (`stare`: 0=start, 1=aplicatii, 2=scripturi, 3=aplicare, 4=incheiat; `dataora_end` gol = neincheiata) |
|
|
| cauza reala a esecului | `UPD_LOG` (`dataora_start` = rularea, `secventa`+`dataora` = ordinea; `explicatie` e CLOB) |
|
|
| ce a raportat jobul | `dba_scheduler_job_run_details` (`log_date`, `status`, `additional_info`) |
|
|
| ce versiuni s-au descarcat | `UPD_PROGRAME` |
|
|
| scripturi disponibile / aplicate | `UPD_DATABASE.script_date` vs `<schema>.VERSIUNE.data_script` |
|
|
| **erorile din aplicarea scripturilor** | **`C:\DMPDIR\script_master.log` pe serverul de baze de date** |
|
|
|
|
Un sir de rulari oprite la aceeasi `stare` da direct etapa vinovata, iar prima zi din sir da data de
|
|
la care s-a schimbat ceva.
|
|
|
|
## Capcane
|
|
|
|
- **`UPD_LOG` se goleste la fiecare rulare.** Nu ai istoric: iei log-ul rularii curente, altfel
|
|
relansezi ca sa-l reproduci.
|
|
- **Eroarea din `additional_info` a jobului e de obicei falsa.** Pe orice esec se apeleaza `EmailLog`,
|
|
iar daca SMTP-ul e picat ridica `ORA-20000` care inlocuieste eroarea originala. Cauza adevarata e
|
|
in `UPD_LOG`.
|
|
- **`UpdateApp` abandoneaza tot la primul program nedescarcat** (`exit` din bucla, `CT_INSUCCES`) —
|
|
deci si programele de dupa el in lista, si ambele etape de baza de date. Un singur fisier
|
|
indisponibil blocheaza actualizarile la infinit, tacut.
|
|
- **`GetStare` refuza o rulare noua** cat timp precedenta e neincheiata si nu a trecut o ora.
|
|
Se deblocheaza cu `exec contafin_oracle.pack_update.IncheiereActualizare`.
|
|
- Programele `%USERREPORTS%` merg toate in directorul `UPD_USERREPORTS`, nu in `UPD_<nume_program>`.
|
|
|
|
## Aplicarea scripturilor (script_master.log)
|
|
|
|
Etapa 3 nu ruleaza scripturile din PL/SQL, ci genereaza in `DMPDIR` (`C:\DMPDIR`) cate un
|
|
`script_<SCHEMA>.sql` plus `script_master.sql`, pe care le da unui **SQL\*Plus extern**, cu iesirea
|
|
in `C:\DMPDIR\script_master.log` (`script_master2.log` = pasii de la final).
|
|
|
|
**Erorile de aici NU ajung in `UPD_LOG`.** O rulare care esueaza la un script arata perfect curata
|
|
in baza: `UPD_LOG` fara nicio eroare, doar `UpdateSchemaSQLPLUS ... / UpdateDatabaseSQLPLUS END`.
|
|
Semnele indirecte sunt ca rularea ramane la `stare = 3` fara `dataora_end`, iar
|
|
`<schema>.VERSIUNE` nu mai avanseaza. Scriptul vinovat e primul din `UPD_DATABASE` de dupa ultima
|
|
versiune inregistrata acolo, iar mesajul real e doar in `script_master.log`.
|
|
|
|
Scripturile au `WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK`, deci primul esec opreste tot lantul
|
|
si se repeta identic la fiecare rulare pana e reparat.
|
|
|
|
Fisierul se poate citi si fara acces la desktopul serverului, prin `UTL_FILE` pe directorul
|
|
`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
|
|
`DMPDIR`, il lanseaza cu `sys.ExecuteScriptOS` si asteapta aparitia fisierului in directorul Oracle
|
|
`UPD_<PROGRAM>`. Daca **folderul de pe disc lipseste**, curl esueaza mut si in log apare doar
|
|
`Fisierul NU s-a salvat pe disc.` — verifica intai directorul, nu reteaua.
|
|
|
|
Verificari rapide (read-only, din `contafin_oracle`):
|
|
|
|
```sql
|
|
-- calea configurata
|
|
select directory_name, directory_path from all_directories where directory_name like 'UPD%';
|
|
-- fisierul chiar exista pe disc?
|
|
select dbms_lob.fileexists(bfilename('UPD_ROACONT','ROACONT-2.11.70.zip')) from dual;
|
|
```
|
|
|
|
```sql
|
|
-- directorul exista si e scriibil? ORA-29283 = cale OS inexistenta sau fara drept de scriere
|
|
declare f utl_file.file_type; begin
|
|
f := utl_file.fopen('UPD_USERREPORTS','__probe.txt','W'); utl_file.fclose(f);
|
|
utl_file.fremove('UPD_USERREPORTS','__probe.txt');
|
|
end;
|
|
/
|
|
```
|
|
|
|
URL-ul se testeaza direct cu `curl` de pe orice masina (`optiuni.UPD_URL_APP`, cu `|CUSTOMERID|`
|
|
inlocuit din `sys.auth_detalii.detalii`); daca da 200, problema e local pe server.
|
|
|
|
## Comenzi OS pe serverul de baze de date
|
|
|
|
`sys.ExecuteScriptOS(<powershell>, <cale .ps1>)` creeaza un job scheduler `executable` — **asincron**,
|
|
deci rezultatul se verifica prin polling, nu imediat. Scriptul se scrie cu
|
|
`pack_utils_file.clob2fileX(<clob>, 'DMPDIR', '<nume>.ps1')`. Utila cand ai doar acces Oracle
|
|
(ex. tunel SSH), fara RDP:
|
|
|
|
```sql
|
|
declare lcPS server_info.value%type; begin
|
|
select value into lcPS from server_info where upper(name)='POWERSHELLPATH';
|
|
pack_utils_file.filedelete('DMPDIR','x.ps1');
|
|
pack_utils_file.clob2fileX('New-Item -ItemType Directory -Force -Path ''D:\...'' | Out-Null',
|
|
'DMPDIR','x.ps1');
|
|
sys.ExecuteScriptOS(lcPS, 'C:\DMPDIR\x.ps1');
|
|
end;
|
|
/
|
|
```
|
|
|
|
## Emailuri: log de actualizare vs buletin informativ
|
|
|
|
Sunt **doua emailuri diferite, trimise de doua masini diferite** — se confunda usor.
|
|
|
|
| | Log de actualizare | Buletin informativ |
|
|
|---|---|---|
|
|
| Cine trimite | baza de date, `PACK_UPDATE.EmailLog` (`UTL_SMTP` direct catre `EMAIL_SMTP:EMAIL_PORT`, `AUTH LOGIN`) | **serverul de update** (ASP.NET); baza doar face un GET pe `optiuni.UPD_URL_BULETININF` (cu `|CUSTOMERID|`) prin `PACK_UTILS.URL2Clob`, din `UpdateApp` |
|
|
| Destinatari | `server_info.EMAIL_TO` + `EMAIL_CC` | configurati pe serverul de update, **nu** in `server_info` (ex. `office@romfast.ro`) |
|
|
| Subiect / continut | `Actualizare ROA dd.mm.yyyy hh24:mi:ss`; liniile din `UPD_LOG`, text simplu separat cu TAB | compus de serverul de update |
|
|
| In `UPD_LOG` | erorile SMTP: `EROARE: utl_smpt ERROR CODE ...` | raspunsul HTTP, verbatim (ex. `ERR-1-BULETIN INFORMATIV NU S-A TRIMIS. MOTIVUL: Error: 1429`) |
|
|
|
|
Detalii care conteaza la depanare:
|
|
|
|
- **`EMAIL_CC` nu produce un antet `Cc:`.** Codul il concateneaza cu virgula la `EMAIL_TO` si trimite
|
|
`RCPT TO` pentru toti; antetul e un singur `To: <toti>`. Deci un email primit *in Cc* nu vine de la
|
|
`EmailLog`.
|
|
- **`EMAIL_FROM` e per server de client** (`roaupdate-<client>@romfast.ro`) si difera de contul
|
|
autentificat, care e acelasi peste tot (`EMAIL_USERNAME = roaupdate@romfast.ro`). Expeditorul e
|
|
singurul indiciu din email despre serverul care l-a trimis. Daca `EMAIL_FROM` lipseste, se compune
|
|
din `UTL_INADDR.get_host_name`.
|
|
- **Un buletin esuat nu opreste nimic**: raspunsul `ERR-1-...` e text normal, se scrie in `UPD_LOG` si
|
|
actualizarea merge mai departe. Doar exceptiile HTTP ajung ca `ERR: <url> ...`.
|
|
- **Un SMTP picat, in schimb, opreste tot** — `EmailLog` ridica `ORA-20000` care mascheaza eroarea
|
|
reala (vezi „Capcane" mai sus). E singurul loc din lantul de email care are voie sa arunce.
|
|
|
|
## Configurare (CONTAFIN_ORACLE)
|
|
|
|
- `server_info`: `POWERSHELLDOWNLOAD`, `POWERSHELLPATH`, `POWERSHELLTIMEOUT`, `CURLPATH`,
|
|
`SQLPLUSPATH`, `EMAIL_METHOD`/`EMAIL_SMTP`/`EMAIL_PORT`/`EMAIL_USERNAME`/`EMAIL_PASSWORD`/
|
|
`EMAIL_FROM`/`EMAIL_TO`.
|
|
- `optiuni`: `UPD_URL_APP`, `UPD_URL_DATABASE`, `UPD_URL_BULETININF` (daca lipsesc, pachetul
|
|
foloseste URL-uri implicite din cod).
|
|
|
|
## Conectare la serverul unui client
|
|
|
|
Tunel SSH pe 1521 + alias TNS pe `127.0.0.1` in `D:\ROA\instantclient_19_18\tnsnames.ora`
|
|
(ex. `ROA_ROMCONSTRUCT`), utilizator `contafin_oracle`. Vezi `oracle_export.md` pentru client si
|
|
capcana de encoding; parolele stau in `COMUN\docs\local\oracle.md` (neversionat in git).
|
|
|
|
Serverele de client pot fi Oracle 10g: unele coloane din `dba_scheduler_*` lipsesc
|
|
(`dba_scheduler_running_jobs.last_start_date`) — foloseste `dba_scheduler_job_run_details`.
|