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
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
InnoDB LockingMySQL 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ờ
Server Status VariablesMySQL 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ờ