Langkah konkret membangun server database produksi-ready: instalasi PostgreSQL 16 dan MySQL 8, penyesuaian postgresql.conf dan my.cnf yang berani menyentuh memory, manajemen user & privilege dengan least privilege, serta connection pooling memakai pgbouncer agar ribuan koneksi aplikasi tidak menjatuhkan server

Di episode 2 kita memahami arsitektur — B-tree, WAL, buffer pool. Sekarang kita mengubah teori menjadi server nyata: menginstall, mengkonfigurasi, dan mengamankan PostgreSQL 16 + MySQL 8 di lab episode 0. Ini adalah momen "first boot" yang menentukan kualitas server untuk episode-episode selanjutnya.
Perhatikan pola pikir penting: default konfigurasi database bukan untuk produksi. Package installer distro menyetel nilai aman yang kecil (misal shared_buffers 128 MB) supaya tidak menolak mesin mana pun. Tugas DBA adalah menyetel ulang sesuai ukuran server — karena itulah "konfigurasi dasar" bukan pekerjaan sepele.
Jika belum terinstall di episode 0, jalankan:
sudo apt update
sudo apt install -y postgresql-16 postgresql-contrib mysql-server
sudo systemctl enable --now postgresql mysqlBeberapa catatan yang sering membuat DBA baru tersandung:
postgres dari socket TCP secara default; login lokal lewat sudo -u postgres psql atau psql -U postgres -h localhost (jika password disetel).auth_socket untuk root — sudo mysql langsung masuk tanpa password. Untuk remote, buat user terpisah, jangan memakai root.5432, MySQL 3306. Jika ada bentrok, kalian sudah tahu cara ceknya: ss -tlnp.File konfigurasi PostgreSQL terletak di PGDATA. Setel empat parameter memory paling berpengaruh untuk server 4 GB RAM:
# memory (server 4 GB)
shared_buffers = 1GB # 25% dari RAM
effective_cache_size = 3GB # ~75% dari RAM
work_mem = 16MB # per sort/hash operation
maintenance_work_mem = 256MB # untuk VACUUM, CREATE INDEX
# checkpoint
checkpoint_completion_target = 0.9
max_wal_size = 2GB
min_wal_size = 80MB
# connections
max_connections = 200Aturan praktis yang dibahas di episode 2: shared_buffers sekitar 25% RAM, effective_cache_size sekitar 75% RAM, work_mem jangan terlalu besar karena dikalikan jumlah sort paralel. checkpoint_completion_target = 0.9 meratakan beban I/O checkpoint.
pg_hba.conf mengatur siapa boleh terhubung dari mana. Untuk produksi, batasi:
# local
local all postgres peer
local all all scram-sha-256
# host (hanya dari subnet aplikasi)
host all all 10.0.0.0/8 scram-sha-256
host all all 0.0.0.0/0 rejectDua baris terakhir menggambarkan kebijakan: hanya subnet internal yang boleh masuk, sisanya ditolak tegas. scram-sha-256 adalah autentikasi password modern pengganti md5. Jangan pernah membiarkan trust di jaringan non-lokal.
MySQL dikonfigurasi di /etc/mysql/mysql.conf.d/mysqld.cnf:
[mysqld]
innodb_buffer_pool_size = 2G # ~50% RAM untuk InnoDB
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 1 # durability penuh (fsync tiap commit)
max_connections = 300
max_allowed_packet = 64M
binlog_format = ROW
server_id = 1innodb_flush_log_at_trx_commit = 1 menjamin durability sesuai ACID; nilai 2 lebih cepat tetapi bisa kehilangan 1 detik transaksi saat power loss — biarkan 1 untuk produksi. binlog_format = ROW adalah prasyarat replikasi yang benar (episode 8).
Tip
Setiap perubahan konfigurasi wajib diuji dengan restart dan periksa log. Untuk PostgreSQL: sudo systemctl restart postgresql && sudo -u postgres psql -c "SHOW shared_buffers;". Untuk MySQL: sudo systemctl restart mysql && mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';". Kalau parameter salah, server bisa gagal start — log akan menjelaskan baris mana yang bermasalah.
Prinsip golden-nya: least privilege — beri akses seminimal mungkin. Contoh lengkap di PostgreSQL:
CREATE ROLE app_user LOGIN PASSWORD 'RahasiaKuat123';
CREATE DATABASE appdb OWNER app_user;
GRANT CONNECT ON DATABASE appdb TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES
IN SCHEMA public TO app_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;Catatan penting: ALTER DEFAULT PRIVILEGES dibutuhkan agar tabel yang dibuat nanti otomatis dapat privilege — ini bug klasik yang membuat aplikasi "tiba-tiba" tidak bisa INSERT setelah migration.
Di MySQL, prosesnya paralel:
CREATE USER 'app_user'@'10.0.0.%' IDENTIFIED BY 'RahasiaKuat123';
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app_user'@'10.0.0.%';
FLUSH PRIVILEGES;Perhatikan 'app_user'@'10.0.0.%' — user terikat host/subnet. Jangan pernah memakai 'app_user'@'%' untuk produksi kecuali benar-benar diperlukan.
Ingat arsitektur PostgreSQL: satu koneksi = satu proses. 500 koneksi aplikasi berarti 500 proses OS yang saling berebut CPU dan memori. Solusinya adalah connection pooler — jembatan yang menjaga jumlah koneksi riil kecil sementara aplikasi bebas membuka ribuan koneksi logis.
sudo apt install -y pgbouncer[databases]
appdb = host=127.0.0.1 port=5432 dbname=appdb
[pgbouncer]
listen_port = 6432
auth_type = md5
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20Aplikasi kini menghubungi 127.0.0.1:6432, dan pgbouncer memetakan 1000 koneksi logis ke hanya 20 koneksi riil ke PostgreSQL. pool_mode = transaction artinya koneksi dibagi per transaksi — mode yang paling umum untuk aplikasi OLTP. Ubah postgresql.conf kalian: max_connections = 200 kini cukup, dan pgbouncer yang menyerap lonjakan.
SHOW/SHOW VARIABLES setelah restart.md5 dan password polos bisa dicegat. Pakai scram-sha-256 + TLS (episode 18).SUPERUSER ke aplikasi. Kredensial aplikasi bisa bocor; superuser = seluruh server masuk ke tangan attacker. Tidak pernah ada alasan.Inti yang harus dibawa pulang:
shared_buffers (~25% RAM), effective_cache_size (~75%), dan work_mem dengan bijak.pg_hba.conf/bind-address mengontrol siapa yang boleh terhubung; batasi jaringan, pakai scram-sha-256/TLS.Di episode 4 selanjutnya kita membahas database design & SQL administration — dari DDL/DML yang bersih, strategi normalisasi vs denormalisasi, hingga membuat index yang tepat sasaran. Ini bagian di mana DBA mencegah masalah performansi sebelum masalah itu lahir. Sampai jumpa di episode 4!