Listarea și Schimbarea Bazelor de Date în PostgreSQL: Ghidul Tehnic Complet
PostgreSQL gestionează mai multe baze de date izolate într-o singură instanță de server, fiecare cu propriul schema, roluri și privilegii. Pentru a lista toate bazele de date, rulați l în interiorul psql sau interogați SELECT datname FROM pg_catalog.pg_database; din orice sesiune. Pentru a comuta între baze de date, trebuie să deschideți o nouă conexiune — PostgreSQL impune o legătură strictă sesiune-bază de date, fără echivalentul comenzii USE în cadrul sesiunii.
Acest ghid acoperă toate metodele disponibile pentru enumerarea și conectarea la bazele de date PostgreSQL, de la comenzile brute psql și interogările catalogului de sistem până la șiruri de conexiune, considerații pg_hba.conf și tipare de flux de lucru multi-baze de date utilizate în mediile de producție.
De ce comutarea bazelor de date în PostgreSQL funcționează diferit
Majoritatea dezvoltatorilor care vin din MySQL se așteaptă la o comandă USE database_name;. PostgreSQL omite deliberat acest lucru. Fiecare sesiune PostgreSQL este legată de exact o bază de date la momentul conectării, iar această legătură este imuabilă pe durata de viață a sesiunii. Aceasta este o decizie arhitecturală înrădăcinată în modelul de proces al PostgreSQL: procesul backend (postgres) încarcă catalogul de sistem al bazei de date în memoria partajată la pornire, iar comutarea cataloagelor în mijlocul sesiunii ar necesita oricum un restart complet al procesului.
Înțelegerea acestei constrângeri de la bun început previne ore de depanare și modelează modul în care arhitecturați instrumentele multi-baze de date, pool-urile de conexiuni și configurațiile aplicațiilor.
Listarea tuturor bazelor de date în PostgreSQL
Metoda 1: Meta-comanda l în psql
Cel mai rapid mod de a enumera bazele de date este meta-comanda l (alias: list) într-o sesiune interactivă psql.
psql -U postgresOdată conectat:
lAceasta produce un tabel formatat similar cu:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
myapp_db | appuser | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
analytics | analyst | UTF8 | en_US.UTF-8 | en_US.UTF-8 | analyst=CTc/analyst
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |Coloanele dezvăluie mai mult decât simple nume: Encoding contează la migrarea datelor între servere, Collate afectează ordinea de sortare și comportamentul indexului, iar Access privileges utilizează notația ACL a PostgreSQL (C = CONNECT, T = TEMPORARY, c = CREATE).
Pentru a obține detalii extinse, inclusiv tablespace și limite de conexiuni, utilizați:
l+Metoda 2: Interogarea catalogului de sistem pg_database
Pentru scripting, monitorizare sau introspecție la nivel de aplicație, interogați direct vizualizarea pg_catalog.pg_database. Aceasta funcționează din orice bază de date din cluster, deoarece cataloagele de sistem sunt vizibile global.
SELECT
datname AS database_name,
pg_catalog.pg_get_userbyid(datdba) AS owner,
pg_encoding_to_char(encoding) AS encoding,
datcollate AS collation,
datctype AS ctype,
datconnlimit AS connection_limit,
pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(datname)) AS size
FROM pg_catalog.pg_database
WHERE datistemplate = false
ORDER BY datname;Filtrarea datistemplate = false exclude template0 și template1 din rezultate — acestea sunt șabloane de sistem, nu baze de date operaționale. Coloana datconnlimit este critică în mediile partajate: o valoare de -1 înseamnă nelimitat, în timp ce orice număr întreg pozitiv limitează conexiunile concurente la acea bază de date.
Sfat pentru producție: Adăugați pg_database_size() la interogările dvs. de monitorizare. O bază de date care crește silențios peste capacitatea tablespace-ului este o cauză frecventă a eșecurilor de scriere care sunt dificil de diagnosticat după fapt.
Metoda 3: Listarea bazelor de date fără a intra în psql
Pentru scripturile shell și pipeline-urile de automatizare, puteți recupera lista bazelor de date fără a intra într-o sesiune interactivă:
psql -U postgres -c "l"Sau pentru o ieșire curată, parsabilă de scripturi:
psql -U postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;"Flag-ul -t suprimă antetele coloanelor și numărul de rânduri, returnând doar valorile brute — ideal pentru a fi transmis prin pipe către grep, awk sau array-uri Bash.
Pentru a exporta lista într-un fișier:
psql -U postgres -t -A -c "SELECT datname FROM pg_database WHERE datistemplate = false;" > db_list.txt-A dezactivează alinierea coloanelor, producând un nume de bază de date per linie.
Comutarea între bazele de date în PostgreSQL
Deoarece nu puteți comuta bazele de date în cadrul unei sesiuni active, abordarea corectă este să terminați conexiunea curentă și să stabiliți una nouă care vizează baza de date dorită. Există mai multe moduri de a face acest lucru eficient.
Metoda 1: Ieșire și reconectare din shell
În interiorul psql, ieșiți din sesiunea curentă:
q
Apoi conectați-vă la baza de date țintă:
psql -U postgres -d target_database
Metoda 2: Utilizați c (Connect) în interiorul psql
Aceasta este cea mai practică metodă pentru lucrul interactiv. Meta-comanda c închide conexiunea curentă și deschide una nouă la baza de date specificată — totul în cadrul aceleiași sesiuni de terminal.
c target_database
Puteți, de asemenea, să comutați utilizatorul și gazda simultan:
c target_database admin_user localhost 5432
Sintaxă: c [database [username [host [port]]]]Când rulați c, psql va afișa o confirmare:
You are now connected to database "target_database" as user "postgres".Caz limită important: Dacă baza de date țintă nu există sau utilizatorul curent nu are privilegiul CONNECT, c va eșua și vă va readuce la conexiunea anterioară. Acest lucru este mai sigur decât pare — nu veți rămâne fără o conexiune, dar trebuie să gestionați acest lucru în scripturi verificând statusul de ieșire.
Metoda 3: Conectarea ca un utilizator diferit
Pentru a vă conecta la o bază de date sub un rol specific:
psql -d myapp_db -U appuser -h localhost -p 5432Sau folosind prescurtarea c într-o sesiune existentă:
c myapp_db appuserAcest lucru este deosebit de util la testarea politicilor de securitate la nivel de rând (RLS) sau la verificarea faptului că utilizatorii aplicației nu pot accesa tabele din afara schemei lor.
Metoda 4: Utilizarea șirurilor de conexiune (format URI)
PostgreSQL suportă formatul URI de conexiune libpq, care încapsulează toți parametrii de conexiune într-un singur șir. Aceasta este metoda preferată pentru configurarea aplicațiilor, pipeline-urile CI/CD și instrumentele de infrastructură-ca-cod.
psql "postgresql://appuser:password@localhost:5432/myapp_db"Sau folosind schema postgres:// (ambele sunt valide):
psql "postgres://appuser:password@db.example.com:5432/analytics?sslmode=require"Parametrul ?sslmode=require impune criptarea TLS pe conexiune — o cerință non-negociabilă pentru orice bază de date expusă dincolo de localhost. Dacă găzduiți PostgreSQL pe un VPS sau server dedicat, asociați întotdeauna șirurile de conexiune cu sslmode=require sau sslmode=verify-full și un certificat SSL valid.
Parametrii URI de conexiune de reținut:
| Parametru | Scop | Valoare exemplu |
|---|---|---|
sslmode | Nivel de impunere TLS | require, verify-full |
connect_timeout | Secunde înainte ca conexiunea să eșueze | 10 |
application_name | Identifică clientul în pg_stat_activity | myapp_worker |
options | Transmite parametri GUC pe partea serverului | -c search_path=myschema |
Metoda 5: Utilizarea psql cu variabile de mediu
Pentru conexiuni repetate la același cluster, setați variabile de mediu pentru a evita tastarea repetată a credențialelor:
export PGHOST=localhost
export PGPORT=5432
export PGUSER=postgres
export PGPASSWORD=secret # Use .pgpass file in production instead
export PGDATABASE=myapp_db
psqlÎn producție, utilizați un fișier .pgpass în loc de PGPASSWORD pentru a evita expunerea credențialelor în istoricul shell-ului sau listele de procese:
# ~/.pgpass format: hostname:port:database:username:password
localhost:5432:myapp_db:appuser:strongpasswordSetați permisiunile corect sau PostgreSQL va ignora fișierul:
chmod 600 ~/.pgpassComparație: Metode de comutare a bazelor de date
| Metodă | Context | Necesită proces nou | Suportă comutarea utilizatorului | Scriptabil |
|---|---|---|---|---|
q + psql -d | Shell | Da | Da | Da |
c dbname | psql interactiv | Nu (psql gestionează) | Da | Limitat |
| URI de conexiune | Shell / Aplicație | Da | Da | Da |
| Variabile de mediu | Shell | Da | Da | Da |
| pgAdmin GUI | Client GUI | Nu | Da | Nu |
| Connection pooler (PgBouncer) | Aplicație | Nu | Depinde de mod | Da |
Gestionarea eficientă a mai multor conexiuni la baze de date
Utilizarea pgAdmin pentru navigare bazată pe GUI
pgAdmin listează toate bazele de date sub fiecare server înregistrat în arborele de obiecte din stânga. Făcând clic pe o bază de date și deschizând Query Tool, toate interogările sunt automat limitate la acea bază de date. Acest lucru este util pentru lucrul exploratoriu, dar nu este potrivit pentru automatizare.
Capcană: pgAdmin menține slot-uri de conexiune separate per bază de date. Dacă serverul dvs. PostgreSQL are o setare max_connections scăzută (implicit este 100), deschiderea mai multor baze de date în pgAdmin poate epuiza pool-ul de conexiuni înainte ca aplicația dvs. să pornească.
Utilizarea PgBouncer pentru pooling de conexiuni
În mediile de producție cu comutare frecventă a bazelor de date, un connection pooler precum PgBouncer reduce dramatic overhead-ul. PgBouncer operează în trei moduri:
- Modul sesiune: O conexiune server per sesiune client. Echivalent funcțional cu conexiunile directe.
- Modul tranzacție: Conexiunea server este menținută doar pe durata unei tranzacții. Cel mai eficient pentru workload-urile OLTP.
- Modul instrucțiune: Conexiunea este returnată după fiecare instrucțiune. Incompatibil cu tranzacțiile multi-instrucțiune.
Când rulați mai multe baze de date ale aplicației pe o singură instanță PostgreSQL — un tipar comun pe hosting VPS sau VPS cu cPanel — PgBouncer în modul tranzacție poate reduce procesele backend active cu un ordin de mărime.
Interogări cross-baze de date cu dblink și postgres_fdw
Deoarece sesiunile sunt limitate la o bază de date, interogarea datelor din mai multe baze de date necesită o extensie. PostgreSQL oferă două opțiuni:
dblink — abordare mai veche, procedurală:
SELECT * FROM dblink(
'dbname=analytics user=analyst host=localhost',
'SELECT user_id, event_count FROM events WHERE date = current_date'
) AS remote(user_id INT, event_count BIGINT);postgres_fdw — Foreign Data Wrapper modern, conform standardelor:
CREATE EXTENSION postgres_fdw;
CREATE SERVER analytics_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', dbname 'analytics', port '5432');
CREATE USER MAPPING FOR appuser
SERVER analytics_server
OPTIONS (user 'analyst', password 'secret');
CREATE FOREIGN TABLE remote_events (
user_id INT,
event_count BIGINT
)
SERVER analytics_server
OPTIONS (schema_name 'public', table_name 'events');După configurare, remote_events se comportă ca un tabel local. postgres_fdw suportă predicate pushdown, ceea ce înseamnă că clauzele WHERE sunt executate pe serverul remote, nu local — o distincție critică de performanță pentru seturi mari de date.
Bazele de date de sistem: Ce nu trebuie să atingeți
PostgreSQL vine cu patru baze de date în fiecare cluster nou:
| Baza de date | Scop | Sigur de conectat? | Sigur de modificat? |
|---|---|---|---|
postgres | Baza de date implicită pentru admin | Da | Cu precauție |
template1 | Șablon pentru CREATE DATABASE | Da | Da, modificările se propagă |
template0 | Șablon de referință curat | Rar | Nu |
pg_catalog | Nu este o bază de date, ci un schema | N/A | Niciodată |
template1 este clonat ori de câte ori rulați CREATE DATABASE fără a specifica un șablon. Dacă instalați extensii sau creați scheme în template1, fiecare bază de date nouă le moștenește. Acest lucru este util pentru standardizarea mediilor, dar periculos dacă se face accidental.
template0 există ca o alternativă pristină. Este singurul șablon care poate fi utilizat la restaurarea unei arhive pg_dump cu o codificare sau localizare diferită, deoarece nu are obiecte create de utilizator care ar putea intra în conflict.
Privilegii, pg_hba.conf și eșecuri de conexiune
O sursă frecventă de confuzie la comutarea bazelor de date este distincția dintre privilegiile la nivel de rol PostgreSQL și regulile de autentificare pg_hba.conf. Ambele trebuie să permită conexiunea în mod independent.
Verificare la nivel de rol: Rolul trebuie să aibă privilegiul CONNECT pe baza de date țintă:
GRANT CONNECT ON DATABASE target_database TO appuser;Verificare pg_hba.conf: Fișierul de autentificare bazat pe gazdă (/etc/postgresql/15/main/pg_hba.conf pe Debian/Ubuntu) trebuie să aibă o regulă corespunzătoare pentru utilizator, baza de date și adresa sursă. O intrare tipică:
# TYPE DATABASE USER ADDRESS METHOD
host myapp_db appuser 10.0.0.0/8 scram-sha-256După editarea pg_hba.conf, reîncărcați configurația fără a reporni serverul:
sudo systemctl reload postgresqlSau din interiorul psql:
SELECT pg_reload_conf();Tipar frecvent de eșec: Un utilizator are privilegiul CONNECT la nivel SQL, dar pg_hba.conf nu are o regulă corespunzătoare. Mesajul de eroare (FATAL: no pg_hba.conf entry for host) este explicit, dar dezvoltatorii ignoră adesea fișierul în totalitate, deoarece se așteaptă ca permisiunile bazei de date să fie gestionate exclusiv prin SQL.
Matrice practică de decizie
Utilizați această listă de verificare pentru a selecta abordarea de conexiune potrivită pentru scenariul dvs.:
- Explorare interactivă pe o mașină de dezvoltare locală: Utilizați
c dbnameîn interiorulpsql. Rapid, fără proces nou. - Script shell care iterează peste mai multe baze de date: Utilizați
psql -U postgres -d $dbname -c "..."într-o buclă cu-t -Apentru o ieșire curată. - Aplicație care se conectează la o singură bază de date: Utilizați un URI de conexiune cu
sslmode=requireși un connection pool (PgBouncer sau pooling integrat în driver). - Aplicație care necesită date din două baze de date: Implementați
postgres_fdwpe baza de date primară în loc să gestionați două pool-uri de conexiuni separate în codul aplicației. - Verificarea izolării RLS sau a privilegiilor: Utilizați
c dbname role_namepentru a imita rolul țintă fără a părăsipsql. - Provizionare automată / infrastructură-ca-cod: Utilizați variabile de mediu sau
.pgpasscu un cont de serviciu; nu hardcodați niciodată credențialele în scripturi. - Workload de producție cu concurență ridicată: Implementați PgBouncer în modul tranzacție între aplicație și PostgreSQL. Pe un server dedicat, ajustați
max_connectionsînpostgresql.confpentru a corespunde capacității de memorie a hardware-ului dvs. (fiecare backend utilizează aproximativ 5–10 MB de RAM). - SaaS multi-tenant cu baze de date per tenant: Luați în considerare multi-tenancy bazat pe scheme într-o singură bază de date în loc de baze de date per tenant, pentru a evita fragmentarea pool-ului de conexiuni și a simplifica strategiile de backup.
Pentru echipele care rulează PostgreSQL alături de aplicații web, asocierea serverului de baze de date cu un mediu de hosting partajat sau VPS configurat corespunzător și un domeniu înregistrat pentru stratul aplicației completează stiva standard de producție.
Întrebări frecvente
Pot comuta bazele de date fără a închide sesiunea psql?
Da. Utilizați meta-comanda c target_database în interiorul psql. Aceasta închide conexiunea backend curentă și deschide una nouă la baza de date specificată, totul în cadrul aceleiași sesiuni de terminal. Puteți specifica opțional un utilizator, gazdă și port diferit în aceeași comandă.
De ce PostgreSQL nu are o comandă USE ca MySQL?
Arhitectura PostgreSQL leagă un proces backend de o singură bază de date la pornire. Catalogul de sistem al bazei de date este încărcat în memoria partajată pentru acel proces, iar comutarea cataloagelor în mijlocul sesiunii este echivalentă arhitectural cu pornirea unui proces nou. Comanda c din psql este echivalentul practic — face doar restartul procesului transparent pentru utilizator.
Cum pot interoga date din două baze de date PostgreSQL diferite simultan?
Utilizați extensia postgres_fdw pentru a crea un server foreign și tabele foreign care se mapează la baza de date remote. După configurare, puteți face JOIN între tabele locale și remote într-o singură interogare. Pentru interogări ocazionale, dblink este mai simplu, dar mai puțin performant și mai greu de întreținut.
Ce se întâmplă dacă mă conectez la template1 și o modific?
Orice obiecte pe care le creați în template1 — tabele, extensii, scheme — vor fi clonate în fiecare bază de date nouă creată cu CREATE DATABASE (cu excepția cazului în care TEMPLATE template0 este specificat explicit). Acest lucru este uneori intenționat (de ex., pre-instalarea uuid-ossp sau pgcrypto), dar modificările accidentale pot corupe toate bazele de date create ulterior.
Cum găsesc la ce bază de date este conectată sesiunea psql curentă?
Rulați următoarele în interiorul psql:
SELECT current_database();Sau verificați promptul psql în sine — implicit afișează dbname=# (superutilizator) sau dbname=> (utilizator obișnuit), unde dbname este baza de date activă.
