ข้ามไปยังเนื้อหา

Operations & Scaling

การเขียน SQL ที่ถูกต้องเป็นแค่ครึ่งเดียวของงาน อีกครึ่งคือการทำให้เซิร์ฟเวอร์ PostgreSQL ตัวเดียวอยู่ดีเมื่อจู่ ๆ ต้องรับใช้ผู้ใช้หลายพัน รอดจากดิสก์พัง เก็บ table ที่มีหลายพันล้าน row และปฏิเสธใครก็ตามที่ไม่ควรเข้ามา ชุดของเรื่องเหล่านี้คือสิ่งที่คนหมายถึงเมื่อพูดว่า operations — งานของการรันฐานข้อมูลใน production ไม่ใช่บนแล็ปท็อปของคุณ

โมดูลนี้ก้าวออกจาก syntax ของ query และดูรูปร่างของ deployment จริง ไม่มีอะไรที่นี่เปลี่ยน SQL ที่คุณรู้แล้ว แต่มันล้อมเซิร์ฟเวอร์ตัวนั้นด้วยชิ้นส่วนที่ทำให้พึ่งพาได้ในระดับใหญ่ ต่างจากโมดูลก่อนหน้า บทเรียนเหล่านี้ส่วนใหญ่ต้องใช้มากกว่าหนึ่ง process จึงรันในแล็บ Docker ใช้แล้วทิ้งบน PostgreSQL 18.6 (Docker Desktop บน Mac, กันยายน 2026): primary และ replica บนเครือข่ายภายใน, pooler PgBouncer 1.26, คอนเทนเนอร์ที่มี WAL archiving และการกู้คืน point-in-time จริง แต่ละบทแสดงคำสั่งและผลลัพธ์จริง ตั้งชื่อคอนเทนเนอร์ postgresql-b3-* และจบด้วยคำสั่งที่ลบมัน

หัวข้อเชิงปฏิบัติการเกือบทั้งหมดใน PostgreSQL อยู่ใต้หนึ่งในสี่หัวข้อ แต่ละอันตอบคำถาม “จะเกิดอะไรขึ้นเมื่อ…” ต่างกัน

ความกังวลคำถามที่มันตอบคำตอบที่พบบ่อย
High availabilityถ้าเซิร์ฟเวอร์หลักตายล่ะ?Replication และ failover
Client จำนวนมากถ้าแอปหลายพันเชื่อมต่อพร้อมกันล่ะ?Connection pooling
Table ใหญ่ถ้า table หนึ่งโตเป็นหลายพันล้าน row ล่ะ?Partitioning
ความคงทนและการเข้าถึงถ้าดิสก์พังหรือผู้โจมตีเชื่อมต่อมาล่ะ?Backup และ security

โปรเจกต์เล็กอาจข้ามทั้งสี่ ระบบ production จริงจังต้องการทุกอันในที่สุด และทั้งสี่ส่งผลต่อกัน: replica ช่วยความพร้อมใช้งาน และ กระจายโหลดอ่าน, pooling ปกป้อง primary ที่กำลังป้อน replica ด้วย และอื่น ๆ

ฟีเจอร์เหล่านี้ส่วนใหญ่ห่างเพียงการตั้งค่าหนึ่งอัน และหลายอันเปิดอยู่แล้ว นี่คือสิ่งที่เซิร์ฟเวอร์ 18.6 ใหม่เอี่ยมบอกเกี่ยวกับตัวมันเอง:

-- sql/defaults.sql
SELECT name, setting
FROM pg_settings
WHERE name IN ('max_connections', 'wal_level', 'max_wal_senders', 'archive_mode', 'ssl', 'listen_addresses', 'password_encryption', 'hot_standby')
ORDER BY name;
name | setting
---------------------+---------------
archive_mode | off
hot_standby | on
listen_addresses | *
max_connections | 100
max_wal_senders | 10
password_encryption | scram-sha-256
ssl | off
wal_level | replica
(8 rows)

บทเรียนต่อยอดจากตัวเลขเหล่านี้เป๊ะ wal_level = replica และ max_wal_senders = 10 แปลว่า streaming replication ไม่ต้อง restart เซิร์ฟเวอร์ แค่มี role และบรรทัด pg_hba.conf max_connections = 100 คือเพดานที่บทเรียน pooling ชน archive_mode = off คือเหตุผลที่เซิร์ฟเวอร์ใหม่ไม่มี point-in-time recovery จนกว่าคุณเปิด ssl = off แสดงว่าการเข้ารหัสเป็นการตัดสินใจของคุณ และ listen_addresses = * เป็นการเลือกของ Docker image (default ของ PostgreSQL เองคือ localhost, docs) การเปิดรับเครือข่ายจึงเป็นอีกการตัดสินใจ และ password_encryption = scram-sha-256 คือ default สมัยใหม่สำหรับรหัสผ่านที่เก็บ

แล็ปท็อปรัน process PostgreSQL หนึ่งตัวและ client หนึ่งตัว การตั้งค่า production กระจายงานไปหลายชิ้น เซิร์ฟเวอร์แอปไม่คุยกับฐานข้อมูลโดยตรง แต่ผ่าน connection pooler ที่เก็บ server connection ที่ใช้ซ้ำได้จำนวนน้อย หนึ่ง node คือ primary ที่รับการเขียน และ replica หนึ่งตัวขึ้นไปรับสำเนาต่อเนื่องของการเปลี่ยนแปลงและตอบ query แบบอ่านอย่างเดียว

