如果我們需要在生產環境中修改mysql資料庫中某個庫表的結構。那麼,需要考慮哪些要點,才能確保不會出問題呢?
這裡先描述一下我在生產環境mysql資料庫中修改庫表結構時遇到的問題。
在開發過程中,我發現mysql中某個庫表需要新增乙個字段,比如庫表:
需要給sname後面新增乙個字段:sheight。那麼就使用命令:
alter table practice.student add column sheight int(4) not null default 0 comment '"身高"
輸入完這個命令後,我就去做別的事情去了。
直到過了一小會,有人反饋說線上的系統有些介面沒有資料。這個時候我才意識到,是這個操作出了問題。導致了線上bug。
我立馬檢視這個操作,發現還沒有執行結束。首先kill了這個執行任務,於是線上系統恢復了正常。
當時,我用命令:show processlist
查詢,看到這個語句的state顯示的是:
waiting for table metadata lock
。我們知道,這個狀態是說,該錶在等待獲取表的metadata lock,也就是mdl。
也就是說,由於前面有mdl讀鎖沒有被釋放,因此我這個命令也就獲取不到mdl寫鎖。導致後面再過來的各種操作都無法被執行,都在等待mdl讀鎖。
這裡解釋下metadata的概念,metadata lock(mdl)也就是元資料鎖,它是一種表級鎖。
各種對該錶的操作,比如增刪改查,都會占有mdl的讀鎖。當修改表結構時,會占用mdl的寫鎖。
讀鎖和讀鎖之間互不衝突,而讀鎖與寫鎖、寫鎖與寫鎖之間互相衝突。
簡單說,就是對乙個表增刪改查同時進行,mdl鎖不會衝突,我們可以用多執行緒同時執行這些操作,只會導致行鎖,而不會鎖整個表。
但是,如果在對錶增刪改查的同時,要對錶結構進行修改,那麼就會造成鎖等待的狀態。
如果有乙個長事務在對該錶進行操作,那麼在修改表結構時,就會有狀態:waiting for table metadata lock
,也就是鎖等待。如果這個時候,另外又有查詢操作過來,那麼,後面這個操作就也要進行waiting for table metadata lock
,也就是鎖等待了。當然,對該錶的查詢操作就會全部阻塞。
我當時的情況就是這樣,有乙個事務操作了該錶,但是可能由於大意沒有關掉該事務,該事務長時間存在。而我同時又進行表結構的更改,於是導致了這次事故。
首先,我們要了解一下有沒有什麼事務對該錶進行了操作,卻長期沒有提交。因為,只有對該錶操作的事務最終提交了,mdl鎖才會被釋放。
換句話說,如果某個事務對該錶進行了操作,比如讀操作,但是最終沒有做提交,那麼,該事務依然會占用mdl鎖的。
檢視事務可以用命令:select * from information_schema.innodb_trx
。
做完這一步之後,基本上可以避免出現waiting for table metadata lock
的情況了,但還有一點需要注意,就是線上會不會對該錶進行頻繁的操作,
有些熱表可能一直處於有人在查詢的狀態,這種時候怎麼做呢?
我們可以在變更表結構的命令中新增乙個超時時間,如果這個命令在該時間段內一直無法執行,那麼會自動超時的,起碼可以保證不會長時間的影響使用者的操作。
該命令為:alter table practice.student wait 100 add column sheight int(4) not null default 0 comment '"身高"
在生產環境中變更mysql資料庫中庫表結構是一件比較有風險的事情,所以一定要三思而後行,避免引起任何可能的線上事故。
DBA 在生產環境中建立監控表DML的觸發器
賽迪網 it技術報道 在生產環境中,總是可能出現這樣的情況 某張或者某些表的資料被莫名其妙的修改了,但是很難定位出是哪個使用者 哪個過程修改的。這是乙個很讓dba頭痛的事情 往往dba對於整個 邏輯並不是非常了解 要定位出 問題 語句,有幾種方法可以選擇 log miner 細節粒度審計 觸發器。l...
在生產環境中安全地執行Docker容器
在生產環境中,強化docker容器的一種方法就是使它們不可變,也就是唯讀。安全地執行容器的其他方法還包括最小化受攻擊面和應用linux安全過程,標準linux安全過程和針對容器環境的特定過程都要應用。u0026 xd n u0026 xd n 在啟動容器時傳入 read only標記就可以在唯讀模式...
在生產環境中安全地執行Docker容器
在生產環境中,強化docker容器的一種方法就是使它們不可變,也就是唯讀。安全地執行容器的其他方法還包括最小化受攻擊面和應用linux安全過程,標準linux安全過程和針對容器環境的特定過程都要應用。在啟動容器時傳入 read only標記就可以在唯讀模式下執行它。這可以防止任何程序寫入檔案系統。任...