Mysql45讲学习笔记

前言:这篇文章主要总结事务,锁、索引的一些知识点,然后分享一下自己学习小心得,我会从点到线在到面展开说说,对于学习任何知识,我们都应该藐其全貌,不要一开始就选入细节

基础

一、基础架构:一条查询sql是怎么执行的?

在这里插入图片描述

二、 日志系统:一条更新语句是怎么执行的?

1.redolog与binlog区别?

① redolog是innodb存储引擎实现,而binlog是在Server层实现

② redolog是物理存储,而binlog是逻辑存储

③ redolog是循环写入(空间会用尽,所以每隔一段时间就需要擦除),而binlog是追加写入(所以说他是归档日志)

2、二阶段提交是怎么样?

3、第一步:写入redolog处于准备阶段

4、第二步:写入binlog

5、第三步:redolog提交阶段、

备注:将 redo log 的写入拆成了两个步骤:prepare 和 commit,这就是"两阶段提交"。

我的理解

从 “两阶段提交”的执行流程看,“ binlog 成功,redo log失败”的场景(备注:数据库 crash-重启后,会对记录对redo log进行检查 )

1、如果 redo log 已经commit,则视为有效。

2、如果 redo log prepare 但未commit,则check对应的bin log记录是否记录成功。

① bin log记录成功则将该prepare状态的redo log视为有效

② bin log记录不成功则将该prepare状态的redo log视为无效

img

3、一些参数补充说明

binlog日志模块

sync_binlog=1的时候,表示每次事务的 binlog 都持久化到磁盘(建议设置成1)

补充:binlog一共有三种模式

① statement模式:记录sql语句,优点占用内存少,如果出现函数可能到回到数据不一致

② row模式:直接记录数据,占用内存大

③ mixed:以上两种模式的混合

redolog日志模块

innodb_flush_log_at_trx_commit={0|1|2} (指定何时将事务日志刷到磁盘,默认为1)

0表示每秒将"log buffer"同步到"os buffer"且从"os buffer"刷到磁盘日志文件中。

1表示每事务提交都将"log buffer"同步到"os buffer"且从"os buffer"刷到磁盘日志文件中。

2表示每事务提交都将"log buffer"同步到"os buffer"但每秒才从"os buffer"刷到磁盘日志文件中。

问题:前面我说到定期全量备份的周期“取决于系统重要性,有的是一天一备,有的是一周一备”。那么在什么场景下,一天一备会比一周一备更有优势呢?或者说,它影响了这个数据库系统的哪个指标?

这个需要根据业务进行评估,空间换时间

三、 事务隔离:为什么你改了我还是看不见?

1、Mysql有哪些隔离级别?

① 读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到。

② 读已提交:别人改数据的事务已经提交,我在我的事务中才能读到。

③ 可重复读:别人改数据的事务已经提交,我在我的事务中也不去读。

④ 串行:我的事务尚未提交,别人就别想改数据

2、事务隔离的实现

RC:每次查询的时候都会去创建一个视图

RR:事务启动的时候就会创建视图

RU:不存在视图

串行化:不存在视图这个概念,都是通过加锁方式实现事务的隔离

3、事务启动方式

① 把自动提交关掉:set autocommit=0

② 例子->显示启动事务

begin;
update t1 set a=1 where id = 2;
commit;
rollback;

这里有个需要注意的点:begin的时候是还没启动事务,在执行第一条sql才会启动

③ 如何查询长事务,查询持续时间超过60秒的事务

select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60; 

*4、**问题:如何避免长事务对业务的影响?*

1、set global general_log=on;开启通用日志,在业务功能测试阶段要求输出所有的 general_log,分析日志行为提前发现问题

1、确认是否有不必要的只读事务。把select语句放在事务外

2、通过 SET MAX_EXECUTION_TIME 命令,避免单sql执行时间过长

3、监控 information_schema.Innodb_trx 表,设置长事务阈值,超过就报警 / 或者 kill;

4、innodb_undo_tablespaces设置成 2,即是不是用系统表空间,使用独立空间,如果真的出现大事务导致回滚段过大,这样设置后清理起来更方便

