15%

Hemat 15% di Semua Layanan Hosting

Uji kemampuanmu dan dapatkan Diskon pada paket hosting apa saja

Gunakan kode:

Skills
Memulai
24.10.2024

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 postgres

Setelah terhubung:

l

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

Atau menggunakan singkatan c di dalam sesi yang sudah ada:

c myapp_db appuser

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

ParameterTujuanContoh Nilai
sslmodeTingkat penegakan TLSrequire, verify-full
connect_timeoutDetik sebelum koneksi gagal10
application_nameMengidentifikasi klien di pg_stat_activitymyapp_worker
optionsMeneruskan 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

psql

Dalam 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:strongpassword

Atur izin dengan benar atau PostgreSQL akan mengabaikan file tersebut:

chmod 600 ~/.pgpass

Perbandingan: Metode Perpindahan Database

MetodeKonteksMemerlukan Proses BaruMendukung Pergantian PenggunaDapat Di-script
q + psql -dShellYaYaYa
c dbnamepsql interaktifTidak (psql menanganinya)YaTerbatas
URI KoneksiShell / AplikasiYaYaYa
Variabel lingkunganShellYaYaYa
pgAdmin GUIKlien GUITidakYaTidak
Connection pooler (PgBouncer)AplikasiTidakBergantung pada modeYa

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.

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:

DatabaseTujuanAman untuk Dihubungkan?Aman untuk Dimodifikasi?
postgresDatabase admin defaultYaDengan hati-hati
template1Template untuk CREATE DATABASEYaYa, perubahan merambat
template0Template baseline yang bersihJarangTidak
pg_catalogBukan database, melainkan skemaN/ATidak 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-256

Setelah mengedit pg_hba.conf, muat ulang konfigurasi tanpa me-restart server:

sudo systemctl reload postgresql

Atau 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 dbname di dalam psql. Cepat, tanpa proses baru.
  • Skrip shell yang mengiterasi beberapa database: Gunakan psql -U postgres -d $dbname -c "..." dalam loop dengan -t -A untuk output yang bersih.
  • Aplikasi yang terhubung ke satu database: Gunakan URI koneksi dengan sslmode=require dan connection pool (PgBouncer atau pooling driver bawaan).
  • Aplikasi yang membutuhkan data dari dua database: Implementasikan postgres_fdw pada database utama daripada mengelola dua connection pool terpisah dalam kode aplikasi.
  • Memverifikasi RLS atau isolasi hak akses: Gunakan c dbname role_name untuk meniru peran target tanpa meninggalkan psql.
  • Provisi otomatis / infrastructure-as-code: Gunakan variabel lingkungan atau .pgpass dengan 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_connections di postgresql.conf agar 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.

15%

Hemat 15% di Semua Layanan Hosting

Uji kemampuanmu dan dapatkan Diskon pada paket hosting apa saja

Gunakan kode:

Skills
Memulai