【从入门到放弃-MySQL】mysql中要避免使用大事务

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

前言

在日常工作中经常会使用一些比较“大”的数据库查询和操作,这里的“大”主要是指

  • 执行时间长:含有较多的逻辑处理、存在较耗时操作等
  • 操作数据多:需要查询或更新操作的数量记录较多,会锁定大量数据造成阻塞和锁超时等。

本文会和大家一起探讨下,为什么 在数据库中要避免使用这些大查询。

事务

大家都清楚事务具备ACID特性(即原子性、一致性、隔离性、持久性),针对隔离性,在数据库事务隔离标准中,定义了四种隔离级别:读未提交、读提交、可重复读、串行化。MySQL默认的事务隔离级别是可重复读,我们以此来展开分析

事务隔离的实现

多版本并发控制(MMVC)

每行记录后面会有两个隐藏列,记录创建版本号及删除版本号。创建本本号记为row trx_id

对于一个事务来说,启动时(申请完事务id后),MySQL会给此事务创建一个活跃事务(即已启动但还未提交的事务)id数组。数组中的最小值记为minTid,最大值记为maxTid。

  • 如果minTid > row trx_id,则数据是可见的。
  • 如果maxTid < row trx_id,则数据是不可见的。
  • 如果minTid <= row trx_id <= maxTid,且:

    • row trx_id在数组中,则说明启动时,此事务未提交,数据不可见
    • row trx_id不在数组中,则说明启动是,此事务已提交,数据可见


如:当前事务id为50,活跃id数组为[35, 43, 44, 45, 46, 50, 51, 52]则

  • row trx_id小于35的数据为可见
  • row trx_id大于52的数据不可见
  • 35 <= row trx_id <= 52且在数组中的数据不可见,不在数组中的数据可见。

对于不可见的数据,则需要依次去数据上一个版本查询,直到查询到可用版本数据为止。

只有在新的RW事务建立的时候 才会新建一个视图 否则继续使用上次创建的视图。

回滚日志(undo log)

上面提到对于不可见数据需要依次查询上一版本来获取到可用数据。
我们知道数据库的数据更新是非常频繁的,不可能将每一版本的数据都存下来,那样数据量会巨大查询也会非常的缓慢。
MySQL通过undo log来获取历史版本的数据。undo log不会记录每个版本的最终数据,它是一个逻辑日志,是反向将之前的操作取消掉。比如对insert的会进行执行delete,delete的执行insert,对于update的数据会执行一个反向update,将之前修改的内容改回去。

例如:

  • S1时刻,事务34启动,进行insert i = 5 操作后,commit,数据记录为D1:i = 5,row_id为34;
  • S2时刻,事务36启动;
  • S3时刻,事务37启动,进行update i + 3 操作后,commit,数据记录为D3:i = 8,row_id为37;
  • S4时刻,事务42启动
  • S5时刻,事务54启动,进行update i * 2 操作后,commit,数据记录为D5:i = 16,row_id为54

此时,如果事务42需要查询i的数据,因为当前i = 16,row_id为54,数据不可见,因此需要根据undo log查询上一版本的数据。update i / 2,得到row_id为37。可见,获取i = 8
如果事务36需要查询i的数据,需要update i / 2, 查到row_id = 37,不可见,继续回滚 update i - 3,查到row_id = 34,可见,获取到i = 5

只有当回滚日志不再需要时,才会删除。系统会判断,当没有事务再需要这些回滚日志的时候,才会删除。

所以长事务意味着系统里面会存在很多非常老的事务视图,因为这些事务可能会访问数据库中的任何数据,所以在这个事务提交之前,系统不得不保留它之后可能用到的所有回滚记录。这就会占用大量的存储空间。

事务启动

autocommit参数控制事务是否自动提交,MySQL默认set autocommit=1,开启自动提交,即每条select、update都会自动提交。所以我们日常使用的SQL语句其实等价于

begin;
select * from table where xxx;
commit;