四、 深入浅出索引(上)

总结:

*第一点:索引模型的选择*

1.索引的作用:提高数据查询效率

2.常见索引模型:哈希表、有序数组、搜索树

3.哈希表:键 - 值(key - value)。

4.哈希思路:把值放在数组里,用一个哈希函数把key换算成一个确定的位置,然后把value放在数组的这个位置

5.哈希冲突的处理办法:链表

6.哈希表适用场景:只有等值查询的场景

7.有序数组:按顺序存储。查询用二分法就可以快速查询,时间复杂度是:O(log(N))

8.有序数组查询效率高,更新效率低 9.有序数组的适用场景:静态存储引擎。

10.二叉搜索树:每个节点的左儿子小于父节点,父节点又小于右儿子

11.二叉搜索树:查询时间复杂度O(log(N)),更新时间复杂度O(log(N))

12.数据库存储大多不适用二叉树,因为树高过高,会适用N叉树

*第二点:Innodb的索引模型介绍*

\1. InnoDB中的索引模型:B+Tree

2.索引类型:主键索引、非主键索引 主键索引的叶子节点存的是整行的数据(聚簇索引),非主键索引的叶子节点内容是主键的值(二级索引)

3.主键索引和普通索引的区别:主键索引只要搜索ID这个B+Tree即可拿到数据。普通索引先搜索索引拿到主键值,再到主键索引树搜索一次(回表)

\4. 一个数据页满了,按照B+Tree算法,新增加一个数据页,叫做页分裂,会导致性能下降。空间利用率降低大概50%。当相邻的两个数据页利用率很低的时候会做数据页合并,合并的过程是分裂过程的逆过程。

5.从性能和存储空间方面考量,自增主键往往是更合理的选择。

*问题:说说下面重建索引的一些方案是否合理?*

*1.重建k索引*

*alter table T drop index k;*

*alter table T add index(k);*

*2.重建主键索引*

*alter table T drop primary key;*

*alter table T add primary key(id);*

*重建索引 k 的做法是合理的,可以达到省空间的目的。但是,重建主键的过程不合理。不论是删除主键还是创建主键,都会将整个表重建。所以连着执行这两个语句的话,第一个语句就白做了。这两个语句,你可以用这个语句代替 : alter table T engine=InnoDB*

五、 深入浅出索引(下)

总结:

\1. 覆盖索引:如果查询条件使用的是普通索引(或是联合索引的最左原则字段),查询结果是联合索引的字段或是主键,不用回表操作,直接返回结果,减少IO磁盘读写读取正行数据

\2. 最左前缀:联合索引的最左 N 个字段,也可以是字符串索引的最左 M 个字符

\3. 联合索引:根据创建联合索引的顺序,以最左原则进行where检索,比如(age,name)以age=1 或 age= 1 and name=‘张三’可以使用索引,单以name=‘张三’ 不会使用索引,考虑到存储空间的问题,还请根据业务需求,将查找频繁的数据进行靠左创建索引。

\4. 索引下推:like 'hello%’and age >10 检索,MySQL5.6版本之前,会对匹配的数据进行回表查询。5.6版本后,会先过滤掉age<10的数据,再进行回表查询,减少回表率,提升检索速度

*问题:*

*CREATE TABLE geek (*

*a int(11) NOT NULL,*

*b int(11) NOT NULL,*

*c int(11) NOT NULL,*

*d int(11) NOT NULL,*

*PRIMARY KEY (a,b),*

*KEY c (c),*

*KEY ca (c,a),*

*KEY cb (c,b)*

*) ENGINE=InnoDB;*

*针对下面两条sql,以上那个索引可以不用,为什么*

*select * from geek where c=N order by a limit 1;*

*select * from geek where c=N order by b limit 1;*

*答案:ca索引可以不用,永久记住最左匹配,以最左为主*

六、 全局所有和表锁:给表加个字段有这么多障碍吗?

1. *MySQL从加锁范围上分为哪三类?*

全局锁、表级锁、行级锁

