Bază de date self-hosted: personal vs producție
Să rulezi propriul PostgreSQL e rezonabil pentru un proiect personal și un angajament serios pentru o afacere. Softul e același, responsabilitățile nu.

Să rulezi PostgreSQL pe propriul server este o alegere rezonabilă pentru un proiect personal. Pentru o afacere este un angajament operațional serios. Softul este identic în ambele cazuri. Ce se schimbă este lista de responsabilități care vin la pachet și dacă există cineva la capătul celălalt atunci când una dintre ele eșuează.
Nu suntem neutri aici. Self-hosting-ul îți dă control asupra locului unde stau datele, asupra costului mașinii și asupra modului în care e configurat serverul. Găzduim la rândul nostru baze de date administrate pentru clienți, pentru că responsabilitățile de mai jos sunt muncă reală.
Ce îți dă de fapt self-hosting-ul?
- Locul datelor. Rândurile stau pe o mașină pe care ai ales-o tu, într-o jurisdicție pe care ai ales-o tu, pe un disc pe care îl poți localiza fizic.
- Forma costului. Un VPS mic are un preț lunar previzibil care nu crește cu volumul de citiri așa cum poate crește un plan administrat. Dacă iese mai ieftin în total depinde de cât îți facturezi propriile ore.
- Libertatea de configurare. Extensiile, setările din
postgresql.conf, structura de fișiere, limitele de conexiuni și momentul upgrade-urilor sunt decizia ta.
Portabilitatea intră și ea pe listă: un dump PostgreSQL se restaurează în orice alt PostgreSQL, iar formatul de dump este documentat și stabil. Schimbul: un serviciu găzduit îți vinde responsabilitățile, nu softul.
Cum arată un setup personal minim, dar sigur?
Pentru un proiect secundar, scopul nu este disponibilitatea ridicată. Scopul este ca o parolă furată, o mașină pierdută sau un DELETE greșit să nu încheie proiectul. Patru lucruri fac aproape toată treaba.
Ține serverul în afara internetului public
PostgreSQL ascultă implicit pe localhost, așa cum arată documentația setărilor de conexiune. Ca să ajungi la el de pe laptop, pune în față un tunel SSH sau o rețea privată, în loc să deschizi portul 5432 către toată lumea. Dacă împarte rețeaua cu aplicația, limitează firewall-ul la subnetul respectiv.
Folosește credentiale reale, cu cel mai mic rol care funcționează
PostgreSQL stochează parolele cu SCRAM-SHA-256 implicit, iar opțiunea MD5 este depreciată și programată pentru eliminare. Creează un rol de login separat pentru aplicație și dă-i doar tabelele și operațiile de care are nevoie. Aplicația nu trebuie să fie superuser, iar un connection string scurs nu ar trebui să poată șterge schema.
Regulile de conectare stau în pg_hba.conf, iar documentația este tranșantă despre felul în care sunt citite: se folosește prima înregistrare care se potrivește, fără fall-through. O linie trust aproape de începutul fișierului lasă pe oricine ajunge la port să se autentifice ca orice utilizator. După editare, reîncarcă serverul cu pg_ctl reload sau SELECT pg_reload_conf(), apoi verifică SELECT * FROM pg_hba_file_rules WHERE error IS NOT NULL.
Criptează conexiunea și verifică certificatul
SSL este oprit implicit. Pornirea lui cere un certificat, o cheie și ssl = on. Pe partea de client, sslmode implicit este prefer, care încearcă criptarea și revine la text simplu. require criptează traficul, dar, cum spune documentația libpq, te lasă să te bazezi pe rețea că te duce la serverul corect, deci oprește interceptarea pasivă și nu un atacator la mijloc. Folosește verify-full cu un certificat rădăcină pentru orice trece prin rețele pe care nu le controlezi.
Fă backup-uri, apoi restaurează unul
Pe o singură mașină, un pg_dump nocturn este suficient. Două detalii se ratează ușor. pg_dump face dump pentru o singură bază de date și nu include rolurile sau tablespace-urile, așa că ai nevoie și de pg_dumpall --globals-only. Dump-ul este consistent intern, o fotografie din momentul în care a pornit, dar bazele de date diferite dintr-un pg_dumpall nu sunt sincronizate între ele.
Scrie fișierul unde alți utilizatori nu pot citi, copiază-l pe altă mașină și păstrează mai mult de o generație. Apoi fă partea pe care majoritatea o sar: restaurează-l într-o bază de test cu pg_restore și uită-te la rânduri. Un backup pe care nu l-a restaurat nimeni este o speranță, nu un backup.
Ce se schimbă când baza de date este în producție?
Producția înseamnă datele altor oameni și, de obicei, o promisiune că serviciul este disponibil. Aceleași elemente rămân valabile, dar fiecare primește un al doilea strat, iar al doilea strat este cel care consumă timpul.
O replică nu este un backup
Replicarea în streaming ține un server standby care aplică write-ahead log-ul primarului. Un hot standby poate răspunde și la interogări de citire, ceea ce e util, dar ce contează e de ce nu te protejează. Replică DELETE-ul. O migrare greșită, un script prost sau un tabel corupt ajung pe standby în câteva secunde.
Două fapte contează în operare. Replicarea în streaming este implicit asincronă, iar documentația avertizează că unele tranzacții confirmate pot să nu fi ajuns pe standby când primarul cade. Promovarea este un act explicit, pg_ctl promote sau pg_promote(), nu ceva ce decide standby-ul singur. Dacă nimeni nu e treaz să o ruleze, standby-ul este capacitate de rezervă.
Recuperarea la un moment în timp
Mecanismul care răspunde la „anulează ultimele douăzeci de minute” este arhivarea continuă. Păstrezi un base backup făcut cu pg_basebackup, trimiți fiecare segment WAL într-o arhivă cu archive_command, iar la restaurare redai log-ul până la un moment ales. Documentația este precisă cu limitele: poți recupera orice moment de la momentul în care a fost făcut base backup-ul, dar nu un punct din timpul backup-ului însuși, și ai nevoie de o secvență continuă de WAL care să ajungă înapoi până acolo.
Tot aici e și partea care eșuează în liniște. Dacă archive_command nu mai reușește, PostgreSQL reîncearcă periodic și pg_wal crește; dacă sistemul de fișiere se umple, serverul se oprește cu PANIC și rămâne offline până se eliberează spațiu. Unele eșecuri ale arhivării nu apar deloc în pg_stat_archiver, de aceea documentația îți cere să monitorizezi arhivarea direct. Fereastra de recuperare în care crezi este doar atât de lungă cât WAL-ul pe care chiar l-ai păstrat.
O procedură de restaurare pe care o poate urma altcineva
Scrie pașii, cu comenzile, locațiile fișierelor, locul unde stau credentialele și ordinea operațiilor. Dă procedurii un proprietar. Apoi ruleaz-o periodic pe o copie, pe o mașină care nu este cea de producție, și cronometreaz-o. Numărul măsurat este timpul tău real de recuperare; orice altceva este o presupunere. Documentația recomandă testarea arhivării înainte de primul base backup, păstrarea mai multor seturi și inspectarea bazei după recuperare.
Ferestre de patch-uri
PostgreSQL suportă fiecare versiune majoră cinci ani, iar versiunile minore apar cel puțin o dată la trei luni, potrivit politicii de versionare a proiectului. Versiunile minore conțin remedieri pentru probleme de securitate, corupere de date și bug-uri frecvente, iar proiectul recomandă rularea celei mai recente versiuni minore din majora ta. Un server self-hosted pe care nu îl actualizează nimeni iese din această fereastră fără să anunțe.
O fereastră de patch-uri este răspunsul operațional: un interval recurent, o verificare pe staging și un plan de revenire. Este și responsabilitatea pe care un serviciu administrat o face după programul lui. Amazon RDS, de exemplu, rulează mentenanța într-o fereastră săptămânală de 30 de minute și programează automat patch-urile obligatorii de securitate și fiabilitate. Fereastra stabilește când începe mentenanța, nu când se termină, iar documentația avertizează că nu împiedică upgrade-urile obligatorii dacă amâni mereu.
Loguri de acces și medii separate
Pornește log_connections, care e gol implicit, și log_disconnections. Autentificările eșuate se loghează oricum, iar acesta este semnalul care contează când cineva încearcă parole. Un prag pentru interogările lente, cum e log_min_duration_statement, îți dă o urmă a ce face aplicația de fapt la trei dimineața.
Ține producția, staging-ul și dezvoltarea pe baze de date separate, cu roluri și credentiale separate. Un staging care împarte connection string-ul de producție este un incident de producție cu pași în plus, iar o copie restaurată din datele de producție într-un mediu de dezvoltare este o problemă de protecție a datelor înainte de a fi una tehnică.
Ce preia de fapt un serviciu găzduit?
Pe Amazon RDS, backup-urile automate rulează zilnic într-o fereastră de backup, perioada de păstrare se poate seta între 0 și 35 de zile, iar 0 le dezactivează. În interiorul perioadei de păstrare poți restaura la un moment în timp. Ștergerea instanței șterge backup-urile automate, dacă nu alegi să le păstrezi, iar snapshot-urile manuale sunt independente și supraviețuiesc.
Google Cloud SQL face backup-uri automate la un interval pe care îl configurezi și le stochează incremental; documentația notează că intervalul de păstrare depinde de opțiunea de backup folosită, așa că citește setarea în loc să presupui o valoare implicită. Recuperarea la un moment în timp se face într-o instanță nouă, nu în cea existentă, ceea ce e igienă bună și o diferență de știut înainte de incident.
Ce nu preia niciunul dintre ele este partea care decide dacă restaurarea este utilă: schema, indexurile, planurile de execuție, credentialele, cunoașterea a ceea ce înseamnă date corecte și decizia de a exersa. O bază de date administrată scoate munca de mentenanță, nu responsabilitatea.
Cât costă să greșești?
Cifrele depind de afacere. Mecanismele sunt aceleași peste tot.
- Punctul de recuperare. Dacă ultimul backup bun este de aseară, o pană la ora 17:00 te costă o zi lucrătoare de înregistrări. Golul este dat de ritmul backup-urilor.
- Timpul de recuperare. O restaurare înseamnă descărcare, dezarhivare, redare de log, verificare. Crește cu dimensiunea bazei de date și cu cât de ruginit este omul care o face. Până nu l-ai cronometrat, nu ai o estimare.
- Eșecul tăcut. Joburile de backup eșuează săptămâni la rând fără să observe nimeni, iar problema apare în incident.
- Greșeala logică. O migrare prost făcută sau un delete din greșeală se copiază instantaneu pe fiecare replică. Doar o arhivă la moment în timp sau un dump mai vechi le mai poate da înapoi.
- Golul de patch-uri. Lunile fără actualizare sunt luni de vulnerabilități cunoscute lăsate deschise, pe un port la care cineva poate ajunge.
- Raza de impact. Un credential de superuser într-un fișier de configurare al aplicației sau un port de bază de date expus pe internet transformă un bug mic într-un compromis complet.
Niciuna dintre ele nu cere răutate. Sunt greșeli obișnuite, iar configurarea operațională există ca să le facă supraviețuibile.
O autoevaluare scurtă
Răspunde sincer. Sunt ordonate aproximativ după cât de des răspunsul este nu.
- Poți restaura baza de date la o anumită oră, nu doar la starea de aseară?
- Ai restaurat un backup în ultimele trei luni, pe altă mașină decât cea care l-a făcut?
- Rolul aplicației nu poate șterge tabele și nu poate citi alte scheme?
- Baza de date este accesibilă doar din rețeaua privată sau de la o adresă pe care o controlezi?
- Știi ce versiune minoră de PostgreSQL rulezi și când a fost actualizată ultima dată?
- Poate altcineva decât tine să facă restaurarea, folosind doar procedura scrisă?
Trei sau mai multe răspunsuri „nu” la o bază de date care ține o afacere, o listă de clienți sau date personale înseamnă că setup-ul este de nivel personal. E o constatare despre starea de acum, rezolvabilă într-o după-amiază.
Unde ajungem
Proiectul personal: self-hosted. Controlul este real, costul e lizibil, iar setup-ul minim înseamnă câteva ore. Pentru o afacere, alege deliberat: o bază de date administrată dacă nimeni nu vrea să își asume responsabilitățile, sau una self-hosted cu un proprietar numit, o procedură de restaurare scrisă, un calendar de patch-uri și o verificare de monitorizare care ajunge la un om.
Combinația de evitat: o bază de date de business self-hosted cu numele și neadministrată în practică. Are costul ambelor modele și siguranța niciunuia.
Întrebări frecvente
- Este self-hosting-ul unei baze de date mai ieftin decât una administrată?
- Factura la server este de obicei mai mică, dar comparația e incompletă fără orele tale. Un serviciu administrat include backup, patch-uri, preluare automată și suport în preț. Self-hosting-ul înlocuiește acel cost cu un server lunar plus timpul pentru a construi și întreține o rutină de backup, un calendar de patch-uri și o procedură de restaurare. Pune timpul în calcul la tariful tău real înainte să decizi.
- Este o replică a bazei de date suficientă ca backup?
- Nu. Replicarea în streaming copiază fiecare modificare, inclusiv un DELETE greșit sau o migrare prost făcută, deci standby-ul reproduce paguba în câteva secunde. Replicarea este și asincronă implicit, ceea ce înseamnă că unele tranzacții confirmate pot să nu ajungă pe standby dacă primarul cade. Folosește replica pentru disponibilitate și un backup separat sau o arhivă la moment în timp pentru recuperare.
- Ce este recuperarea la un moment în timp în PostgreSQL?
- Recuperarea la un moment în timp combină un base backup cu o arhivă continuă de segmente write-ahead log. La restaurare, serverul redă log-ul până la un moment ales, așa că poți reveni la starea de dinaintea unei modificări greșite. Cere ca arhivarea WAL să fi funcționat continuu de la base backup și ca ținta să fie după terminarea backup-ului.
- Cât de des ar trebui să testez o restaurare?
- Alege un ritm pe care chiar îl vei respecta și rulează-l din nou după orice schimbare a dimensiunii bazei de date, a uneltelor de backup sau a găzduirii. Scopul exercițiului este o restaurare măsurată pe o mașină care nu e producția, nu o bifă. Dacă restaurarea nu a fost niciodată cronometrată, nu îți cunoști timpul de recuperare.
- Ce ar trebui să conțină un setup PostgreSQL minim?
- Un server care nu e accesibil din internetul public, un rol de login cu privilegii minime pentru aplicație și parole SCRAM-SHA-256, TLS cu verificarea certificatului pentru conexiunile la distanță și un backup care a fost restaurat cel puțin o dată. Acestea patru acoperă eșecurile care încheie proiectele mici.
- Bazele de date administrate elimină nevoia de administrator de bază de date?
- Elimină munca de infrastructură: patch-uri pentru engine, rularea backup-urilor, înlocuirea hardware-ului defect, snapshot-uri. Nu îți proiectează schema, nu optimizează interogările, nu administrează credentialele aplicației și nu decid cum arată o restaurare corectă. Cineva tot trebuie să analizeze interogările lente și să facă un exercițiu de restaurare, chiar dacă persoana aceea nu se numește DBA.


