大量删除MySQL中的数据
出现的背景:
公司做了一个redis相关的项目,其中mysql存储了很多统计数据。比如客户端上报的数据,redis实例的数据,应用的数据,机器的数据等。每天都在上报,采集,由于没有定期删除,数据大量累积。大概有一年左右的数据,一个表的数据已经达到亿级别的。这样算下来,一个表的数据至少是几十GB了。因此需要删除过期的数据,暂时保留近三个月的统计数据。
解决方案:
基本每个表都有个字段叫create_time或者collect_time的字段,只要删除这个字段三个月之前的数据就ok了
delete from table_name where create_time < '2017-04-06'
只要执行这句SQL应该就可以了
遇到的问题:
The total number of locks exceeds the lock table size in MySQL
因为需要删除的数据太大,mysql给的buffer好像只有8MB左右(网上搜到的)
后面找到DBA帮忙看,问这个表建了索引没有
show index from table_name
通过查看索引,我们在create_time和collect_time上是建了索引的,索引类型是BTree,ASC。这里我们用的Mysql引擎是InnoDb
delete from table_name where create_time < '2017-07-06' order by create_time asc limit 10000
接着,我想用order by + limit实现删除,还是出现了上面的错误
后面DBA提示我说,为啥不用ID删除,说按id删除,速度和按索引列删除,不是一个数量级的
接着我想到了拆分一下。
最终解决方案:
找出符合条件的create_time和collect_time的最大ID
select max(id) from table_name where create_time < '2017-04-06'
这里千万左右的数据大概需要10多秒
接着按id删除,一次删除10k,循环删除
delete from table_name where id < maxId limit 10000
直到把过期的时间删除完成
这里我没有msyql服务器的权限,通过java客户端连接删除,使用的spring jdbcTemplate这个接口
另外,这里一次删除10k还有个原因是,事务太大,影响其他服务的运行
还用到的技术,就是使用线程池来执行sql删除,实现异步删除。和同事吃饭的时候,同事也提供了一个解决方案,每次删一秒的数据,这样一次次的删。看了一下数据,一秒的数据基本在几十万,左右,这样不太好控制数据量大小。还是通过主键id + limit 10k这里稳妥一点。
还有一点就是,为了怕压到mysql服务器,这里线程池删除的时候回sleep(1000),阻塞1s再删除,减轻mysql服务器的压力
今天搞了一下数据删除这一点东西,感觉mysql水很深,比如一个select count(*)的执行过程,select from table_name order by id limit 的过程,索引,各种连接,引擎的工作原理。走的时候还有点没有调完,明天应该可以搞定这些了。
大量删除MySQL中的数据的更多相关文章
- PHP MySQL Delete删除数据库中的数据
PHP MySQL Delete DELETE 语句用于从数据库表中删除行. 删除数据库中的数据 DELETE FROM 语句用于从数据库表中删除记录. 语法 DELETE FROM table_na ...
- PHP mysql 删除表中所有数据只保留一条
DELETE FROM `logs` WHERE wangzhi='www.juhutang.com' and id<>101072; 上面这段代码的意思为 删除表logs中 所有字段wa ...
- 超实用--删除MYSQL中指定的数据的全部表
作过的人都知道,重复测试数据库的苦恼. 用法:# Usage: ./script user password dbnane mysql.nixcraft.in ~~~~~~~~~~~~~ #!/bin ...
- PHP读取mysql中的数据
<!DOCTYPE HTML> <html> <head> <title> PHP动态读取mysql中的数据 </title> <me ...
- 辛星浅谈mysql中的数据碎片以及引擎为MyISAM下的操作
对于mysql中的数据碎片,事实上和我们删除数据是息息相关的,删除数据的时候必定会在数据文件里造成不连续的空白空间,对于少量的数据的删除,并不会产生多少的空白空间.假设在一段时间内的大量的删除操作,会 ...
- Vusual C++连接Mysql和从MySql中取出数据的API介绍
.1 mysql_real_connect() 2.1.1 函数原型: MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const ...
- 用python批量向数据库(MySQL)中导入数据
用python批量向数据库(MySQL)中导入数据 现有数十万条数据,如下的经过打乱处理过的数据进行导入 数据库内部的表格的数据格式如下与下面的表格结构相同 Current database: pyt ...
- PHP如何批量更新MYSQL中的数据
最近项目需要用到批量更新数据库里的数据,在网上找了一下这方面的例子,觉得这个还不错,分享给大家. 在这个业务里里面涉及到了更新两张数据表,那么大家是不是会想到非常简单,马上上代码 $sql ,type ...
- ROWID面试题-删除表中重复数据(重复数据保留一个)
/* ROWID是行ID,通过它一定可以定位到r任意一行的数据记录 ROWID DNAME DEPTNO LOC ------------------ ------------------------ ...
随机推荐
- 安卓 运行、调试 配置 android Run/debug configurations
android 运行.调试 配置 android Run/debug configurations 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq. ...
- C#窗体向另一个窗体实时传值及传值问题
C#窗体向另一个窗体实时传值 另外的传值方法:
- HDU.2829.Lawrence(DP 斜率优化)
题目链接 \(Description\) 给定一个\(n\)个数的序列,最多将序列分为\(m+1\)段,每段的价值是这段中所有数两两相乘的和.求最小总价值. \(Solution\) 写到这突然懒得写 ...
- 前端性能优化 —— 减少HTTP请求
简要:对于影响页面呈选 的因素有3个地方:服务器连接数据库并计算返回数据 , http请求以及数据(文件)经过网络传输 , 文件在浏览器中计算渲染呈选: 其中大约80%的时间都耗在了http请求上,所 ...
- webstorm更改字体大小
webstorm是一款不错的开发软件,一起来看看webstorm怎么更改字体大小. 1,打开该软件后,点击上面菜单栏的“文件”/File,找到其子菜单中的“设置”/Setting,点击打开. 2,在新 ...
- Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) C. Bear and Different Names 贪心
C. Bear and Different Names 题目连接: http://codeforces.com/contest/791/problem/C Description In the arm ...
- oracle 列相减——(Oracle分析函数Lead(),Lag())
lag和lead函数,用于取出数据的前n行的数据和后n行的数据,当然要和over(order by)一起组合 其实这2个函数的作用非常好理解,Lead()就是取当前顺序的下一条记录,相对Lag()就是 ...
- tcp keepalive选项
之前一直对tcp keepalive选项理解有误, 以为通过setsockopt函数设置SO_KEEPALIVE和相关参数后该socket则使用设置的keepalive相关参数 否则使用系统默认的:k ...
- API判断本机安装的Revit版本信息
start [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class c ...
- What’s Brewing for .NET Developers
Microsoft hosted its premier fall developer event – Connect(); // 2016 in New York on November 16-17 ...