*2. 全局锁加锁方法的执行命令是什么?主要的应用场景是什么?*

flush tables with read lock 应用场景:全库逻辑备份

*3. 做整库备份时为什么要加全局锁?*

不加锁的话,系统备份得到的库,不是同一个逻辑时间点的,会导致数据不一致。

*4. MySQL的自带备份工具, 使用什么参数可以确保一致性视图, 在什么场景下不适用?*

使用参数:-single-transaction 只适用于所有表使用事务引擎的库,部分表使用的引擎不支持事务的话,不能用该方法。

*5. 不建议使用set global readonly = true的方法加全局锁有哪两点原因?*

① 有些系统用readonly判断是主库还是备库,修改这个值对整个系统影响太大;

② 如果客户端发生异常,数据库就会一直保持readonly,会导致长时间无法写入数据,风险很高。

*6. 表级锁有哪两种类型? 各自的使用场景是什么?*

①表锁。lock tables xxx read/write。数据库引擎不支持行锁时,才会用到表锁。

②元数据锁。MDL,分为MDL 读锁和 MDL 写锁。执行DML的时候,会申请 MDL读锁;执行DDL的时候,会申请 MDL写锁。

7. *MDL中读写锁之间的互斥关系怎样的?*

读读共享,读写互斥,写写互斥。

*8. 如何安全的给小表增加字段?*

①减少长事务,避免跟长事务竞争 MDL锁,如果获取 MDL写锁阻塞,会影响后面 MDL读锁获取,导致所有会话阻塞。

②Alter table语句,设置超时时间,超过时间未获取到 MDL写锁,则放弃,后面再进行重试,避免影响后面的会话。

问题:

备份一般都会在备库上执行,你在用–single-transaction 方法做逻辑备份的过程中,如果主库上的一个小表做了一个 DDL,比如给一个表上加了一列。这时候,从备库上会看到什么现象呢?

DDL binlog同步到备库后,此时备库有MDL读锁,而同步过来的DDL变更到备库上需要MDL写锁,那么这个DDL会被阻塞,所以该DDL不会反应在备份的数据里面。当使用该备份数据进行恢复时,由于加了一列,那么恢复会异常

七、 行锁的功过:怎么减少行锁对性能的影响?

\1. 行锁两阶段协议:不是事务开始的时候开启,而是语句执行的时候上锁

这个就涉及到插入和更新sql的先后顺序去优化减少锁冲突

\2. 死锁:互相持有对方资源

\3. 死锁检测优劣,怎么避免大量死锁检测、高并发下避免死锁检测带来的负面影响:

① 确保业务上不会产生死锁,直接将死锁检测关闭。(innodb 自带死锁检测)

② 在数据库中间件中统一对更新同一行的请求进行排队,控制并发度。

③ 业务逻辑上进行优化,将一行数据分解成多行,降低写入压力。

八、 事务到底是隔离还是不隔离?

\1. mysql中有两个视图的概念

① 一个是view 用来创建虚表

② 另一个一致性视图,主要用来解决rr和rc问题

  1. “快照”在 MVCC 里是怎么工作的?

参考事务隔离流程图

实战

一、唯一索引和普通索引怎么选?

1、唯一索引和普通索引怎么选?

① 查询情况下,普通索引和唯一索引性能都差不多,因为mysql以页形式读到内存,在内存判断是很快的

② 更新情况下,唯一索引没有用到change buffer,而普通索引有用到,因为唯一索引就一条记录,如果内存有,直接就可以在内存操作,就没必要用change buffer

③ chang buffer与merge结合使用,有change buffer如果数据不存在,就不用重新查磁盘,直接写入到change buffer,等一下次查询就合并磁盘和增量修改,或者定时merge增量修改

④ 所以怎么选,写入比较频繁的建议用普通索引,如果是写完马上读,会触发merge,io次数不会减少,反而增加change buffer维护代价

2、merge 的执行流程是这样的:

① 从磁盘读入数据页到内存(老版本的数据页);

② 从 change buffer 里找出这个数据页的 change buffer 记录 (可能有多个),依次应用,得到新版数据页;

