mysql 活跃事务_关于MySQL事务的简单讲解-阿里云开发者社区

事务:

mysql要开始一个事务需要begin

扁平事务 不能提交或者回滚一部分,最常见的一种事务

三种结果 主动提交 (遇到错误)主动回滚  被动回滚

带有保存点的扁平事务可以回滚一部分,保存点仅仅是一个标签,事务没提交前,一旦数据库崩溃,事务全部回滚,不会因为保存点而部分回滚

链事务(基本不用):应用于 一个大事务分多次提交, (提交释放锁资源),但是一个大事务多次提交缺不能回回滚

嵌套事务(MYSQL不支持嵌套事务 oracle支持):由若干个事务组成, 中间的部分事务提交 只要总的回滚,那么里面的事务也都会回滚

分布式事务:

核心是 一个事务跨两个数据库

当一个事务跨两个数据库并且需要独自提交,这时候需要使用分布式事务 可以保证两事务同时提交或者回滚

但是MySQL支持的分布式事务并不好

对于innodb支持 扁平 带有保存点的扁平 链事务 分布式事务

对于MySQL数据库来讲无论是事务还是sql都要尽可能的简单 。为了减少MySQL中的分布式事务等复杂事务我们可以在程序层面控制,将不同的商品放在不同的数据库中,避免一个事务同时访问两台数据库

对事务的实现必须要有redo 和undo

redo log 作用:

保证事务的持久性,

支持缓冲写

崩溃恢复(前滚恢复速度快,速度稳定,(速度主要取决于io))

redo 分为 两部分: 内存: redo log buffer

磁盘: redo log file

redo记录方式:

物理日志的记录方式(对某文件某个页所做的操作),不需要解析,

因为物理日志写的单元是512字节,所以不需要double write

redo保证了事务的持久性:

原因:

日志先行

1、当事务提交的时候,会将redo log buffer中的日志写入到磁盘

2、当log buffer大小占用1/2的时候,会往磁盘里刷新

3、 数据写入磁盘的时候会触发检查点  log chechkpoint

所谓的检查点我们可以认为:

系统恢复的最早的那个点即写入到磁盘的最新脏块的redo log的位置(被记录到ibdata中即最早脏的那个数据块 系统崩溃恢复的时候,检查点作为崩溃恢复检查的起点)

redo 由两部分组成: redo log buffer 、 redo log file(区别与bin log)

通过 innodb_flush_log_at_trx_commit参数来控制写入重做日志的级别;默认值是1

0:日志缓冲每秒一次地被写到日志文件,并且对日志文件做到磁盘操作的刷新,但是在一个事务提交不做任何操作。

1:在每个事务提交时,日志缓冲被写到日志文件,对日志文件做到磁盘操作的刷新。

2:在每个提交,日志缓冲被写到文件,但不对日志文件做到磁盘操作的刷新。对日志文件每秒刷新一次。网易技术部 67

默认值是 1,也是最安全的设置,即每个事务提交的时候都会从 log buffer 写到日志文件,而且会实际刷新磁盘,但是这样性能有一定的损失。

如果可以容忍在数据库崩溃的时候损失一部分数据,那么设置成 0 或者 2 都会有所改善。设置成 0,则在数据库崩溃的时候会丢失那些没有被写入日志文件的事务,最多丢失 1 秒钟的事务,

种方式是最不安全的,也是效率最高的。设置成 2 的时候,因为只是没有刷新到磁盘,但是已经写入日志文件,所以只要操作系统没有崩溃,那么并没有丢失数据 ,比设置成 0 更安全一些。

当我们批量导数据的时候可以将该参数改为0  (50W个insert 事务,设为1需要50秒,设为0仅需要13秒就可以完成)

redo  特点: 顺序写,在数据库正常运行情况下我们不去读脏块:

事务已经提交,redo log一定已经写入了磁盘

事务没有提交,脏块已经写入到了磁盘,redo log 一定写入到了磁盘

这个事务没有提交,因此回滚的数据一直存在,这个回滚的数据被redo log保护,,保证崩溃恢复的时候undo的正确回滚

