丁奇mysql学习笔记-基础篇

2023-11-04

一、 mysql的逻辑架构

① 问题解决

如果表 T 中没有字段 k,而你执行了这个语句 select * from T where k=1, 那肯定是会报“不存在这个列”的错误: “Unknown column ‘k’ in ‘where clause’”。你觉得这个错误是在我们上面提到的哪个阶段报出来的呢

答案:分析器,分析器会判断表是否存在,字段是否存在

② 当我们在一张表更新的时候,跟这张表有关的查询缓存都会被清空,所以不建议使用查询缓存。MySQL 8.0 版本直接将查询缓存的整块功能删掉了,也就是说 8.0 开始彻底没有这个功能了,如果不需要这个功能可以将参数 query_cache_type 设置成 DEMAND。

③ 一条select语句执行就是上面的从上往下的流程

二、一条SQL更新语句是如何执行的

更新语句除了上面的逻辑架构层的处理,还需要两个走两个重要的日志模块。

① redo log 重做日志

重做日志是innoDB存储引擎存产生的。

InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB

redo log是记录的是页上面的修改,binlog则是类似于sql语句一样的逻辑日志

② 更新流程

当执行一条update语句,数据库会先把更新记录写入到redo log里并更新内存数据,这时候更新就算完成了,同时innoDB会在适当的时候,将redo log批量刷新到磁盘中。这样做的好处就是:操作都在内存,减少磁盘读写的IO。

 update T set c=c+1 where ID=2;

执行上面的sql语句流程如下

1) 执行器先到内存中找有没有id = 2的数据,如果没有则到引擎层取出 

2) 执行器拿到数据并 计算 c = c+1,得到新的一行数据,再调用新的引擎接口写入这行数据

3) InnoDB存储引擎将数据更新到内存中,同时将这个更新操作写入redo log中,此时redo log处于prepare 状态,然后告知执行器执行完成,随时可以提交事务 

4) 执行器生成这个操作的binlog,并把binlog写入磁盘

5) 执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log的状态改成提交(commit)状态,更新完成

③ 参数innodb_flush_log_at_trx_commit

redo log 用于保证 crash-safe 能力。innodb_flush_log_at_trx_commit 这个参数设置成 1 的时候,表示每次事务的 redo log 都直接持久化到磁盘。这个参数我建议你设置成 1,这样可以保证 MySQL 异常重启之后数据不丢失。 

④ sync_binlog

sync_binlog 这个参数设置成 1 的时候,表示每次事务的 binlog 都持久化到磁盘。这个参数我也建议你设置成 1,这样可以保证 MySQL 异常重启之后 binlog 不丢失 

三、索引 

① 覆盖索引

② 最左前缀原则

③ 索引下推 

索引下推也是建立在复合索引下面的,索引index(a, b)  select * from t where a=10 AND b = 2; mysql不会根据index索引先找到a = 10的数据回表判断b = 2的数据,而是先找到a = 10和b = 2的再去回表

④ mysql选错索引

对于由于索引统计信息不准确导致的问题,你可以用analyze table来解决。 而对于其他优化器误判的情况,你可以在应用端用force index来强行指定索引,也可以通过修改 语句来引导优化器,还可以通过增加或者删除索引来绕过这个问题

四、redo log重做日志 

① 脏页刷新到磁盘的情况

1)redo log日志满了,必须要刷新脏页,给redo log腾出空间

2)内存满了,因为脏页的数据都是放到内存的,需要给innoDB pool腾出空间

3)   Master Thread Checkpint 线程会定时去刷新脏页

4)mysql关闭,脏页会刷新到磁盘

②刷新脏页的控制参数

innodb_io_capacity 读写磁盘的能力 这个值表示innodb读写磁盘的能力(IOPS),可以用工具测试出来

innodb_max_dirty_pages_pct 脏页的比例上限 可以看Mysql5.7 checkpoint和LSN_天道酬勤-明天会更好的博客-CSDN博客

这个最下面的统计到,数据库实际的比例 

五、 删除数据,mysql的储存大小没有变小

① delete 删除数据后,表的存储为什么没有变小,

mysql的存储都是以页为单位的。删除一条记录,就会产生复用的记录,而删除多条记录,假如删除了一页的数据,则会产生复用的数据页,这些页并没有被mysql释放,而是当做备用的复用页,等待下次的数据使用。 

