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,自行修复。

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

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

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…

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

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

vue实现表格的动态高度

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

【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程…

Maven的超级POM

对于我们创建的一个maven工程&#xff0c;即便我们自己的pom.xm文件中没有明确指定一个父工程&#xff08;父POM&#xff09;&#xff0c;其实也默认继承了超级POM&#xff0c;就好比JAVA类继承Object类一样。 maven官网关于超级POM的介绍&#xff1a; https://maven.apache.o…

MyBatis plus 多数据源实现

1. 项目背景 最近写文章发布到【笑小枫】小程序和我的个人网站上&#xff0c;因为个人网站用的是halo框架搭建&#xff0c;两边数据结构不一致&#xff0c;导致我每次维护文章都需要两边维护&#xff0c;这就很烦~ 于是&#xff0c;本文就诞生了。通过项目连接这两个数据库&a…

左偏树\可并堆

https://www.luogu.com.cn/problem/P3377 作用&#xff1a;可并堆 形态&#xff1a;堆满二叉树 即左节点最小深度大于等于右节点最小深度 合并过程&#xff1a;

Scikit-learn降维与度量学习代码批注及相关练习

一、代码批注 代码来自&#xff1a;https://scikit-learn.org/stable/auto_examples/decomposition/plot_pca_iris.html#sphx-glr-auto-examples-decomposition-plot-pca-iris-py import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes…

idea连接linux远程docker详细教程操作

1&#xff1a;修改docker配置文件docker.service vi /usr/lib/systemd/system/docker.service2&#xff1a;找到 ExecStart&#xff0c;在最后面添加 -H tcp://0.0.0.0:2375 # for containers run by docker ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/…