Open Source Relational Database

PostgreSQL บน Ubuntu

ติดตั้ง PostgreSQL แบบ Step-by-Step บน Ubuntu 22.04 และ 24.04 พร้อมการตั้งค่าพื้นฐาน

เนื้อหาในบทความนี้

สถานะบทความ

อัปเดตล่าสุด: กุมภาพันธ์ 2026 | ระดับความยาก: ทุกระดับ (Beginner-Friendly) | เวลาอ่าน: 25 นาที

บทความนี้เขียนขึ้นเพื่อเป็นคู่มือการติดตั้งและใช้งาน PostgreSQL บนระบบ Ubuntu อย่างครอบคลุม

1 บทนำ: PostgreSQL คืออะไร?

PostgreSQL คือระบบจัดการฐานข้อมูลเชิงสัมพันธ์ (Relational Database Management System - RDBMS) แบบ Open Source ที่มีความเสถียร สูง และรองรับคุณสมบัติขั้นสูงต่างๆ PostgreSQL ถูกพัฒนาต่อจากระบบ Postgres ที่มหาวิทยาลัย Berkeley และมาเป็น PostgreSQL ในปี 1996

คุณสมบัติเด่นของ PostgreSQL

  • ACID Compliant: รับประกันความถูกต้องของข้อมูล
  • Open Source: ฟรีและเปิด source code 100%
  • ขยายขนาดได้: รองรับการใช้งานขนาดเล็กถึงใหญ่มาก (Enterprise)
  • JSON Support: จัดการข้อมูลแบบ NoSQL ได้ดี
  • Stored Procedures: เขียนโค้ดด้วย PL/pgSQL, Python, JavaScript
  • Replication: รองรับการ Replication และ HA

PostgreSQL ใช้งานจริง

  • ธนาคาร: ระบบการเงินที่ต้องการความถูกต้องสูง
  • E-Commerce: ระบบสั่งซื้อสินค้าและจัดการสต๊อก
  • โรงพยาบาล: ระบบจัดการข้อมูลผู้ป่วย
  • Startup: ฐานข้อมูลหลักสำหรับแอปพลิเคชัน
  • DevOps: ใช้ร่วมกับ Docker, Kubernetes

โครงสร้างระบบ PostgreSQL

Client Application Python, Node.js, PHP Connection Pooler PgBouncer / pgpool PostgreSQL Port 5432 Data Files /var/lib/postgresql/data Legends: Database connection Data storage

2 ทำไมเลือก PostgreSQL แทน MySQL?

ทั้ง PostgreSQL และ MySQL เป็นระบบจัดการฐานข้อมูลที่ดี แต่มีจุดแข็งที่ต่างกัน การเลือกใช้ขึ้นอยู่กับความต้องการของโปรเจกต์

จุดแข็งของ PostgreSQL

  • ACID Compliance 100%: เหมาะสำหรับระบบการเงิน ธนาคาร
  • JSON/JSONB Support: จัดการข้อมูลแบบเอกสารได้ดี
  • Stored Procedures แบบมาตรฐาน: PL/pgSQL มีความยืดหยุ่นสูง
  • Full-text Search: ค้นหาข้อความได้ดีโดยไม่ต้องพึ่ง Elasticsearch
  • Table Inheritance: รองรับ Object-Oriented features
  • Extensibility: สามารถขยายฟังก์ชันด้วยภาษาอื่นได้

จุดแข็งของ MySQL

  • ความเร็ว Read-only: เร็วมากสำหรับการอ่านข้อมูล
  • ใช้งานง่าย: ติดตั้งและตั้งค่าง่ายกว่า
  • Community ใหญ่: มีเอกสารและ forum มาก
  • MariaDB Alternative: มี MariaDB เป็นทางเลือก
  • Default for LAMP: มาตรฐานของ LAMP stack
  • Embedded: MySQL Embedded Library สำหรับแอปพลิเคชัน

สรุป: เลือก PostgreSQL เมื่อไหร่?

เลือก PostgreSQL ถ้าโปรเจกต์ของคุณต้องการ:

  • ความถูกต้องและข้อมูลที่น่าเชื่อถือสูง (เช่น ธนาคาร การเงิน)
  • ต้องการใช้งานข้อมูล JSON หรือข้อมูลโครงสร้างซับซ้อน
  • ต้องการความยืดหยุ่นในการปรับแต่งและขยายฟังก์ชัน
  • ต้องการระบบฐานข้อมูลที่ขยายขนาดได้ในระยะยาว