flowchart TD
  App1[App server] --> Pool[Connection pooler]
  App2[App server] --> Pool
  App3[App server] --> Pool
  Pool --> Primary[(Primary - reads and writes)]
  Primary -->|streams changes| R1[(Replica - reads)]
  Primary -->|streams changes| R2[(Replica - reads)]
  Primary -->|base backup plus WAL| Backup[Backup and archive storage]
deployment PostgreSQL รูปแบบ production

อ่านแผนภาพจากบน แอปเซิร์ฟเวอร์จำนวนมากผ่าน pooler ตัวเดียวเพื่อไม่ให้ primary เห็น connection ดิบท่วมท้น primary stream ทุกการเปลี่ยนแปลงไปยัง replica ซึ่งรับทราฟฟิกอ่านออกจากหลังมัน และข้อมูลของ primary ถูกคัดลอกต่อเนื่องไปยัง backup storage เพื่อสร้างทั้งหมดใหม่ได้หลังภัยพิบัติ

  • Replication — primary และ replica จริง: pg_basebackup, replication lag ที่มองเห็น, synchronous commit ที่ค้างเมื่อ standby หายไป, pg_promote และ timeline และ logical replication พร้อมกับดักเรื่อง replica identity, DDL และการเก็บ slot
  • Connection pooling — ทำไมแต่ละ connection ของ PostgreSQL เป็น process ระบบปฏิบัติการ (ราว 3 MB ต่ออันในแล็บ), PgBouncer รับใช้ 200 client ด้วย 10 server connection ได้อย่างไร, อะไรพังใน transaction mode และวิธีกำหนดขนาด pool
  • Partitioning — range, list และ hash partition, pruning ที่พิสูจน์ด้วย plan, กับดัก default partition และสิ่งที่ partitioning เร่งและไม่เร่ง วัดบน 3 ล้าน row
  • Backup และ security — pg_dump และ pg_restore, point-in-time recovery ที่หยุดก่อน DELETE, incremental backup, pg_hba.conf, TLS, GRANT และ row-level security

คุณรู้แล้วว่าจะ model ข้อมูล query index และห่อการเปลี่ยนแปลงด้วย transaction อย่างไร operations คือสิ่งที่ทำให้ความรู้นั้นรอดจากการเจอทราฟฟิกจริง ไม่มีอะไรที่นี่เป็น PostgreSQL คนละตัว มันคือเซิร์ฟเวอร์เดิมที่ตั้งค่าและล้อมรอบเพื่อให้ข้อจำกัดของเครื่องเดียวและความล้มเหลวของเครื่องเดียวไม่ใช่ข้อจำกัดและความล้มเหลวของแอปคุณ

คิดว่าเซิร์ฟเวอร์ฐานข้อมูลคือเชฟที่ยุ่งมากคนเดียว replication ให้ครัวมีเชฟคนที่สองที่อ่านสมุดสูตรเล่มเดียวกัน pooling วางพนักงานต้อนรับที่ประตูเพื่อไม่ให้เชฟถูกรุม partitioning จัดห้องเก็บของเพื่อเคลียร์ชั้นหนึ่งได้เร็ว backup คือรูปถ่ายของครัวที่คุณเก็บไว้ในอีกอาคาร และ security คือใครเข้าได้ ใช้ประตูไหน และแตะอะไรได้ ไม่มีอะไรในนี้เปลี่ยนวิธีที่เชฟทำอาหาร

  • อย่าหยิบ replication หรือ partitioning ตั้งแต่วันแรก เซิร์ฟเวอร์เดียวที่จูนดีพร้อม index ที่ดีรับโหลดได้มากอย่างน่าประหลาดใจ เพิ่มความซับซ้อนเมื่อวัดความต้องการได้เท่านั้น
  • replica มีไว้สำหรับความพร้อมใช้งานและขยายการอ่าน ไม่ใช่รับการเขียน — ทุกการเขียนยังไปที่ primary เดียว และ replica ไม่ใช่ backup
  • backup ที่ไม่เคยกู้คืนคือความหวัง ไม่ใช่ backup หลักฐานเดียวคือการทดสอบกู้คืนที่สำเร็จ
  • security ไม่ใช่ขั้นสุดท้ายที่เอามาติด role แบบ least privilege และการจำกัดการเข้าถึงเครือข่ายถูกที่สุดเมื่อตั้งก่อนที่อะไรจะพึ่งพารุ่นหลวม
  • “operations แปลว่าฐานข้อมูลอีกตัว” มันคือเซิร์ฟเวอร์เดิมที่มี process ที่สองอยู่ข้าง ๆ (replica, pooler, archive)
  • “connection มากขึ้นแปลว่า throughput มากขึ้น” ในแล็บ pooling 200 client บน 10 server connection รันที่ throughput เท่ากับที่น้อยกว่า connection ที่เกินมีแต่เสียหน่วยความจำ
  • “high availability กับ backup เป็นสิ่งเดียวกัน” replication คัดลอก DELETE ที่ผิดพลาดไปทุก replica; มีแต่ backup พร้อม WAL ที่ archive ไว้ที่ให้ย้อนกลับได้
งานหลักของ connection pooler หน้า PostgreSQL คืออะไร?
ในการตั้งค่าแบบมี replica คำสั่งเขียนไปที่ไหน?
partitioning แก้ความกังวลด้าน production ข้อใดเป็นหลัก?
เพื่อนร่วมงานบอกว่า "เรามี replica แล้ว ไม่ต้องมี backup" ข้อบกพร่องคืออะไร?
เซิร์ฟเวอร์ PostgreSQL 18 ใหม่เอี่ยมมีค่า wal_level และ archive_mode เป็นอะไร?