③ 写 redo log。这个 redo log 包含了数据的变更和 change buffer 的变更。

问题:如果某次写入使用了 change buffer 机制,之后主机异常重启,是否会丢失 change buffer 和数据。

这个问题的答案是不会丢失,虽然是只更新内存,但是在事务提交的时候,我们把 change buffer 的操作也记录到 redo log 里了,所以崩溃恢复的时候,change buffer 也能找回来。

二、mysql为什么有时候会选错索引?

*1、为什么有时候mysql会选错索引?*

扫描的行数过多情况下,优化器会选择扫描全表而不用索引

*2、解决办法*

通过explain sql后发现选错索引,可以采取以下方式:

① 通过指定索引 force index

② 通过sql优化让其走预期的索引

③ 删除不必要的索引

备注:这种情况生产上是比较少发生,索引不必过多关注

三、怎么给字符串加索引?

*1.为什么需要优化字符串上的索引*

如果字符串较长,索引字段占用内存空间大,B+树高度较高,这样查询IO次数较多,耗时长。 个人认为未出现性能瓶颈,不需要过度优化,全字段索引也ok。

*2.优化方法及优缺点、适用场景*

方法一:前缀索引 概念:在建立索引的时候指定索引长度,且该长度的字段区分度高

优点:a. 相比全字段索引,每页存储的索引更多,查询索引IO次数少,效率高。即既节省了内存空间,又提高了查询效率。

缺点:

a. 指定索引长度的区分度低的话,扫描主键索引次数就会多,效率低;

b. 不会使用覆盖索引,即使索引长度定义为全字段,也会去主键索引查询 适用场景:前缀索引区分度高

方法二:倒序存储 概念:字段保存的时候反序存储 优点:同前缀索引

缺点:

a.只适用于等值查询,不适用于范围、模糊查询。

b.每次保存、查询时需调用reverse()函数;

c.若后缀索引区分度低,扫描行数会增多。 适用场景:索引字段后缀区分度高,前缀区分度低。

方法三:添加hash字段,作为索引 概念:在表中添加一个hash字段并加索引,用于存储索引字段的哈希值如使用crc32()哈希函数,每次查询时先计算出字段的hash值,再利用hash字段查询。可能存在hash冲突,所以where需要加索引字段字段的等值条件。

优点:哈希函数冲突概率低的话,平均扫描行数接近1。

缺点:只适用于等值查询,不适用于范围、模糊查询。 适用场景:只适用于等值查询,不适用范围查询或模糊查询。

四、为什么我的mysql会抖一下

*1、首先,理解一下什么是脏页,什么是干净页*

① 脏页:内存与磁盘的内容不一致的时候,我们称这个内存也就是脏页

② 干净页:内存写入磁盘后,内容一致了,该内存页就是干净页

深层理解:每个表都是一个ibd文件, 每个文件都是分成n个16kb的page,page是IO的基本单位, 也就是从硬盘到内存每次都载入一个page,所以用到的page既在内存也在硬盘ibd文件里. 在内存page上写写改改后, 这个page没写回ibd文件, 就成了脏页

2、*那么,什么时候会刷脏页呢?*

*redolog写满了*:redo log是在同一块地方进行循环的写,redo log记录的变动会被清除,在清除时可能redo log中有记录变更的数据还未刷入磁盘中,这时就得需要去判断这些变动的数据是否刷入磁盘,没有则进行刷脏页

*内存满了*:内存不够用的时候,就要淘汰一些数据页,空出内存给别的数据页使用。如果淘汰的是“脏页”,就要先将脏页写到磁盘

③ 系统空闲的时候

④ mysql正常关闭

说明第②点为什么要刷脏页:反证法->如果内存满了不刷脏页到磁盘中,下次请求磁盘中的干净页到内存时,还是要额外判断redolog是否对该也有修改,有修改的话还是要刷到磁盘中,这样还不如在内存满了的时候,直接将它刷到磁盘中

*3、InnoDB 刷脏页的控制策略?*

