9 điểm bởi GN⁺ 2025-07-28 | 2 bình luận | Chia sẻ qua WhatsApp
  • Giới thiệu cách tiếp cận mang tính thử nghiệm về tổ hợp tham số có thể làm suy giảm hiệu năng Postgres một cách cực đoan
  • Thực hiện tinh chỉnh ngược các yếu tố như bộ đệm, chỉ mục, WAL, I/O vốn thường được tối ưu để tăng tốc
  • Thao tác cực đoan với shared_buffers, autovacuum và các tùy chọn liên quan đến WAL để đạt mức giảm TPS tới 42.000 lần
  • Áp dụng cả các tính năng mới như io_method và io_workers của Postgres 18/19 để thử nghiệm giới hạn I/O chỉ còn một luồng
  • Kết quả chứng minh rằng chỉ với tệp cấu hình Postgres cũng có thể gây suy giảm hiệu năng ở mức cực đoan

Tổng quan

Bài viết này trình bày một thí nghiệm đi ngược với hướng tinh chỉnh Postgres thông thường vốn tập trung vào việc làm cho hệ thống nhanh hơn, mà thay vào đó chỉ nhắm đến việc làm nó chậm đi, bằng cách thay đổi nhiều giá trị cấu hình của PostgreSQL để kéo hiệu năng xuống tới giới hạn.
Bài kiểm thử dựa trên workload TPC-C của BenchBase (128 kho, 100 kết nối, mỗi kết nối cố gắng đạt tối đa 10.000 giao dịch/giây, Postgres 19devel mới nhất, Ryzen 7950x, RAM 32GB, SSD 2TB, chạy trong 120 giây).
Ở giá trị mặc định, hiệu năng là 7082 TPS, và tác giả quan sát theo từng bước xem mỗi lần thao tác tham số làm hệ thống chậm đi đến mức nào.

Cắt giảm mạnh bộ đệm

  • Postgres sử dụng bộ đệm mạnh mẽ (shared_buffers) để giảm disk I/O
  • Khi giảm shared_buffers từ giá trị mặc định (10GB) xuống 8MB, TPS giảm còn khoảng 1/7 (1052 TPS)
  • Quan sát thấy tỷ lệ cache hit giảm từ 99,90% xuống 70,52%, còn số lần gọi read syscall tăng hơn 300 lần
  • Đã thử giảm xuống 128kB, nhưng Postgres chỉ cho phép tối thiểu khoảng 2MB, và TPS tiếp tục giảm xuống 485

Tăng công việc nền (autovacuum tuning)

  • Đưa mọi ngưỡng liên quan đến autovacuum xuống mức thấp nhất để vacuum gần như chạy ở mỗi thao tác
    • Kết hợp như autovacuum_vacuum_insert_threshold=1, autovacuum_naptime=1 v.v.
    • vacuum lặp lại gần như mỗi giây ngay cả khi thực tế không có nhiều việc để làm
  • Trong quá trình này, giảm maintenance_work_mem xuống 128kB và bật toàn bộ logging cho autovacuum
  • Kết quả là TPS giảm xuống 293 (chưa tới 1/20 so với ban đầu)
  • Log thời gian thực liên quan đến autovacuum xác nhận rằng công việc nền diễn ra thường xuyên là nguyên nhân làm giảm hiệu năng

Làm tệ nhất việc ghi WAL (Write-Ahead Log)

  • Điều chỉnh toàn bộ tham số liên quan đến WAL sang trạng thái tệ nhất
    • wal_writer_flush_after=0, wal_writer_delay=1, wal_sync_method=open_datasync v.v.
    • Ép checkpoint mỗi 30 giây, giữ min/max_wal_size=32MB ở mức tối thiểu
    • wal_level=logical, wal_log_hints=on để ghi cả những thông tin không cần thiết vào WAL
    • Bật thêm tải như track_wal_io_timing, summarize_wal
  • Kết quả TPS giảm xuống 98 (chưa tới 1/70 so với ban đầu)
  • Log cho thấy các checkpoint lặp lại chỉ sau vài trăm ms, xác nhận hành vi bất thường

Loại bỏ hiệu quả của chỉ mục

  • Đặt các giá trị khiến chi phí sử dụng chỉ mục đều bị tính ở mức tối đa (random_page_cost=1e300, cpu_index_tuple_cost=1e300), về thực chất là vô hiệu hóa chỉ mục
  • Tăng shared_buffers trở lại 8MB (để đảm bảo ổn định), TPS giảm xuống 0,87 (đạt mức chậm hơn 7.000 lần)

Ép I/O về một luồng duy nhất

  • Tận dụng tính năng mới của Postgres 18+
  • Đặt io_method=worker, io_workers=1 để ép mọi I/O chạy qua một worker thread duy nhất
  • TPS tiếp tục giảm xuống 0,016 (chậm hơn 42.000 lần)
  • Với 100 kết nối và thời gian thử nghiệm 120 giây, chỉ có 11 giao dịch thành công, cho thấy hiệu năng bị bóp nghẹt nghiêm trọng

Kết luận và hướng dẫn tái hiện

  • Chứng minh rằng chỉ với tổng cộng 32 thao tác chỉnh tham số cũng có thể đẩy DB vận hành vào trạng thái gần như "tê liệt"
  • Có thể tối đa hóa mức suy giảm hiệu năng chỉ bằng cách can thiệp vào cấu hình postgresql.conf
  • Người muốn tái hiện thí nghiệm có thể tham khảo BenchBase Postgres, môi trường TPC-C đã nêu ở trên và toàn bộ danh sách thiết lập
  • Một số tham số phụ hoặc các thử nghiệm làm chậm thêm không được đưa vào

