[MySQL] 跑個 migration 怎麼就倒站了
- Database
- 19 Jun, 2020
如果網站正在 migrate 時,剛好遇到一個 transaction 沒有結束,就算只是 SELECT ,也有可能讓網站倒站。
一個血淋淋的例子
某個沒有經驗的工程師 A:
對 users table 做一些簡單的查詢,但是開啟了 transaction 沒有 commit
BEGIN;
SELECT * FROM users;
...
正在部署的工程師 B:
對資料庫做 migration
ALTER TABLE users ADD COLUMN email VARCHAR(255);
心中 OS:怎麼好像不應該 migrate 這麼久
瀏覽器的 client 端 A、B、C:
SELECT * FROM users WHERE id = 1;
SELECT * FROM users WHERE id = 2;
SELECT * FROM users WHERE id = 3;
全部都卡住了,然後就倒站了。
發生了什麼事
因為 session A
# session A
BEGIN;
SELECT * FROM users;
在開啟 transaction 後,會拿到 users table 的 shared metadata lock,防止在 transaction 結束前,users table 被做了結構的更動。
而 session B
# session B
ALTER TABLE users ADD COLUMN email VARCHAR(255);
需要拿到的 user table 的 exclusive metadata lock,但是需要等到 session A 釋放 metadata lock 。
此外 session C
# session C
SELECT * FROM users WHERE id = 1;
則被 session B pending 的 exclusive metadata lock block 住。