3 สิ่งที่ต้องเตรียม (Prerequisites)

ฮาร์ดแวร์ขั้นต่ำ

  • CPU: 2 cores ขึ้นไป (แนะนำ 4+ cores สำหรับ production)
  • RAM: 4 GB ขึ้นไป (แนะนำ 8+ GB สำหรับ production)
  • Storage: 20 GB ขึ้นไป (แนะนำ SSD สำหรับ performance)
  • Network: ค่า latency ต่ำ หากใช้ remote connection

ซอฟต์แวร์ที่ต้องมี

  • Ubuntu: 22.04 LTS หรือ 24.04 LTS
  • User: ผู้ใช้ที่มีสิทธิ์ sudo
  • Internet: เชื่อมต่ออินเทอร์เน็ตเพื่อดาวน์โหลด packages
  • Time: ประมาณ 15-30 นาทีในการติดตั้งและตั้งค่า

แผนผังขั้นตอนการติดตั้ง

อัปเดตระบบ apt update & upgrade Step 1 ติดตั้ง PostgreSQL apt install postgresql Step 2 ตั้งค่าพื้นฐาน postgresql.conf, pg_hba.conf Step 3 ผู้ใช้และ DB CREATE USER, CREATE DATABASE Step 4 ทดสอบการใช้งาน psql, CREATE TABLE, INSERT

4 ขั้นตอนการติดตั้ง PostgreSQL บน Ubuntu

PostgreSQL มีอยู่ใน repository ของ Ubuntu โดยค่าเริ่มต้น แต่เพื่อให้ได้เวอร์ชั่นล่าสุด เราจะใช้ PostgreSQL Global Development Group (PGDG) repository

1

4.1 อัปเดตระบบและติดตั้ง dependencies

เริ่มต้นด้วยการอัปเดต package list และติดตั้ง programs ที่จำเป็น

sudo apt update -y
sudo apt install wget curl gnupg2 lsb-release -y
คำอธิบาย:
- wget: สำหรับดาวน์โหลด repository key
- curl: สำหรับเชื่อมต่อกับ web
- gnupg2: สำหรับตรวจสอบ signature
- lsb-release: เพื่อตรวจสอบเวอร์ชั่น Ubuntu
2

4.2 เพิ่ม PostgreSQL repository

เพิ่ม official PostgreSQL repository เพื่อได้เวอร์ชั่นล่าสุด

wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
  sudo gpg --dearmor -o /usr/share/keyrings/postgresql.gpg

echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] \
http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | \
  sudo tee /etc/apt/sources.list.d/pgdg.list
