首页 > 数据库 >Mysql的事务操作问题

Mysql的事务操作问题

时间:2023-12-08 20:32:59浏览次数:34  
标签:事务 版本号 Mysql -- InnoDB MVCC 操作


什么是数据库事务?

一组sql语句组成的数据库逻辑处理单元,在这组的sql操作中,要么全部执行成功,要么全部执行失败。

事务支持是在引擎层实现的。MySQL 原生的 MyISAM 引擎不支持事务,这也是 MyISAM 被 InnoDB 取代的重要原因之一。

你能说一说Redo/Undo机制吗?

Redo/Undo机制比较简单,它们将所有对数据的更新操作都写到日志中。

Redo log用来记录某数据块被修改后的值,可以用来恢复未写入 data file 的已成功事务更新的数据;Undo log是用来记录数据更新前的值,保证数据更新失败能够回滚。

假如数据库在执行的过程中,不小心崩了,可以通过该日志的方式,回滚之前已经执行成功的操作,实现事务的一致性。

例子:假如某个时刻数据库崩溃,在崩溃之前有事务A和事务B在执行,事务A已经提交,而事务B还未提交。当数据库重启进行 crash-recovery 时,就会通过Redo log将已经提交事务的更改写到数据文件,而还没有提交的就通过Undo log进行roll back。

那回滚日志什么时候删?

当系统里没有比这个回滚日志更早的 read-view 的时候。

InnoDB的MVCC实现机制 MVCC可以认为是行级锁的一个变种,它可以在很多情况下避免加锁操作,因此开销更低。MVCC的实现大都都实现了非阻塞的读操作,写操作也只锁定必要的行。InnoDB的MVCC实现,是通过保存数据在某个时间点的快照来实现的。一个事务,不管其执行多长时间,其内部看到的数据是一致的,也就是事务在执行的过程中不会相互影响。

简述一下MVCC在InnoDB中的实现:

InnoDB的MVCC,通过在每行记录后面保存两个隐藏的列来实现:一个保存了行的创建时间,一个保存行的过期时间(删除时间),当然,这里的时间并不是时间戳,而是系统版本号,每开始一个新的事务,系统版本号就会递增。在RR隔离级别下,MVCC的操作如下:

select操作: InnoDB只查找版本早于(包含等于)当前事务版本的数据行。可以确保事务读取的行,要么是事务开始前就已存在,或者事务自身插入或修改的记录。 行的删除版本要么未定义,要么大于当前事务版本号。可以确保事务读取的行,在事务开始之前未删除。 insert操作:将新插入的行保存当前版本号为行版本号。 delete操作:将删除的行保存当前版本号为删除标识。 update操作:变为insert和delete操作的组合,insert的行保存当前版本号为行版本号,delete则保存当前版本号到原来的行作为删除标识。 由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做purge。

例子

CREATE TABLE account (
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(10),
	balance DOUBLE
);

-- 添加数据
INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000)
SELECT * FROM account;

-- 张三给李四转账 500 元			
-- 0. 开启事务
START TRANSACTION;

-- 1. 张三账户 -500			
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';

-- 2. 李四账户 +500
-- 出错了...
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
			
-- 发现执行没有问题,提交事务
COMMIT;
			
-- 发现出问题了,回滚事务
ROLLBACK;

事务的四大特征:

原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。 持久性:当事务提交或回滚后,数据库会持久化的保存数据。 隔离性:多个事务之间,相互独立。 一致性:事务操作前后,数据总量不变

标签:事务,版本号,Mysql,--,InnoDB,MVCC,操作
From: https://blog.51cto.com/u_16123336/8741625

相关文章

  • mysql慢查询分析
    一、实用druid自带web管理页面查看Druid是一个开源的高性能数据库连接池,由阿里巴巴集团开发并开源,主要用于Java应用程序中与数据库的连接管理和资源池化。它提供了一系列功能和配置选项,旨在提供高效、可靠的数据库连接管理。特性和功能:高性能:Druid连接池通过一些优化策略实现高性......
  • 使用django连接MySQL
    使用python311+pycharm社区版+MySQL80,使用django连接MySQL1.下载1.1.官网下载pythonhttps://www.python.org/downloads/如我的python3.11.4,可以进入如下的页面进行hash校验https://www.python.org/downloads/release/python-3114/1.2.官网下载pycharmhttps://www.......
  • 通过C语言连接MySQL数据库
    一、如何连接MySQL首先需要安装MySQLsudoapt-getupdatesudoapt-getinstallmysql-serverC语言的API代码是与MySQL一起提供的,它包含在mysqlclient库中,并允许C程序访问数据库,如果安装MySQL后仍提示缺少库,则需要安装如下:sudoapt-getinstalllibmysqlclient-devsudoa......
  • 目录与文件操作
    VMwareWorkstation的安装完成,然后就试着把老师第一节课上课的东西,按照书上的一一完成。学习了目录与文件操作,第一次接触到了一些linux操作系统的命令,通过mkdir命令创建目录,通过pwd命令查看目录,通过cd命令切换目录,使用cat命令查看内容较少的文件,通过more和less命令以逐页的方式显......
  • 软件测试/人工智能|一文告诉你Python元组相关操作
    前言当我们谈及Python数据结构时,元组(tuple)是一个重要且常用的概念。元组类似于列表,但是它是不可变的数据结构,其中的元素不能被修改。让我们深入了解一下元组的各种方面。什么是元组?在Python中,元组是由逗号分隔的值组成的有序集合。和列表类似,但不同的是,元组是不可变的,一旦创建......
  • MySQL数据库-1
    MySQL数据库-11.为什么要使用数据库持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以"固化”,而持久化的实现过程大多通过各种关系数据库来完成。持久化的主要作用是将内存中......
  • 汇编-标志位操作指令
     CF置0.386.modelflat,stdcalloptioncasemap:none.stack4096ExitProcessPROTO,dwExitCode:DWORD.data.codemainPROCmoval,10000110bshlal,1;cf=1clc;CF置0cf=0IN......
  • Mysql Full-Text Index 介绍
    MysqlFull-TextIndex介绍ngramFull-TextParser参考链接Thebuilt-inMySQLfull-textparserusesthewhitespacebetweenwordsasadelimitertodeterminewherewordsbeginandend,whichisalimitationwhenworkingwithideographiclanguagesthatdono......
  • 如何实现Java file.mkdir()失败的具体操作步骤
    如何实现Javafile.mkdir()失败的具体操作步骤Java中的file.mkdir()失败问题解析在Java中,使用file.mkdir()方法可以创建一个新的文件夹。然而,有时候我们可能会遇到file.mkdir()失败的情况,这可能导致程序没有按照预期创建文件夹。本篇文章将详细解析file.mkdir()失败的原因,并提供......
  • 数据库数据恢复—无备份,binlog未开启的Mysql数据库误删表数据的数据恢复案例
    mysql数据库数据恢复环境:本地服务器,windowsserver操作系统,部署有mysql单实例,数据库引擎类型为innodb,独立表空间,无数据库备份,未开启binlog。mysql数据库故障:工作人员使用Delete命令删除数据时未添加where子句进行筛选,导致全表数据被删除,删除后未对该表进行任何操作。针对mysql......