暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Mysql分区(PARTITION)实战--解决Mysql大量删除数据效率低的问题

云时代的运维开发 2015-03-05
2158

有一个表netmon_history , 表结构如下:


每五分钟要做一次数据更新,要插入约50万条数据,完成这50万条数据的插入大概需要3分钟。由于数据的插入,表会越来越大。但是应用只需要保留1个小时内的数据,时间戳超过一个小时的数据要删除掉。


刚开始的时候采用一条一条删除的方法,每5分钟删除一次,每次清除一个小时前的数据。但是遇到一个问题是,经常返回错误“Lock wait timeout exceeded; try restarting transaction”。发现mysql的netmon_history这张表被锁定了。无法执行删除操作,只要是因为delete操作要删除的数据量超过全表数据量的1/10,因而进行了表级锁定。


要解决这个问题,有两种解决方案。


法一: 减少每次delete的数据量,写一个循环语句分多次删除。这种方法没有测过,但是目测效率也不会高到哪里,而且对一张表进行频繁读写和删数据操作,会造成很高的I/O.


法二:对netmon_history这张表进行分区。这种方法的优点是减少I/O操作,避免表的锁定,而且还能提高mysql表的查询效率。我采用的是这种做法,具体操作如下:


CREATE TABLE `netmon_history` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`item_id` int(11) NOT NULL,

`value` bigint(20) unsigned DEFAULT NULL,

`clock` int(11) NOT NULL,

`md5value` varchar(40) NOT NULL,

`add_time` datetime NOT NULL,

PRIMARY KEY (`id`,`clock`),

KEY `idx_clock` (`clock`),

KEY `idx_item_id_value` (`item_id`,`value`),

KEY `idx_add_time` (`add_time`),

KEY `idx_item_id` (`item_id`)

)

partition by range (clock) (

partition p0 values less than (1425384760),

partition p1 values less than (1425384760 + 300),

partition p2 values less than (1425384760 + 600),

partition p3 values less than (1425384760 + 900),

partition p4 values less than (1425384760 + 1200),

partition p5 values less than (1425384760 + 1500),

partition p6 values less than (1425384760 + 1800),

partition p7 values less than (1425384760 + 2100),

partition p8 values less than (1425384760 + 2400),

partition p9 values less than (1425384760 + 2700),

partition p10 values less than (1425384760 + 3000),

partition p11 values less than (1425384760 + 3300),

partition p12 values less than (1425384760 + 3600),

partition p13 values less than (1425384760 + 3900),

partition p14 values less than (1425384760 + 4200),

partition p15 values less than (1425384760 + 4500),

partition p16 values less than (1425384760 + 4800),

partition p17 values less than (1425384760 + 5100),

partition p18 values less than (1425384760 + 5400),

partition pMax values less than MAXVALUE

);


备注:1425384760是我创立这张表时的当前时间戳。根据自己的情况去定。


建立了大概20个分区,5分钟的数据一个分区。最后的pMax表可以防止数据溢出。


分区表建立之后,查看下分区情况。

select PARTITION_NAME from information_schema.partitions where table_name='netmon_history';


以后每次都要做删除操作的时候,都要删除第一个分区,然后删除pMax分区,添加一个新分区,最后再添加pMax分区。例如:


等表保存了一个小时的数据后,然后开始执行删除数据操作,每5分钟执行一次。步骤如下:


  1. 删除p0分区, alter table netmon_history drop partition p0;


2. 删除pMax分区, alter table netmon_history drop partition pMax;

备注,如果不先删除这个分区,就添加新的分区,会提示错误“ERROR 1481 (HY000): MAXVALUE can only be used in last partition definition


3. 添加新的分区, alter table netmon_history add partition (partition p21 values less than (1425384760 + 5700));


备注:如果新添加的分区的时间戳的范围小于前一个分区,会提示错误“VALUES LESS THAN value must be strictly increasing for each partition”


4. 重新添加pMax分区, alter table netmon_history add partition (partition pMax values LESS THAN MAXVALUE)


问题解决。


*****扩展阅读********

MySQL分区表(总结)

http://blog.csdn.net/jiao_fuyou/article/details/16801389

MYSQL分区表功能测试简析

http://www.2cto.com/database/201204/127397.html

通过分区(Partition)提升MySQL性能

http://fanqiang.chinaunix.net/db/mysql/2006-05-08/4135.shtml

mysql —— 分表分区(1)

http://pmghong.blog.51cto.com/3221425/1301945

文章转载自云时代的运维开发,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论