*影响因素有:*

\1. 脏页比例

\2. 脏页刷盘速度

\3. 刷新相邻页面策略 (bufferpool脏页比例 或 redolog 都可能成为读写sql的瓶颈)

*参数控制:*

\1. 脏页比例默认75%,一定不要让其接近75%=脏页/总页

\2. 刷脏页速度 innodb_io_capacity定义的能力乘以R%来控制刷脏页的速度

\3. innodb_flush_neighbors=0(不开启脏页相邻淘汰) (对于机械硬盘顺序读写会有提升,ssd无提升,mysql8直接默认不开启)

\4. 避免大量刷脏页,脏页flush可能会产生内存抖动

五、为什么数据删减一半,表文件大小不变?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/54494.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于ssm+vue德云社票务系统源码和论文

基于ssmvue德云社票务系统源码和论文063 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 1.选题的依据和意义 互联网时代&#xff0c;随着生活节奏的加快和不断上升的压力&#xff0c;人们急需寻找到情绪的宣泄…

docker第二次作业

1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘。 拉取镜像 docker pull mysql:5.6 docker pull ow ncloud 运行镜像生成容器 [rootharbor ~]# docker run -d --name mydb1 --env MYSQL_ROOT_PASSWORD123456 mysql:5.6 [rootharbor ~]# docker run -d --name…

Axure RP软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Axure RP是Axure公司开发的一款原型设计工具&#xff0c;广泛应用于产品设计和UI/UX设计领域。以下是Axure RP软件的主要特点和功能&#xff1a; 原型设计&#xff1a;Axure RP提供了丰富的界面元素和交互元素&#xff0c;用户…

THINKPHP 微联云投票系统源码独立版 + 支持刷礼物

THINKPHP 微联云投票系统源码独立版 支持刷礼物 nginxphp7.2以上 mysql5.6以上 简单测试后台基本没什么问题&#xff0c;暂时发现H5前端有bug,自行修复。

VS2022 C++修改Window系统DNS源代码V2.0

