活见鬼,明明删除了数据,空间却没减少( 二 )


从 Mysql 5.6.6 版本开始 , innodb_file_per_table 默认为 ON 状态 。
2、参数设置
通过 show variables like '%per_table%' 命令 , 可以查看 innodb_file_per_table 参数的当前状态:
活见鬼,明明删除了数据,空间却没减少文章插图
如果想修改参数的状态 , 可通过 SET GLOBAL 动态地修改为 ON 或 OFF , 也可以在 my.cnf 中做永久性修改 。 需要注意的是 , 在 my.cnf 中修改后生效的话需要重启 mysqld 服务 。
疑问:如果之前参数为 OFF 状态 , 设置为 ON 状态后 , 表空间如何分配?
答案是仅对后续操作生效 。
什么意思呢?修改前的数据还维持原状 , 也就是说之前的数据继续存放于 ibdata* 文件中 , 修改后可使用独立表空间 。
所以建议在开始就将该参数设置为 ON 状态 。
活见鬼,明明删除了数据,空间却没减少文章插图
第二天
活见鬼,明明删除了数据,空间却没减少文章插图
活见鬼,明明删除了数据,空间却没减少文章插图
活见鬼,明明删除了数据,空间却没减少文章插图
阿丁二次开讲
在这之前要先介绍下 Innodb 存储数据所用的 B+ 树结构 , 画个图你理解下:
活见鬼,明明删除了数据,空间却没减少文章插图
在图中 , P 代表一页数据 , R 代表一行数据 。
假设我们要删掉 R2 这条记录 , InnoDB 引擎只会将其标记为删除状态 , 并不会真正把这行数据所占的空间释放掉 , 也就是说这个坑位还留着 。 如果后续所插入的数据在 R1 与 R3 之间的话 , 这个空间是可以被使用上的 。
假设我们恰好删除了 R1、R2、R3 这三条记录 , 也就是说 P1 这一页的数据都被删掉了 , 那么 P1 所在的空间都会被标记为可复用 。 如果插入的数据需要使用新页的话 , P1 的坑位就可以被利用起来了 。
那么你可能会问了 , 我插入的数据恰好巧妙的避开了这些位置呢 。 那我还能说啥 , 骚呗 。 这样会造成很多空间被浪费 , 如果删除大量的数据的话 , 被浪费的空间也会是巨大的 。
活见鬼,明明删除了数据,空间却没减少文章插图
optimize table 的本质是 ALTER TABLE xxx ENGINE = InnoDB;
在5.5版本之前 , 重建表的过程是这样的:
活见鬼,明明删除了数据,空间却没减少文章插图
活见鬼,明明删除了数据,空间却没减少文章插图
活见鬼,明明删除了数据,空间却没减少文章插图
活见鬼,明明删除了数据,空间却没减少文章插图
活见鬼,明明删除了数据,空间却没减少文章插图
活见鬼,明明删除了数据,空间却没减少文章插图
然后用临时文件替换旧表 , 这样便实现了表的重建 。
活见鬼,明明删除了数据,空间却没减少文章插图
注意
1、控制迁移速度 , 防止主从延迟导致线上故障;
2、创建大表时 , 使用下面的建表语句可节省 50% 左右的空间:


推荐阅读