Log-ul de actualizare (PACK_UPDATE.EmailLog, din baza) si buletinul informativ (trimis de serverul de update) sunt doua fluxuri diferite, cu destinatari configurati in locuri diferite. Scripturile de migrare se scriu la nivelul Oracle 10.2 si trebuie sa ruleze si pe 11.x; tabel cu versiunea minima a constructiilor uzuale si limitele XE. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TM9Cxpzrn9wBSkyBNr22Qc
142 lines
7.7 KiB
Markdown
142 lines
7.7 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.
|
|
|
|
## 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).
|
|
|
|
## 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 `docs/local/` al proiectului, neversionat.
|
|
|
|
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`.
|