首页 > 数据库 >MySQL三大日志,mvcc、DateTime 类型等

MySQL三大日志,mvcc、DateTime 类型等

时间:2024-01-05 14:35:48浏览次数:42  
标签:事务 log MySQL 回滚 DateTime mvcc 查询 redo

1、MySQL事务隔离级别详解 解决幻读的方法 解决幻读的方式有很多,但是它们的核心思想就是一个事务在操作某张表数据的时候,另外一个事务不允许新增或者删除这张表中的数据了。解决幻读的方式主要有以下几种:

  1. 将事务隔离级别调整为 SERIALIZABLE 。
  2. 在可重复读的事务级别下,给事务操作的这张表添加表锁。
  3. 在可重复读的事务级别下,给事务操作的这张表添加 Next-key Lock(Record Lock+Gap Lock)
  2、undo log 我们知道如果想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,在 MySQL 中,恢复机制是通过 回滚日志(undo log) 实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,我们直接利用 回滚日志 中的信息将数据回滚到修改之前的样子即可!并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚将之前未完成的事务。 另外,MVCC 的实现依赖于:隐藏字段、Read View、undo log。在内部实现中,InnoDB 通过数据行的 DB_TRX_ID 和 Read View 来判断数据的可见性,如不可见,则通过数据行的 DB_ROLL_PTR 找到 undo log 中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 Read View 之前已经提交的修改和该事务本身做的修改   3、MySQL三大日志(binlog、redo log和undo log)详解总结 MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性,使用 undo log(回滚日志) 来保证事务的原子性MySQL数据库的数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性。   4、简单理解两阶段提交:更新数据时然后调用引擎 API 接口,写入这一行数据,InnoDB 引擎把数据保存在内存中,同时记录 redo log,此时 redo log 进入 prepare 状态,然后告诉执行器,执行完成了,随时可以提交。执行器收到通知后记录 binlog,然后调用引擎接口,提交 redo log 为提交状态。

两阶段提交的方式好处,写完 binlog 后,然后再提交 redo log 就会防止出现上述的问题,从而保证了数据的一致性。那么问题来了,有没有一个极端的情况呢?假设 redo log 处于预提交状态,binlog 也已经写完了,这个时候发生了异常重启会怎么样呢? 这个就要依赖于 MySQL 的处理机制了,MySQL 的处理过程如下:

  • 判断 redo log 是否完整,如果判断是完整的,就立即提交。
  • 如果 redo log 只是预提交但不是 commit 状态,这个时候就会去判断 binlog 是否完整,如果完整就提交 redo log, 不完整就回滚事务。
  4、MVCC➕Next-key-Lock 防止幻读 InnoDB存储引擎在 RR 级别下通过 MVCC和 Next-key Lock 来解决幻读问题: 1、执行普通 select,此时会以 MVCC 快照读的方式读取数据 在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 Read View ,并使用至事务提交。所以在生成 Read View 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读” 2、执行 select...for update/lock in share mode、insert、update、delete 等当前读 在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!InnoDB 使用 Next-key Lock 来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读  

5、简单总结一下查询缓存的适用场景:

  • 表数据修改不频繁、数据较静态。
  • 查询(Select)重复度高。
  • 查询结果集小于 1 MB。

对于一个更新频繁的系统来说,查询缓存缓存的作用是很微小的,在某些情况下开启查询缓存会带来性能的下降。

简单总结一下查询缓存不适用的场景:

  • 表中的数据、表结构或者索引变动频繁
  • 重复的查询很少
  • 查询的结果集很大
根据我们的经验,在高并发压力环境中查询缓存会导致系统性能的下降,甚至僵死。如果你一 定要使用查询缓存,那么不要设置太大内存,而且只有在明确收益的时候才使用(数据库内容修改次数较少)。 6、什么是执行计划? 执行计划 是指一条 SQL 语句在经过 MySQL 查询优化器 的优化会后,具体的执行方式。 执行计划通常用于 SQL 性能分析、优化等场景。通过 EXPLAIN 的结果,可以了解到如数据表的查询顺序、数据查询操作的操作类型、哪些索引可以被命中、哪些索引实际会命中、每个数据表有多少行记录被查询等信息。

可以看到,执行计划结果中共有 12 列,各列代表的含义总结如下表:

 

列名含义
id SELECT查询的序列标识符
select_type SELECT关键字对应的查询类型
table 用到的表名
partitions 匹配的分区,对于未分区的表,值为 NULL
type 表的访问方法
possible_keys 可能用到的索引
key 实际用到的索引
key_len 所选索引的长度
ref 当使用索引等值查询时,与索引作比较的列或常量
rows 预计要读取的行数
filtered 按表条件过滤后,留存的记录数的百分比
Extra 附加信息

 

 

