61 mysql 存储引擎之动态格式 MyISAM

前言

我们这里来看一下 MyISAM 存储引擎, 我们常见的那些 user, db, table_priv, proc 等等是基于 MyISAM

这是我们经常会提及的 两种持久化的存储引擎之一, 一是 MyISAM存储引擎, 另外一个是 InnoDB存储引擎 

我们这里来看一下 MyISAM 中动态长度的数据表的相关处理 

 

mysql.user 的表结构创建如下 

CREATE TABLE `user` (`Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',`User` char(32) COLLATE utf8_bin NOT NULL DEFAULT '',`Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',`ssl_cipher` blob NOT NULL,`x509_issuer` blob NOT NULL,`x509_subject` blob NOT NULL,`max_questions` int(11) unsigned NOT NULL DEFAULT '0',`max_updates` int(11) unsigned NOT NULL DEFAULT '0',`max_connections` int(11) unsigned NOT NULL DEFAULT '0',`max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',`plugin` char(64) COLLATE utf8_bin NOT NULL DEFAULT 'mysql_native_password',`authentication_string` text COLLATE utf8_bin,`password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',`password_last_changed` timestamp NULL DEFAULT NULL,`password_lifetime` smallint(5) unsigned DEFAULT NULL,`account_locked` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'

 

 

基于 动态长度MyISAM 的数据表的数据输出 

执行 sql 如下 “select * from user;” 我们着重关注 User 为 “tz_test” 的这条用户记录 

从 MYD 中读取 block_header 相关信息, 然后 mi_get_block_info 是从 block_header 中解析数据到 block_info

如果当前 block 是已经被删除掉的 block, 迭代下一个 block

d8ac549328addb00e97281a075ab2a94.png

 

然后是 上面 mi_read_cache 读取了 sizeof(block_info.header) 20 个字节的数据, 但是前面 block_header 可能仅仅只占用了 一部分字节

block_header 之后的数据, 也是数据部分, 需要将这部分数据填充到结果 buffer 中 

“if (block_of_record == 0)” 的处理是在更新当前记录的 left_len 表示的是当前记录的总共长度, 以及更新输出目标缓冲 

比如这里说明了当前记录 总共长度为 116, 然后 block_header 长度为 4

上面 mi_read_cache 中读取的, 还有 16 个字节属于记录的数据部分 

9f088b1e5806351e52024f81021b40ce.png

 

然后就是 读取当前 block 的剩余的数据部分了, 然后内容输出到 输出缓冲区中

然后更新 left_len, 如果 left_len 表示当前记录还是有 block, 需要继续 向后遍历

c424186f6b60a20d0f8e6b1e7c4d6730.png

 

动态长度的 MyISAM 这边的数据记录组织是以 block 为单位的 

一个 或者 多个 block 组成一个 record 

 

 

基于 动态长度MyISAM 的数据表的数据行

数据行 的信息如下

INSERT INTO `mysql`.`user`(`Host`, `User`, `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`, `Create_priv`, `Drop_priv`, `Reload_priv`, `Shutdown_priv`, `Process_priv`, `File_priv`, `Grant_priv`, `References_priv`, `Index_priv`, `Alter_priv`, `Show_db_priv`, `Super_priv`, `Create_tmp_table_priv`, `Lock_tables_priv`, `Execute_priv`, `Repl_slave_priv`, `Repl_client_priv`, `Create_view_priv`, `Show_view_priv`, `Create_routine_priv`, `Alter_routine_priv`, `Create_user_priv`, `Event_priv`, `Trigger_priv`, `Create_tablespace_priv`, `ssl_type`, `ssl_cipher`, `x509_issuer`, `x509_subject`, `max_questions`, `max_updates`, `max_connections`, `max_user_connections`, `plugin`, `authentication_string`, `password_expired`, `password_last_changed`, `password_lifetime`, `account_locked`) VALUES ('%', 'tz_test', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', 0, 0, 0, 0, 'mysql_native_password', '*3F42368149F6125F466E32249394BC6D395E6D4A', 'N', '2023-08-06 05:01:16', NULL, 'N');

22378a19c6aef1ef68ff28444a2b9dfe.png

 

 

 基于 动态长度MyISAM 的数据表的数据录入

执行 sql 如下 

create user 'tz_test_001'@'%' identified by 'tz_test_001';
grant select on tz_test_001.tz_test_02 to 'tz_test_001'@'%';
drop user 'tz_test_001';

新增 “tz_test_001” 对应的用户, 记录长度为 118

mi_find_writepos 是查询可用的节点, 如果不是必须在文件末尾增加数据, 可以吧删除的节点使用起来 

否则 在末尾创建 block, 来存放当前记录 

然后 就是写入 目标记录, 或者 目标记录的一部分

如果当前 block 写不完 record 的所有信息, 则进入下一个循环 mi_find_writepos + mi_write_part_record

089200f4fcb85e1c70d0a908ed47c798.png

 

查询可用空间方式如下, 如果是 不必须在末尾添加数据 则可以使用 删除链表的各个 block 

否则 在文件末尾新建 block

6a79914ce111869194d450c5d2a360db.png

 

写出 block 方式如下 

根据各种情况封装 block_header, 这里是 tz_test_001 走的如下展开的 block 的处理 

接着是写出 record 中的数据到 当前 block

4d680ee6e16688d12773b5a13963e949.png

 

将 block_header 写入 record – head_length

将当前 block 可以容纳的数据写入 record

然后将当前 block 的数据写入到 MYD 中文件对应的当前 block 的地方 

32c8584a5f62a340a1e8e96b1fbf9b87.png

 

 

基于 动态长度MyISAM 的数据表的数据删除  

遍历当前记录的 block 列表, 依次将 block 添加到 info->s->state->delink 的删除链表中 

将 “block_header[0] = 0;” 表示的就是标记删除当前 block 

cf3d0d8d0746c09b8edfab1927dd1dfb.png

 

 

 

 

 

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

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

相关文章

图片怎么转换成word文档?5种方法快速实现转换

不管是在学校学习还是在工作中,我们经常需要将图片中的文字转换成Word文档,以便于编辑和保存,但是很多小伙伴不知道该怎样转换,今天,就为大家介绍5种高效的图片转Word文档的方法,一起来学习下吧。 方法一&a…

IDEA设置JDK

IDEA设置JDK的前提是我们电脑中要下载安装了JDK 下面有JDK下载安装的详细教程 2024最新版JDK安装-CSDN博客文章浏览阅读3.4k次,点赞33次,收藏38次。安装JDK以及配置环境变量,检查是否安装成功_jdkhttps://blog.csdn.net/m0_61840987/articl…

威胁 Windows 和 Linux 系统的新型跨平台勒索软件:Cicada3301

近年来,网络犯罪世界出现了新的、日益复杂的威胁,能够影响广泛的目标。 这一领域最令人担忧的新功能之一是Cicada3301勒索软件,最近由几位网络安全专家进行了分析。他们有机会采访了这一危险威胁背后的勒索软件团伙的成员。 Cicada3301的崛…

笔记本电脑充不进去电怎么回事 笔记本电脑充不上电解决

当你满心欢喜地准备使用笔记本电脑,却突然发现它充不进去电,这无疑会让人感到十分困扰。究竟是什么原因导致了这一问题的出现呢?别着急,让我们一起来探寻笔记本电脑充不进去电的奥秘,并找到相应的解决办法。 一、原因…

批量修改YOLO格式的标注类别

1.解决的问题 假如你有一个YOLO格式的数据集,标注类别为0,1,2,3四个类别标签。如果你想删除标签1,只保留0,2,3类别的标注信息,或者想将标签0和标签1合并为标签1,只剩下标…

【Vulnhub靶场】DC-2

DC-2 靶场下载地址:https://download.vulnhub.com/dc/DC-2.zip 目标 本机IP:192.168.118.128 靶机IP:192.168.118.0/24 信息收集 常规我使用nmap三扫描,扫存活主机、扫端口、扫服务 第一步探测到存活主机IP为:192.1…

虚拟机网络设置为桥接模式

1、打开VMware Workstation Pro,点击“虚拟机—设置”,进入虚拟机设置页面 2、点击“网络适配器”,网络连接选择桥接模式 3、点击“编辑—虚拟网络编辑器”,进入虚拟网络编辑器页面 4、选择桥接模式,并选择要桥接到的…

Docker 部署 EMQX 一分钟极速部署

部署 EMQX ( Docker ) [Step 1] : 拉取 EMQX 镜像 docker pull emqx/emqx:latest[Step 2] : 创建目录 ➡️ 创建容器 ➡️ 拷贝文件 ➡️ 授权文件 ➡️ 删除容器 # 创建目录 mkdir -p /data/emqx/{etc,data,log}# 创建容器 docker run -d --name emqx -p 1883:1883 -p 1808…

内网穿透:如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)

内网穿透:如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)-含详细原理配置说明介绍 前言 远程桌面协议(RDP, Remote Desktop Protocol)可用于远程桌面连接,Windows系统(家庭版除外)也是支持这种协议的,无需安装…

代理与 Hubstudio 集成

文章目录 一、什么是 Hubstudio?二、为什么是动态住宅代理?三、使用 Hubstudio 设置 Smartdaili 代理3.1. 与动态住宅代理的整合 3.2. 使用 Hubstudio 设置代理 总结 将 Smartdaili 动态住宅代理与 Hubstudio 反检测浏览器配对使用,即可轻松管理多个账户…

npm、yarn、pnpm的workspaces使用

示例项目中总会遇到npm的packages中出现的workspaces键值对,自己的项目中没接触过这个东西,到底是什么?怎么用的?简单研究记录一下: abbrev是一个npm包,提供缩写展开功能。‌ 当你定义一个缩写后&#xff0…

设计一个html+css+js的注册页,对于注册信息进行合法性检测

综合使用HTML、JavaScript和CSS进行注册页面设计,实现以下若干功能: 注意整个页面的色调和美观使用FramesetTable布局(div也可)对用户ID和用户名、口令不符合条件及时判断对口令不一致进行及时判断(34的及时判断&#…

使用 Pake 一键打包网页为桌面应用 / 客户端

项目 项目:https://github.com/tw93/Pake/ 免费ICO图片:https://icon-icons.com/zh/ 设置环境 以下教程仅针对windows系统适用 请确保您的 Node.js 版本为 18 或更高版本 文档:https://v1.tauri.app/zh-cn/v1/guides/getting-started/prerequ…

Web3的核心概念:去中心化如何改变互联网

Web3,作为互联网的下一代技术架构,正在重新定义用户与数据、平台之间的关系。与以往的Web2.0时代相比,Web3的核心在于去中心化的理念,旨在通过区块链等技术实现更高的透明度、安全性和用户控制权。 1. 数据的掌控与隐私保护 在W…

分页列表缓存

写这篇文章&#xff0c;我们聊聊分页列表缓存&#xff0c;希望能帮助大家提升缓存技术认知。 1 直接缓存分页列表结果 这是最简单易懂的方案&#xff0c;我们按照不同的分页条件查询出结果后&#xff0c;直接缓存分页结果 。 伪代码如下&#xff1a; public List<Product&…

基于LSTM-Transformer混合模型实现股票价格多变量时序预测(PyTorch版)

前言 系列专栏:【深度学习&#xff1a;算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域&#xff0c;讨论了各种复杂的深度神经网络思想&#xff0c;如卷积神经网络、循环神经网络、生成对…

修改huggingface的缓存目录以及镜像源

执行以下语句查看当前配置 huggingface-cli env默认输出应该如下 (py39-transformers) PS D:\py_project\transformers_demo> huggingface-cli envCopy-and-paste the text below in your GitHub issue.- huggingface_hub version: 0.26.1 - Platform: Windows-10-10.0.22…

09_实现reactive之代理 Set 和 Map

目录 创建代理建立响应式联系避免污染原始数据处理 forEachfor...ofvalues 与 keys 方法 Set 和 Map 都有特定的属性和方法来操作自身&#xff0c;因此需要单独处理。 创建代理 我们来看一段案例代码&#xff0c;体验一下和它们的独特之处&#xff0c;如下&#xff1a; const…

第二代 GPT-SoVITS V2:解锁语音克隆与合成的无限可能

在 AI 技术蓬勃发展的今天&#xff0c;第二代 GPT-SoVITS V2 如一颗璀璨的明星闪耀登场&#xff0c;为语音处理领域带来了前所未有的变革。它是一款集先进技术与强大功能于一身的声音克隆与语音合成工具&#xff0c;由 RVC 变声器创始人 “花儿不哭” 与 AI 音色转换技术 Sovit…

使用 pydub 的 AudioSegment 获取音频时长 - python 实现

通过使用 pydub 的 AudioSegment 获取音频时长&#xff0c;音频常用格式如 m4a,wav等。 安装 python 库&#xff1a; pip install pydub 获取 m4a 格式的音频时长代码如下&#xff0c;代码如下&#xff1a; #-*-coding:utf-8-*- # date:2024-10 # Author: DataBall - XIAN #…