极客时间-MySQL实战45讲(实践篇)2

20 | 幻读是什么,幻读有什么问题?

InnoDB 的默认事务隔离级别是可重复读--rr

    1. 快照读(snapshot read)
      单纯的select操作,不包括上述 select ... lock in share mode, select ... for update。    
        Read Committed隔离级别:每次select都生成一个快照读。
        Read Repeatable隔离级别:开启事务后第一个select语句才是快照读的地方,而不是一开启事务就快照读。
      快照读的实现方式:undolog和多版本并发控制MVCC
  • 2.当前读(current read)
    当前读, 读取的是最新版本, 并且对读取的记录加锁, 阻塞其他事务同时改动相同记录,避免出现安全问题。
    select ... lock in share mode
    select ... for update
    insert,update,delete
    在RR级别下,当前读的实现方式:next-key锁(行记录锁+Gap间隙锁)

    幻读是什么?


    这里,我需要对“幻读”做一个说明:

    • 1.在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此,幻读在“当前读”下才会出现。
    • 2.上面 session B 的修改结果,被 session A 之后的 select 语句用“当前读”看到,不能称为幻读。幻读仅专指“新插入的行”。

      如何解决幻读?

      现在你知道了,产生幻读的原因是,行锁只能锁住行,但是新插入记录这个动作,要更新的是记录之间的“间隙”。因此,为了解决幻读问题,InnoDB 只好引入新的锁,也就是间隙锁 (Gap Lock)。
      顾名思义,间隙锁,锁的就是两个值之间的空隙。比如文章开头的表 t,初始化插入了 6 个记录,这就产生了 7 个间隙。这样就确保了无法再插入新的记录。

  • 间隙锁和行锁合称 next-key lock,每个 next-key lock 是前开后闭区间。
    也就是说,我们的表 t 初始化以后,如果用 select
    from t for update 要把整个表所有记录锁起来,就形成了 7 个 next-key lock,分别是 (-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +supremum]。
    间隙锁和 next-key lock 的引入,帮我们解决了幻读的问题,但同时也带来了一些“困扰”。
    如果我们的项目中需要解决幻读的话也有两个办法:
    1.使用串行化读的隔离级别
    2.mysql的innodb引擎--间隙锁和 next-key lock 解决了幻读的问题
    ---

    21 | 为什么我只改一行的语句,锁这么多?

我总结的加锁规则里面,包含了两个“原则”、两个“优化”和一个“bug”。

原则 1:加锁的基本单位是 next-key lock。希望你还记得,next-key lock 是前开后闭区间。

原则 2:查找过程中访问到的对象才会加锁。

优化 1:索引上的等值查询,给唯一索引加锁的时候,next-key lock 退化为行锁。

优化 2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁。

一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止。

22 | MySQL有哪些“饮鸩止渴”提高性能的方法?

第一种方法:先处理掉那些占着连接但是不工作的线程。
max_connections 的计算,不是看谁在 running,是只要连着就占用一个计数位置。对于那些不需要保持的连接,我们可以通过 kill connection 主动踢掉。这个行为跟事先设置 wait_timeout 的效果是一样的。设置 wait_timeout 参数表示的是,一个线程空闲 wait_timeout 这么多秒之后,就会被 MySQL 直接断开连接。
第二种方法:减少连接过程的消耗。

慢查询性能问题
在 MySQL 中,会引发性能问题的慢查询,大体有以下三种可能:
索引没有设计好;
SQL 语句没写好;
MySQL 选错了索引。
---

23 | MySQL是怎么保证数据不丢的?

binlog 的写入机制

其实,binlog 的写入逻辑比较简单:事务执行过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到 binlog 文件中。

一个事务的 binlog 是不能被拆开的,因此不论这个事务多大,也要确保一次性写入。这就涉及到了 binlog cache 的保存问题。

系统给 binlog cache 分配了一片内存,每个线程一个,参数 binlog_cache_size 用于控制单个线程内 binlog cache 所占内存的大小。如果超过了这个参数规定的大小,就要暂存到磁盘。

redo log 的写入机制


这三种状态分别是:

1.存在 redo log buffer 中,物理上是在 MySQL 进程内存中,就是图中的红色部分;

