MySQL 空间碎片详解

news2024/11/24 0:42:39

文章目录

    • 前言
    • 1. 空间碎片如何产生
    • 2. 空间碎片如何查看
    • 3. 空间碎片如何回收
    • 后记

前言

MySQL 数据库在运行过程中,随着时间的推移,可能会出现空间碎片的问题。空间碎片是指数据库表中不再使用的空间,但由于各种原因,这些空间并没有被有效地回收和再利用,从而导致数据库文件占用的磁盘空间比实际存储的数据要大。

1. 空间碎片如何产生

MySQL InnoDB 引擎中,删除一条记录分为两种情况,一种称为删除标记(delete mark)仅在记录头部中设置 DELETED_FLAG 标记,记录链中依然保留该记录。另一种是真正删除,将记录从记录链中移除,记录占用的空间可被重用。

如下图,Record 2 被 delete mark 后,还在记录链表中。这行记录占用的空间可以理解为是空间空洞,空间空洞多起来就成为空间碎片。
在这里插入图片描述

上图来源于:YunChe MySQL 运维实战 系列文章。

标记删除导致的空间空洞,会被重新利用,但是依然可能会造成空间浪费。

如果页面内的未使用空间不足,无法容纳新插入的数据,但是碎片空间中有足够的空间,则可以对页面进行碎片回收后,再插入新的数据。碎片回收时,会先在内存中申请一个空闲页面,将存在碎片空间的旧页面中的记录依次插入到新页面,然后释放旧页面。

被动触发空间碎片回收条件,是页面空间碎片中有足够的空间,可以容纳新插入的记录,那如果无法容纳,就需要新申请页面。在大规模连续删除过的数据的表上,写入数据时,表空间可能不会明显增长或者不会增长。

除了 Delete 会产生空间空洞外,Update 语句也会引起空间空洞问题,比如修改 varchar 变长字符串类型字段,改短一些的时候就会出现非常小的空洞,改长的话就有可能因为页面空间不足,导致把 Record 迁移到其他页面中去。

2. 空间碎片如何查看

MySQL 系统表中,可以查看空间碎片情况。下方 SQL 是统计库粒度空间统计信息,其中 FREE_MB 为空间碎片大小。

SELECT TABLE_SCHEMA,
       round(SUM(data_length + index_length + DATA_FREE) / 1024 / 1024, 2) AS TOTAL_MB,
       round(SUM(data_length) / 1024 / 1024, 2)                            AS DATA_MB,
       round(SUM(index_length) / 1024 / 1024, 2)                           AS INDEX_MB,
       round(SUM(DATA_FREE) / 1024 / 1024, 2)                              AS FREE_MB,
       COUNT(*)                                                            AS TABLES
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_SCHEMA NOT IN ('sys', 'mysql', 'INFORMATION_SCHEMA', 'performance_schema')
GROUP BY TABLE_SCHEMA
ORDER BY 2 DESC;

下方为查看指定库和指定表,空间使用情况的 SQL 语句。其中 FREE_MB 表示碎片大小 FREE_PCT 表示碎片率。

SELECT TABLE_SCHEMA,
       TABLE_NAME,
       round((data_length + index_length + DATA_FREE) / 1024 / 1024, 2) AS TOTAL_MB,
       round(data_length / 1024 / 1024, 2)                              AS DATA_MB,
       round(index_length / 1024 / 1024, 2)                             AS INDEX_MB,
       round(DATA_FREE / 1024 / 1024, 2)                                AS FREE_MB,
       CONCAT(ROUND(DATA_FREE / data_length, 2), ' %')                  AS FREE_PCT
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_SCHEMA = '数据库名'
  and TABLE_NAME = '表名'
ORDER BY TOTAL_MB DESC;

3. 空间碎片如何回收

MySQL 中可以使用下方命令回收空间碎片,支持 online DDL。

ALTER TABLE tbl_name ENGINE=INNODB;

表中碎片多大需要回收呢?这里提供一个参考标准:单表大于 6G 且碎片率大于 30% 需要清理空间碎片。

Tips: 空间碎片回收,是一个代价比较高的操作,虽然支持 Online DDL,但是依然会带来额外的负载,建议业务低峰执行。如果是一套 MySQL 集群,需要注意主从延迟问题。

对于一些需要周期删除的日志表,可以使用 MySQL 中的分区表来管理,需要清理一批数据的时候,可以用 partition truncate 的方式进行清理,磁盘空间也能直接释放掉。

后记

总结一下,InnoDB 引擎中 Delete 和 Update 都会产生空间空洞,积累起来就会出现空间碎片问题,MySQL 有对应的回收算法让空间空洞会重新利用起来,但是很难保证充分利用。空间碎片可以使用重建表的方式进行回收。

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

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

相关文章

集简云SDK嵌入支持传值,支持通过接口创建和管理流程

集简云SDK嵌入方案,允许开发者将集简云的产品功能直接嵌入到自己的产品中,用户无需单独注册或登录集简云,即可在第三方产品内使用集简云提供的功能。 目前,SDK嵌入方案已支持传值功能,通过SDK嵌入,可以在创…

电子电器架构刷写策略 —— 队列刷写

电子电器架构刷写策略 —— 队列刷写 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己…

嵌入式面试

1.关键字static的作用是什么?为什么static变量只初始化一次? 1)修饰局部变量:使得变量变成静态变量,存储在静态区,存储在静态区的数据周期和程序相同, 在main函数开始前初始化,在退…

