02.08 Day 20 - 提炼 Day 1-5

2024-02-04 09:08
文章标签 提炼 day 20 02.08

本文主要是介绍02.08 Day 20 - 提炼 Day 1-5,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是 Snow Hide,作为《MySQL 实战》这个专栏的学员之一,这是我打卡的第 20 天,也是我第 75 次进行这种操作。

今天我温习了该专栏里叫《基础架构:一条SQL查询语句是如何执行的?》、《日志系统:一条 SQL 更新语句是如何执行的?》、《事务隔离:为什么你改了我还看不见?》、《深入浅出索引(上)》、《深入浅出索引(下)》、《全局锁和表锁 :给表加个字段怎么有这么多阻碍?》、《行锁功过:怎么减少行锁对性能的影响?》的文章。

关键词总结:Server 层(连接器、查询缓存、分析器、优化器、执行器、内置函数(日期、时间、数学、加密函数)、跨存储引擎功能(存储过程、触发器、视图))、存储引擎层(存储、提取、InnoDB)、重要的日志模块:redo log(所属层、WAL 技术、Redo Log、Write Pos、Checkpoint、Crash-Safe)、重要的日志模块:binlog(所属层、两种日志的三个区别点)、两阶段提交(恢复到指定的某一秒、先写 redo log 后写 binlog、先写 binlog 后写 redo log)、隔离性与隔离级别、(隔离级别(读未提交、读提交、可重复读、串行化)、隔离级别的事务效果(读未提交、读提交、可重复读、串行化))、事务隔离的实现、事务的启动方式(显式启动、隐式启动)、索引常见模型(哈希表、有序数组、搜索树)、InnoDB 索引模型(主键索引/聚簇索引、非主键索引/二级索引、主键索引与普通索引的查询区别)、索引维护(占用空间)、覆盖索引(提升查询性能)、最左前缀原则(建立联合以及单字段索引)、索引下推、锁分类、全局锁(加锁方法、应用场景、风险、建议使用 FTWRL 方式的两个原因)、表级锁(表级锁种类(表锁、元数据锁、MDL 读写锁))、支持行锁的引擎、两阶段锁(行锁的释放时间)、死锁和死锁检测(解决死锁的两种策略、解决热点行更新导致的性能问题)。

 

所学总结:

 

MySQL 基础架构

Server 层

连接器

负责与客户端建立连接、获取权限、维持以及管理连接。

查询缓存

不经常更改的表才适合使用查询缓存,例如系统配置表。

分析器

MySQL 需要识别出里面的字符串分别是什么,代表什么。

优化器

优化器是当表有多个索引时,决定使用哪个索引;或在多表关联语句时,决定表的连接顺序。

执行器

开始执行的时候,片段用户对操作表是否有对应操作类型的权限,没有则返回权限错误消息。
 

MySQL 日志系统

重要的日志模块:redo log / 重做日志

所属层

redo log 处在 InnoDB 引擎层。独有的 crash-safe 能力。

WAL 技术

WAL 的全称是 Write-Ahead Logging。它的原理是先写日志,再写磁盘。

Redo Log

当有记录需要更新时, InnoDB 引擎会先记录到 redo log (暂存)中,并更新内存,在系统空闲的时候再将记录更新至磁盘。

Write Pos

当前记录的未知,写完后移至下一个位置。循环写。

Checkpoint

write pos 与 checkpoint 之间空着的部分是用来记录新操作的。

Crash-Safe

redo log 可以确保数据库发生异常,重启后之前提交的记录依然存在,这个被称为 crash-safe(奔溃安全)。

重要的日志模块:binlog / 归档日志

所属层

binlog 处在 Server 层。没有 crash-safe 能力。

两种日志的三个区别点
  • redo log 为 InnoDB 引擎独有;binlog 由 MySQL 的 Server 层所实现,所有引擎均可使用;
  • redo log 属于物理日志,记录语句所做的改动;binlog 则是逻辑日志,记录的是语句的原始逻辑;
  • redo log 是循环写,空间可以被用完;binlog 是追加写,可以在到达指定数据量后切换至新的文件,不会覆盖原有日志。

两阶段提交

由于 redo log 与 binlog 是两个独立的逻辑,不用两阶段提交的话,只能是先写 redo log 再写 binlog,或者将操作反转。

恢复到指定的某一秒
  • 找到最近的一次全量备份,将其恢复至临时库;
  • 从备份的时间点开始,将备份的 binlog 依次取出并重放至误删表之前的那一时刻。
先写 redo log 后写 binlog

假设 redo log 写完,但 binlog 还未写完时,MySQL 进程发生异常。由于 redo log 已写完,即使系统奔溃,我们仍然能将数据恢复。但是 binlog 就不会存在该语句逻辑的记录。

先写 binlog 后写 redo log

倘若 binlog 写完,但 redo log 还未写完时,在奔溃重启后,该事务不成立。此时,binlog 里的语句逻辑记录是新的,而 redo log 里的物理数据则是旧的。
 

