optimize 回收表空间的一些说明

optimize命令回收表空间的说明

线上服务器,有张大表需要用pt-archiver根据时间划分归档大量数据到另一个新表中。原先200G的表,在归档完成后,du -hs 显示依然是200G的大小,删除了大量的行记录但是实际上空间是不会释放的。

这种情况下,我们就要使用optimize命令重建表以达到释放表空间的目的。

(好像是从5.6.6之后,optimize不锁表了,但是optimize操作会进行rebuild表操作,要确保磁盘剩余空间足够存放新表的大小,不然操作会失败)

另外,如果在主库执行optimize table会造成从库延迟,这种情况下,可以使用 optiminze no_write_to_binlog table xxxx ; 这样就不会把optimize操作写入binlog。主库执行完后,再到从库执行optimize table操作。

姜承尧的py_innodb_page_info 工具 下载地址:http://pan.baidu.com/s/1c2o0Tag (永久有效)

模拟过程如下:

use test;

CREATE TABLE `t` (

`a` int(10) unsigned NOT NULL AUTO_INCREMENT,

`b` char(10) DEFAULT NULL,

PRIMARY KEY (`a`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;

insert into t (b) select ‘aaaaaaa‘;

insert into t(b) select b from t;    多执行几次这个命令,造出大量的行数据

然后使用py_innodb_page_info分析page,如下,可以看到存了数据的page很多【下图红色部分】

[[email protected] /root/py_innodb_page_type ]#./py_innodb_page_info.py -v /data/mysql/test/t.ibd

page offset 00000000, page type <FileSpace Header>

page offset 00000001, page type <Insert BufferBitmap>

page offset 00000002, page type <FileSegment inode>

page offset 00000003, page type<B-tree Node>, page level <0000>

page offset 00000004, page type<B-tree Node>, page level <0000>

page offset 00000005, page type<B-tree Node>, page level <0000>

page offset 00000006, page type<B-tree Node>, page level <0000>

page offset 00000007, page type<B-tree Node>, page level <0000>

page offset 00000008, page type<B-tree Node>, page level <0000>

page offset 00000009, page type<B-tree Node>, page level <0000>

page offset 0000000a, page type<B-tree Node>, page level <0000>

page offset 0000000b, page type<B-tree Node>, page level <0000>

page offset 0000000c, page type<B-tree Node>, page level <0000>

page offset 0000000d, page type<B-tree Node>, page level <0000>

page offset 0000000e, page type<B-tree Node>, page level <0000>

page offset 0000000f, page type<B-tree Node>, page level <0000>

page offset 00000010, page type<B-tree Node>, page level <0000>

page offset 00000000, page type <Freshly AllocatedPage>

page offset 00000000, page type <FreshlyAllocated Page>

Total number of page: 19:

Freshly Allocated Page: 2

Insert Buffer Bitmap: 1

File Space Header: 1

B-tree Node: 14

File Segment inode: 1

然后大量删除数据

delete from test.t where a>100;  开始删除大量的数据(只保留100条记录,确保数据应该在第一个数据页存的下)

然后用hexdump去看下innodb的第二个page信息

hexdump -C -s 65536 -n 16384 /data/mysql/test/t.ibd   发现这个page的数据还是很多,它们并没有被真正的删除 (实际上当一条记录被删除后,该空间只是标记为空闲了,它会被加入到空间链表里面)

### hexdump命令说明:

## -s 从啥位置开始取数据,-n 取出多少bytes的数据。

## 因为每个page 16k。InnoDB前3个page是存放其它数据的。第一个data page是从16*1024*3=49152位置开始的。第二个data page是从16*1024*4=65536开始的。

重建下test.t试试效果:

[email protected] [test]> optimize table t;

再次使用py_innodb_page_info分析page,如下,可以看到page少了很多【下图红色部分】,基本上都被回收了。

[[email protected] /root/py_innodb_page_type ]#./py_innodb_page_info.py -v /data/mysql/test/t.ibd

page offset 00000000, page type <FileSpace Header>

page offset 00000001, page type <InsertBuffer Bitmap>

page offset 00000002, page type <FileSegment inode>

page offset 00000003, page type<B-tree Node>, page level <0000>

page offset 00000000, page type <FreshlyAllocated Page>

page offset 00000000, page type <FreshlyAllocated Page>

Total number of page: 6:

Freshly Allocated Page: 2

Insert Buffer Bitmap: 1

File Space Header: 1

B-tree Node: 1

File Segment inode: 1

然后再用hexdump去看下innodb的第二个page信息,发现这个page的数据已经全部是0了,是一个空白的page

[[email protected] /tmp ]# hexdump -C -s 65536 -n16384 /data/mysql/test/t.ibd

00010000 00 00 00 00 00 00 00 00  00 00 0000 00 00 00 00  |................|

*

00014000

时间: 2024-08-24 16:00:36

optimize 回收表空间的一些说明的相关文章

oracle 回收表空间的数据文件大小

查看表空间的使用情况: select a.tablespace_name,a.bytes/1024/1024 "Sum MB",(a.bytes-b.bytes)/1024/1024 "used MB",b.bytes/1024/1024 "free MB", round(((a.bytes-b.bytes)/a.bytes)*100,2) "percent_used" from (select tablespace_name

表空间及回收

一. Innodb存储引擎表中所有数据都是存储在表空间中的,表空间又分为系统表空间,以ibdata1来命名,在数据安装初始化时系统会创建一个ibdata1的表空间文件,它会存储所有数据的信息以及回滚段(undo)的信息.在MySQL5.6以后,undo表空间可以通过参数单独设置存储位置了,可从ibdata1中独立出来.Innodb_data_file_path负责定义系统表空间的路径.初始化大小.自动化扩展策略.数据库默认的自动扩展大小是64MB. mysql> show variables l

MySQL InnoDB 共享表空间和独立表空间

共享表空间 某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目录下. 默认的文件名为ibdata1, 初始化为10M. 由于是默认的方式,就暂且理解为Mysql官方推荐的方式.相对而言所有的数据都在一个(或几个)文件中,比较利于管理,而且在操作的时候只需要open这一个(或几个)文件即可,相对来说代价很低.但问题是在数据达到以G为单位来计算的时候优劣逆转.一个过大的文件很不利于管理,而且对于一个如此巨大的文件来说,读写它需要耗费的资源一样巨大.更加令

Ora-01536:超出了表空间users的空间限量(转)

Ora-01536:超出了表空间users的空间限量(转) 正在开会,同事跑过来说数据库有问题,通讯程序不能入库,赶快获取一条insert into a values()语句后在toad工具中手动插入,发现报错:Ora-01536:超出了表空间users的空间限量. 该表a的是用户A下的一个大表,表空是users,而非A用户的默认表空间.users表空间有大约70%的空闲空间,为什么a表就不能使用了呢?从网上搜索后终于明白: ora-1536 是指的你建表的那个user 所能使用的空间没有了,不

[原创] ORA-01536 超出表空间 &#39;xxxx&#39; 的空间限额

1.故障情况 星期一上班一早,客户打电话来,说数据库空间满了.检查表空间情况,还有剩余,检查alert_XXX.log也未有报错. 软件方手工测试,执行插入数据时报错,如下: ORA-01536: 超出表空间 'xxxx' 的空间限额 2.故障解决 使用业务用户'AA'登陆数据库,查询业务用户'AA'对表空间'XXXX'的限额 select * from user_ts_quotes; max_bytes字段为“0”,说明限额用完了,需要调整 增大用户对表空间的读写限额,由原来的2.5G加大到5

【转】利用optimize、存储过程和系统表对mysql数据库表进行批量碎片清理释放表空间

本文收集于本人的笔记本,由于找不到原文出处.在此省略,如哪位知道可以联系我加上. 核心是利用mysql系统表和“optimize table 表名”命令,对mysql数据表进行空间的释放.由于delete和drop table都不会释放表空间(truncate 命令会释放表空间[将所有的数据都删除]),所以需要利用optimize 命令进行释放. 这个存储过程目的是给一个库的所有表来整理碎片的.一个表随着插入很频繁,或者一直更新不停的,就会积累好多碎片.如果及时整理一下,查询效率会高出好多. D

回收数据库表空间的一个思路

有些项目比较小,硬盘空间也只有40多G,加上无人维护,久而久之就出现了硬盘空间告警的问题.经过查看之后,发现有些数据文件一开始就设置成2G,但实际可能就只使用了100M左右.为了解决硬盘空间告警的问题,就想到了重置数据文件大小的方法. 第一步是查看各个表空间的适用率,找出可以缩小的数据文件. --查看表空间使用率,找到闲置的表空间 SELECT Upper(F.TABLESPACE_NAME)         "表空间名", D.TOT_GROOTTE_MB              

表空间回收操作判断

今天刚上班,一个朋友问我“我们这边有个表空间扩大到,1.4T,但是删除数据没有用,这个都不变小?”. 我给他这样解释了下 "这个数据文件:你删除数据是不会影响到它的大小:可以这样理解:这个数据文件相当于一个水桶:这个水桶的大小是1.4T:删除数据这个操作相当于把里面水抽出来. 水桶的大小是不变的:水是变少了.水桶可用的空间变大了:可以装更多的水." 想一个表空间扩张到1T多.有下面两种可能 1. 真的有怎么多的数据量的业务. 2. 这表空间一定是设置为自动扩张的:导致数据文件暴涨:其中

MySQL表空间集

--MySQL表空间集 ----------------------2014-09-20 1. 收缩ibdata的方法,目前MySQL依然没有提供收缩ibdata的方法,只能重构,下面是5.7的步骤. Decreasing the Size of the InnoDB Tablespace Currently, you cannot remove a data file from the system tablespace. To decrease the system tablespace s