② 怎么让数据表数据得到实际大小了

执行 alter table y engine=InnoDB;

原理是:建立一张新的表,然后把数据移动到新表,然后改名;

MySQL 5.6版本前不能在线操作,如果online DDL 会造成数据流失,因为在移动数据时,可能有新的数据添加到旧表。

MySQL 5.6版本后就优化了,可以online DDL,因为在移动的数据时,如果有数据进行了更新,会记录日志,等数据移动完了,在用日志更新。

六、sql没有走索引分析

① 隐式类型转换 

select * from tradelog where tradeid=110717;

如果tradeid是字符串且有索引,当执行上面的sql,数据库不会走索引。是因为mysql会默认把上面的sql转换成

 select * from tradelog where CAST(tradid AS signed int) = 110717;

这种左边有函数的where查询时不走索引的。 

 ② 隐式字符编码转换

做表连接查询的时候用不上关联字段的索引。

如果两个表的字符集不同,一个是utf8,一个是 utf8mb4,做表连接查询的时候会关联不上字段的,内部mysql会进行字符集转码。

七、 查看MDL锁 

 lock table x write;会加一个MDL的写锁;

select查询会产生一个MDL的读锁,所以session B会有阻塞。

可以通过

select blocking_pid from sys.schema_table_lock_waits\G

 找到processlist的id,然后kill 杀掉。

mysql7.22版本后才有MDL的锁记录到schema_table_lock表中。

如果大于mysql7.22版本没有记录,需要配置 vim /etc/my.cnf

performance-schema-instrument='wait/lock/metadata/sql/mdl=ON'

在线开启,但这种方式是临时生效,实例重启后,又会恢复为默认值。

UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME = 'wait/lock/metadata/sql/mdl';

八、解决幻读带来的锁(隔离级别是RR)

幻读是:在同一个事务中,同一个SQL查询范围,后查询的看到前查询没有的行。

幻读指的是一个事务在前后两次查 询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。(这个是比较经典的)

为了解决幻读mysql引用了Gap锁和Next-key Lock,怎么理解了。



*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `c` (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.01 sec)

