当前位置: 首页 > article >正文

数据库学习02——mysql清空表数据后 IBD 文件仍很大的解决方案

  • 推荐学习文档
    • golang应用级os框架,欢迎star
    • 数据库学习01——mysql怎么创建数据库和表

文章目录

    • 原因分析
      • 1.InnoDB 存储引擎特性
      • 2.事务和日志记录
    • 解决方案
      • 1.使用 OPTIMIZE TABLE 命令
      • 2.使用 ALTER TABLE 命令
      • 3.直接删除并重新创建表

在 MySQL 中,有时候我们会遇到这样一种情况:已经清空了表中的数据,但是对应的.ibd文件却仍然占用很大的磁盘空间。这可能会导致磁盘空间浪费,影响数据库的管理和性能。本文将详细介绍出现这种情况的原因以及相应的解决方法,并配合代码示例进行说明。

原因分析

1.InnoDB 存储引擎特性

  • InnoDB 是 MySQL 8 的默认存储引擎,它采用了 MVCC(多版本并发控制)机制。当数据被删除时,InnoDB 并不会立即回收磁盘空间,而是将这些空间标记为可重用。这就导致即使表中的数据被清空,.ibd文件大小可能不会立即减小。

2.事务和日志记录

  • 如果在清空表数据之前存在未提交的事务或者有大量的日志记录与该表相关,这些信息可能仍然占用磁盘空间,从而使得.ibd文件保持较大的体积。

解决方案

1.使用 OPTIMIZE TABLE 命令

  • 原理

    • OPTIMIZE TABLE命令会重建表并释放未使用的空间。它实际上是先创建一个新的表结构,将旧表中的数据复制到新表中(由于数据已清空,这里实际复制的数据量很少),然后删除旧表并将新表重命名为旧表的名称。
  • 示例代码

    • 假设我们有一个名为test_table的表,数据已经清空但.ibd文件很大。在 MySQL 命令行中执行以下命令:
OPTIMIZE TABLE test_table;
  • 如果是在编程环境中(例如使用 Python 连接 MySQL 并执行该操作),可以使用如下代码示例(这里以mysql - connector - python为例):
import mysql.connector

# 连接数据库
mydb = mysql.connector.connect(
    host="your_host",
    user="your_user",
    password="your_password",
    database="your_database"
)

mycursor = mydb.cursor()

# 执行OPTIMIZE TABLE命令
sql = "OPTIMIZE TABLE test_table"
mycursor.execute(sql)

mydb.commit()

mycursor.close()
mydb.close()

2.使用 ALTER TABLE 命令

  • 原理

    • 可以通过修改表的存储引擎或者添加和删除一些约束等方式,让 MySQL 重新组织表结构,从而释放未使用的空间。例如,将表的存储引擎从 InnoDB 改为 MyISAM(在某些场景下可行,但需注意两者的特性差异),然后再改回 InnoDB。
  • 示例代码

    • 在 MySQL 命令行中执行以下操作:
-- 先将表转换为MyISAM(注意备份数据,因为MyISAM和InnoDB有不同的特性)
ALTER TABLE test_table ENGINE = MyISAM;
-- 再转换回InnoDB
ALTER TABLE test_table ENGINE = InnoDB;

3.直接删除并重新创建表

  • 原理
    • 如果表结构比较简单,并且可以接受暂时的数据不可用(需要先备份数据),直接删除表然后重新创建相同结构的表是一种简单有效的方法。这样可以确保新创建的表占用最小的磁盘空间。
  • 示例代码
    • 在 MySQL 命令行中:
-- 备份表数据(假设表有列col1, col2, col3)
CREATE TABLE test_table_backup AS SELECT col1, col2, col3 FROM test_table;
-- 删除原表
DROP TABLE test_table;
-- 创建新表(根据原表结构创建,这里假设原表结构为CREATE TABLE test_table (col1 INT, col2 VARCHAR(255), col3 TIMESTAMP))
CREATE TABLE test_table (col1 INT, col2 VARCHAR(255), col3 TIMESTAMP);
-- 将备份的数据重新插入新表(如果需要)
INSERT INTO test_table SELECT * FROM test_table_backup;
-- 删除备份表(如果不再需要)
DROP TABLE test_table_backup;

在实际应用中,需要根据具体的业务场景和数据库状态选择合适的方法来解决.ibd文件过大的问题。同时,在对数据库进行任何操作之前,一定要做好数据备份工作,以防止数据丢失。

关注我看更多有意思的文章哦!👉👉


http://www.kler.cn/news/310640.html

相关文章:

  • 面向开发者的LLM入门教程(学习笔记01)
  • 探索学习Python的最佳开发环境和编辑器
  • 家用燃气报警器-家庭可燃气体探测器-旭华智能
  • 【网络安全】服务基础第二阶段——第四节:Linux系统管理基础----Linux网络与日志服务器
  • Docker 镜像制作(Dockerfile)
  • 为解决bypy大文件上传报错—获取百度云文件直链并使用Aria2上传文件至服务器
  • Mini-Omni:语言模型可以在流中听、说和思考
  • Docker本地部署Chatbot Ollama搭建AI聊天机器人并实现远程交互
  • Spring boot aop集成(面向切面的编程)
  • TMStarget学习——T1 Segmentation数据处理及解bug
  • js进阶-作用域是什么
  • idear导入他人项目如何快速运行
  • 【PostgreSQL】安装及使用(Navicat/Arcgis),连接(C#)
  • 环境搭建2(游戏逆向)
  • 深入解析:ECMAScript与JavaScript的区别与联系
  • 江科大笔记—OLED显示屏
  • golang的sync包浅析
  • ARM驱动学习之 IOremap实现GPIO 读
  • 安卓13去掉下拉菜单的Dump SysUI 堆的选项 android13删除Dump SysUI 堆
  • react hooks--概述
  • Linux从入门到开发实战(C/C++)Day12-ICMP协议
  • linux-软件包管理-编译与安装源码包
  • 人工智能-GPU版本机器学习、深度学习模型安装
  • swc 编译 es6为commonjs
  • 「数组」堆排序 / 大根堆优化(C++)
  • 双端队列double-ended queue
  • c/c++语言中extern的用法(VS编译)
  • 代码结构之结构体
  • 算法面经手撕系列(2)--手撕BatchNormlization
  • 【每日一诗】【诗词创作】【诗】《雨前秋夜》