谈谈MySQL的底层存储

news2024/11/27 0:48:46

这个题目启的很大,但其实只是最近在复习MySQL知识的一点心得,比较零散。

更新数据时,底层page的变化

下面这个图,我还需要解释么?
在这里插入图片描述
上面的绿色是b+数的索引块,分别说明了101号page的最大id是7,102号page的最大id是12
底下的蓝色块是b+数的叶子节点,使用聚簇索引的组织形式。在每个page里面以记录的id为序顺序存储了记录的所有数据。
那我现在问一个问题,假如我现在更新id为6的记录的某个字段,之后b+数是什么样子。
好了别猜了,更新后的数据图如下:
在这里插入图片描述
如上图,我们假定id6的记录更新后,数据记录膨胀了,那mysql就会把原来的pageNo101的数据都读出来,更新完之后,重新申请新的page,然后再写入。
假如记录缩短了,还需要重新申请一个新的page在写入么?还是说直接原地更新?
答案是原地更新。
还有一个问题,假定我先给某个page里面写了id为1和5的数据,然后又写了id为3的数据(暂时不要管为什么id乱序了)那么page里面的数据会怎么变呢?换句话说在一个page内部记录是使用顺序存储还是链式存储呢?
在这里插入图片描述
其实就是上面的图,新加入的3是跟在5后面写入然后使用链表维护先后关系(上图中间的示意),还是整体先把101page读到内存,加入id为3的数据后,进行排序然后再整体写入新的page呢(上图右边的示意,也就是说page内部是绝对的顺序存储)?
答案是上图右边的示意,也就是说整体先读入内存,然后内存整理好了之后,再顺序写入磁盘(当然此时也有可能没有申请新的page,直接写到原来的page101也是有可能的)

有朋友说,那上面的写放大岂不是很大?
理论上是的。但是其实不是问题,为什么?原因见后面的随机写入一节。
另外,就上面那个图,page104里面空了很大空间怎么办?
mysql后面肯定会进行page整理的,如果相邻的两个块里有效数据变短了(包括update甚至直接delete),那mysql自然就会merge两个page为一个新的page。

分表后的主键策略

我们知道,InnoDB为每个表构建索引的时候,是使用表的主键来做索引的。一般情况我们都会为表指定一个不会出现重复数据的字段为主键。当然即使你不指定,系统也会为你默认来一个。
ok,在一个物理表表内部,我们大家都是默认存在一个唯一的主键。
那么假定数据急剧膨胀,我把一个逻辑表拆分成了1024个物理子表。那么这个时候,表1和表2的主键可以重叠么?
我个人认为可以重叠也可以不重叠。(当然在某个具体的物理子表内部,主键肯定是不能重复的)

  • 为什么说可以重叠呢?
    因为从mysql的角度来讲,那两个物理子表是没有任何关系,两个表的b+索引也是没有任何关系的,mysql并没有强制要求两个表的主键一定不能重叠。
    那既然没有禁止重叠,那我自然就可以重叠么。

  • 另一种说法是尽量不要重叠。
    为啥?因为这样业务更方便处理。

其实多个表不重叠,从业务层来说自然是更好的,但是为了保证全局不重复,还是需要一些额外的技术方案的。例如淘宝的tddl-sequence或者SnowFlake雪花算法等等。

随机写入(更新的写放大问题)

在上面那一节说的,假定我要求业务的各个分表的主键不能重复,也就是我需要全局唯一,那每个表的主键就不能设置成自增,那每次insert的时候,id我就得指定。

假如我使用tddl-sequence的方案,一共有5个应用服务器。服务器A使用0-99号段,服务B使用100-199号段。。。。
假定5个应用服务器此时收到的请求,最终数据都落到了相同的某一个物理表上。
那再负载均衡的情况下,那个表收到的id 就有可能是0,100,200,300,400,1,101,201,301,401。。。。
那大家想想,底层的叶子节点的数据岂不是要一直变动。
其实上面的前置条件就构造的很没有必要,用户对表的update本身就是完全无序的。用户就是完全无顺序的更新任意的数据,那写放大怎么办?

我上面的各种读写例子都是完全基于磁盘的,但是我问大家一个例子。难道mysql是每收到一个请求都需要数据立刻落盘然后再返回给用户结果么?这个延迟大家有想过么?
答案是不言而喻的,数据肯定是先在内存里然后才写到磁盘的。
这个内存的大于,就是mysql的bufferPoolSize 那这个值一般会设置多少呢?
对于真实的db服务器(也就是说这个机器上,只有mysql,不再部署别的应用服务),我查询到的bufferpool一般是物理机内存的60%-80%。
知道了有这么大的bufferpool,那你还担心什么。以上面的例子为准,虽然mysql收到的请求0,100,200,300,400,1,101,201,301,401。。。 但是最终写入的时候 相邻的数据量早都凑够了一个page的大小了。
看看下面几个命令

show variables like 'innodb_buffer_pool_size';
show variables like 'Innodb_buffer_pool_pages_data';
show variables like 'Innodb_buffer_pool_pages_total';

这些参数的意义如下:

Innodb_buffer_pool_pages_data:缓存池中包含数据的页的数目,包括脏页。单位是page。
Innodb_buffer_pool_pages_dirty:缓存池中脏页的数目。单位是page。
Innodb_buffer_pool_pages_flushed:缓存池中刷新页请求的数目。单位是page。
Innodb_buffer_pool_pages_free:剩余的页数目。单位是page。
Innodb_buffer_pool_pages_misc:缓存池中当前已经被用作管理用途或hash index而不能用作为普通数据页的数目。单位是page。
Innodb_buffer_pool_pages_total:缓冲池的页总数目。单位是page。

我自己机子上的mysql配置如下:BufferPool 是默认的128MB
在这里插入图片描述
咱们看看一共8192个page,使用了1152个page 使用率14%,嗯bufferpoolsize还是够的。
另外 总共128MB的size,单个page16KB,那算下来一共也就是8192个page,嗯数据是能对得上的。

参考资料

https://blog.csdn.net/qq_41044636/article/details/123483334
https://blog.csdn.net/wzngzaixiaomantou/article/details/121064577
https://blog.csdn.net/wangqinyi574110/article/details/131984748

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

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

相关文章

ACM MM 2023 | 清华、华为联合提出MISSRec:兴趣感知的多模态序列推荐预训练

©PaperWeekly 原创 作者 | 王锦鹏 单位 | 清华大学深圳国际研究生院 研究方向 | 多模态检索、推荐系统 序列推荐是一种主流的推荐范式,目的是从用户的历史行为中推测用户偏好,并为之推荐感兴趣的物品。现有的大部分模型都是基于 ID 和类目等信息做…

相机滤镜软件Nevercenter CameraBag Photo mac中文版特点介绍

Nevercenter CameraBag Photo mac是一款相机和滤镜应用程序,它提供了一系列先进的滤镜、调整工具和预设,可以帮助用户快速地优化和编辑照片。 Nevercenter CameraBag Photo mac软件特点介绍 1. 滤镜:Nevercenter CameraBag Photo提供了超过2…

【嵌入式 – GD32开发实战指南(ARM版本)】第2部分 外设篇 - 第2章 温湿度传感器AHT10

1 理论分析 1.1 AHT10介绍 AHT10,新一代温湿度传感器在尺寸与智能方面建立了新的标准:它嵌入了适于回流焊的双列扁平无引脚SMD封装,底面4 x 5mm ,高度1.6mm。传感器输出经过标定的数字信号,标准I2C格式。 AHT10 配有一个全新设计的ASIC专用芯片、一个经过改进的MEMS半导体…

难题来了:分库分表后,查询太慢了,如何优化?

说在前面: 尼恩社群中,很多小伙伴反馈, Sharding-JDBC 分页查询的速度超级慢, 怎么处理? 反馈这个问题的小伙伴,很多很多。 而且这个问题,也是面试的核心难题。前段时间,有小伙伴…

一看就懂的java对象内存布局

前言 Java 中一切皆对象,同时对象也是 Java 编程中接触最多的概念,深入理解 Java 对象能够更帮助我们深入地掌握 Java 技术栈。在这篇文章里,我们将从内存的视角,带你深入理解 Java 对象在虚拟机中的表现形式。 学习路线图&…

2023第二届全国大学生数据分析大赛A题思路

某电商平台用户行为分析与挖掘 背景:电商是当今用户最大的交易市场之一,电商行业也逐渐成熟, 所有市场中可售卖的商品全都在平台中存在,并且在网络和疫情的影 响下,在线上的消费行为满足全年龄段用户。 用户的交易行为…

unittest 通过TextTestRunner(buffer=True)打印断言失败case的输出内容

buffer是unittest.TextTestRunner的一个参数,它决定了测试运行时是否将输出结果缓存,并在测试完成后一次性打印。 当buffer设置为True时,测试运行期间的输出结果会被缓存起来,并在测试完成后一次性打印。这对于一些输出频繁的测试…

Lamport Clock算法

Lamport Clock 是一种表达逻辑时间的逻辑时钟(logical clock),能够计算得到历史事件的时间偏序关系。 假设 P0进程是分布式集群中心节点中的监控者,用于统一管理分布式系统中事件的顺序。其他进程在发送消息之前和接受事件消息之后…

操作系统——内存映射文件(王道视频p57)

1.总体概述: 2.传统文件访问方式: 我认为,这种方式最大的劣势在于,如果要对整个文件的不同部分进行多次操作的话,这样确实开销可能会大一些,而且程序员还要指定对应的“分块”载入到内存中 3.内存映射文件…

Qt的事件

2023年11月5日,周日上午 还没写完,不定期更新 目录 事件处理函数的字体特点Qt事件处理的工作原理一些常用的事件处理函数Qt中的事件类型QEvent类的type成员函数可以用来判断事件的类型事件的类型有哪些?有多少种事件类 事件处理函数的字体特…

unittest 通过TextTestRunner(failfast=True),失败或错误时停止执行case

failfast是unittest.TextTestRunner的一个参数,它用于控制测试运行过程中遇到第一个失败或错误的测试方法后是否立即停止执行。 当failfast设置为True时,一旦发现第一个失败或错误的测试方法,测试运行就会立即停止,并输出相应的失…

插值表达式 {{}}

前言 持续学习总结输出中,今天分享的是插值表达式 {{}} Vue插值表达式是一种Vue的模板语法,我们可以在模板中动态地用插值表达式渲染出Vue提供的数据绑定到视图中。插值表达式使用双大括号{{ }}将表达式包裹起来。 1.作用: 利用表达式进行…

教你烧录Jetson Orin Nano的ubuntu20.04镜像

Jetson Orin Nano烧录镜像 视频讲解 教你烧录Jetson Orin Nano的ubuntu20.04镜像 1. 下载sdk manager https://developer.nvidia.com/sdk-manager sudo dpkg -i xxxx.deb2. 进入recovery 插上typeC后,短接J14的FORCE_RECOVERY和GND,上电 如下图&#…

【调度算法】单机调度遗传算法

问题描述 工件ABCDEFG工件编号0123456加工时间4765835到达时间3245321交货期10153024141320 目标函数 最小化交货期总延时时间 运算结果 最佳调度顺序: [6, 3, 2, 5, 0, 1, 4] 最小交货期延时时间: 47python代码 import random import numpy as np…

自动驾驶行业观察之2023上海车展-----智驾供应链(3)

智驾解决方案商发展 华为:五项重磅技术更新,重点发布华为ADS 2.0和鸿蒙OS 3.0 1)产品方案:五大解决方案都有了全面的升级,分别推出了ADS 2.0、鸿蒙OS 3.0、iDVP智能汽车数字平台、智能车云服务和华为车载光最新 产品…

linux下使用vscode对C++项目进行编译

项目的目录结构 头文件swap.h 在自定义的头文件中写函数的声明。 // 函数的声明 void swap(int a,int b);swap.cpp 导入函数的声明&#xff0c;写函数的定义 #include "swap.h" // 双引号表示自定义的头文件 #include <iostream> using namespace std;// 函…

2023年中国商业密码行业研究报告

第一章 行业概况 1.1 定义及分类 根据《密码法》相关规定&#xff0c;密码是指采用特定变换的方法对信息等进行加密保护、安全认证的技术、产品和服务。 密码产业是指为了保障信息安全&#xff0c;提供加密保护、安全认证相关技术、产品和服务的相关行业总称&#xff0c;主 要…

为机器学习算法准备数据(Machine Learning 研习之八)

本文还是同样建立在前两篇的基础之上的&#xff01; 属性组合实验 希望前面的部分能让您了解探索数据并获得洞察力的几种方法。您发现了一些数据怪癖&#xff0c;您可能希望在将数据提供给机器学习算法之前对其进行清理&#xff0c;并且发现了属性之间有趣的相关性&#xff0c…

python 机器学习 常用函数

一 np.random.randint "randint" 是 "random integer" 的缩写&#xff0c;表示生成随机整数。 np.random.randint 是 NumPy 库中的一个函数&#xff0c;用于生成随机整数。以下是该函数的一般语法&#xff1a; np.random.randint(low, high, size)其中…

MongDB 的安装 无废话

MongDB 的安装 1 安装 MongDB https://www.mongodb.com/try/download/community-kubernetes-operator 这里我们选择 ZIP 解压到文件夹 创建 data 文件 在 data 文件夹里面创建 db 和 logs 文件夹 进入 bin 目录 输入 cmd 回车 2 启动 MongDB 输入启动命令 mongod --dbpath..\…