====== PG Restore ======
===== pg_restore =====
Ovaj alat sadrži brojne opcije prilikom vraćanja baze podataka, i predstavlja prirodnog parnjaka **[[:pgs_dump|pg_dump]]** funkcije. Opcija ima jako mnogo, evo nekoliko osnovnih.
==== Prenos baze podataka na drugi server ====
Pri prenosu celih baza podataka, veoma je važno da izlazni fajl bude kompresovan jer se može desiti da zbog veličine bude nepodesan za prenos/manipulaciju. Kompresijom upravlja [[:pgs_dump|pg_dump]], a niže je primer prenosa baze pod nazivom **b1**, sa **extenzijama**, šemama i svim ostalim Pg objektima. Operaciju izvodim pod sistemskim //postgres// nalogom, iako to može biti bilo koji drugi korisnik sa odgovarajućim pravima :
pg_dump -U postgres -Fc -d b1 -f b1.backup
Objašnjenje parametara:
**-U postgres** znači da operaciju izvodim pod korisničkim nalogom //postgres//.\\
**-Fc** znači da koristim //custom format// fajla, koji dozvoljava najviše opcija pri raspakivanju (pg_restore) baze. Istovremeno, ovaj format automatski podrazumeva kompresovanje podataka.\\
**-d b1** je ime baze podataka koju prenosim/bekapujem/čuvam\\
**-f b1.backup** je ime fajla u koji se podaci pohranjuju.
Ovako kompresovana baza može se vratiti na drugi server sledećom komandom:
pg_restore -U balans_admin -C --disable-triggers -d postgres b1.backup
Objašnjenje parametara:
**-U balans_admin** znači da operaciju izvodim, na novom serveru, pod korisničkim nalogom //balans_admin//. Dobro je znati da novi server ne mora imati iste korisničke naloge.\\
**-C** znači da se na će se pri raspakivanju napraviti nova baza podataka, sa istim imenom kao što ga je imala izvorna.\\
**--disable-triggers** se koristi kada postoje podaci unutar baze koja se restaurira kako bi se izbegle greške u referencijalnim vezama među podacima koji nisu u potpunosti vraćeni. \\
**-d postgres** je parametar koji pravi najviše zabune, jer izgleda kao da dajemo instrukciju da se baza raspakuje u bazu sa imenom //postgres//. Ustvari, parametar -C sprečava da se ovo desi, pa je ime //postgres// iskorišćeno samo zato što takvo sigurno postoji na novom serveru. Moglo je poslužiti i bilo koje drugo, za koje znamo da postoji. Kako smo zadali parametar -C, pg_restore će automatski napraviti bazu pod imenom **b1**, kako je u izvornom b1.backup fajlu i navedeno.\\
**b1.backup** je ime fajla u kom se nalazi spakovana i kompresovana baza koju raspakujemo.
=== Vraćanje samo tekuće baze ===
Kada je baze sadrže mnogo arhiva a potrebno je izvući samo tekuću godinu koristi se sledeći format komande:
pg_restore -U balans_admin -C --disable-triggers -O -x -d bxx -n bcus -n bpub -n btek -f b1.backup
Objašnjenje parametara:
''-n'' - navodim šeme koje želim da izvučem iz bekapa \\
''-O'' - naređujem da se ne rekonstruiše vlasništvo nad objektima (vlasnik postaje korisnik naveden pod ''-U'' opcijom) \\
''-x'' - naređujem da se ne rekonstruišu ni posebne privilegije nad objektima \\
===== psql - vraćanje iz "plain-text" formata =====
Za restore PostgreSQL baze podataka najsvrsishodnije je koristiti postojeci uz mogućnost izmene izvornog fajla koristi se **psql.exe** koji je lociran u folderu kome je instaliran Postgres, **bin **poddirektorijumu. Ovaj način prenosa podataka pravi velike fajlove, i nije pogodan za prenos celih baza, ali pošto se baza izvozi kao veliki SQL skript, lako ga je modifikovati (promena nazvia šeme, itd.).
==== Procedura ====
- Pokretanje command prompta (cmd.exe) u administratorskom rezimu
- Navigacija u folder gde se nalazi psql.exe npr: cd Program Files\PostgreSQL\9.6\bin
- Pokretanje komande za restore sa opcijama restore-a:
- **psql -U -d -o -f **
- znacenje opcija: -U , -d , -o -f
Sa psql alatom se može odraditi i skript za pravljenje nulte baze npr. psql -f "k:\Data 20\0\9934\b0.9934.10520.20010.sql" -o createb0.log -U postgres postgres
"Switch" parametre treba navesti pre parametara baze i korisničkog imena.
Psql alatu se može zadati i server, port, baza, korisničko ime i lozinka u ovom formatu kao u primerima na https://razvoj.melany.rs/issues/1087
===== Aktivna opcija "zaključavanja perioda" =====
Usled razloga opisanih u [[pgs_dump|pg_dump]] proceduri, a ukoliko prilikom bekapovanja baze nisu preduzeti nikakvi koraci, rekonstrukcija baze treba da ide sledećim tokom. \\
Opisan je najgori scenario: poslovni period u bekapovanij bazi je bio je zaključan na tekući dan u momentu bekapa. \\
Primer je iz realnog sveta, bekap je napravljen na bazi MgMivela, a rekonstruišu se samo šeme **bcus**, **bpub** i **btek** (tekuća godina). \\
Rekonstrukcija šema i podataka istovremeno ne može biti sprovedena. Prvo je neophodno rekonstruisati šeme. \\
#> pg_restore -h 192.168.0.5 -p 5432 -U postgres -v -n bcus -n bpub -n btek -O -d b3 -x -s c:\b3_mivela.backup 2>restore.log
Objašnjavam ređe opcije:
''-v'' - //verbose// režim rada, znači bogatiji opisi grešaka i akcija \\
''-n'' - navodim šeme koje želim da izvučem iz bekapa \\
''-O'' - naređujem da se ne rekonstruiše vlasništvo nad objektima (vlasnik postaje korisnik naveden pod ''-U'' opcijom) \\
''-x'' - naređujem da se ne rekonstruišu ni posebne privilegije nad objektima \\
''-s'' - naređujem da se radi **samo rekonstrukcija šeme objekata baze** (definicije tabela, pogleda, funkcija itd.) \\
''2>'' - ovo nije vezano za ''pg_restore'' već ukazuje //shell-u// da izlaz (opis radova) usmeri u fajl ''restore.log'' umesto na ekran (beskorisno). \\ \\
Sada kada imamo definiciju svih objekata može se promeniti funkcija ''bpub.maxdatstocklock()'' \\
CREATE OR REPLACE FUNCTION bpub.maxdatstocklock() RETURNS timestamp AS
$BODY$
DECLARE result timestamp;
BEGIN
SELECT CASE WHEN (MAX(datStockLock) IS NULL)
THEN '1970-03-22'::timestamp
ELSE MAX(datStockLock)
END
FROM btek.firme -- <<< u potpunosti zakucavamo na koju tabelu firme mislimo; search_path više nije bitan
INTO result;
RETURN result;
END;
$BODY$
LANGUAGE plpgsql
STABLE;
Kako je rečeno, u ovom primeru je pored svega još i zaključan period na tekući dan, te rekonstrukcija zapisa nije moguća pre njegovog otključavanja. Za ovaj korak potrebni su nam samo podaci tabele ''btek.firme'' pa ćemo izvući samo njih:
#> pg_restore -h 192.168.0.5 -p 5432 -U postgres -v -n btek -t firme -O -d b3 -x -a c:\b3_mivela.backup 2>restore2.log
Objašnjavam ređe opcije:
''-t'' - navodim tabelu čije podatke želim rekonstruisati \\
''-a'' - naređujem da želim **samo podatke** \\ \\
Otključavam period:
UPDATE btek.firme SET datStockLock=NULL
Ukoliko je potrebno vratiti zaključavanje u prethodno stanje pre postavke u NULL treba očitati tekuću vrednost.
Sada smo spremni da preuzmemo i ostale podatke, ali ovaj put dodajemo i ''--disable-triggers'' parametar kako uvozu ne bi zasmetale privremeno nedostajuće relacije:
#> pg_restore -h 192.168.0.5 -p 5432 -U postgres -v -n bcus -n bpub -n btek -O -d b3 -x -a --disable-triggers c:\b3_mivela.backup 2>restore3.log
Po završetku procesa otvoriti fajl ''restore3.log'' i proveriti ima li grešaka zbog kojih podaci nisu mogli biti učitani. \\
Očekivana je samo jedna greška - tabela ''firme'' neće biti učitana jer su podaci već bili u njoj.
Vreme je da se funkcija ''bpub.maxdatstocklock()'' vrati u izvorni oblik \\
CREATE OR REPLACE FUNCTION bpub.maxdatstocklock() RETURNS timestamp AS
$BODY$
DECLARE result timestamp;
BEGIN
SELECT CASE WHEN (MAX(datStockLock) IS NULL)
THEN '1970-03-22'::timestamp
ELSE MAX(datStockLock)
END
FROM firme -- <<< sada opet search_path upravlja odabirom tabele za regulisanje zaključavanja
INTO result;
RETURN result;
END;
$BODY$
LANGUAGE plpgsql
STABLE;
Ukoliko treba sada je trenutak da se vrati i prethodni datum zaključavanja u ''firme.datStockLock''. \\
Proveriti broj zapisa u tabelama ''racuni'',''otpremnice'',''ulaz'' i ''nalozi''. \\
Trebalo bi da je sve savršeno !