(root@localhost) [test]> select * from t;
+----+------+------+
| id | c    | d    |
+----+------+------+
|  0 |    0 |    0 |
|  5 |    5 |    5 |
| 10 |   10 |   10 |
| 15 |   15 |   15 |
| 20 |   20 |   20 |
| 25 |   25 |   25 |
+----+------+------+
6 rows in set (0.00 sec


id是主键,c是普通索引,d没有索引

① begin; select * from t where id = 5 for update;

不会有Gap 锁和 next-key锁,因为id是唯一的,上面的sql会加入一个主键行锁,插入id = 5是不可以的。

② begin; select * from t where c = 5 for update;

会有一个Gap锁和next-key锁, next-key锁是 ( 0, 5 ],  Gap锁是 ( 5, 10 )

我们可以反向思考:我们执行下面的sql,假如成功了,就会产生幻读,这是不允许的。

insert into t value (100, 5, 5);

那么为什么还有范围了( 0, 5 ] 和  ( 5, 10 )了,这是根据二级索引来的,

当我们插入c = 5时,需要添加到二级索引,二级索引的存储是(二级索引,主键索引)

(0,0) (5,5) (10,10) (15,15) (20,20) (25,25)这样的,所以数据有可能是插入到 (5,5) 的左边和右边,所以这样是不允许的,所以要加上( 0, 5 ] 和  ( 5, 10 )范围了,这是我的理解哈,

 ③ begin; select * from t where d = 5 for update;

 我们假设执行下面的sql

insert into t value (N, N, 5);

是不是都会产生幻读了,所以上面的sql会有所有主键的Gap锁,就是什么数据都插入不了

 九、锁的规则

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

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

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

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

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

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

上面的原则和优化是需要理解的,可以看一下丁奇的21讲案例说明。

十、读写分离数据不一致怎么处理

mysql的一主多从的架构,一般是master写,多个从机读,一般采用半复制的模式;

在多个从机读的时候就有可能会产生过期读,即写的数据,从机还没有同步,读出来的数据不一致的问题。

会有下面的这几个方案

①强制走主库方案;

需要查询同步的sql就放到master主机查询,不着急的放到slave备机查询

② sleep方案;

要同步查询的sql可以,休眠1s再查询

③ 判断主备无延迟方案;

就是下面的主库点位的方案

④配合semi-sync方案;

半同步的方案,多个从机读的话,可能只有一台从机是无损同步了

⑤等主库位点方案;

1. trx1事务更新完成后,马上执行showmaster status得到当前主库执行到的File和Position;

2. 选定一个从库执行查询语句;

3. 在从库上执行select master_pos_wait(File, Position, 1);

4. 如果返回值是>=0的正整数,则在这个从库执行查询语句;

5. 否则,到主库执行查询语句。

⑥等GTID方案。

1. trx1事务更新完成后,从返回包直接获取这个事务的GTID,记为gtid1;

2. 选定一个从库执行查询语句;

3. 在从库上执行 select wait_for_executed_gtid_set(gtid1, 1);

4. 如果返回值是0,则在这个从库执行查询语句;

5. 否则,到主库执行查询语句 

select wait_for_executed_gtid_set方法很好用,其实就是判断传入的gtid和当前的gtid对比,返回0则表示,从库已经执行了这个gtid对应的事务。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

丁奇mysql学习笔记-基础篇 的相关文章

  • 这个 SQL DELETE FROM 语法有什么问题?

    我正在尝试删除 96k 记录 删除表 xoops bb posts text 页面中没有与 xoops bb posts 匹配的 post id 的所有记录 此查询返回 91k 条记录 SELECT FROM xoops bb posts
  • 使用 Hibernate 在 MySQL 中存储字节数组

    我正在尝试保存带有字节数组字段的实体 我在 MySQL 数据库之上使用 Hibernate 和 JPA 这是字段定义 对于嵌入式 H2 数据库来说效果很好 Entity name blob public class Blob Lob Bas
  • Mysql - Mysql2::错误:字符串值不正确:

    所以我建造了一个刮刀并拉动一些物体 问题是有些是外语 它使 mysql 数据库有点崩溃 这是我得到的错误 知道我能用这个做什么吗 谢谢 Mysql2 错误 列的字符串值不正确 xC5 x8Dga 第 1 行的 描述 插入sammiches
  • SQL 检查一组日期是否在指定的日期范围内

    我有一个表 其中保存架构中房间不可用的日期 ROOM ID DATE UNAVAILABLE 我需要一个 sql 查询来检查两个日期范围内是否有可用房间 类似于 Select All rooms that are constantly av
  • MYSQL 查询返回“资源 id#12”而不是它应返回的数值

    不知道为什么 但这返回了错误的值 我正在取回此资源 ID 12 而不是我正在寻找的数值 1 执行此操作的代码是 type SELECT account type from user attribs WHERE username userna
  • MySQL InnoDB 查询性能

    我正在尝试优化一个简单的 sql 查询 该查询将多次运行大量数据 这是场景 MySQL 与 InnoDB 表 where 和 join 中使用的所有字段都已索引 表有 FK 我不需要查询的整个缓存 但每个表的缓存是可能的 表有更多的更新 插
  • mysql语句中的*星号是什么意思?

    Ex mysql query SELECT FROM members WHERE id id 这意味着选择表中的所有列
  • C#:SQL 查询生成器类

    在哪里可以找到好的 SQL 查询构建器类 我只需要一个简单的类来构建 SQL 字符串 仅此而已 我需要它用于 C 和 MySql 我真的不需要像 Linq 或 NHibernate 这样的东西 谢谢 由于 Google 将我引导至此页面 我
  • 在docker中使用MySQL数据库设置aspnetcore

    我正在尝试设置一个 docker compose 文件 其中包含 asp net core mysql 数据库和 phpmyadmin 的容器 设置我的 mysql 服务器没有问题 我可以使用 phpmyadmin 访问它 我的 asp n
  • MySQL 全文搜索不适用于某些单词,例如“house”

    我已经在 3 个字段中的一小部分记录上设置了全文索引 也尝试了 3 个字段的组合 并得到了相同的结果 有些单词返回结果很好 但某些单词如 house 和 澳大利亚 不这样做 有趣的是 澳大利亚 和 家乡 这样做 这似乎是奇怪的行为 如果我添
  • 使用按位函数查询 BIT 字段时,MySQL 不使用索引

    我的 MySQL 表中有一个 BIT 类型的字段 我想使用位值存储记录的状态 例如 1 status1 2 status2 4 status3 8 status4 每条记录可以同时具有多种状态 对于 status1 和 status3 该值
  • 将记录分成两列

    我的数据库中有一个 学生 表 其中包含大约 5 000 条记录 我想将这些记录显示在two分区 如何在不执行查询两次的情况下做到这一点 仅使用单个查询 显示示例http www freeimagehosting net uploads f1
  • 如何在 phpmyadmin 中创建 MySQL 触发器

    我想在 MySQL 中创建一个触发器 我运行以下命令 mysql gt delimiter mysql gt CREATE TRIGGER before insert money BEFORE INSERT ON money gt FOR
  • Mysql innoDB 不断崩溃[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我的数据库 mysql 服务器不断崩溃 重新启动 我不知道该怎么办 我不断在 dbname org err 文件中收到以下内容 13120
  • PDO SQLSRV 和 PDO MySQL 在获取 int 或 float 时返回字符串

    当您获取时 PDO MS SQL Server 和 PDO MySQL 都会返回一个字符串数组 即使列的 SQL 类型本应是数字类型 例如 int 或 float 我设法解决了这个问题 但我想了解为什么它们一开始就这样设计 是不是因为PDO
  • 无法启动 MySQL 服务器 - 控制进程退出并出现错误代码

    我的 mysql 服务器停止后无法启动 命令使用 sudo etc init d mysql restart Error 重新启动 mysql 通过 systemctl mysql serviceJob for mysql service
  • Hibernate 对集合的查询过滤器

    我想执行以下查询 from Item i where i categoryItems catalogId catId 然而 这会产生以下异常 非法尝试取消引用集合 所以我用谷歌搜索 找到了这个 Hibernate 论坛帖子https for
  • 使用 PHP 的 MySQL 连接字符串

    我正在尝试通过本地计算机连接到托管在我的服务器上的数据库 我的服务器有cPanel 11 它是一个典型的共享服务器 由CentOS提供支持 安装了PHP和MySQL 准确地说 我在同一台服务器上持有经销商帐户 我想在不同帐户或域之间访问数据
  • Mysql 中 UNION 子句的替代方案

    我有两张桌子 表 a 表 b table a ID 1 2 3 4 5 7 table b ID 2 3 4 5 6 我必须得到这样的输出而无需UNION命令 ID 1 2 3 4 5 6 7 注意 我有一个联合解决方案 select fr
  • MySQL 按重复项从上到下排序

    我有一个lammer问题 因为我不是mysql专业人士 我有类似的字段 id color 1 red 2 green 3 yellow 4 green 5 green 6 red 我想按重复项进行分组 最常见的重复项先进行分组 所以应该这样

随机推荐

  • OpenCV代码提取 warpPerspective函数的实现

    For perspective transformation you need a 3x3 transformation matrix Straight lines will remain straight even after the t
  • 万众瞩目,谷歌的反击来了!全新PaLM 2反超GPT-4,办公全家桶炸裂升级,Bard史诗进化...

    Datawhale干货 最新 谷歌 PaLM 2 来源 量子位 万众瞩目 谷歌的反击来了 现在 谷歌搜索终于要加入AI对话功能了 排队通道已经开放 当然这还只是第一步 大的还在后面 全新大语言模型PaLM 2正式亮相 谷歌声称它在部分任务超
  • python 贪心算法解决找零钱问题

    target 99 找零钱目标数 money 5 29 10 5 2 1 纸币种类 number 0 0 0 0 0 0 纸币种类 for i in range 6 排循环 从最大面值开始考虑 number i target money i
  • 利用nodemcu和mqtt协议让嵌入式设备接入互联网(三.实现数据交互)

    文章目录 前言 KOA2框架 koa2初步使用 koa示例代码解释 koa static中间件 Aedes mqtt协议 用aedes创建broker并测试 MQTT server over WebSocket http协议和websock
  • 从开源组件安全看SCA软件成分分析技术

    1 基本概念 软件成分分析 SCA Software Composition Analysis 是一种对二进制软件的组成部分进行识别 分析和追踪的技术 专门用于分析开发人员使用的各种源码 模块 框架和库 以识别和清点开源软件 OSS 的组件
  • 2020美赛F奖论文(三):足球团队指标和基于机器学习的球队表现预测

    上接 2020美赛F奖论文 二 传球网络模型 PNM 的建立和影响因子分析 全文 2020美赛F奖论文 一 摘要 绪论和模型准备 2020美赛F奖论文 二 传球网络模型 PNM 的建立和影响因子分析 2020美赛F奖论文 三 足球团队指标和
  • 全面总结sizeof的用法(定义、语法、指针变量、数组、结构体、类、联合体、位域位段)

    一 前言 编译环境是vs2010 32位 span style font size 18px include span
  • 微信小程序图片自适应大小(炒鸡详细)

    开发小程序图片是非常重要的部分 小程序开发想要提升用户的体验感图片是必不可少的部分 因此对图片的各种操作也是咱不可或缺的技能 我遇到的坑 本来想放入一张好看的图片
  • 设计模式对程序员的必要性

    其实设计模式的应用基础是面向对象的程序设计方法 没有面向对象的理论 设计模式的实现就没有了基础 可能从方法论的角度说 设计模式是一种思想和具体的程序设计语言没有必然的联系 可软件最终还是要通过代码来实现 不同的语言体现了对面向对象理论的不同
  • Mybatis读取和存储json类型的数据

    目录 一 测试使用JSONObject来获取json 二 设置 TableName的autoResultMap为true TableField的typeHandler为JacksonTypeHandler class 三 设置xml当中的r
  • 3个权威免费资源下载网站!

    hello大家好 这里是预计今天可以到家的老Y工作室 因为这几天在出差 也没花太多时间帮大家搜罗一些好玩有趣的网站 等回家后 会把补一些软件和教程 有朋友之前问老Y有没有免费的标准下载网站或者查询 于是老Y找了3个给有需要的朋友分享一下 0
  • Redis初级篇

    Redis 视频地址 https www bilibili com video BV1Rv41177Af p 38 资料地址 https pan baidu com s 1GxYRq5UkZHKhk3KB0nOioQ q7vj 概述 Red
  • Windows C++多线程:生产者消费者模型编程

    Windows C 多线程 生产者消费者模型编程 生产者消费者模型是一种常见的并发编程模型 用于解决生产者和消费者之间的数据交互问题 在这个模型中 生产者负责生成数据并将其放入共享的缓冲区 而消费者则从缓冲区中获取数据进行处理 在Windo
  • 软件项目管理

    一 填空题 1 项目是为创造独特的产品 服务或成果而进行的临时性的工作 2 PMBOK 2016 将项目管理分为五个过程组 即启动 计划 执行 控制和收尾 与十大知识领域 整合管理 范围管理 时间管理 成本管理 质量管理 人力资源管理 沟通
  • 如何申请国内博士

    博士申请过程还算平坦 在申请过程中得到了很多学长学姐的帮助 为了将这份帮助传递下去 我便将我的经历写下来 希望可以帮到一些同学 先介绍一下自己的情况 专业是计算机 研究方向是深度学习 机器视觉 硕士是一所排名较低的211 博士最终申请的学校
  • Lodash 总结

    数组 数组创建 随机创建数组 range range start 0 end step 1 let arr range 24 console log arr 0 1 2 3 23 创建相同元素数组 fill fill array value
  • 数据通信-路由基础

    1 IP路由选择原理 路由器的工作内容 路由器知道目标地址 发现到达目标地址的可能的路由 选择最佳路径 路由表 维护路由信息 转发IP数据 IP路由表 初始化情况下 路由器所知的网段 只有其直连接口所在网段 路由器自动将接口所在网段的路由写
  • 【注意】Kafka生产者异步发送消息仍有可能阻塞

    文章目录 问题描述 原因分析 解决办法 总结 问题描述 Kafka是常用的消息中间件 在Spring Boot项目中 使用KafkaTemplate作为生产者发送消息 有时 为了不影响主业务流程 会采用异步发送的方式 如下所示 Slf4j
  • GIS 图层

    GIS图层 从直观的角度看 就是按某种属性对数据分为若干文件 比如铁路L 公路 城市道路 乡村道路 分成若干层 从开发的角度 图层对应一张数据库表 这张表可能存在数据库中 也可能存在GIS相关文件中 图层包含要素 要素对应一条记录 做开发时
  • 丁奇mysql学习笔记-基础篇

    一 mysql的逻辑架构 问题解决 如果表 T 中没有字段 k 而你执行了这个语句 select from T where k 1 那肯定是会报 不存在这个列 的错误 Unknown column k in where clause 你觉得