

为什么要避免大事务以及大事务如何解决?
source link: https://segmentfault.com/a/1190000023273980
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

什么是大事务
运行时间比较长,长时间未提交的事务就可以称为大事务
大事务产生的原因
- 操作的数据比较多
- 大量的锁竞争
- 事务中有其他非DB的耗时操作
- 。。。
大事务造成的影响
- 并发情况下,数据库连接池容易被撑爆
- 锁定太多的数据,造成大量的阻塞和锁超时
- 执行时间长,容易造成主从延迟
- 回滚所需要的时间比较长
- undo log膨胀
- 。。。
如何查询大事务
注:本文的sql的操作都是基于mysql5.7版本
以查询执行时间超过10秒的事务为例:
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>10
如何避免大事务
通用解法
- 在一个事务里面, 避免一次处理太多数据
- 在一个事务里面,尽量避免不必要的查询
- 在一个事务里面, 避免耗时太多的操作,造成事务超时。一些非DB的操作,比如rpc调用,消息队列的操作尽量放到事务之外操作
基于mysql5.7的解法
- 在InnoDB事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。 如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放
- 通过SETMAX_EXECUTION_TIME命令, 来控制每个语句查询的最长时间,避免单个语句意外查询太长时间
- 监控 information_schema.Innodb_trx表,设置长事务阈值,超过就报警/或者kill
- 在业务功能测试阶段要求输出所有的general_log,分析日志行为提前发现问题
- 设置innodb_undo_tablespaces值,将undo log分离到独立的表空间。如果真的出现大事务导致回滚段过大,这样设置后清理起来更方便
附录查询事务相关语句
注:sql语句都是基于mysql5.7版本
# 查询所有正在运行的事务及运行时间 select t.*,to_seconds(now())-to_seconds(t.trx_started) idle_time from INFORMATION_SCHEMA.INNODB_TRX t # 查询事务详细信息及执行的SQL select now(),(UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(a.trx_started)) diff_sec,b.id,b.user,b.host,b.db,d.SQL_TEXT from information_schema.innodb_trx a inner join information_schema.PROCESSLIST b on a.TRX_MYSQL_THREAD_ID=b.id and b.command = 'Sleep' inner join performance_schema.threads c ON b.id = c.PROCESSLIST_ID inner join performance_schema.events_statements_current d ON d.THREAD_ID = c.THREAD_ID; # 查询事务执行过的所有历史SQL记录 SELECT ps.id 'PROCESS ID', ps.USER, ps.HOST, esh.EVENT_ID, trx.trx_started, esh.event_name 'EVENT NAME', esh.sql_text 'SQL', ps.time FROM PERFORMANCE_SCHEMA.events_statements_history esh JOIN PERFORMANCE_SCHEMA.threads th ON esh.thread_id = th.thread_id JOIN information_schema.PROCESSLIST ps ON ps.id = th.processlist_id LEFT JOIN information_schema.innodb_trx trx ON trx.trx_mysql_thread_id = ps.id WHERE trx.trx_id IS NOT NULL AND ps.USER != 'SYSTEM_USER' ORDER BY esh.EVENT_ID; # 简单查询事务锁 select * from sys.innodb_lock_waits # 查询事务锁详细信息 SELECT tmp.*, c.SQL_Text blocking_sql_text, p.HOST blocking_host FROM ( SELECT r.trx_state wating_trx_state, r.trx_id waiting_trx_id, r.trx_mysql_thread_Id waiting_thread, r.trx_query waiting_query, b.trx_state blocking_trx_state, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id ) tmp, information_schema.PROCESSLIST p, PERFORMANCE_SCHEMA.events_statements_current c, PERFORMANCE_SCHEMA.threads t WHERE tmp.blocking_thread = p.id AND t.thread_id = c.THREAD_ID AND t.PROCESSLIST_ID = p.id
参考
Recommend
-
39
PDO为PHP访问各类数据库定义了一个轻量级一致性的接口,无论什么数据库,都可以通过一致的方法执行查询和获取数据,而不用考虑不同数据库之间的差异,大大简化了数据库操作。使用PDO可以支持mysql、postgresql、oracle、mssql等多种数据库...
-
13
Go程序内存泄漏的分析以及避免2016-10-18给系统打压力,内存占用上去了,停止打压后,仍然降不下来,就可能是有泄漏。对于无状态的服务,连接上有请求过来,内存上去了。停了请求,但是内存仍然居高不下,等到连接断开内存才降,则sessi...
-
9
自动化是美好的,但也不总是那样。确保你的电子邮件自动回复和抄送配置正确,这样你就不会浪费大家的时间。 来源: https://...
-
11
云计算投入以及需要避免的六个最具破坏性的错误-51CTO.COM 云计算投入以及需要避免的六个最具破坏性的错误 作者:HERO编译 2022-05-10 14:08:56 云计算具有巨大的价值和潜力,但仅限于...
-
8
当涉及到“老式”网页时,对内存管理的关注不足通常不会产生戏剧性的后果。当用户浏览链接并加载新页面时,每次加载都会从内存中删除页面信息。 SPA(单页应用程序)的兴起促使我们更加关注与内存相关的
-
5
记一次.Net分布式事务死锁现象以及解决方法 在本文中,...
-
0
译:如何避免事务期间读取不一致 2023-08-26 技术 ...
-
22
为什么GenAI是CIO的噩梦以及如何解决这个问题 责任编辑:cres 作者:Brandon Deer | 2023-12-26 17:32:00 原创文章 企业网D1Net ChatGPT推出已经一年了,随着商界领袖想方设法利用这项技术并在竞争中领先,人们对...
-
5
在项目中如何避免Java中的内存泄漏和解决内存泄漏问题 作者:科技企业软件工程师 2024-01-30 10:12:00 开发 在Java中,内存泄漏通常指...
-
3
在 Hacktoberfest 期间,我在一个开源计算器软件仓库工作时,发现某些小数计算没有产生预期的结果,比如 0.6+0.3 的结果不会是 0.9,于是我在想是不是代码出了问题。但进一步分析后发现,这是 JavaScript 的实际行为。于是深入研究,了解其内部工作原理。 在...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK