Innodb核心特性——事务

1.什么是事务

主要针对DML语句(update,delete,insert)

一组数据操作执行步骤,这些步骤被视为一个工作单元:

1)用于对多个语句进行分组

2)可以在多个客户机并发访问同一个表中的数据时使用


所有步骤都成功或都失败

1)如果所有步骤正常,则执行

2)如果步骤出现错误或不完整,则取消

2.事务的通俗理解

伴随着“交易”出现的数据库概念。

我们理解的“交易”是什么?

1)物与物的交换(古代)

2)货币现金与实物的交换(现代1)

3)虚拟货币与实物的交换(现代2)

4)虚拟货币与虚拟实物交换(现代3)


数据库中的“交易”是什么?

1)事务又是如何保证“交易”的“和谐”?

2)ACID

3.事务ACID特性


Atomic(原子性)

所有语句作为一个单元,要么全部成功执行或全部取消。

Consistent(一致性)

如果数据库在事务开始时处于一致状态,则在执行该事务结束时也是一致状态。
事务期间将保留一致状态。

Isolated(隔离性)

事务之间不会被其他事务影响。

Durable(持久性)

事务成功完成后,所做的所有更改都会准确地记录在
数据库中。所做的更改不会丢失。


4.事务流程举例

5.事务的控制语句

如下:

START TRANSACTION(或 BEGIN):显式开始一个新事务

SAVEPOINT:分配事务过程中的一个位置,以供将来引用(存档)

COMMIT:永久记录当前事务所做的更改

ROLLBACK:取消当前事务所做的更改

ROLLBACK TO SAVEPOINT:取消在 savepoint 之后执行的更改 (读档)

RELEASE SAVEPOINT:删除 savepoint 标识符 (删档)

SET AUTOCOMMIT:为当前连接禁用或启用默认 autocommit 模式

一个成功事务的生命周期

begin;

sql1

sql2

sql3

...

commit;

一个失败事务的生命周期

begin;

sql1

sql2

sql3

...

rollback;

**结束事务的控制语句: commit 和 rollback **

注意:其实事务开启,不需要执行 begin 或者 start transaction ,只要执行DML 语句,自动开启事务。

  • 3.自动提交
#查看自动提交
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.01 sec) #临时关闭自动提交
mysql> set autocommit=0;
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
1 row in set (0.01 sec) #永久关闭自动提交(在配置文件修改,修改后重启mysqld)
[root@db01 world]# vim /etc/my.cnf
[mysqld]
autocommit=0 mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
1 row in set (0.00 sec)

注意:自动提交关闭后,数据不会立即提交,还可以执行rollback回滚回来。

  • 4.事务演示

1)成功事务

mysql> create table stu(id int,name varchar(10),sex enum('f','m'),money int);
mysql> begin;
mysql> insert into stu(id,name,sex,money) values(1,'zhang3','m',100), (2,'zhang4','m',110);
mysql> commit; #查看
mysql> select * from stu;
+------+--------+------+-------+
| id | name | sex | money |
+------+--------+------+-------+
| 1 | zhang3 | m | 100 |
| 2 | zhang4 | m | 110 |
+------+--------+------+-------+
2 rows in set (0.00 sec)

2)事务回滚

mysql> begin;
mysql> update stu set name='zhang3';
mysql> delete from stu;
mysql> rollback;

6.事务隐式提交情况

1)现在版本在开启事务时,不需要手工begin,只要你输入的是DML语句,就会自动开启事务。

2)有些情况下事务会被隐式提交

例如:

  1. 在事务运行期间,手工执行begin的时候会自动提交上个事务
  2. 在事务运行期间,加入DDL、DCL操作会自动提交上个事务
  3. 在事务运行期间,执行锁定语句(lock tables、unlock tables)
  4. load data infile
  5. select for update
  6. 在autocommit=1的时候

示例:

# 执行了多少个成功的事务? 7个
begin;
sql1
sql2
begin; #提交了一个
begin; #提交了一个
create database xxx; #提交了一个
update; #提交了一个
begin; #提交了一个
select * from xxx;
begin; #提交了一个
commit; #提交了一个
rollback; #算是一个失败的事务

7.事务日志redo基本功能

1)Redo是什么?

redo,顾名思义“重做日志”,是事务日志的一种。

2)作用是什么?

在事务ACID过程中,实现的是“D”持久化的作用。

特性:WAL(Write Ahead Log)日志优先写

REDO:记录的是,内存数据页的变化过程

3)REDO工作过程

#执行步骤
#查询
mysql> select * from course;
+-----+--------+-----+
| cno | cname | tno |
+-----+--------+-----+
| 1 | 英语 | 1 |
| 2 | 语文 | 2 |
| 3 | 数学 | 3 |
+-----+--------+-----+
3 rows in set (0.00 sec) #执行步骤
mysql> update course set cno=6 where cno=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 #再次查询
mysql> select * from course;
+-----+--------+-----+
| cno | cname | tno |
+-----+--------+-----+
| 2 | 语文 | 2 |
| 3 | 数学 | 3 |
| 6 | 英语 | 1 |
+-----+--------+-----+
3 rows in set (0.00 sec)

1)首先将t1表中num=1的行所在数据页加载到内存中buffer page

2)MySQL实例在内存中将num=1的数据页改成num=2

3)num=1变成num=2的变化过程会记录到,redo内存区域,也就是redo buffer page中

#提交事务执行步骤
commit;

1)当敲下commit命令的瞬间,MySQL会将redo buffer page写入磁盘区域redo log

2)当写入成功之后,commit返回ok

8.redo数据实例恢复过程

恢复过程的几个步骤:

1.首先将t1表中 id=1 的行所在数据页加载到内存中buffer page中

2.实时写入数据undo

3.修改过程加载到redo中

4.redo缓冲区的内容读入数据缓冲区

5.undo找事务日志有没有最后执行commit

6.没有commit, undo会回滚到原数据

注意:不同情况下的恢复结果

1.还没有commit的时候,数据也没有定时写入,断电了

数据缓冲区和redo缓冲区都是原状态,undo找不到commit, 会回滚事务日志到原数据。结果:保持不变,不会修改。

2.还没有commit,数据定时写入了,断电了

数据缓冲区是原状态,redo缓冲区是修改后的状态, undo 找不到commit , 会回滚到事务日志到原数据。 结果: 保持不变,不会修改。

3.commit了,但是数据还没有写入到ibd文件中,断电了

数据缓冲区是原状态,redo缓冲区是修改后的状态, undo 找到commit , 会认为要修改数据。 结果:修改。

9.事务日志undo

1)undo是什么?

undo,顾名思义“回滚日志”,是事务日志的一种。

_2)作用是什么?

在事务ACID过程中,实现的是“A”原子性的作用。当然CI的特性也和undo有关

10.redo和undo的存储位置

#redo位置
[root@db01 data]# ll /application/mysql/data/
-rw-rw---- 1 mysql mysql 50331648 Aug 15 06:34 ib_logfile0
-rw-rw---- 1 mysql mysql 50331648 Mar 6 2017 ib_logfile1
#undo位置
[root@db01 data]# ll /application/mysql/data/
-rw-rw---- 1 mysql mysql 79691776 Aug 15 06:34 ibdata1
-rw-rw---- 1 mysql mysql 79691776 Aug 15 06:34 ibdata2

在MySQL5.6版本中undo是在ibdata文件中,在MySQL5.7版本会独立出来。

11.事务中的锁

1)什么是“锁”?

“锁”顾名思义就是锁定的意思。

2)“锁”的作用是什么?

在事务ACID特性过程中,“锁”和“隔离级别”一起来实现“I”隔离性的作用。

排他锁:保证在多事务操作时,数据的一致性。

共享锁:保证在多事务工作期间,仍然允许被查询,数据查询时不会被阻塞。

乐观锁:谁先提交谁为准(例如:以前买火车票,提交订单,在指定时间还未付款时,票的信息还是谁都能看到,谁抢到算谁的)

悲观锁:谁先修改谁为准(例如:现在买火车票,提交订单,在指定时间还未付款时,票的信息别人看不到,自己优先。除非超过世间)

12.多版本并发控制(MVCC)

1)只阻塞修改类操作,不阻塞查询类操作(排它锁和共享锁)

2)乐观锁的机制(谁先提交谁为准)

13.锁的粒度

MyIsam:低并发锁(表级锁),不支持事务。

Innodb:高并发锁(行级锁),必须要有聚集索引才能做到行级锁

14.事务的隔离级别

四种隔离级别:

READ UNCOMMITTED(独立提交) RU级别

允许事务查看其他事务所进行的未提交更改

READ COMMITTED RC级别

允许事务查看其他事务所进行的已提交更改

REPEATABLE READ RR级别

确保每个事务的 SELECT 输出一致

InnoDB 的默认级别

SERIALIZABLE 串行化级别

将一个事务的结果与其他事务完全隔离

#查看隔离级别
mysql> show variables like '%iso%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec) #修改隔离级别为RU
vim /etc/my.cnf
[mysqld]
transaction_isolation=read-uncommit
mysql> use oldboy
mysql> select * from stu;
mysql> insert into stu(id,name,sex,money) values(2,'li4','f',123);
#修改隔离级别为RC
vim /etc/my.cnf
[mysqld]
transaction_isolation=read-commit

15.脏读 幻读 重复读 查询原因,和解决办法 (RR级别)

1.脏读

一个事务读到另一个事务,尚未提交的修改,就是脏读。这里所谓的修改,除了Update操作,还包括Insert和Delete操作。

脏读的后果:如果后一个事务回滚,那么它所做的修改,统统都会被撤销。前一个事务读到的数据,就是垃圾数据。

示例:

例子:预订房间。

有一张Reservation表,往表中插入一条记录,来订购一个房间。

事务1:在Reservation表中插入一条记录,用于预订99号房间。

事务2:查询,尚未预定的房间列表,因为99号房间,已经被事务1预订。所以不在列表中。

事务1:信用卡付款。由于付款失败,导致整个事务回滚。

所以插入到Reservation 表中的记录并不置为持久(即它将被删除)。

现在99号房间则为可用。

所以,事务2所用的是一个无效的房间列表,因为99号房间,已经可用。如果它是最后一个没有被预定的房间,那么这将是一个严重的失误。

注:脏读的后果很严重。

2.不可重复读

在同一个事务中,再次读取数据时【就是你的select操作】,所读取的数据,和第1次读取的数据,不一样了。就是不可重复读。

示例:

举个例子:

事务1:查询99号房间是否为双人床房间。结果99号是。

事务2:将99号房间,改成单人床房间。

事务1:再次执行查询,99号房间不是双人房了。也就是说, 事务1,可以看到其他事务所做的修改。

在不可重复读,里面,可以看到其他事务所做的修改,而导致2次的查询结果不再一样了。

这里的修改,是提交过的。也可以是没有提交的,这种情况同时也是脏读。

如果,数据库系统的隔离级别。允许,不可重复读。那么你启动一个事务,并做一个select查询操作。

查询到的数据,就有可能,和你第2次,3次...n次,查询到的数据不一样。一般情况下,你只会做一次,select

查询,并以这一次的查询数据,作为后续计算的基础。因为允许出现,不可重复读。那么任何

时候,查询到的数据,都有可能被其他事务更新,查询的结果将是不确定的。

注:如果允许,不可重复读,你的查询结果,将是不确定的。一个不确定的结果,你能容忍吗?

3.幻读

事务1读取指定的where子句所返回的一些行。然后,事务2插入一个新行,这个新行也满足事务1使用的查询

where子句。然后事务1再次使用相同的查询读取行,但是现在它看到了事务2刚插入的行。这个行被称为幻象,

因为对事务1来说,这一行的出现是不可思议的。

示例:

事务1:请求没有预定的,双人床房间列表。99号在其中。

事务2:向Reservation表中插入一个新纪录,以预订99号房间,并提交。

事务1:再次请求有双人床的未预定的房间列表,99号房间,不再位于列表中。

注:幻读,针对的是,Insert操作。如果事务2,插入的记录,没有提交。那么同时也是脏读。

