Adding a column or index to a table during live service can make every request that uses that table wait, all because of one lock that’s needed only briefly.
Why A hotfix adds a column or index to a table in live use → Effect The schema change waits for a long transaction opened earlier, and every request that comes after waits for the schema change → On screen Features that use that table (inventory, mail, and so on) stop entirely and time out
Primary owner Infra team (DB infrastructure) · Also Game team (Server development)
Game team action items
Coordinate the timing of hotfixes that include schema changes with DB infrastructure, deploy code that works without the new column first.
Infra team action items
Set a short lock wait timeout and retry on failure, run it when there are no long transactions, use online schema change tools, change large tables during maintenance.
On the graph
Step change · Sessions waiting on locks, query latency on that table
Where to look
MySQL: count sessions in SHOW PROCESSLIST whose State is Waiting for table metadata lock, and find the blocking session (blocking_pid) with sys.schema_table_lock_waits. PostgreSQL: requests whose granted is false and AccessExclusiveLock in pg_locks, and find the blocking session with pg_blocking_pids()
Confirmed if
From the moment the schema change starts, every query on that table piles up waiting on the lock, with an unfinished transaction or the schema change statement at the front
Ruled out if
Waits concentrate on specific rows while other rows in the same table go through fine: a hot row (db-hot-row)
Check with
Infra tools (no game code needed)
Learn more
MySQL briefly takes a metadata lock when changing a schema, and PostgreSQL briefly takes its strongest table lock. Even if the change itself is instant, a single unfinished transaction ahead of it makes every request behind it wait.
Sources
Online DDL Performance and ConcurrencyMySQL Even online DDL briefly needs an exclusive metadata lock to finish; it waits if there is a long transaction, and the waiting lock request blocks every transaction behind it
Server System VariablesMySQL lock_wait_timeout: metadata lock wait limit, default 31,536,000 seconds (1 year)