Mencantumkan dan Beralih Database di PostgreSQL: Panduan Teknis Lengkap
PostgreSQL mengelola beberapa database terisolasi dalam satu instance server, masing-masing dengan skema, peran, dan hak aksesnya sendiri. Untuk menampilkan semua database, jalankan l di dalam psql atau query SELECT datname FROM pg_catalog.pg_database; dari sesi mana pun. Untuk berpindah database, Anda harus membuka koneksi baru — PostgreSQL memberlakukan pengikatan sesi-ke-database yang ketat tanpa perintah setara USE dalam sesi.
Panduan ini mencakup setiap metode yang tersedia untuk mengenumerasi dan terhubung ke database PostgreSQL, mulai dari perintah psql mentah dan query katalog sistem hingga string koneksi, pertimbangan pg_hba.conf, dan pola alur kerja multi-database yang digunakan di lingkungan produksi.
Mengapa Perpindahan Database PostgreSQL Bekerja Secara Berbeda
Sebagian besar pengembang yang berasal dari MySQL mengharapkan perintah USE database_name;. PostgreSQL sengaja menghilangkan ini. Setiap sesi PostgreSQL terikat pada tepat satu database pada saat koneksi, dan pengikatan tersebut tidak dapat diubah selama masa hidup sesi. Ini adalah keputusan arsitektur yang berakar pada model proses PostgreSQL: proses backend (postgres) memuat katalog sistem database ke dalam memori bersama saat startup, dan perpindahan katalog di tengah sesi akan memerlukan restart proses penuh.
Memahami batasan ini sejak awal mencegah berjam-jam debugging dan membentuk cara Anda merancang tooling multi-database, connection pool, dan konfigurasi aplikasi.
Menampilkan Semua Database di PostgreSQL
Metode 1: Meta-Perintah l di psql
Cara tercepat untuk mengenumerasi database adalah meta-perintah l (alias: list) di dalam sesi psql interaktif.
psql -U postgresSetelah terhubung:
lIni menghasilkan tabel berformat seperti:
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 |Kolom-kolom tersebut mengungkapkan lebih dari sekadar nama: Encoding penting saat memigrasikan data antar server, Collate memengaruhi urutan pengurutan dan perilaku indeks, dan Access privileges menggunakan notasi ACL PostgreSQL (C = CONNECT, T = TEMPORARY, c = CREATE).
Untuk mendapatkan detail yang diperluas termasuk tablespace dan batas koneksi, gunakan:
l+Metode 2: Melakukan Query pada Katalog Sistem pg_database
Untuk scripting, pemantauan, atau introspeksi di tingkat aplikasi, query tampilan pg_catalog.pg_database secara langsung. Ini berfungsi dari database mana pun dalam cluster karena katalog sistem terlihat secara 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;Memfilter datistemplate = false mengecualikan template0 dan template1 dari hasil — keduanya adalah template sistem, bukan database operasional. Kolom datconnlimit sangat penting di lingkungan bersama: nilai -1 berarti tidak terbatas, sementara bilangan bulat positif apa pun membatasi koneksi bersamaan ke database tersebut.
Tips produksi: Tambahkan pg_database_size() ke query pemantauan Anda. Database yang diam-diam tumbuh melampaui kapasitas tablespace adalah penyebab umum kegagalan penulisan yang sulit didiagnosis setelah terjadi.
Metode 3: Menampilkan Database Tanpa Masuk ke psql
Untuk skrip shell dan pipeline otomasi, Anda dapat mengambil daftar database tanpa memasuki sesi interaktif:
psql -U postgres -c "l"Atau untuk output yang bersih dan dapat diurai oleh skrip:
psql -U postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;"Flag -t menekan header kolom dan jumlah baris, hanya mengembalikan nilai mentah — ideal untuk disalurkan ke grep, awk, atau array Bash.
Untuk mengekspor daftar ke file:
psql -U postgres -t -A -c "SELECT datname FROM pg_database WHERE datistemplate = false;" > db_list.txt-A menonaktifkan perataan kolom, menghasilkan satu nama database per baris.
Berpindah Antar Database di PostgreSQL
Karena Anda tidak dapat berpindah database dalam sesi yang sedang berjalan, pendekatan yang benar adalah mengakhiri koneksi saat ini dan membuat koneksi baru yang menargetkan database yang diinginkan. Ada beberapa cara untuk melakukan ini secara efisien.
Metode 1: Keluar dan Sambungkan Kembali dari Shell
Di dalam psql, keluar dari sesi saat ini:
q
Kemudian hubungkan ke database target:
psql -U postgres -d target_database
Metode 2: Gunakan c (Connect) di Dalam psql
Ini adalah metode paling praktis untuk pekerjaan interaktif. Meta-perintah c menutup koneksi saat ini dan membuka koneksi baru ke database yang ditentukan — semuanya dalam sesi terminal yang sama.
c target_database
Anda juga dapat berpindah pengguna dan host secara bersamaan:
c target_database admin_user localhost 5432
Sintaks: c [database [username [host [port]]]]Saat Anda menjalankan c, psql akan menampilkan konfirmasi:
You are now connected to database "target_database" as user "postgres".Kasus tepi penting: Jika database target tidak ada atau pengguna saat ini tidak memiliki hak CONNECT, c akan gagal dan mengembalikan Anda ke koneksi sebelumnya. Ini lebih aman dari yang terdengar — Anda tidak akan dibiarkan tanpa koneksi, tetapi Anda harus menangani ini dalam skrip dengan memeriksa status keluar.
Metode 3: Menghubungkan sebagai Pengguna Berbeda
Untuk terhubung ke database dengan peran tertentu:
psql -d myapp_db -U appuser -h localhost -p 5432Atau menggunakan singkatan c di dalam sesi yang sudah ada:
c myapp_db appuserIni sangat berguna saat menguji kebijakan keamanan tingkat baris (RLS) atau memverifikasi bahwa pengguna aplikasi tidak dapat mengakses tabel di luar skema mereka.
Metode 4: Menggunakan String Koneksi (Format URI)
PostgreSQL mendukung format URI koneksi libpq, yang merangkum semua parameter koneksi ke dalam satu string. Ini adalah metode yang disukai untuk konfigurasi aplikasi, pipeline CI/CD, dan alat infrastructure-as-code.
psql "postgresql://appuser:password@localhost:5432/myapp_db"Atau menggunakan skema postgres:// (keduanya valid):
psql "postgres://appuser:password@db.example.com:5432/analytics?sslmode=require"Parameter ?sslmode=require memberlakukan enkripsi TLS pada koneksi — persyaratan yang tidak dapat dinegosiasikan untuk database mana pun yang terekspos di luar localhost. Jika Anda menghosting PostgreSQL di VPS atau server dedicated, selalu pasangkan string koneksi dengan sslmode=require atau sslmode=verify-full dan sertifikat SSL yang valid.
Parameter URI koneksi yang perlu diperhatikan:
| Parameter | Tujuan | Contoh Nilai |
|---|---|---|
sslmode | Tingkat penegakan TLS | require, verify-full |
connect_timeout | Detik sebelum koneksi gagal | 10 |
application_name | Mengidentifikasi klien di pg_stat_activity | myapp_worker |
options | Meneruskan parameter GUC sisi server | -c search_path=myschema |
Metode 5: Menggunakan psql dengan Variabel Lingkungan
Untuk koneksi berulang ke cluster yang sama, atur variabel lingkungan untuk menghindari pengetikan kredensial berulang kali:
export PGHOST=localhost
export PGPORT=5432
export PGUSER=postgres
export PGPASSWORD=secret # Use .pgpass file in production instead
export PGDATABASE=myapp_db
psqlDalam produksi, gunakan file .pgpass sebagai pengganti PGPASSWORD untuk menghindari paparan kredensial dalam riwayat shell atau daftar proses:
# ~/.pgpass format: hostname:port:database:username:password
localhost:5432:myapp_db:appuser:strongpasswordAtur izin dengan benar atau PostgreSQL akan mengabaikan file tersebut:
chmod 600 ~/.pgpassPerbandingan: Metode Perpindahan Database
| Metode | Konteks | Memerlukan Proses Baru | Mendukung Pergantian Pengguna | Dapat Di-script |
|---|---|---|---|---|
q + psql -d | Shell | Ya | Ya | Ya |
c dbname | psql interaktif | Tidak (psql menanganinya) | Ya | Terbatas |
| URI Koneksi | Shell / Aplikasi | Ya | Ya | Ya |
| Variabel lingkungan | Shell | Ya | Ya | Ya |
| pgAdmin GUI | Klien GUI | Tidak | Ya | Tidak |
| Connection pooler (PgBouncer) | Aplikasi | Tidak | Bergantung pada mode | Ya |
Mengelola Beberapa Koneksi Database Secara Efisien
Menggunakan pgAdmin untuk Navigasi Berbasis GUI
pgAdmin mencantumkan semua database di bawah setiap server yang terdaftar di pohon objek sisi kiri. Mengklik database dan membuka Query Tool secara otomatis membatasi semua query ke database tersebut. Ini berguna untuk pekerjaan eksplorasi tetapi tidak cocok untuk otomasi.
Jebakan: pgAdmin mempertahankan slot koneksi terpisah per database. Jika server PostgreSQL Anda memiliki pengaturan max_connections yang rendah (default adalah 100), membuka banyak database di pgAdmin dapat menghabiskan connection pool sebelum aplikasi Anda bahkan dimulai.
Menggunakan PgBouncer untuk Connection Pooling
Di lingkungan produksi dengan perpindahan database yang sering, connection pooler seperti PgBouncer secara dramatis mengurangi overhead. PgBouncer beroperasi dalam tiga mode:
- Mode sesi: Satu koneksi server per sesi klien. Secara fungsional setara dengan koneksi langsung.
- Mode transaksi: Koneksi server hanya ditahan selama transaksi. Paling efisien untuk beban kerja OLTP.
- Mode pernyataan: Koneksi dikembalikan setelah setiap pernyataan. Tidak kompatibel dengan transaksi multi-pernyataan.
Saat menjalankan beberapa database aplikasi pada satu instance PostgreSQL — pola umum pada hosting VPS atau VPS dengan cPanel — PgBouncer dalam mode transaksi dapat mengurangi proses backend aktif hingga satu tingkat besaran.
Query Lintas Database dengan dblink dan postgres_fdw
Karena sesi dibatasi pada database, melakukan query data lintas database memerlukan ekstensi. PostgreSQL menyediakan dua opsi:
dblink — pendekatan prosedural yang lebih lama:
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 yang sesuai standar:
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');Setelah penyiapan, remote_events berperilaku seperti tabel lokal. postgres_fdw mendukung predicate pushdown, artinya klausa WHERE dieksekusi di server jarak jauh, bukan secara lokal — perbedaan performa yang kritis untuk dataset besar.
Database Sistem: Yang Tidak Boleh Anda Sentuh
PostgreSQL hadir dengan empat database di setiap cluster baru:
| Database | Tujuan | Aman untuk Dihubungkan? | Aman untuk Dimodifikasi? |
|---|---|---|---|
postgres | Database admin default | Ya | Dengan hati-hati |
template1 | Template untuk CREATE DATABASE | Ya | Ya, perubahan merambat |
template0 | Template baseline yang bersih | Jarang | Tidak |
pg_catalog | Bukan database, melainkan skema | N/A | Tidak pernah |
template1 dikloning setiap kali Anda menjalankan CREATE DATABASE tanpa menentukan template. Jika Anda menginstal ekstensi atau membuat skema di template1, setiap database baru akan mewarisinya. Ini berguna untuk menstandarkan lingkungan tetapi berbahaya jika dilakukan secara tidak sengaja.
template0 ada sebagai fallback yang murni. Ini adalah satu-satunya template yang dapat digunakan saat memulihkan arsip pg_dump dengan encoding atau locale yang berbeda, karena tidak memiliki objek yang dibuat pengguna yang dapat menimbulkan konflik.
Hak Akses, pg_hba.conf, dan Kegagalan Koneksi
Sumber kebingungan yang umum saat berpindah database adalah perbedaan antara hak akses tingkat peran PostgreSQL dan aturan autentikasi pg_hba.conf. Keduanya harus mengizinkan koneksi secara independen.
Pemeriksaan tingkat peran: Peran harus memiliki hak CONNECT pada database target:
GRANT CONNECT ON DATABASE target_database TO appuser;Pemeriksaan pg_hba.conf: File autentikasi berbasis host (/etc/postgresql/15/main/pg_hba.conf di Debian/Ubuntu) harus memiliki aturan yang cocok untuk pengguna, database, dan alamat sumber. Entri tipikal:
# TYPE DATABASE USER ADDRESS METHOD
host myapp_db appuser 10.0.0.0/8 scram-sha-256Setelah mengedit pg_hba.conf, muat ulang konfigurasi tanpa me-restart server:
sudo systemctl reload postgresqlAtau dari dalam psql:
SELECT pg_reload_conf();Pola kegagalan umum: Pengguna memiliki hak CONNECT di tingkat SQL tetapi pg_hba.conf tidak memiliki aturan yang cocok. Pesan kesalahan (FATAL: no pg_hba.conf entry for host) sudah jelas, tetapi pengembang sering mengabaikan file tersebut sepenuhnya karena mereka mengharapkan izin database dikelola sepenuhnya melalui SQL.
Matriks Keputusan Praktis
Gunakan daftar periksa ini untuk memilih pendekatan koneksi yang tepat untuk skenario Anda:
- Eksplorasi interaktif di mesin dev lokal: Gunakan
c dbnamedi dalampsql. Cepat, tanpa proses baru. - Skrip shell yang mengiterasi beberapa database: Gunakan
psql -U postgres -d $dbname -c "..."dalam loop dengan-t -Auntuk output yang bersih. - Aplikasi yang terhubung ke satu database: Gunakan URI koneksi dengan
sslmode=requiredan connection pool (PgBouncer atau pooling driver bawaan). - Aplikasi yang membutuhkan data dari dua database: Implementasikan
postgres_fdwpada database utama daripada mengelola dua connection pool terpisah dalam kode aplikasi. - Memverifikasi RLS atau isolasi hak akses: Gunakan
c dbname role_nameuntuk meniru peran target tanpa meninggalkanpsql. - Provisi otomatis / infrastructure-as-code: Gunakan variabel lingkungan atau
.pgpassdengan akun layanan; jangan pernah hardcode kredensial dalam skrip. - Beban kerja produksi dengan konkurensi tinggi: Deploy PgBouncer dalam mode transaksi antara aplikasi dan PostgreSQL. Di server dedicated, sesuaikan
max_connectionsdipostgresql.confagar sesuai dengan kapasitas memori perangkat keras Anda (setiap backend menggunakan sekitar 5–10 MB RAM). - SaaS multi-tenant dengan database per-tenant: Pertimbangkan multi-tenancy berbasis skema dalam satu database alih-alih database per-tenant, untuk menghindari fragmentasi connection pool dan menyederhanakan strategi backup.
Bagi tim yang menjalankan PostgreSQL bersama aplikasi web, memasangkan server database dengan lingkungan shared hosting atau VPS yang dikonfigurasi dengan benar dan domain yang terdaftar untuk lapisan aplikasi melengkapi stack produksi standar.
FAQ
Bisakah saya berpindah database tanpa menutup sesi psql saya?
Ya. Gunakan meta-perintah c target_database di dalam psql. Ini menutup koneksi backend saat ini dan membuka koneksi baru ke database yang ditentukan, semuanya dalam sesi terminal yang sama. Anda dapat secara opsional menentukan pengguna, host, dan port yang berbeda dalam perintah yang sama.
Mengapa PostgreSQL tidak memiliki perintah USE seperti MySQL?
Arsitektur PostgreSQL mengikat proses backend ke satu database saat startup. Katalog sistem database dimuat ke dalam memori bersama untuk proses tersebut, dan perpindahan katalog di tengah sesi secara arsitektur setara dengan memulai proses baru. Perintah c di psql adalah padanan praktisnya — hanya saja membuat restart proses tersebut transparan bagi pengguna.
Bagaimana cara melakukan query data dari dua database PostgreSQL yang berbeda secara bersamaan?
Gunakan ekstensi postgres_fdw untuk membuat server asing dan tabel asing yang memetakan ke database jarak jauh. Setelah penyiapan, Anda dapat melakukan JOIN tabel lokal dan jarak jauh dalam satu query. Untuk query sekali pakai, dblink lebih sederhana tetapi kurang performan dan lebih sulit dikelola.
Apa yang terjadi jika saya terhubung ke template1 dan memodifikasinya?
Objek apa pun yang Anda buat di template1 — tabel, ekstensi, skema — akan dikloning ke setiap database baru yang dibuat dengan CREATE DATABASE (kecuali TEMPLATE template0 ditentukan secara eksplisit). Ini terkadang disengaja (misalnya, pra-instalasi uuid-ossp atau pgcrypto), tetapi modifikasi yang tidak disengaja dapat merusak semua database yang dibuat setelahnya.
Bagaimana cara mengetahui database mana yang sedang terhubung dengan sesi psql saat ini?
Jalankan perintah berikut di dalam psql:
SELECT current_database();Atau periksa prompt psql itu sendiri — secara default menampilkan dbname=# (superuser) atau dbname=> (pengguna biasa), di mana dbname adalah database yang aktif.