事务没有提交,redo log也没有写入磁盘

innodb_log_group_home_dir,最好将redo放在写性能很高的磁盘 如ssd

innodb_log_file_in_group  设置redo file的每组多少个 建议设置5个,设置过低,当切换redo的时候,数据库会出出现短暂的停顿,。

保护了redo log就是保护了事务(redo log的保护比数据文件的保护还要重要)

binlog : 备份恢复, 主从复制   redo log 只对innodb引擎有效,bin log 对innodb 和 myism引擎都有效

redo log是基于页的物理记录方式即记录着该数据对应的页 行的地址,恢复的时候指定在哪恢复

bin log 逻辑层面 是基于语句级的记录方式

LSN号; 每条日志,每个数据页

每一个数据页,每一条日志都有lsn号 检查点也有lsn号  lsn号记录的就是数据的位置

double write技术

redo lock

log group

mysql中,组之间是镜像关系

redo 的日志格式:

redo_log_type 重做日志的类型

space 表空间的ID

page_no 页的偏移量

redo_log_body具体的操作格式

undo主要的三个作用:

1、事务回滚

2、MVCC

3、崩溃恢复

ibdata 共享表空间里第五个页是属于 undo的默认128个段

128个段各自又有多个块,

每个段的第一个块成为段头块

uodo的第一个块被称为系统事务表,分别指向不同段的段头块

段头块:

一个段头块最多可以有1024的slot(可以认为每个段最多可以有1024个事务,即一个数据库最多可以并发128*1024个事务)

一个事务的起始、

事务开始是会生成一个事务id:xid(依次递增),在系统事务表里找到一个相对空闲(活跃事务较少的段)的undo段,将自己的xid写进段头块的一个空闲槽位slot,事务修改数据前,将数据存放到空闲的块中,需要多个块的时候,地址依次相连(undo块使用了链条进行链接),最后一个用到的块会指向段头块的那个槽位

commit: 修改slow 已提交

rollback:

事务没有被提交,slot不会被覆盖,undo块不会被覆盖

找到最后一个块,依次往前回滚

所以如果是一个大事务,回滚时间会很长

崩溃恢复,回滚完,开始前滚,记录了事务的最大id,那说明所有未提交的事务都小于该id

但是并不会马上回滚,当新的事务修改数据块时,发现该数据块的事务未提交,就会前去回滚

事务提交但是没被写入磁盘需要redo 前滚,有些事务没提交但是被写入磁盘则需要undo回滚

undo 段 默认128个

undo页需要回收。 通过purge线程

同时支持的活动事务的数量 =undo段数*1024

可以用py_innodb_page_info.py工具来查看当前共享表空间的undo的数量

history list:

按照事务提交的顺序将已提交的事务连起来,(这些事务也都分别对应着自己的undo块),当我们在purge清空回收undo块的时候,会根据history list 的顺序从尾端依次清空,即先清空事务最早的提交的undo块

ee0d71664fa50ffce126ae81e0aa6813.png

show engine innodb status 在transactions中可以监控到history list的长度,当这个长度增长较快的时候

说明数据库undo的刷新可能出现了问题这时可以考虑是否有大量的未提交的事务

表示该数据库的undo已经刷新到了1793,这个事务id, 也就是比这个事务id还小的事务都已经执行

b933d6e870041b50669fe52d5d4bd0c1.png

通过以下参数来控制undo

innodb_undo_directory :可以设置undo段文件所在的路径(默认在默认表空间里可以通过修改路径将其放在单独的文件中)

innodb_undo_logs : 设置回滚段的个数(最大值就是128)

innodb_undo_tablespaces  :用来设置构成undo段的文件的数量,即将undo段分配到多个文件里因为下面已经设置了多个raid所以该参数没哟多大意义

关于内存中undo 页的回收即purge 是一个磁盘离散读取的过程消耗Io为了节约undo采用了重用模式,即一个undo页如果备用空间小于3/4那么其他的事务也可以将undo数据存放到该页上节约undo的占用空间

关于事务控制: auto_commit自动提交的原因是 mysql在解决锁的问题上压力很大

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值