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

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

Tranh chấp khóa trên hot row Hot row lock contention

ID nguyên nhân db-hot-row · 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 →

Khi ai cũng muốn sửa cùng một dòng (kho bang hội, vật phẩm hot ở nhà đấu giá, bộ đếm toàn server), mỗi lúc chỉ một người lấy được khóa.

Vì sao Sự kiện hoặc vật phẩm hot làm các lần sửa dồn vào cùng một dòng → Dẫn đến Các yêu cầu phải chờ đến khi lấy được khóa → Trên màn hình Giao dịch thất bại, “Vui lòng thử lại sau”, timeout

Triệu chứng
Nuốt thao tác·rollback, Trễ thao tác
Yếu tố
Ngưng trệ, Độ trễ
Ai gặp phải
Chỉ một tính năng
Khi nào
Khi đông người
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)
Chia nhỏ dòng (sharded counter), giữ transaction ngắn, gom trong bộ nhớ rồi ghi một lượt.
Việc cần làm (Đội hạ tầng)
Giám sát thời gian và số lần chờ khóa dòng để tìm ra dòng bị tranh chấp nhiều, rồi chia sẻ.
Con số tham khảo
Nếu mỗi yêu cầu giữ khóa 10 ms thì dòng đó chỉ sửa được tối đa 100 lần trong 1 giây. Nếu trong transaction còn xen một lượt khứ hồi tới server khác thì con số này càng giảm.
Trên đồ thị
Tăng theo số người và tải · Số lần và thời gian chờ khóa dòng
Chỗ cần xem
MySQL: xem mức tăng của Innodb_row_lock_waits, Innodb_row_lock_time và giá trị Innodb_row_lock_current_waits, dùng sys.innodb_lock_waits để tìm ai đang chờ ai. PostgreSQL: xem các session có wait_event_type là Lock trong pg_stat_activity, các yêu cầu có granted là false trong pg_locks; bật log_lock_waits (mặc định tắt) thì các lần chờ khóa lâu được ghi vào log
Đúng nếu
số lần chờ khóa tăng dốc theo sự kiện hoặc số người, và phần lớn yêu cầu đang chờ cùng trỏ tới một dòng (cùng key) của cùng một bảng
Loại trừ nếu
chờ khóa rải đều trên nhiều bảng, nhiều dòng → ổ đĩa hoặc CPU bão hòa. Một session giữ khóa lâu không nhả → transaction mở quá lâu (db-long-tx)
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)

Nguồn

  1. InnoDB Locking MySQL
    Khi một transaction khóa một dòng (index record), transaction khác không sửa được dòng đó và phải chờ
  2. How to Minimize and Handle Deadlocks MySQL
    Khuyến nghị giữ transaction nhỏ và ngắn, commit ngay sau các thay đổi liên quan để giảm xung đột
  3. Server Status Variables MySQL
    Innodb_row_lock_waits, Innodb_row_lock_time cho biết số lần và thời gian chờ khóa dòng, Innodb_row_lock_current_waits cho biết số yêu cầu đang chờ
  4. The innodb_lock_waits and x$innodb_lock_waits Views MySQL
    Query đang chờ (waiting_query), session đang chặn (blocking_pid), thời gian chờ (wait_age)
  5. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    wait_event_type trong pg_stat_activity: là Lock thì đang chờ một khóa nặng (heavyweight lock)
  6. pg_locks (PostgreSQL Documentation) PostgreSQL
    granted là false nghĩa là tiến trình đó đang chờ để lấy khóa
  7. Error Reporting and Logging (PostgreSQL Documentation) PostgreSQL
    log_lock_waits: ghi log khi chờ khóa lâu hơn deadlock_timeout, mặc định tắt

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 (Nuốt thao tác·rollback)

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