วิธีตรวจสอบ: ตรวจสอบไฟล์ /etc/apt/sources.list.d/pgdg.list
deb [signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt focal-pgdg main
3

4.3 ติดตั้ง PostgreSQL

อัปเดต package list แล้วติดตั้ง PostgreSQL 16 (เวอร์ชั่นล่าสุดเมื่อพิมพ์บทความนี้)

sudo apt update
sudo apt install postgresql-16 postgresql-contrib-16 -y
pkg postgresql-contrib: รวม extension ต่างๆ เช่น pg_stat_statements, fuzzystrmatch และอื่นๆ
4

4.4 ตรวจสอบการติดตั้ง

ตรวจสอบว่า PostgreSQL service กำลัง running และตรวจสอบเวอร์ชั่น

# ตรวจสอบ status ของ service
sudo systemctl status postgresql

# ตรวจสอบเวอร์ชั่น
psql --version
# หรือ
sudo -u postgres psql -c "SELECT version();"

เมื่อติดตั้งเสร็จ PostgreSQL จะ auto-start และตั้งค่าให้ run on boot โดยอัตโนมัติ

5 การตั้งค่า PostgreSQL หลังการติดตั้ง

หลังจากติดตั้งเสร็จแล้ว คุณจำเป็นต้องตั้งค่า PostgreSQL ให้เหมาะกับความต้องการของคุณ

1. ตั้งค่า Listening Address

แก้ไขไฟล์ postgresql.conf เพื่อรับการเชื่อมต่อจากภายนอก

sudo nano /etc/postgresql/16/main/postgresql.conf

ค้นหาบรรทัด listen_addresses และแก้ไข:

# ค่าเริ่มต้น (local only)
listen_addresses = 'localhost'

# รับการเชื่อมต่อจากทุกที่ (ระวังด้าน security!)
listen_addresses = '*'

# หรือระบุ IP ที่เฉพาะเจาะจง
listen_addresses = '127.0.0.1,192.168.1.100'

2. ตั้งค่าการยืนยันตัวตน (Authentication)

แก้ไขไฟล์ pg_hba.conf เพื่อกำหนดรูปแบบการยืนยันตัวตน

sudo nano /etc/postgresql/16/main/pg_hba.conf

การตั้งค่าแบบทั่วไป:

# ท้องถิ่น (Unix domain socket)
local   all             all                                     peer

# IPv4 local connections
host    all             all             127.0.0.1/32            md5

# IPv6 local connections
host    all             all             ::1/128                 md5

# รับการเชื่อมต่อจากเครือข่าย (เปลี่ยนให้เหมาะกับคุณ)
host    all             all             192.168.1.0/24          md5
peer = ใช้ Unix username | md5 = ใช้รหัสผ่าน md5

3. ตั้งค่า Connection Limits

ปรับค่า max_connections ให้เหมาะกับ RAM ที่มี

sudo nano /etc/postgresql/16/main/postgresql.conf

ในไฟล์ postgresql.conf ค้นหา max_connections:

# สำหรับ server ที่มี RAM 4GB
max_connections = 100

# สูตรประมาณ: max_connections = (RAM_in_MB / 4) / 10

# โดยทั่วไป:
# - 4GB RAM    -> 100 connections
# - 8GB RAM    -> 200 connections
# - 16GB RAM   -> 400 connections

อย่าตั้งค่าสูงเกินไป เพราะ PostgreSQL ใช้ memory ต่อ connection

4. ตั้งค่าหน่วยความจำ (Memory)

ปรับค่า shared_buffers และ work_mem

sudo nano /etc/postgresql/16/main/postgresql.conf

แนะนำตามสูตร:

# shared_buffers: 25% ของ RAM
shared_buffers = 1GB

# effective_cache_size: 50-75% ของ RAM
effective_cache_size = 3GB

# work_mem: ต่อ connection (ระวัง!)
work_mem = 64MB

# maintenance_work_mem: สำหรับ maintenance operations
maintenance_work_mem = 512MB

รีสตาร์ท PostgreSQL Service

หลังเปลี่ยนการตั้งค่าทุกครั้ง คุณต้อง restart service

# Restart service
sudo systemctl restart postgresql

# ตรวจสอบ status
sudo systemctl status postgresql

# ตรวจสอบว่า service run on boot
sudo systemctl enable postgresql

6 การจัดการผู้ใช้และฐานข้อมูล

PostgreSQL มี user และ database แยกจาก Linux system users คุณต้องสร้าง user และ database แยกกัน

6.1 เข้าสู่ system user 'postgres'

ระบบ PostgreSQL ทำงาน under system user ชื่อ postgres คุณต้องเข้าสู่ user นี้ก่อน

# เข้าสู่ shell ของ postgres user
sudo -u postgres psql

# หรือเข้า shell ก่อนแล้วเข้า psql
sudo -u postgres bash
psql
วิธีออกจาก psql: พิมพ์ quit หรือ \q

6.2 สร้าง User ใหม่

สร้าง user สำหรับแอปพลิเคชันของคุณ

-- เข้าสู่ psql แล้วพิมพ์คำสั่งนี้
CREATE USER appuser WITH PASSWORD 'your_secure_password';

-- หรือสร้างโดยมีสิทธิ์ create database
CREATE USER appuser WITH CREATEDB PASSWORD 'your_secure_password';

-- หรือสร้าง superuser (ระวัง!)
CREATE USER admin WITH SUPERUSER PASSWORD 'your_secure_password';

-- ตรวจสอบ user ที่มีอยู่
\du

6.3 สร้าง Database ใหม่

สร้าง database และกำหนด owner

-- สร้าง database ใหม่
CREATE DATABASE appdb;

-- สร้าง database พร้อมระบุ owner
CREATE DATABASE appdb OWNER appuser;

-- หรือใช้ชื่อ user ปัจจุบันเป็น owner
CREATE DATABASE appdb OWNER CURRENT_USER;

-- ตรวจสอบ database ที่มีอยู่
\l

6.4 กำหนดสิทธิ์ (Privileges)

ให้สิทธิ์กับ user เกี่ยวกับ database ที่สร้าง

-- เข้าเชื่อมต่อ database
\c appdb

-- ให้สิทธิ์ทั้งหมดบน database
GRANT ALL PRIVILEGES ON DATABASE appdb TO appuser;

-- ให้สิทธิ์บน public schema
GRANT ALL ON SCHEMA public TO appuser;

-- ให้สิทธิ์บนตารางทั้งหมด (สำหรับ table ที่สร้างใหม่)
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO appuser;

-- ให้สิทธิ์บน sequence ทั้งหมด
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO appuser;

-- สำหรับ table ที่มีอยู่แล้ว
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO appuser;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO appuser;

6.5 เปลี่ยนรหัสผ่าน

เปลี่ยนรหัสผ่านของ user ที่มีอยู่

-- เปลี่ยนรหัสผ่านของ oneself
\password

-- เปลี่ยนรหัสผ่านของ user อื่น (ต้องเป็น superuser)
\password username

-- หรือใช้ SQL command
ALTER USER username WITH PASSWORD 'new_password';

7 คำสั่ง SQL พื้นฐาน

หลังจากสร้าง database และ user แล้ว คุณสามารถเริ่มใช้งาน SQL commands ได้

7.1 เชื่อมต่อกับ Database

วิธีเชื่อมต่อกับ database ที่สร้างไว้

# เชื่อมต่อด้วย user ที่มีอยู่
psql -U appuser -d appdb -h localhost

# หรือระบุ password ใน command (ไม่แนะนำสำหรับ production)
PGPASSWORD='your_password' psql -U appuser -d appdb -h localhost

# ตรวจสอบการเชื่อมต่อ
SELECT current_user, current_database();

7.2 สร้าง Table

ตัวอย่างการสร้าง table พื้นฐานสำหรับผู้ใช้

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    full_name VARCHAR(100),
    role VARCHAR(20) DEFAULT 'user',
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

7.3 เพิ่มข้อมูล (INSERT)

เพิ่มข้อมูลลงใน table

-- เพิ่มข้อมูลข้อมูลเดียว
INSERT INTO users (username, email, password_hash, full_name, role)
VALUES ('john_doe', 'john@example.com', 'hashed_password_here', 'John Doe', 'admin');

-- เพิ่มข้อมูลหลายแถว
INSERT INTO users (username, email, password_hash, full_name, role)
VALUES
    ('jane_smith', 'jane@example.com', 'hashed_password2', 'Jane Smith', 'user'),
    ('bob_wilson', 'bob@example.com', 'hashed_password3', 'Bob Wilson', 'user'),
    ('alice_jones', 'alice@example.com', 'hashed_password4', 'Alice Jones', 'moderator');

7.4 อ่านข้อมูล (SELECT)

ดึงข้อมูลจาก database

-- เลือกทุกคอลัมน์ทุกแถว
SELECT * FROM users;

-- เลือกคอลัมน์ที่ต้องการ
SELECT id, username, email, role FROM users;

-- ใช้ WHERE filter
SELECT * FROM users WHERE role = 'admin';

-- ใช้ LIMIT และ OFFSET (สำหรับ pagination)
SELECT * FROM users ORDER BY created_at DESC LIMIT 10 OFFSET 0;

-- ใช้ LIKE search
SELECT * FROM users WHERE username LIKE '%john%';

-- ใช้ aggregate functions
SELECT COUNT(*) as total_users, AVG(id) as avg_id FROM users;

-- ใช้ GROUP BY
SELECT role, COUNT(*) as count FROM users GROUP BY role;

-- ใช้ JOIN (ถ้ามี table อื่น)
-- SELECT u.username, p.title FROM users u JOIN posts p ON u.id = p.user_id;

7.5 แก้ไขข้อมูล (UPDATE)

แก้ไขข้อมูลที่มีอยู่

-- อัปเดตข้อมูลทั้งหมด (ระวัง!)
UPDATE users SET role = 'guest';

-- อัปเดตข้อมูลด้วย WHERE
UPDATE users SET role = 'moderator' WHERE username = 'bob_wilson';

-- อัปเดตหลายคอลัมน์
UPDATE users 
SET email = 'new_email@example.com', 
    updated_at = CURRENT_TIMESTAMP 
WHERE id = 1;

-- อัปเดตด้วย subquery
UPDATE users 
SET role = 'admin' 
WHERE id IN (SELECT user_id FROM posts WHERE is_pinned = true);

7.6 ลบข้อมูล (DELETE)

ลบข้อมูลออกจาก database

-- ลบข้อมูลทั้งหมด (ระวัง!)
DELETE FROM users;

-- ลบด้วย WHERE
DELETE FROM users WHERE is_active = false;

-- ลบด้วย subquery
DELETE FROM users WHERE id NOT IN (SELECT DISTINCT user_id FROM posts);

-- ใช้ RETURNING เพื่อดูข้อมูลที่ถูกลบ
DELETE FROM users WHERE username = 'test_user' RETURNING *;

แผนผัง CRUD Operations

PostgreSQL appdb C CREATE INSERT R READ SELECT U UPDATE UPDATE D DELETE DELETE
C CREATE = INSERT | R READ = SELECT | U UPDATE = UPDATE | D DELETE = DELETE

8 การสำรองและกู้คืนข้อมูล

การสำรองข้อมูลเป็นสิ่งสำคัญมาก การมีระบบ backup ที่ดีจะช่วยป้องกันการสูญเสียข้อมูลจากความผิดพลาดหรืออุบัติเหตุ

8.1 สำรองข้อมูล (Backup) ด้วย pg_dump

pg_dump คือเครื่องมือสำหรับสำรองข้อมูล database เดียวในรูปแบบ SQL หรือ archive

# สำรอง database เดียว (format SQL)
pg_dump -U appuser -d appdb -f /backup/appdb.sql

# สำรอง database เดียว (format custom - compressed)
pg_dump -U appuser -d appdb -Fc -f /backup/appdb.dump

# สำรองทุก database
pg_dumpall -U postgres -f /backup/all_databases.sql

# สำรองเฉพาะ schema (ไม่มีข้อมูล)
pg_dump -U appuser -d appdb --schema-only -f /backup/appdb_schema.sql

# สำรองเฉพาะข้อมูล (ไม่มี schema)
pg_dump -U appuser -d appdb --data-only -f /backup/appdb_data.sql

# สำรองเฉพาะ table ที่ต้องการ
pg_dump -U appuser -d appdb -t users -t posts -f /backup/users_posts.sql

สร้าง script สำรองอัตโนมัติ

#!/bin/bash
# backup_script.sh

BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="appdb"
DB_USER="appuser"

# สร้าง directory ถ้ายังไม่มี
mkdir -p $BACKUP_DIR

# สำรอง database
pg_dump -U $DB_USER -d $DB_NAME -Fc -f $BACKUP_DIR/${DB_NAME}_${DATE}.dump

# ลบ backup เก่าเกิน 30 วัน
find $BACKUP_DIR -name "*.dump" -mtime +30 -delete

echo "Backup completed: ${DATE}"
ตั้งค่า crontab สำหรับ backup อัตโนมัติทุกวันเวลา 03:00 น.:
0 3 * * * /path/to/backup_script.sh >> /var/log/pg_backup.log 2>&1

8.2 กู้คืนข้อมูล (Restore) ด้วย pg_restore

pg_restore คือเครื่องมือสำหรับกู้คืนข้อมูลจาก file ที่สำรองไว้

# กู้คืนจาก SQL format
psql -U appuser -d appdb -f /backup/appdb.sql

# กู้คืนจาก custom format (แนะนำ)
pg_restore -U appuser -d appdb /backup/appdb.dump

# สร้าง database ก่อนแล้วค่อย restore
createdb -U appuser appdb
pg_restore -U appuser -d appdb /backup/appdb.dump

# ล้างข้อมูลเก่าแล้ว restore
pg_restore -U appuser -d appdb --clean --if-exists /backup/appdb.dump

# สร้าง database ใหม่แล้ว restore (สำหรับ restore เวอร์ชั่นใหม่)
dropdb -U appuser appdb
createdb -U appuser appdb
pg_restore -U appuser -d appdb /backup/appdb.dump

8.3 Physical Backup (File System Backup)

สำรองไฟล์ข้อมูลโดยตรง วิธีนี้ต้องใช้เฉพาะเมื่อ database ไม่ running (cold backup)

# 1. Stop PostgreSQL service
sudo systemctl stop postgresql

# 2. สำรองไฟล์ข้อมูล
sudo tar -czvf /backup/pgdata_full_$(date +%Y%m%d).tar.gz /var/lib/postgresql/16/main/

# 3. Start PostgreSQL service
sudo systemctl start postgresql

# 4. สำรอง configuration files ด้วย
sudo tar -czvf /backup/pgconfig_$(date +%Y%m%d).tar.gz \
  /etc/postgresql/16/main/ \
WARNING ระวัง!Physical backup ไม่สามารถ restore ไปยัง Postgres เวอร์ชั่นที่ต่างกันมาก
ควรใช้ pg_dump แทนสำหรับการ backup ทั่วไป

โครงสร้าง Backup System

PostgreSQL appdb pg_dump SQL / Custom Local Storage /backup/*.dump Daily backup Remote Server NAS / S3 / OSS Off-site backup pg_restore Recovery Backup Flow: Database -> pg_dump -> Backup Storage Backup Storage -> pg_restore -> Recovery

9 แก้ไขปัญหาที่พบบ่อย

คู่มือแก้ไขปัญหาสำหรับ error ที่พบบ่อยเมื่อใช้งาน PostgreSQL

ERROR 1 ไม่สามารถเชื่อมต่อ PostgreSQL

psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed:
    Is the server running locally and accepting connections on that socket?

วิธีแก้:

1 ตรวจสอบว่า PostgreSQL service กำลังทำงาน
sudo systemctl status postgresql
sudo systemctl start postgresql
2 ตรวจสอบว่า service ตั้งค่าให้ run on boot
sudo systemctl enable postgresql
3 ตรวจสอบ log สำหรับ error ที่แท้จริง
sudo tail -f /var/log/postgresql/postgresql-16-main.log

ERROR 2 Authentication failed

psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed:
    FATAL:  password authentication failed for user "appuser"

วิธีแก้:

1 ตรวจสอบว่า user นั้นมีอยู่จริงและมีรหัสผ่านที่ถูกต้อง
# เข้าสู่ psql ด้วย superuser
sudo -u postgres psql

# เปลี่ยนรหัสผ่าน
\password appuser

# หรือตรวจสอบ user
\du
2 ตรวจสอบไฟล์ pg_hba.conf ว่าการตั้งค่า authentication ถูกต้อง
sudo nano /etc/postgresql/16/main/pg_hba.conf

# ต้องมีบรรทัดแบบนี้สำหรับ host connections
host    all             all             127.0.0.1/32            md5

# restart service หลังแก้ไข
sudo systemctl restart postgresql

ERROR 3 Permission denied หรือ privilege error

ERROR:  permission denied for table users
HINT: You need to execute the GRANT command.

ERROR:  permission denied for schema public

วิธีแก้:

1 ให้สิทธิ์กับ user บน schema และ table
# เข้าสู่ psql
sudo -u postgres psql -d appdb

# ให้สิทธิ์
GRANT ALL PRIVILEGES ON DATABASE appdb TO appuser;
GRANT ALL ON SCHEMA public TO appuser;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO appuser;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO appuser;

# หรือให้แค่สิทธิ์พื้นฐานที่จำเป็น
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO appuser;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO appuser;
2 ตั้งค่าให้สิทธิ์ใหม่ที่สร้างขึ้นในอนาคตด้วย
# ให้สิทธิ์อัตโนมัติสำหรับ object ที่สร้างในอนาคต
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO appuser;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT USAGE, SELECT ON SEQUENCES TO appuser;

ERROR 4 Out of memory หรือ connection limit exceeded

FATAL:  too many connections for role "appuser"
FATAL:  remaining connection slots are reserved for non-replication superuser connections

ERROR:  could not fork new process for connection
        : Cannot allocate memory

วิธีแก้:

1 ตรวจสอบและปรับ max_connections
sudo nano /etc/postgresql/16/main/postgresql.conf

# ค้นหา max_connections
max_connections = 100

# restart service
sudo systemctl restart postgresql
2 ตรวจสอบ connection ที่กำลังใช้งานอยู่
# เข้าสู่ psql
sudo -u postgres psql

# ดู connection ที่มีอยู่
SELECT pid, usename, application_name, state, query_start
FROM pg_stat_activity
ORDER BY query_start;

# ยกเลิก query ที่ค้าง (ระวัง!)
SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction';

# หรือ force kill
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction';
3 ใช้ connection pooler (PgBouncer)
แนะนำให้ใช้ PgBouncer เพื่อลดจำนวน connection ที่เชื่อมต่อโดยตรงกับ PostgreSQL