問題描述:
? ? 7*24聯機交易系統,傍晚時分,從客戶端后臺對3千萬行的大表執行縮短varchar類型字段長度的ddl語句,執行期間,為了查看ddl進度,從TDSQL-MySQL赤兔前端頁面點擊異常會話查詢,之后數據庫卡住,發生主備切換,主備切換后的幾分鐘內數據庫交易耗時上升。
問題分析:
? ?查看tdsql記錄的processlist的日志,發現ddl語句之后,就是對performance_schema.data_locks試圖的查詢語句,其余sql語句都阻塞在該data_locks查詢sql后面。點擊查看主備切換原因,是因為心跳檢測中斷時間超過20s,數據庫誤以為主庫掛掉,發起主備切換。
原因總結:
? ? 從客戶端后臺執行ddl語句時,會對全表加行鎖,由于該實例為分布式實例,每一個set行數為500萬行左右。在TDSQL-MySQL赤兔前端頁面點擊異常會話查詢,會使用到performance_schema.data_locks視圖,查詢data_locks視圖時,首先需要獲取trx_sys->mutex這個信號量,獲取到trx_sys->mutex后掃描trx_sys結構下面trx_lock_list和mysql_lock_list兩個記錄鎖信息的雙向鏈表,當掃描到執行ddl語句的表的鎖信息時,要等把這個表的所有行鎖信息掃描完后才會釋放trx_sys->mutex互斥量,掃描時間過長造成trx_sys->mutex長時間未釋放。其他dml語句在執行時,也需要申請trx_sys->mutex互斥量,向trx_sys結構中的事務鏈表注冊一個事務。但data_locks視圖異常會話持有的trx_sys->mutex長時間未釋放,使得其余dml語句獲取不到trx_sys->mutex被阻塞,這其中就包括心跳檢測的dml語句,心跳檢測sql中斷超過20s,TDSQL數據庫認為主庫掛掉,發起主備切換。
解決方案:
? ? 1、執行ddl時,避開業務高峰期。
? ? 2、從赤兔前端執行ddl操作,使用到pt工具執行online ddl。
? ? 3、執行ddl語句時,謹慎使用異常會話查詢功能。