15%

Economisește 15% la toate serviciile de găzduire

Testează-ți abilitățile și obține Reducere la orice plan de găzduire

Utilizați codul:

Skills
Începeți
24.10.2024

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 postgres

Odată conectat:

l

Aceasta 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 5432

Sau folosind prescurtarea c într-o sesiune existentă:

c myapp_db appuser

Acest 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:

ParametruScopValoare exemplu
sslmodeNivel de impunere TLSrequire, verify-full
connect_timeoutSecunde înainte ca conexiunea să eșueze10
application_nameIdentifică clientul în pg_stat_activitymyapp_worker
optionsTransmite 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:strongpassword

Setați permisiunile corect sau PostgreSQL va ignora fișierul:

chmod 600 ~/.pgpass

Comparație: Metode de comutare a bazelor de date

MetodăContextNecesită proces nouSuportă comutarea utilizatoruluiScriptabil
q + psql -dShellDaDaDa
c dbnamepsql interactivNu (psql gestionează)DaLimitat
URI de conexiuneShell / AplicațieDaDaDa
Variabile de mediuShellDaDaDa
pgAdmin GUIClient GUINuDaNu
Connection pooler (PgBouncer)AplicațieNuDepinde de modDa

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.

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 dateScopSigur de conectat?Sigur de modificat?
postgresBaza de date implicită pentru adminDaCu precauție
template1Șablon pentru CREATE DATABASEDaDa, modificările se propagă
template0Șablon de referință curatRarNu
pg_catalogNu este o bază de date, ci un schemaN/ANiciodată

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-256

După editarea pg_hba.conf, reîncărcați configurația fără a reporni serverul:

sudo systemctl reload postgresql

Sau 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 interiorul psql. 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 -A pentru 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_fdw pe 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_name pentru a imita rolul țintă fără a părăsi psql.
  • Provizionare automată / infrastructură-ca-cod: Utilizați variabile de mediu sau .pgpass cu 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 în postgresql.conf pentru 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ă.

15%

Economisește 15% la toate serviciile de găzduire

Testează-ți abilitățile și obține Reducere la orice plan de găzduire

Utilizați codul:

Skills
Începeți