7、本文总结下自增值不连续的 4 个场景:

  1. 自增初始值和自增步长设置不为 1
  2. 唯一键冲突
  3. 事务回滚
  4. 批量插入(如 insert...select 语句)
  8、DateTime 类型耗费空间更大 Timestamp 只需要使用 4 个字节的存储空间,但是 DateTime 需要耗费 8 个字节的存储空间。但是,这样同样造成了一个问题,Timestamp 表示的时间范围更小。
  • DateTime :1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
  • Timestamp: 1970-01-01 00:00:01 ~ 2037-12-31 23:59:59
  9、时间戳的定义是从一个基准时间开始算起,这个基准时间是「1970-1-1 00:00:00 +0:00」,从这个时间开始,用整数表示,以秒计时,随着时间的流逝这个时间整数不断增加。这样一来,我只需要一个数值,就可以完美地表示时间了,而且这个数值是一个绝对数值,即无论的身处地球的任何角落,这个表示时间的时间戳,都是一样的,生成的数值都是一样的,并且没有时区的概念,所以在系统的中时间的传输中,都不需要进行额外的转换了,只有在显示给用户的时候,才转换为字符串格式的本地时间。   10、分析和总结 通过上面的测试我们发现 MySQL 使用操作符的一些特性:
  1. 当操作符左右两边的数据类型不一致时,会发生隐式转换
  2. 当 where 查询操作符左边为数值类型时发生了隐式转换,那么对效率影响不大,但还是不推荐这么做。
  3. 当 where 查询操作符左边为字符类型时发生了隐式转换,那么会导致索引失效,造成全表扫描效率极低。
  4. 字符串转换为数值类型时,非数字开头的字符串会转化为0,以数字开头的字符串会截取从第一个字符到第一个非数字内容为止的值为转化结果。
所以,我们在写 SQL 时一定要养成良好的习惯,查询的字段是什么类型,等号右边的条件就写成对应的类型。特别当查询的字段是字符串时,等号右边的条件一定要用引号引起来标明这是一个字符串,否则会造成索引失效触发全表扫描。

标签:事务,log,MySQL,回滚,DateTime,mvcc,查询,redo
From: https://www.cnblogs.com/lengsong/p/17947196

相关文章

  • 解决Django Elastic Beanstalk与RDS MySQL连接问题
    根据错误消息,问题在于您的ElasticBeanstalk环境中缺少MySQL配置。这可能是由于缺少所需的软件包或依赖项导致的。解决此问题的步骤如下:在您的项目根目录中创建一个名为.ebextensions的文件夹。在.ebextensions文件夹中创建一个名为packages.config的文件,并在其......
  • MySQL 8.0的SQL查询JSON返回的数据类型为字符串而非数组
    在MySQL8.0中,SQL查询JSON返回的数据类型确实是字符串,而不是数组。这是因为MySQL将JSON数据存储为字符串,并提供了一些函数和操作符来处理JSON数据。但是,你可以使用内置的JSON函数来处理返回的JSON字符串。例如,你可以使用JSON_EXTRACT函数来提取JSON字符串......
  • Docker下MySQL 8.0如何通过xtrabackup进行增量备份
    看到网上很多Docker环境下MySQL8.0的xtrabackup都是通过dockercompose的方式来进行备份的,个人觉得太麻烦了,于是通过修改MySQLDocker镜像的方式来扩展备份功能第一部分 MySQL8.0功能扩展1.MySQL8.0官方镜像扩展xtrabackup,Dockerfile如下FROMdocker.io/mysql:8.0.34-oracleR......
  • MySQL 数据库归档工具pt-archive 与归档数据的安全存储 与 为什么每次归档都少数...
    DBA在日常的工作中,数据归档是DB人员工作中的必选项。这里有技术的因素和法律的因素,数据库中的业务在使用一段时间内,数据表中必然存在大量的过期的数据,这些数据将不在与当前的业务有关,同时这些数据的存在会影响当前一些SQL的执行的性能,所以从技术的角度需要进行数据的归档。从法......
  • 2038年MySQL5.7和MariaDB 10.6自动终止服务进程。MySQL 8.0.31未受影响。
    2038年MySQL5.7和MariaDB10.6自动终止服务进程。MySQL8.0.31未受影响。14年内,必须升级MySQL5.7数据库,重要的事情说三遍。见下面截图[Warning]Currenttimehasgotpastyear2038.Validatingcurrenttimewith5iterationsbeforeinitiatingthenormalservershutdownpr......
  • mysql8.0存储过程和存储函数的查看、修改、删除
    5、存储过程和存储函数的查看、修改、删除5.1、查看创建完之后,怎么知道我们创建的存储过程、存储函数是否成功了呢?MySQL存储了存储过程和函数的状态信息,用户可以使用SHOWSTATUS语句或SHOWCREATE语句来查看,也可直接从系统的information_schema数据库中查询。这里介绍3种方法。......
  • 基于各种场景使用mysqldump逻辑备份数据库
    1.mysqldump备份工具的语法格式mysqldump的使用语法:备份指定数据库mysqldump选项数据库备份指定数据库下的某张表mysqldump选项数据库表备份多个数据库mysqldump选项--database/-B数据库1数据库2备份所有数据库mysqldump选项--all-databases/-......
  • mysql8.0大小写的坑
    这两天又被mysql8.0大小写的问题坑到了,看下面的报错:chown:cannotaccess'./proc/38/fd/6':Nosuchfileordirectorychown:cannotaccess'./proc/38/fd/7':Nosuchfileordirectorychown:cannotaccess'./proc/38/fdinfo/4':Nosuchfileordire......
  • 基于ETLCloud的MySQL到SqlServer实时同步解决方案
    背景在以下场景下会用到不同数据库的实时同步问题,比如:数据备份与容灾、多地域数据同步、数据共享与协作、数据分析与报表生成、实时监控与报警系统等等。大多数情况用到的就是数据备份了吧,相同的数据库还好,不同的数据库不能完全兼容就很麻烦,所以会用到SymmetricDS、Maxwell、Debezi......
  • mysql8.0存储函数
    4、存储函数的使用4.1、语法分析学过的函数:LENGTH、SUBSTR、CONCAT等语法格式CREATEFUNCTION函数名(参数名参数类型,...)RETURNS返回值类型[characteristics...]BEGIN函数体#函数体中肯定有RETURN语句END说明:1、参数列表:指定参数为IN、OUT或INOUT只对PROCE......