2.写到磁盘 (write),但是没有持久化(fsync),物理上是在文件系统的 page cache 里面,也就是图中的黄色部分;

3.持久化到磁盘,对应的是 hard disk,也就是图中的绿色部分。

日志写到 redo log buffer 是很快的,wirte 到 page cache 也差不多,但是持久化到磁盘的速度就慢多了。

24 | MySQL是怎么保证主备一致的?

图 2 中,包含了我在上一篇文章中讲到的 binlog 和 redo log 的写入机制相关的内容,可以看到:主库接收到客户端的更新请求后,执行内部事务的更新逻辑,同时写 binlog。

备库 B 跟主库 A 之间维持了一个长连接。主库 A 内部有一个线程,专门用于服务备库 B 的这个长连接。一个事务日志同步的完整过程是这样的:

1.在备库 B 上通过 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及要从哪个位置开始请求 binlog,这个位置包含文件名和日志偏移量。

2.在备库 B 上执行 start slave 命令,这时候备库会启动两个线程,就是图中的 io_thread 和 sql_thread。其中 io_thread 负责与主库建立连接。

3.主库 A 校验完用户名、密码后,开始按照备库 B 传过来的位置,从本地读取 binlog,发给 B。

4.备库 B 拿到 binlog 后,写到本地文件,称为中转日志(relay log)。

5.sql_thread 读取中转日志,解析出日志里的命令,并执行。

binlog 的三种格式对比
一种是 statement,一种是 row ,第三种格式,叫作 mixed
---

25 | MySQL是怎么保证高可用的?

正常情况下,只要主库执行更新生成的所有 binlog,都可以传到备库并被正确地执行,备库就能达到跟主库一致的状态,这就是最终一致性。

主备延迟

在介绍主动切换流程的详细步骤之前,我要先跟你说明一个概念,即“同步延迟”。与数据同步有关的时间点主要包括以下三个:
1.主库 A 执行完成一个事务,写入 binlog,我们把这个时刻记为 T1;
2.之后传给备库 B,我们把备库 B 接收完这个 binlog 的时刻记为 T2;
3.备库 B 执行完成这个事务,我们把这个时刻记为 T3。

所谓主备延迟,就是同一个事务,在备库执行完成的时间和主库执行完成的时间之间的差值,也就是 T3-T1。

主备延迟的来源

首先,有些部署条件下,备库所在机器的性能要比主库所在的机器性能差。
第二种常见的可能了,即备库的压力大
这就是第三种可能了,即大事务。
不要一次性地用 delete 语句删除太多数据。其实,这就是一个典型的大事务场景。

原文地址:https://www.cnblogs.com/chenbensheng/p/11620050.html

时间: 2024-08-02 08:25:00

极客时间-MySQL实战45讲(实践篇)2的相关文章

MySQL实战45讲

1. 锁分类 MySQL中主要分为全局锁.表级锁和行锁三类.本篇主要涉及全局锁和表级锁. 2. 全局锁 全局锁是对整个数据库实例进行加锁. Flush table with read lock(FRTWRL)该命令用于加全局锁.使用该命令之后,整个库处于只读状态,不能执行数据的增删改查.建表.修改表和更新类事务的提交操作. 使用命令unlock tables接触锁. 全局锁的典型使用场景是做全库的数据备份.不加全局锁备份的话,备份系统拿到的不是一个逻辑时间点的库,这个视图逻辑是不一致的. 在可重

Mysql实战45讲学习详情----一条SQL更新语句是如何执行的?

相关词语: redo log:日志模块(临时记录,类似于便签),InnoDB 引擎特有日志 WAL(Write-Ahead Logging):写入方式 binlog:日志模块(归档日志),Server 层的日志 crash-safe:redo log带来的好处(MySQL 可以恢复到固定时间内任意一秒的状态) WAL执行过程(redo log日志的存储方式): write pos 是当前记录的位置,checkpoint 是当前要擦除的位置,它们之间的是“便签”上还空着的部分.如果 write p

Mysql实战45讲学习详情----为什么你改了我还看不见?