但有些客户端连接框架默认会在连接成功后执行一条set autocommit = 0,这样会导致你只有执行一条select语句其实就开启了事务。这样会意外导致长事务的出现。
因此还是建议set autocommit = 1配合begin来显示的启动事务。

大事务还会长时间、大量占用锁资源,阻塞DML、DDL操作、造成锁超时影响系统并发能力,并且很容易引发死锁问题。

连接数

大事务会长时间占用数据库连接,并发情况下容易造成连接数满的问题 拖垮整个应用

主备延迟

MySQL主备复制只会在事务执行完毕后才会进行,即binlog在事务commit后才会生成(两阶段提交)。
大事务执行多久就会造成多长时间的主备延迟,主备延迟的时间越长带来的风险也就越高

缓存

MySQL的buffer pool对查询具有缓存效果,对于很多高频查询可以直接从缓存返回不需要查找磁盘文件。但是当有大量数据需要返回时通常有很多顺序查询,记录在同一磁盘页中就会命中缓存机制 对缓存造成一定影响
MySQL buffer pool的缓存机制是使用的改良LRU算法(主要增加了访问时间控制)

内存&CPU

MySQL数据返回默认是边取边发,因此数据较多,传输时间较长也也会引发长事务带来的问题。
还有如果返回大量数据给客户端处理,对客户端的内存及CPU也会带来较大的压力。

超时和超出大小限制

容易引起超时的问题和超出max_binlog_cache_size导致执行失败。(还要注意,避免出现为了让主库大事务顺利进行,临时调大主库max_binlog_cache_size,忽略备库导致的服务宕掉等严重后果)

回滚

回滚大事务也是非常耗时和占用内存的,需要注意

总结

应该尽量避免使用大事务,开发时要注意尽量

  • 如果可以,将一个大事务拆分成多个小事务执行
  • 将事务中可以提出的select查询放在事务外执行

更多文章

见我的博客:https://nc2era.com

written by AloofJr,转载请注明出处

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
安全 关系型数据库 MySQL
PHP与MySQL交互:从入门到实践
【9月更文挑战第20天】在数字时代的浪潮中,掌握PHP与MySQL的互动成为了开发动态网站和应用程序的关键。本文将通过简明的语言和实例,引导你理解PHP如何与MySQL数据库进行对话,开启你的编程之旅。我们将从连接数据库开始,逐步深入到执行查询、处理结果,以及应对常见的挑战。无论你是初学者还是希望提升技能的开发者,这篇文章都将为你提供实用的知识和技巧。让我们一起探索PHP与MySQL交互的世界,解锁数据的力量!
|
2月前
|
关系型数据库 MySQL 数据库
MySQL基本操作入门指南
MySQL基本操作入门指南
72 0
|
16天前
|
存储 SQL 关系型数据库
MySQL的事务隔离级别
【10月更文挑战第17天】MySQL的事务隔离级别
91 43
|
29天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1607 14
|
22天前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
2月前
|
存储 Oracle 关系型数据库
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
从基本特性、技术选型、字段类型、事务提交方式、SQL语句、分页方法等方面对比Oracle和MySQL的区别。
416 18
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
|
2月前
|
SQL 关系型数据库 MySQL
MySQL基础:事务
本文详细介绍了数据库事务的概念及操作,包括事务的定义、开启、提交与回滚。事务作为一组不可分割的操作集合,确保了数据的一致性和完整性。文章还探讨了事务的四大特性(原子性、一致性、隔离性、持久性),并分析了并发事务可能引发的问题及其解决方案,如脏读、不可重复读和幻读。最后,详细讲解了不同事务隔离级别的特点和应用场景。
124 4
MySQL基础:事务
|
1月前
|
SQL 关系型数据库 MySQL
【MySQL】索引和事务
【MySQL】索引和事务
51 0
|
2月前
|
SQL 关系型数据库 MySQL
MySQL入门到精通
MySQL入门到精通
|
2月前
|
SQL Oracle 关系型数据库
详解 MySQL 的事务以及隔离级别
详解 MySQL 的事务以及隔离级别
37 0