事务隔离级别与实现

隔离性与隔离级别

用以解决脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)等问题。

隔离级别

SQL 标准的事务隔离级别有:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)以及串行化(serializable)。

读未提交

事务提交之前其所做的变更可被其他事务看见。

读提交

事务提交之后其所做的变更才可被其他事务看见。

可重复读

事务执行过程看到的数据总是和事务在启动时看到的数据一致。事务提交之前其所做的变更对其他事务不可见。

串行化

对于同一条记录,写时加写锁,读时加读锁。出现读写锁冲突时需要等事务执行完成才能继续。

隔离级别的事务效果
读未提交

虽然事务 B 还未提交,但事务 A 能看到其结果。

读提交

事务 B 的更新在提交后才能被事务 A 所看到。

可重复读

事务在执行期间看到的数据在提交前后必须是一致的。

串行化

事务 B 无法操作事务 A 正在操作的数据,等事务 A 提交并释放锁后,事务 B 才能继续。

事务隔离的实现

每条记录在更新的时候都会同时记录一条回滚操作。通过回滚操作,记录上的最新值可以得到前一个状态的值。

事务的启动方式

显式启动

通过 begin 或 start transaction 的语句开始,以 commit 结尾或异常时以 rollback 结束。

隐式启动

将 set autocommit 设置为 0 时会讲线程自动提交关闭,当执行 select 语句时就触发了事务,该事务会一直存在直至遇到 commit 或 rollback 语句或断开与数据库的连接。
这是通常所说的长连接。建议将 set autocommit 设置为 1,并在 CUD 时显式启动事务。频繁使用事务的地方可以使用 commit work and chain 语法,其作用时将当前事务提交并立即开启下一个事务,从而省去再次调用 begin 语句所带来的开销。
 

MySQL 的索引

索引常见模型

索引可以提高查询效率。

哈希表

键值数据结构,根据 key 找 value。通过哈希函数将 key 换算成一个下标,然后将 value 放在数组中该下标所处的位置。
哈希表只适用于等值查询的场景,例如 Memcached 或其他 NoSQL 存储。

有序数组

在等值或范围查询中都能有比价好的性能表现。
有序数组只适合静态存储,例如一些不会做改动的数据。

搜索树

二叉树的搜索效率最高,但实际上大多数数据库存储却不适用。因为索引不止存在于内存,还要同时写到磁盘。
为了尽量减少 IO 操作,要让查询尽量少访问或不访问数据块,所以我们就不使用二叉树。

InnoDB 索引模型

使用了 B+ 树索引模型,所以数据存储在 B+ 树中。
每个索引对应一棵 B+ 树。

主键索引/聚簇索引 / Clustered Index

叶子结点所存的是一整行数据。

非主键索引/二级索引 / Secondary Index

叶子结点所存的是逐渐的值。

主键索引与普通索引的查询区别
  • 主键索引:只需要搜索主键字段所对应的 B+ 树;
  • 普通索引:需要先搜索普通字段的索引树,得到其主键值,再借助主键值到主键字段所对应的索引树中再查询一次。这个过程叫回表。
  • 非主键索引的查询需要多扫描一棵索引树,因此,应尽量使用主键查询。

索引维护

占用空间

主键长度越小,普通索引的叶子结点就越小,普通索引占用的空间也就越小。
以性能以及空间利用率为出发点的话,自增主键是比较合理的选择。

覆盖索引

提升查询性能

覆盖索引可以减少树的搜索次数,能很明显的提高查询性能,所以使用覆盖索引是常见的优化方式。

最左前缀原则

可以利用 B+ 树索引结构的 “最左前缀” 来定位记录。

建立联合以及单字段索引

第一原则是当通过调整顺序后,如果能少维护一个索引,那该顺序则很有可能被优先采用。

索引下推

在索引遍历过程中对其所包含的字段先做判断,过滤不匹配的记录以减少回表次数。
 

MySQL 的全局锁、表锁、行锁

锁分类

全局锁、表级锁、行锁。

全局锁

加锁方法

FTWRL(Flush Tables With Read Lock),让整库处于只读状态,此时其他线程所运行的一些语句会被阻塞:数据更新(增删改)、数据定义(建表、修改表结构)、更新类事务提交。

应用场景

全库逻辑备份。

风险
  • 主库加锁期间不能执行更新,业务暂停运作;
  • 从库加锁期间不能执行主库同步过来的 binlog,导致主从延迟。
建议使用 FTWRL 方式的两个原因
  • readonly 在一些系统中会被用作其他逻辑,例如判断是主库还是备库。因此修改 global 变量的影响比较大;
  • 执行 FTWRL 后客户端如果发生异常断开,库全局锁会自动释放,并回到正常状态。如果设置为 readonly 期间客户端发生异常,库会一直保持 readonly 状态,不会回到正常状态。

表级锁

表级锁种类