Danh sách tham số tóm tắt

  • shared_buffers = 8MB
  • Các thresholds/scale_factor liên quan đến autovacuum = hạ xuống mức thấp nhất 0~1
  • Chi phí, bộ nhớ và log liên quan đến vacuum: hạ thấp/tăng tối đa
  • Đồng bộ/flush/log/level liên quan đến WAL: giữ ở trạng thái chậm
  • random_page_cost, cpu_index_tuple_cost liên quan đến chỉ mục: đặt thành 1e300
  • io_method = worker, io_workers = 1
  • Các giá trị chi tiết khác xem danh sách trong bài

Kết bài

  • Chỉ riêng tệp postgresql.conf cũng có thể gây ra suy giảm hiệu năng cực lớn
  • Trong thực tế, có thể tham khảo ngược tổ hợp này để cải thiện hiệu năng một cách hiệu quả
  • Bài viết khép lại với việc tác giả nhắc đến chuyện phải dừng thử nghiệm vì đau lưng

2 bình luận

 
GN⁺ 2025-07-28
Ý kiến Hacker News
  • Giới thiệu cách bỏ qua hoàn toàn những thứ như chỉ mục, nhiều bảng, giao dịch, quan hệ thực thể, tính toàn vẹn tham chiếu, rồi dùng mọi dữ liệu trong một bảng duy nhất theo kiểu KVS NoSQL SQL như các phiên bản đầu của TRIRIGA
  • Cách làm này vui đến mức khiến tôi nghĩ sẽ thật hay nếu có hẳn một loạt sách kiểu "cách làm mọi thứ tệ hơn nữa", vì khi học những cách sai thì ngược lại cũng có thể tìm ra cách tốt hơn, và nếu làm theo phong cách O’Reilly thì bìa nên là một con vật giả tưởng vẽ vụng về nào đó, chẳng hạn một con kỳ lân có đầu ở cả hai phía đang gọi bằng AirPods, đưa tiền cho kẻ lừa đảo, làm PowerPoint, ăn quá nhiều và dùng chất kích thích
    • Thực tế từng có ví dụ kiểu chiến lược này được dùng trong Thế chiến II: để tăng tỷ lệ phi công sống sót, các nhà khí tượng học trước tiên tìm ra những điều kiện gây thương vong nhiều nhất, rồi thiết kế nhiệm vụ để tránh các điều kiện đó, xem thêm Suppose I wanted to kill a lot of pilots
    • Trong lớp học viết sáng tạo cũng có bài tập đọc và phân tích những đoạn văn viết dở khi đang luyện tập, hoặc cố tình viết lại một đoạn văn hay theo cách tệ đi, và đó là bài tập viết hữu ích nhất với tôi
    • Cũng có thể tham khảo trang parody ORLYBooks
  • Tôi thật sự muốn có một sandbox môi trường production để thử nghiệm các công cụ quan sát, với một hệ thống kiểu SaaS cỡ vừa có mô phỏng sử dụng, rồi một cấu hình postgres/rabbit ở mức tạm ổn để kiểm tra trình độ của các công cụ hoặc chiến lược gỡ lỗi
  • Ý tưởng này đúng là thiên tài, nếu muốn giỏi tối ưu hóa thì nên thử phá hỏng mọi thứ theo hướng hoàn toàn ngược lại ngay từ đầu hoặc làm nhóm đối chứng trước, và tự hỏi xem mình có thật sự đang tiếp cận cơ sở dữ liệu hay hệ thống một cách khoa học hay chỉ làm theo cảm tính
    • Mỗi lần dùng dịch vụ cloud mới tôi đều làm vậy: trước hết cố tiêu tiền Series A nhanh nhất có thể, rồi sau đó mới bắt đầu tối ưu chi phí cloud
  • Cuốn The Defence of Duffer's Drift là một ví dụ rất sớm của thể loại này: ở câu chuyện đầu tiên, nhân vật làm chiến thuật cấp tiểu đội tệ đến mức gần như mất sạch người; ở các câu chuyện sau, các điều kiện chiến thuật được thay đổi dần và kết quả ngày càng tốt hơn. Những sách chiến thuật hiện đại như Musicians of Mars 2 cũng dùng cùng cách tiếp cận. Câu chuyện Team Badger đầu tiên rất giống Duffer's Drift, nhưng là phiên bản thay đổi theo vị trí, trang bị và công nghệ. Có thể xem PDF liên quan tại The Defence of Duffer's DriftMusicians of Mars 2, và phần vị chỉ huy Team Badger nhìn lại thất bại thảm hại của mình, tự hỏi vì sao lại thua tan tác đến vậy so với mức độ tự tin và chuẩn bị, thật sự rất ấn tượng
    • Các bộ phim có tinh thần tương tự là Groundhog Day và đặc biệt là Edge of Tomorrow, ngoài ra còn có một bản hommage hiện đại đăng gần đây trên blog quân sự Anh: Defence Baltic Bridge Dreams
  • Chi tiết nhắc đến deadlock khá thú vị, tôi cũng tò mò liệu có phần nào nói về việc điều chỉnh thiết lập mức cô lập giao dịch hay không
  • Rất vui khi thấy nhắc đến B Sanderson
  • Cảm giác như sự kết hợp giữa Hyperbole and a Half và quản trị viên db, đọc rất vui và tôi cũng học được vài điều
  • Văn phong và cách triển khai suy nghĩ thật sự rất xuất sắc, đọc rất duyên
 
sonic0987 2025-07-29

Tuyệt vời. Tôi rất thích cách tiếp cận này.