mysql修改字段卡住問題總結

2021-10-10 02:19:37 字數 3758 閱讀 2924

線上環境如何修改表字段才能保證服務的穩定執行呢?大概方法羅列:

方案1:業務低峰期進行alter table操作。

方案2:建立臨時表、加欄位、插入舊資料,增量資料插入和重新命名表名。

方案4:在從庫進行新增字段操作,然後進行mysql主從切換

注意事項:主從複製日誌格式如果為row格式,新增的新列必須是在表的最後。

參考文章:

筆者就是採用方案1來操作的,但是遇到乙個問題,執行完這個表就卡住了。。。。。。。。

還好筆者有點東西,立馬 show processlist 檢視程序 然後kill掉剛才執行的操作。表也恢復正常了。

雖然暫時問題解決了,但是沒辦法該錶呀,趕緊查原因。

可以通過show processlist檢視正在執行的sql程序

說明各列的含義和用途,

id列:乙個標識,你要kill 乙個語句的時候很有用。

user列: 顯示當前使用者,如果不是root,這個命令就只顯示你許可權範圍內的sql語句。

host列:顯示這個語句是從哪個ip 的哪個埠上發出的。可用來追蹤出問題語句的使用者。

db列:顯示這個程序目前連線的是哪個資料庫。

command列:顯示當前連線的執行的命令,一般就是休眠(sleep),查詢(query),連線(connect)。

通常代表資源未釋放,如果是通過連線池,sleep狀態應該恆定在一定數量範圍內

實戰範例:因前端資料輸出時(特別是輸出到使用者終端)未及時關閉資料庫連線,導致因網路連線速度產生大量sleep連線,在網速出現異常時,資料庫too many connections掛死。

簡單解讀,資料查詢和執行通常只需要不到0.01秒,而網路輸出通常需要1秒左右甚至更長,原本資料連線在0.01秒即可釋放,但是因為前端程式未執行close操作,直接輸出結果,那麼在結果未展現在使用者桌面前,該資料庫連線一直維持在sleep狀態!

time列:此這個狀態持續的時間,單位是秒。

state列:顯示使用當前連線的sql語句的狀態,很重要的列,後續會有所有的狀態的描述,請注意,state只是語句執行中的某乙個狀態,乙個sql語句,已查詢為例,可能需要經過copying to tmp table,sorting result,sending data等狀態才可以完成。

info列:顯示這個sql語句,因為長度有限,所以長的sql語句就顯示不全,但是乙個判斷問題語句的重要依據。

單憑show processlist有時不能檢視到問題之所在,就像前言中的問題,筆者通過show processlist沒有發現問題。

通過執行

select * from information_schema.innodb_trx
檢視正在執行的事務

field

type

null

keydefault

extra

trx_id

varchar(18)

no事務id

trx_state

varchar(13)

no事務狀態:

trx_started

datetime

no0000-00-00 00:00:00

事務開始時間;

trx_requested_lock_id

varchar(81)

yesnull

innodb_locks.lock_id

trx_wait_started

datetime

yesnull

事務開始等待的時間

trx_weight

bigint(21) unsignedno0

事務權重

trx_mysql_thread_id

bigint(21) unsignedno0

事務執行緒id

trx_query

varchar(1024)

yesnull

具體sql語句

trx_operation_state

varchar(64)

yesnull

事務當前操作狀態

trx_tables_in_use

bigint(21) unsignedno0

事務中有多少個表被使用

trx_tables_locked

bigint(21) unsignedno0

事務擁有多少個鎖

trx_lock_structs

bigint(21) unsignedno0

trx_lock_memory_bytes

bigint(21) unsignedno0

事務鎖住的記憶體大小(b)

trx_rows_locked

bigint(21) unsignedno0

事務鎖住的行數

trx_rows_modified

bigint(21) unsignedno0

事務更改的行數

trx_concurrency_tickets

bigint(21) unsignedno0

事務併發票數

trx_isolation_level

varchar(16)

no事務隔離級別

trx_unique_checks

int(1)no0

是否唯一性檢查

trx_foreign_key_checks

int(1)no0

是否外來鍵檢查

trx_last_foreign_key_error

varchar(256)

yesnull

最後的外來鍵錯誤

trx_adaptive_hash_latched

int(1)no0

trx_adaptive_hash_timeout

bigint(21) unsignedno0

可以通過執行的事務關聯 showprocesslist聯合查詢,然後kill 程序

select b.*, a.trx_started from  information_schema.innodb_trx a

left join (select * from information_schema.`processlist`) b on a.trx_mysql_thread_id=b.id

殺掉程序後,在修改表字段很快就會完事。當然基於表的資料,表資料越大,修改的時間會稍微長一點。

這裡要明確一點,當你執行任何乙個sql的時候,都是帶著事務的,就算你執行乙個查詢的sql,也是有事務的。

為什麼要說慢查詢,因為當你修改表字段屬性的時候,切好有乙個正在執行的慢查詢,預估這個慢查詢會持續100s,那麼你修改表字段的屬性時會一直卡著等待,直到這個慢查詢執行完,它才會去修改表屬性。

所以,在生產環境,修改表字段屬性的時候,一定要注意先檢視當前表是否有正在執行的事務。假如有先讓這個事務執行完,否則修改會一直阻塞。

這裡要明白一點,查詢的事務,只會阻塞修改表屬性等操作,不會影響其他增刪改查的事務操作。但是它會間接影響增刪改查事務操作。

為什麼說是間接呢,假如當前有個正在執行的事務,然後你修改表字段實行,那麼修改表字段屬性會阻塞,它的阻塞會直接影響後續對該錶的所有增刪改查操作都阻塞。

所以,修改表字段屬性一定要慎重和謹慎,稍有不慎,會使整個表癱瘓,間接影響其他關聯這個表的所有操作。

慢查詢同時會使cpu飆公升,間接影響所有對mysql的操作。

最後通過檢視執行中的事務,然後結束掉程序就ok了,修改和新增表字段也沒有出現卡住不動的情況。到此結束。記錄一下,便於以後檢視。

Mysql修改字段

新增乙個字段,預設值為0,非空,自動增長,主鍵 alter table tabelname add new field name field type default 0 not null auto increment add primary key new field name 增加乙個新字段 a...

MySQL 字段修改

有時候需要對資料庫的某些字段進行修改,例如字段型別 名稱 備註等等,除了直接的表設計,可以編寫 sql 命令進行修改。alter table user modify column create time varchar 11 default 0 comment 建立時間 上面的 sql 命令代表修改...

MySQL新增字段,修改字段,刪除字段,修改表資訊

mysql的簡單語法,常用,卻不容易記住。當然,這些sql語法在各資料庫中基本通用。下面列出 一 查詢資訊 1.登入資料庫 mysql u root p 資料庫名稱 2.查詢所有資料表 show tables 3.查詢表的字段資訊 desc 表名稱 二 修改表資訊 1.修改表名 2.修改表注釋 三 ...