Wireshark_labs TCP

在本实验中,我们将详细研究著名的TCP协议的行为。我们将通过从您的电脑向远程服务器传输一份150KB 的文件(一份Lewis Carrol 的“爱丽丝梦游仙境”文本), 并分析TCP传输内容的发送和接收过程来实现。我们将研究TCP对序列和确认号的使用,以提供…

Sparse A*算法的时间复杂度

Sparse A*(SAS)算法是A*算法的变型算法,下面将结合A*算法的流程分析SAS的时间复杂度。对于SAS算法而言,其航迹规划的时间 T T T主要由两部分组成: T s T_s Ts​:在当前结点扩展可行子结点的时间; T 0 T_0 T0​&#…

LeetCode每日一题只 快乐数

目录 题目介绍: 算法原理: 鸽巢原理: 如何找到环里元素: 代码实现: 题目介绍: 题目链接:. - 力扣(LeetCode) 算法原理: 我先简单举两个例子&#xff…

阿里云重新更新系统导致秘钥失效

报错解决方案: ssh-keygen -f "/Users/pengzhanliang/.ssh/known_hosts" -R "39.105.149.49"这个命令会从~/.ssh/known_hosts文件中移除与IP地址39.105.149.49相关的所有条目 再次尝试连接到远程服务器。这次,SSH将提示您接受新的主…

力扣hot100:239.滑动窗口最大值(优先队列/单调队列)

本题是一个经典的单调队列题。不过用优先队列也能解决。 一、优先队列 在使用优先队列时,我们会遇到这样的问题:如何将一个目标数从优先队列中弹出?如果使用stl这是办不到的,虽然可以自行实现这样的功能。但是我们可以这样思考&am…

Cesium 自定义Primitive - 圆

一、创作思路 1、创建一个自定义CustomPrimitive 2、然后根据两个点,生成圆 3、方便后期绘制圆 二、实现代码 1、在vue的包中加入turf. npm install turf/turf 1、创建一个CustomCirclePrimitive类,并加入更新的代码 export default class CustomCirclePrimitive …

面试问答之Spring进阶

文章目录 🐒个人主页:信计2102罗铠威🏅JavaEE系列专栏📖前言:🎀说说你对Spring的认识与理解🐕Bean的分类🐕 BeanFactory 接口和ApplicationContex 接口 的区别🐕SpringBe…

Text-to-SQL任务中的思维链(Chain-of-thought)探索

导语 在探索LLM在解决Text-to-SQL任务中的潜能时,本文提出了一种创新的‘问题分解’Prompt格式,结合每个子问题的表列信息,实现了与顶尖微调模型(RASATPICARD)相媲美的性能。 会议:EMNLP 2023链接&#x…

Python给图片加水印

受到“手动给证件加文字太麻烦”的感触,想用Python来实现给图片加水印,这不方便多了。 这里使用PIL模块: from PIL import Image from PIL import ImageFont from PIL import ImageDrawimg_t Image.open(cat.jpg) img_size_t img_t.size…

力扣hot100:560.和为K的子数组(前缀和+哈希表)

分析: 这个题目乍一看,数据大小用暴力解法大概率会超时,可能想用双指针,但是问题出现在 可能存在负数,也就是说即使是找到了一个答案,后面也可能存在负数和正数抵消,又是答案,因此不…

【教程】uni-app iOS打包解决profile文件与私钥证书不匹配问题

摘要 当在uni-app中进行iOS打包时,有时会遇到profile文件与私钥证书不匹配的问题。本文将介绍如何解决这一问题,以及相关的技术细节和操作步骤。 引言 在uni-app开发过程中,iOS打包是一个常见的操作。然而,有时会出现profile文…

Seata 2.x 系列【2】数据库事务

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列Seata 版本 2.0.0 源码地址:https://gitee.com/pearl-organization/study-seata-demo 文章目录 数据库事务什么是事务事务的作用数据库事务模型显式事…

基于Java springboot+VUE+redis实现的前后端分类版网上商城项目

基于Java springbootVUEredis实现的前后端分类版网上商城项目 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言…

linux上的xtrabackup更换版本

linux上安装的xtrabackup版本为8.0版本,与当前库的版本不一致,如何更换xtrabackup的版本 xtrabackup --version xtrabackup version 8.0.35-30 based on MySQL server 8.0.35 Linux (x86_64) (revision id: 6beb4b49)如何下载 首先到percona的官网去下…

Excel中怎么求排名

使用Rank函数 1.在需要显示排名的单元格内,输入“RANK(数值,数值列表,排序方式)” 2.将“数值”替换为需要计算排名的单元格的地址,例如E2单元格。 3.将“数值列表”替换为排名的数值范围,例…

vue接入百度地图获取经纬度

通过城市名称和城市中心经纬度来获取当前所在地图,当前经纬度中心获取可以通过后端获取 静态文件包,替换baidu.html中的ak值,ak值通过百度地图官方网站申请 申请:百度地图API申请步骤 - 知乎 代码示例文件: 链接&a…

【Linux基础(一)】设备和文件IO

学习分享 1、Linux中的设备管理1.1、设备管理的特点1.2、设备分类1.3、设备工作原理1.4、Linux设备操作1.5、系统调用和系统API等区别 2、文件IO2.1、C库的文件操作2.2、文件描述符2.3、特殊文件描述符2.4、系统调用2.4.1、open系统调用4-12.4.2、open系统调用4-22.4.3、write系…