相关词汇: MyISAM:MySQL原生引擎(不支持事务) InnoDB:第三方引擎(支持事务) ACID(Atomicity.Consistency.Isolation.Durability):原子性.一致性.隔离性.持久性 MVCC:数据库的多版本并发控制 事务的概念: 事务就是要保证一组数据库操作,要么全部成功,要么全部失败. 当数据库上有多个事务同时执行时,会出现脏读(dirty read).不可重复读(non-repeatable read).幻读(phantom read)的问题,为

# "做中学"之“极客时间”课程学习指导

目录 "做中学"之"极客时间"课程学习指导 所有课程都可以选的课程 Java程序设计 移动平台开发 网络攻防实践 信息安全系统设计基础 信息安全专业导论 极客时间课程介绍 Winter.程劭非.重学前端 宝玉.软件工程之美 蔡能.从0开始学游戏开发 陈旸.数据分析实战45讲 丁雪丰.玩转Spring全家桶 范学雷.代码精进之路 高磊.9小时搞定微信小程序开发 郝林.Go语言核心36讲 洪亮劼.AI技术内参 胡峰.程序员进阶攻略 胡忠想.从0开始学微服务 黄申.程序员

极客时间的专栏

专栏学习 极客时间 极客时间是极客邦科技出品的 IT 类知识服务产品,内容包含专栏订阅.极客新闻.热点专题.直播.视频和音频等多种形式的知识服务.产品形态包括移动 App,移动端网站.PC 端网站.微信平台等. 我订阅的专栏 丁奇老师带我们去学习mysql的45讲,有mysql的完整学习路径,数据库是编程界必备基础,还是比较推荐的. 这是我买的第一篇专栏,老师带我们去深入剖析tomcat和jetty,虽然不是特别新的技术,但是市场很成熟了,tomcat内部的代码还是很值的我们去学习的. 这是极客

极客时间-左耳听风-程序员攻略-软件设计

程序员练级攻略:软件设计 编程范式 学习编程范式可以让你明白编程的本质和各种语言的编程方式.因此,我推荐以下一些资料,以帮助你系统化地学习和理解. 极客时间的<编程范式游记>系列文章,目录如下. 编程范式游记(1)- 起源 编程范式游记(2)- 泛型编程 编程范式游记(3)- 类型系统和泛型的本质 编程范式游记(4)- 函数式编程 编程范式游记(5)- 修饰器模式 编程范式游记(6)- 面向对象编程 编程范式游记(7)- 基于原型的编程范式 编程范式游记(8)- Go 语言的委托模式 编程范式

极客时间 零基础学Python全套视频分享 尹会生 全套完结

极客时间 零基础学Python全套视频分享 尹会生  全套完结 链接: https://pan.baidu.com/s/1AirTGkP95vIoEKeXKo10jQ 提取码: cpf3 复制这段内容后打开百度网盘手机App,操作更方便哦 基于 Python 3 :考虑到网上很多教程都是基于 Python 2 来进行讲解,而 Python 最后一个 2.x 版本—— Python 2.7 的发布也已经是 8 年前的事情了,这几年一些大型项目已经停止了对 Python 2 的支持(Python 官

asm 极客时间学习

导入极客时间的asm demo学习,编译的时候遇到一些问题, 1, 导入的依赖太旧 2, groovy里面有语法错误(声明为final 又去赋值) 3, ASMCode文件里有些语法与现有语法不匹配错误(getType) 这里有些东西是使用groovy写的,主要也是对接给gradle看的,因为gradle认groovy和kotlin但是不认java, 这也可能是为什么didi的booster使用kotlin写. 4, 还有一点,这个作者也在issue里面说了,使用方法是: 执行编译asm对应的插

我在极客时间的首次分享

文章首发于公众号 松花皮蛋的黑板报 作者就职于京东,在稳定性保障.敏捷开发.高级JAVA.微服务架构有深入的理解 当时我将自己的文章投稿到InfoQ,然后总编辑郭总邮件邀请我来分享,于是有了这次值得纪念的演讲.欢迎朋友们前往极客时间App观看. 主题为:如何利用有效的资源抗住618大促流量 大概内容如下: 性能测试 性能优化 硬件优化可包括配置升级比如使用支持NIO的Tomcat版本代替低版本.集群水平扩展.摘取集群短板. 软件优化包括代码审查然后优化SQL和低性能代码. 扩展点 一.开发语言基