Mysql --09 Innodb核心特性——事务的更多相关文章

  1. MySQL与MariaDB核心特性比较详细版v1.0(覆盖mysql 8.0/mariadb 10.3,包括优化、功能及维护)

    注:本文严禁任何形式的转载,原文使用word编写,为了大家阅读方便,提供pdf版下载. MySQL与MariaDB主要特性比较详细版v1.0(不含HA).pdf 链接:https://pan.baid ...

  2. MySql中innodb存储引擎事务日志详解

    分析下MySql中innodb存储引擎是如何通过日志来实现事务的? Mysql会最大程度的使用缓存机制来提高数据库的访问效率,但是万一数据库发生断电,因为缓存的数据没有写入磁盘,导致缓存在内存中的数据 ...

  3. 【mysql】Innodb三大特性之adaptive hash index

    1.Adaptive Hash Indexes 定义 If a table fits almost entirely in main memory, the fastest way to perfor ...

  4. 【mysql】Innodb三大特性之double write

    1.doublewrite buffer(mysql官方的介绍) InnoDB uses a novel file flush technique called doublewrite. Before ...

  5. 【mysql】Innodb三大特性之insert buffer

    一.什么是insert buffer insert buffer是一种特殊的数据结构(B+ tree)并不是缓存的一部分,而是物理页,当受影响的索引页不在buffer pool时缓存 secondar ...

  6. MySQL InnoDB存储引擎事务的ACID特性

    1.前言 相信工作了一段时间的同学肯定都用过事务,也都听说过事务的4大特性ACID.ACID表示原子性.一致性.隔离性和持久性.一个很好的事务处理系统,必须具备这些标准特性: 原子性(Atomicit ...

  7. 利用 Forcing InnoDB Recovery 特性解决 MySQL 重启失败的问题

    小明同学在本机上安装了 MySQL 5.7.17 配合项目进行开发,并且已经有了一部分重要数据.某天小明在开发的时候,需要出去一趟就直接把电脑关掉了,没有让 MySQL 正常关闭,重启 MySQL 的 ...

  8. MySQL 8.0 InnoDB新特性

    MySQL 8.0 InnoDB新特性 1.数据字典全部采用InnoDB引擎存储,支持DDL原子性.crash safe,metadata管理更完善 2.快速在线加新列(腾讯互娱DBA团队贡献) 3. ...

  9. Mysql InnoDB三大特性-- double write

    转自:http://www.ywnds.com/?p=8334 一.经典Partial page write问题? 介绍double write之前我们有必要了解partial page write( ...

随机推荐

  1. ATM机取款过程

    假设一个简单的ATM机的取款过程是这样的:首先提示用户输入密码,最多只能输入三次,超过3次则提示用户“密码错误,请取卡”结束交易.如果用户密码正确,再提示用户输入取款金额,ATM机只能输出100元的纸 ...

  2. Linux学习-基于CentOS7的MariaDB数据库的安装

    一.实验环境: 系统:CentOS7.6,关闭了防火墙与SELINUX 数据库版本:mariadb-10.2.25(二进制安装与源码安装) 二.安装方法: 1.yum源安装 (1) 配置yum源,官方 ...

  3. TreeView拖动并存入数据库(可判断拖动)

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  4. Milking Grid poj2185

    Milking Grid POJ - 2185 时限: 3000MS   内存: 65536KB   64位IO格式: %I64d & %I64u 提交 状态 已开启划词翻译 问题描述 Eve ...

  5. xsxsxsxsxsxsxsxs

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  6. css3的各种属性的讲解

    1.渐变(gradients) 水平渐变:linear gradient 语法:background:linear-gradient(direction,color1,color2); directi ...

  7. P2158仪仗队

    今天早上你谷崩了 由于脑子抽筋,所以选了一道数学题来做.做着做着就疯了 传送 窝盟先画张图冷静冷静 这是样例的图,其中蓝点是有学生的地方. 窝盟来看一下那些学生可以被C君看到. 假设这张图是一个坐标系 ...

  8. mysql错误:1093-You can’t specify target table for update in FROM clause的解决方法

    update语句中包含的子查询的表和update的表为同一张表时,报错:1093-You can’t specify target table for update in FROM clause my ...

  9. 20150803--JS学习笔记(1)

    JS中对象的 prototype 的含义: javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用. A.pro ...

  10. jenkins之定时任务配置

    jenkins可以配置任务定时执行 1.jenkins配置解释说明 在每个job的配置项里,有一个构建触发器配置,勾选“定时检查版本库选项”,在输入框可根据需求配置时间: 日程表填写格式: 日程表(S ...