前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DBBrain最佳实践:未提交事务的处理与应对

DBBrain最佳实践:未提交事务的处理与应对

原创
作者头像
王文安@DBA
发布2022-03-03 14:19:09
2.6K2
发布2022-03-03 14:19:09
举报

背景

DBBrain 上经常会有用户来咨询“未提交事务”的事件会有什么问题,该如何处理等。其实这个问题的影响属于可大可小,所以正好来专门分析一下,避免因为轻视了这个问题导致严重的业务故障。

问题描述

未提交事务指的是有连接在数据库中开启了事务,但是却一直没有提交事务的现象。如果事务一直不提交,那么对应数据行的锁始终无法释放,表的元数据锁也会一直持有,导致这个表的 DDL 会被一直阻塞。

DBBrain 针对这个问题有专门的监控,当发现这个现象之后就会推送“未提交事务”的异常事件。

分析

点开DBBrain可以看到有异常事件“未提交事务”。

示例图
示例图

这一类未提交事务的信息可以在DBBrain的事件详情,或者在命令行检查:

代码语言:txt
复制
mysql> select * from information_schema.INNODB_TRX\G
*************************** 1. row ***************************
                    trx_id: 149573207
                 trx_state: RUNNING
               trx_started: 2022-03-03 13:17:36
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 3
       trx_mysql_thread_id: 194632
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 1
         trx_rows_modified: 1
   trx_concurrency_tickets: 0
       trx_isolation_level: READ COMMITTED
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_is_read_only: 0
trx_autocommit_non_locking: 0

这段信息中,比较重要的信息是事务开始时间和 thread_id,如上例中,可以根据事务开始时间估算是什么业务模块/脚本发起的。trx_mysql_thread_id 显示的是这个事务是由哪个连接发起的,通过 processlist 中的 id 找到这个线程。

代码语言:txt
复制
mysql> show processlist;
+--------+------+----------------+--------------------+---------+------+----------+------------------+
| Id     | User | Host           | db                 | Command | Time | State    | Info             |
+--------+------+----------------+--------------------+---------+------+----------+------------------+
| 194631 | root | 10.0.0.6:37912 | information_schema | Query   |    0 | starting | show processlist |
| 194632 | root | 10.0.0.6:37914 | test               | Sleep   | 1611 |          | NULL             |
+--------+------+----------------+--------------------+---------+------+----------+------------------+
2 rows in set (0.00 sec)

可以看到 194632 这个 id 对应的是 test 用户,info 显示的 NULL,不显示具体 SQL 是因为 SQL 语句已经执行完了,然后没有再执行任何操作,处于空闲状态。

如果事务未提交,那么其他连接在操作同样的数据库行时,就会遇到锁等待报错,DDL 也会有 MDL 锁,通过简单的示例模拟一下:

代码语言:txt
复制
Seesion 1:
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> update t1 set name = 'stu-108-m' where id = 8;
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
mysql>
mysql> alter table t1 engine=innodb;
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
mysql>

Session 2:
mysql> show processlist;
+--------+------+----------------+------+---------+------+---------------------------------+------------------------------+
| Id     | User | Host           | db   | Command | Time | State                           | Info                         |
+--------+------+----------------+------+---------+------+---------------------------------+------------------------------+
| 194632 | root | 10.0.0.6:37914 | test | Query   |    0 | starting                        | show processlist             |
| 195373 | root | 10.0.0.6:57056 | test | Query   |   11 | Waiting for table metadata lock | alter table t1 engine=innodb |
+--------+------+----------------+------+---------+------+---------------------------------+------------------------------+
2 rows in set (0.00 sec)

如果 lock_wait 默认设置得很高,那么未提交事务会长时间阻塞其他的连接,严重一点的会导致大量的连接堆积在数据库中导致数据库hang死,DDL 操作同理,不管是 MDL 锁还是线程堆积都会影响到线上的业务语句。

解决办法其实比较简单,在 DBBrain 的会话中杀死这个 id 为 195373 的连接,或者是在命令行,使用 test 这个用户登录进去,使用 kill 命令杀死 195373 的连接。

PS:使用 test 的原因是腾讯云数据库 MySQL 默认是没有 super 权限的,所以必须要使用同一个账号来操作。

总结

未提交事务产生的影响整体来说还是有比较大的影响的,一般来说临时的解决方案是尽快 kill 掉这个事务对应的连接,之后再根据事务开始的时间去排查未提交事务引起的原因,是脚本、临时操作、还是业务代码上的漏洞。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 问题描述
  • 分析
  • 总结
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档