这是自己使用VS2022 C++编写开发的Window系统下修改DNS脚本程序第2个版本,适合Win10系统和Win7系统。cfg.txt文件存放要修改的DNS,最多4个。 详细源代码如下: setdns.cpp /* 1.全部清空DNSstring strParameter;strParameter = "netsh interface ip delete dns name=\…

苹果新健康专利:利用 iPhone、Apple Watch 来分析佩戴者的呼吸情况

根据美国商标和专利局&#xff08;USPTO&#xff09;公示的清单&#xff0c;苹果获得了一项健康相关的技术专利&#xff0c;可以利用 iPhone、Apple Watch 来分析佩戴者的呼吸系统。 苹果在专利中概述了一种测量用户呼吸功能的系统&#xff0c;通过 iPhone 上的光学感测单元&am…

Linux Shell 搜索命令 grep

grep 是一个强大的文本搜索工具&#xff0c;用于在文件或标准输入中查找匹配指定模式的行。 它的基本语法是&#xff1a; grep [options] pattern [file...]其中&#xff0c;pattern 是要搜索的模式&#xff0c;可以是普通字符串或使用正则表达式表示的模式。file 是要被搜索…

6. 使用python将多个Excel文件合并到同一个excel-附代码解析

【目录】 文章目录 6. 使用python将多个Excel文件合并到同一个excel-附代码解析1. 目标任务2. 结果展示3. 代码示例4. 代码解析4.1 导入库4.2 调用库的类、函数、变量语法4.3 os.listdir-返回目录中的文件名列表4.4 startswith-用于判断一个字符串是否以指定的前缀开头4.5 ends…

Class ‘com.xxxx.Log‘ was compiled with an incompatible version of Kotlin.

Class com.xxxx.Log was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.7.1, expected version is 1.5.1. 原因&#xff1a;在build.gradle中使用了1.5.30版本的kotlin插件&#xff0c;与第三方库中的kotlin插件版本不同&#…

如何在Ubuntu 18.04上安装PHP 7.4并搭建本地开发环境

引言 PHP是一种流行的服务器脚本语言&#xff0c;用于创建动态和交互式web页面。开始使用你选择的语言是学习编程的第一步。 本教程将指导您在Ubuntu上安装PHP 7.4&#xff0c;并通过命令行设置本地编程环境。您还将安装依赖管理器Composer&#xff0c;并通过运行脚本来测试您…

React 使用 useRef() 获取循环中所有子组件实例

目录 背景思考实现完整代码&#xff1a;成功运行后的界面如下&#xff1a; 知识点总结uesRef() 作对象处理useImperativeHandle() 父组件操作引入子组件的内部方法最后 背景 之前项目中使用了antd pro 中的 可编辑表格 (EditableProTable)&#xff0c;在页面中表格要经过多层遍…

vue实现表格的动态高度

需求:表格能够根据窗口的大小自动适配页面高度 防抖和节流函数的使用场景是当需要对频繁触发的事件进行限制时,例如: 防抖函数常用于限制用户在短时间内多次触发某一事件,例如搜索框输入并搜索,当用户一直在输入时,我们可以使用防抖函数来避免多次请求搜索结果,减轻服…

Http与Https

1.简单介绍 HTTP&#xff1a;最广泛应用的网络通信协议&#xff0c;基于TCP&#xff0c;数据传输简单高效&#xff0c;数据是明文。 HTTPS&#xff1a;是HTTP的加强版&#xff0c;是HTTPSSL。在HTTP的基础上加了安全机制&#xff0c;一方面保证数据的安全传输&#xff0c;另一…

【UniApp开发小程序】私聊功能后端实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】

声明 本文提炼于个人练手项目&#xff0c;其中的实现逻辑不一定标准&#xff0c;实现思路没有参考权威的文档和教程&#xff0c;仅为个人思考得出&#xff0c;因此可能存在较多本人未考虑到的情况和漏洞&#xff0c;因此仅供参考&#xff0c;如果大家觉得有问题&#xff0c;恳…

【Flutter】Flutter 使用 infinite_scroll_pagination 实现无限滚动分页

【Flutter】Flutter 使用 infinite_scroll_pagination 实现无限滚动分页 文章目录 一、前言二、安装和基本使用1. 添加依赖2. 基础配置和初始化 三、实际业务中的用法1. 与 API 集成2. 错误处理 四、完整示例1. 创建一个无限滚动列表2. 使用在你的应用中3. 完整代码示例 五、总…

VSCode如何为远程安装预设(固定)扩展

背景 在使用VSCode进行远程开发时&#xff08;python开发之远程开发工具选择_CodingInCV的博客-CSDN博客&#xff09;&#xff0c;特别是远程的机器经常变化时&#xff08;如机器来源于动态分配&#xff09;&#xff0c;每次连接新的远程时&#xff0c;都不得不手动安装一些开…

Unity - MenuItem特性

MenuItem(string itemName, bool isValidateFunction, int priority) 参数1&#xff1a;菜单名 参数2&#xff1a;是否使用自定义条件控制菜单项是否可点击&#xff0c;默认为false&#xff0c;一般不赋值&#xff0c;需要用的话需要定义两个MenuItem MenuItem 1 : 自定义条件…

Springboot_Redis

Springboot默认使用lettuce操作redis,底层是netty jdeis并发差些 Redis的Template 分为两种, 一种是StringRedisTemplate&#xff0c;另一种是RedisTemplate 根据不同的数据类型&#xff0c;大致的操作也分为这5种&#xff0c;以StringRedisTemplate为例 stringRedisTempla…

软件设计师学习笔记5-流水线技术

目录 1.流水线的概念 2.流水线计算 2.1流水线周期及执行时间 2.2流水线吞吐量 1.流水线的概念 考点&#xff1a;相关参数计算&#xff1a;流水线执行时间计算、流水线吞吐率、流水线加速比、流水线效率(后两者的计算中级不考) 流水线是指在程序执行时多条指令重叠进行操作…

聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化

聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化 目录 聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化&#xff0c;聚类结果可视化&#xff0c;MATLAB程…