表锁、元数据锁(MDL,Meta Data Lock)

表锁

lock tables … read/write。与 FTWRL 类似,可以借助 unlock tables 来释放锁或在客户端断开时自动释放锁。lock tables 除了限制其他线程的读写外,还会限制本线程接下来的操作对象。

元数据锁

无须显式声明,访问表时自动上锁,并保证读写正确性。

MDL 读写锁
  • 读锁不互斥,可以多线程对表进行增删改查;
  • 读写锁的写锁互斥,保证表结构变更的安全性。多线程按顺序操作表结构。

支持行锁的引擎

InnoDB 支持行锁。

两阶段锁

行锁的释放时间

等到事务结束时才释放。

死锁和死锁检测

解决死锁的两种策略
  • 等待超时。设置超时参数:innodb_lock_wait_timeout;
  • 发起死锁检测,回滚死锁链条的一个事务,让其他事务可以继续。设置参数 innodb_deadlock_detech 为 on。
解决热点行更新导致的性能问题
  • 在确保业务不会出现死锁的情况下临时关掉死锁检测,关掉死锁检测可能会出现大量超时;
  • 控制并发度。同行更新在进入引擎之前排队,以减少 InnoDB 内部的死锁检测工作;
  • 通过将一行改成逻辑上的多行来减少冲突,以减少锁等待个数。

 

末了

重新总结了一下文中提到的内容:MySQL 逻辑架构、SQL 语句完整执行流程、redo log 物理日志、binlog 逻辑日志、redo log 保证 crash-safe 特性需要配置的参数、日志系统的两阶段提交、跨系统维持数据逻辑一致性方案、事务隔离级别的现象和实现、长事务存在的风险、通过正确方式避免长事务、数据库索引概念、覆盖索引、前缀索引、索引下推、减少资源访问和消耗、全局锁、表级锁、全局锁应用场景、表锁应用场景、MDL 元数据锁、行锁、两阶段锁协议、死锁以及死锁检测、控制访问相同资源的并发事务量。

这篇关于02.08 Day 20 - 提炼 Day 1-5的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/676971

相关文章

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

Linux基础入门 --9 DAY

文本处理工具之神vim         vi和vim简介 一、vi编辑器 vi是Unix及类Unix系统(如Linux)下最基本的文本编辑器,全称为“visual interface”,即视觉界面。尽管其名称中包含“visual”,但vi编辑器实际上工作在字符模式下,并不提供图形界面。vi编辑器以其强大的功能和灵活性著称,是Linux系统中不可或缺的工具之一。 vi编辑器具有三种主要的工作模

day-50 求出最长好子序列 I

思路 二维dp,dp[i][h]表示nums[i] 结尾,且有不超过 h 个下标满足条件的最长好子序列的长度(0<=h<=k),二维数组dp初始值全为1 解题过程 状态转换方程: 1.nums[i]==nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h]+1) 2.nums[i]!=nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h-1

[Day 73] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

AI在健康管理中的應用實例 1. 引言 隨著健康管理需求的提升,人工智能(AI)在該領域的應用越來越普遍。AI可以幫助醫療機構提升效率、精準診斷疾病、個性化治療方案,以及進行健康數據分析,從而改善病患的健康狀況。這篇文章將探討AI如何應用於健康管理,並通過具體代碼示例說明其技術實現。 2. AI在健康管理中的主要應用場景 個性化健康建議:通過分析用戶的健康數據,如飲食、運動、睡眠等,AI可

Vue day-03

目录 Vue常用特性 一.响应更新 1. 1 v-for更新监测 1.2 v-for就地更新 1.3 什么是虚拟DOM 1.4 diff算法更新虚拟DOM 总结:key值的作用和注意点: 二.过滤器 2.1 vue过滤器-定义使用 2.2 vue过滤器-传参和多过滤器 三. 计算属性(computed) 3.1 计算属性-定义使用 3.2 计算属性-缓存 3.3 计算属

用Python实现时间序列模型实战——Day 14: 向量自回归模型 (VAR) 与向量误差修正模型 (VECM)

一、学习内容 1. 向量自回归模型 (VAR) 的基本概念与应用 向量自回归模型 (VAR) 是多元时间序列分析中的一种模型,用于捕捉多个变量之间的相互依赖关系。与单变量自回归模型不同,VAR 模型将多个时间序列作为向量输入,同时对这些变量进行回归分析。 VAR 模型的一般形式为: 其中: ​ 是时间  的变量向量。 是常数向量。​ 是每个时间滞后的回归系数矩阵。​ 是误差项向量,假

【语句】如何将列表拼接成字符串并截取20个字符后面的

base_info = "".join(tree.xpath('/html/head/script[4]/text()'))[20:] 以下是对这个语句的详细讲解: tree.xpath('/html/head/script[4]/text()')部分: tree:通常是一个已经构建好的 HTML 文档树对象,它是通过相关的 HTML 解析库(比如 lxml)对 HTML 文档进行解