한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Sách trắng lag game › L12 Cơ sở dữ liệu

Transaction mở quá lâu Long-running transaction / MVCC purge lag

ID nguyên nhân db-long-tx · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)

Mở thẻ gốc có hình minh họa và thí nghiệm →

Nếu một transaction mở quá lâu, nó giữ khóa mãi, và DB không dọn (purge) được dữ liệu phiên bản cũ nên toàn bộ hệ thống chậm dần.

Vì sao Mở transaction rồi chờ phản hồi của server khác, hoặc chạy query tổng hợp dài trên DB chính trong giờ vận hành → Dẫn đến Khóa đã giữ không được nhả, dữ liệu phiên bản cũ cần dọn cứ tích tụ → Trên màn hình Tính năng dùng dòng đó bị timeout, việc lưu và truy vấn nói chung chậm dần trong vài giờ

Triệu chứng
Trễ thao tác, Nuốt thao tác·rollback
Yếu tố
Độ trễ, Ngưng trệ
Ai gặp phải
Chỉ một tính năng, Cả server
Khi nào
Càng chạy lâu càng nặng, Thỉnh thoảng bất chợt
Phụ trách
Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng DB (Đội hạ tầng)
Việc cần làm (Đội phát triển game)
Không chờ gọi mạng hay input của người dùng bên trong transaction, chạy query tổng hợp trên bản sao.
Việc cần làm (Đội hạ tầng)
Cảnh báo và buộc dừng transaction mở quá lâu, cung cấp bản sao cho tổng hợp, theo dõi mức tăng của undo log và dòng chết.
Trên đồ thị
Tăng dần · Độ dài undo log (History list length), số dòng chết
Chỗ cần xem
MySQL: dùng trx_started trong INFORMATION_SCHEMA.INNODB_TRX để tìm transaction cũ nhất, xem History list length (lượng undo log chưa dọn) trong phần TRANSACTIONS của SHOW ENGINE INNODB STATUS. PostgreSQL: xem xact_start và các session có state là idle in transaction trong pg_stat_activity, n_dead_tup trong pg_stat_user_tables
Đúng nếu
có transaction đã mở từ vài phút đến vài giờ, trong thời gian đó History list length hoặc n_dead_tup tăng liên tục, rồi giảm xuống khi transaction đó kết thúc và việc dọn dẹp (purge, VACUUM) chạy
Loại trừ nếu
không có transaction cũ mà vẫn chậm nói chung → checkpoint (db-checkpoint) hoặc ổ đĩa
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)
Tìm hiểu thêm
DB giữ lại phiên bản cũ để bên đọc vẫn thấy được dữ liệu như trước khi sửa (MVCC). Chỉ khi transaction cũ nhất kết thúc thì mới xóa được các bản ghi này, nên nếu một transaction mở suốt vài giờ, MySQL sẽ tích tụ undo log, còn PostgreSQL tích tụ các dòng chết (dead tuple) mà VACUUM không dọn được. Với SQL Server, transaction log không thu nhỏ được, có khi làm đầy cả ổ đĩa.

Nguồn

  1. InnoDB Multi-Versioning MySQL
    Nếu vẫn còn transaction có thể thấy phiên bản cũ thì update undo log không bỏ được, rollback segment phình to; khuyến nghị commit thường xuyên cả với transaction chỉ đọc
  2. Routine Vacuuming (PostgreSQL Documentation) PostgreSQL
    Phiên bản dòng cũ không xóa được chừng nào transaction khác còn thấy nó; transaction mở quá lâu phải được kết thúc hoặc ngắt session
  3. Client Connection Defaults (PostgreSQL Documentation) PostgreSQL
    idle_in_transaction_session_timeout: ngắt các session mở transaction rồi để đó, để chúng không giữ khóa quá lâu
  4. Troubleshoot a full transaction log (SQL Server Error 9002) Microsoft SQL Server
    Transaction đang hoạt động chạy lâu sẽ chặn việc dọn transaction log
  5. The INFORMATION_SCHEMA INNODB_TRX Table MySQL
    TRX_STARTED: thời điểm bắt đầu transaction
  6. Purge Configuration MySQL
    purge dọn danh sách undo log của các transaction đã commit (history list), lượng tồn đọng hiển thị ở History list length trong phần TRANSACTIONS của SHOW ENGINE INNODB STATUS
  7. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    xact_start (thời điểm bắt đầu transaction) và state (idle in transaction) trong pg_stat_activity, n_dead_tup (ước lượng số dòng chết) trong pg_stat_user_tables

Nguyên nhân nên xem cùng

Cùng tầng: L12 Cơ sở dữ liệu

Nguyên nhân ở tầng khác gây cùng triệu chứng (Trễ thao tác)

Xem thẻ gốc có hình minh họa và thí nghiệm