2022-10-27 383
####2019121910:10:10,234|com.alibaba.druid.filter.logging.Log4jFilter.statementLogError(Log4jFilter.java:152)|ERROR|{conn-10593,pstmt-38675}executeerror.updatexxxsetxxx=?,xxx=?whereRowGuid=? com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:Lockwaittimeoutexceeded;tryrestartingtransaction
之前在 [如何有效排查解决 MySQL 行锁等待超时问题] 文章中介绍了如何监控解决行锁超时报错,当时介绍的监控方案主要是以 shell 脚本 + general_log 来捕获行锁等待信息,后来感觉比较麻烦,因此优化后改成用 Event + Procedure 的方法定时在 MySQl 内执行,将行锁等待信息记录到日志表中,并且加入了 pfs 表中的事务上下文信息,这样可以省去登陆服务器执行脚本与分析 general_log 的过程,更加便捷。
因为用到了 Event 和 performance_schema 下的系统表,所以需要打开两者的配置,pfs 使用默认监控项就可以,这里主要使用到的是 events_statements_history 表,默认会保留会话 10 条 SQL。
performance_schema=on event_scheduler=1
目前该方法仅在 MySQL 5.7 版本使用过,MySQL 8.0 未测试。
createdatabase`innodb_monitor`;
create database `innodb_monitor`;
2.2 创建存储过程
useinnodb_monitor; delimiter;; CREATEPROCEDUREpro_innodb_lock_wait_check() BEGIN declarewait_rowsint; setgroup_concat_max_len=1024000; CREATETABLEIFNOTEXISTS`innodb_lock_wait_log`( `report_time`datetimeDEFAULTNULL, `waiting_id`int(11)DEFAULTNULL, `blocking_id`int(11)DEFAULTNULL, `duration`varchar(50)DEFAULTNULL, `state`varchar(50)DEFAULTNULL, `waiting_query`longtextDEFAULTNULL, `blocking_current_query`longtextDEFAULTNULL, `blocking_thd_last_query`longtext, `thread_id`int(11)DEFAULTNULL ); selectcount(*)intowait_rowsfrominformation_schema.innodb_lock_waits; ifwait_rows>0THEN insertinto`innodb_lock_wait_log`SELECTnow(),r.trx_mysql_thread_idwaiting_id,b.trx_mysql_thread_idblocking_id,concat(timestampdiff(SECOND,r.trx_wait_started,CURRENT_TIMESTAMP()),'s')ASduration, t.processlist_commandstate,r.trx_querywaiting_query,b.trx_queryblocking_current_query,group_concat(left(h.sql_text,10000)orderbyh.TIMER_STARTDESCSEPARATOR';\n')Asblocking_thd_query_history,thread_id FROMinformation_schema.innodb_lock_waitswJOINinformation_schema.innodb_trxbONb.trx_id=w.blocking_trx_idJOINinformation_schema.innodb_trxrONr.trx_id=w.requesting_trx_id LEFTJOINperformance_schema.threadstont.processlist_id=b.trx_mysql_thread_idLEFTJOINperformance_schema.events_statements_historyhUSING(thread_id)groupbythread_id,r.trx_idorderbyr.trx_wait_started; endif; END ;;
2.3 创建事件
事件 每隔 5 秒 (通常等于 innodb_lock_wait_timeout 的值)执行一次,持续监控 7 天,结束后会自动删除事件,也可以自定义保留时长。
useinnodb_monitor; delimiter;; CREATEEVENT`event_innodb_lock_wait_check` ONSCHEDULEEVERY5SECOND STARTSCURRENT_TIMESTAMP ENDSCURRENT_TIMESTAMP+INTERVAL7DAY ONCOMPLETIONNOTPRESERVE ENABLE DO callpro_innodb_lock_wait_check(); ;;
2.4 事件启停
--1为全局开启事件,0为全局关闭 mysql>SETGLOBALevent_scheduler=1; --临时关闭事件 mysql>ALTEREVENTevent_innodb_lock_wait_checkDISABLE; --关闭开启事件 mysql>ALTEREVENTevent_innodb_lock_wait_checkENABLE;
再根据应用日志报错时间点及 SQL 分析 innodb_lock_wait_log 表。其中主要有 2 种场景:
原文链接:https://77isp.com/post/10304.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态