开发环境

  • Yii1版本
  • MySQL
  • PHP5.6.27

前言

物流规则匹配日志表记录订单匹配规则相关日志信息,方便管理员维护和查阅不匹配的订单,四个月时间,该日志表数据就有174G,当前,这么大的数据量,不仅对数据库造成了很大的负载压力,同时查询等维护也缓慢,所以采取将日志记录移出到文件进行存储。但是短期内,还需要数据库中的部分日志记录,故而有了下面的删除记录、优化表操作。

日志表大小一览

表本身有六七百万条数据,从六七百万删到五百多万,发现数据占用空间大小一点也没变,如下图所示。网上查到需要释放删除了的数据占用的空间、也就是优化表或碎片整理,使用到的命令是:OPTIMIZE TABLE tableName

问题出现原因

在删除sql语句中,写法如下:DELETE FROM ueb_logistics_rule_logs WHERE type=0 LIMIT 100; 凡是这样,delete带有where条件的,都不是真删除,只是MySQL给记录加了个删除标识,自然这样操作后表数据占有空间也不会变小了

注意:DELETE FROM ueb_logistics_rule_logs; 这条sql语句执行后,就清空了表数据,占有空间就变为0了

解决方法

主要就是执行下面三条sql语句(轮询删除delete,避免一次性删除数据太多造成MySQL负载崩溃,另外数据量大的时候需要等待网站访问流量小的时候执行)

  • DELETE FROM ueb_logistics_rule_logs WHERE type=0 LIMIT 100;
  • OPTIMIZE TABLE ueb_logistics_rule_logs;

源码

基于yii1版本框架,命令行下执行,可以加入定时脚本任务里,自动执行

<?php

/**
* 定时清理相关表数据
* Class Logisticstable
*/
class LogisticstableCommand extends CConsoleCommand
{
public $before15Days;
public $oneMonthAgo;
public $halfYearAgo; /**
* 清理表数据
*
* windows环境:
* >yiic.bat Logisticstable Execute
* >yiic.bat Logisticstable Execute 10
* linux环境:
* >./yiic Logisticstable Execute
* >./yiic Logisticstable Execute 10
*
* @param int $limit 清理的条数
*/
public function actionExecute($limit = 100)
{
$sTime = microtime(true);
$this->initDaytime();
$dbList = $this->tableData(); $cacheKey = 'command:logisticstable:%s:%s';
foreach ($dbList as $db=>$tableList){
foreach ($tableList as $tableInfo){
$tableName = $tableInfo['tableName'];
$cacheKeyTmp = sprintf($cacheKey, $db, $tableName);
$isRunning = Redis::getCache($cacheKeyTmp);
if (!empty($isRunning)){
//当前表正在清理中……
continue;
}
Redis::setCache($cacheKeyTmp, 1, 36000);
//轮询删除表数据
while(!$this->myDeleteData($db, $tableName, $tableInfo['whereStr'], $limit)){
sleep(3);
}
//优化表空间
$this->myOptimizeTable($db, $tableName);
Redis::deleteCache($cacheKeyTmp);
sleep(10);
}
} echo '共计耗时:'. (microtime(true)-$sTime).' s'.PHP_EOL;
exit(0);
} /**
* 删除表数据
* @param $db
* @param $tableName
* @param $where
* @param int $limit
* @return bool
*/
protected function myDeleteData($db, $tableName, $where, $limit = 1000)
{
//连接数据库
$connection = Yii::app()->$db; $findSql = "SELECT * FROM `".$tableName."` WHERE $where ";
$arrRow = $connection->createCommand($findSql)->queryRow();
if (empty($arrRow)){
//没有要删除的数据了
return true;
} //删除
$deleteSql = "DELETE FROM `".$tableName."` WHERE $where LIMIT $limit ";
$connection->createCommand($deleteSql)->execute();
return false;
} /**
* 释放被删除数据占用的空间
* @param $db
* @param $tableName
* @return mixed
*/
protected function myOptimizeTable($db, $tableName)
{
//连接数据库
$connection = Yii::app()->$db; //优化表空间
$optimizeSql = "OPTIMIZE TABLE `".$tableName."`";
return $connection->createCommand($optimizeSql)->execute();
} /**
* 初始化时间
*/
protected function initDaytime()
{
$this->before15Days = date('Y-m-d H:i:s', strtotime('-15 day'));
$this->oneMonthAgo = date('Y-m-d H:i:s', strtotime('-1 month'));
$this->halfYearAgo = date('Y-m-d H:i:s', strtotime('-6 month'));
} /**
* 相关表数据
*/
protected function tableData()
{
return [
'db_logistics'=>[
[
//check_task_is_run 保留最新15天
'tableName'=>'check_task_is_run',
'whereStr'=> "create_time < '{$this->before15Days}'"
],
[
//check_task_run_get_logistict_cost 30天
'tableName'=>'check_task_run_get_logistict_cost',
'whereStr'=> "create_time < '{$this->oneMonthAgo}'"
],
[
//ueb_logistics_rule_opration_log 半年
'tableName'=>'ueb_logistics_rule_opration_log',
'whereStr'=> "create_time < '{$this->before15Days}'"
],
]
];
}
}

总结

惭愧,今天才碰到这类问题,MySQL delete表数据,之前一直的感觉就是直接删除掉了,数据所占的空间也自然会释放,但是今天才发现,delete sql语句后加where条件删除的数据MySQL会自动加个delete标识而不会真的删掉。学的太浅了,还需多多努力!

参考资料

针对mysql delete删除表数据后占用空间不变小的问题的更多相关文章

  1. mysql 清空或删除表数据后,控制表自增列值的方法

    http://blog.sina.com.cn/s/blog_68431a3b0100y04v.html 方法1: truncate table 你的表名 //这样不但将数据全部删除,而且重新定位自增 ...

  2. mysql:删除表数据drop、truncate和delete的用法

    程度从强到弱 1.drop  table tb        drop将表格直接删除,没有办法找回 2.truncate (table) tb       删除表中的所有数据,不能与where一起使用 ...

  3. mysql mariadb 删除表中的数据时数据库变大

    删除表中数据以前 [root@RM uar3]# du -sh * 3.3G apache-tomcat-7.0.54 150M instalRM4UAR 0 mariadb 903M mariadb ...

  4. MySQL删除表数据

    原文请点这里 在MySQL中有两种方法可以删除数据,一种是DELETE语句,另一种是TRUNCATE TABLE语句.DELETE语句可以通过WHERE对要删除的记录进行选择.而使用TRUNCATE ...

  5. mysql进阶(二十一)删除表数据

    MySQL删除表数据 在MySQL中有两种方法可以删除数据,一种是DELETE语句,另一种是TRUNCATE TABLE语句.DELETE语句可以通过WHERE对要删除的记录进行选择.而使用TRUNC ...

  6. sql语句中----删除表数据drop、truncate和delete的用法

    sql语句中----删除表数据drop.truncate和delete的用法 --drop drop table  tb   --tb表示数据表的名字,下同 删除内容和定义,释放空间.简单来说就是把整 ...

  7. 删除表数据drop、truncate和delete的用法

    说到删除表数据的关键字,大家记得最多的可能就是delete了 然而我们做数据库开发,读取数据库数据.对另外的两兄弟用得就比较少了 现在来介绍另外两个兄弟,都是删除表数据的,其实也是很容易理解的 老大- ...

  8. 数据库之删除表数据drop、truncate和delete的用法

    数据库中删除表数据的关键字,最常用的可能就是delete了,另外其实还有drop和truncate两个关键字. 老大:drop 命令格式:drop table  tb  ---tb表示数据表的名字,下 ...

  9. [转] sql 删除表数据的drop、truncate和delete用法

    删除表数据的关键字,大家记得最多的可能就是delete.然而,我们做数据库开发,读取数据库数据.对另外的drop.truncate用得就比较少了. 1 drop 出没场合:drop table  ta ...

随机推荐

  1. text-decoration和text-indent和text-shadow

    text-decoration 属性规定添加到文本的修饰,规定划线的位置. <html> <head> <style type="text/css"& ...

  2. 第17月第26天 setImageForState变形

    1. 关于UIButton,既可以采用setBackgroundImage 来设置底部图片,同时也可以采用  setImage方法: 两者还是有一定区别的: 首先setBackgroundImage, ...

  3. Struts的JSON机制

    需要加入jar包 Struts的JSON帮助我们自动将对象解析为JSON对象,不用我门借助第三方进行JSON的解析 .具体的使用机制如下: 1.Action类 package StrutsJSON; ...

  4. 【转】Python之装饰器

    [转]Python之装饰器 本节内容 必要知识回顾 情景模拟 装饰器的概念及实现原理 回马枪(带参数的装饰器) 一. 必要知识回顾 在开始说装饰器之前,需要大家熟悉之前说过的相关知识点: 函数即“变量 ...

  5. 网络常用的linux系统调用

    网络之常用的Linux系统调用 下面一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数将在前面标上“*”号以示区别. 一.进程控制 fo ...

  6. oracle数据库自增主键重复

    select max(t.id) from T_PLAT_ENUM_VALUE tdrop sequence T_PLAT_ENUM_VALUE;create sequence T_PLAT_ENUM ...

  7. WebsphereMQ搭建集群

    #https://www.ibm.com/developerworks/cn/websphere/library/techarticles/1202_gaoly_mq/1202_gaoly_mq.ht ...

  8. ASP.NET Core Identity 实战(4)授权过程

    这篇文章我们将一起来学习 Asp.Net Core 中的(注:这样描述不准确,稍后你会明白)授权过程 前情提要 在之前的文章里,我们有提到认证和授权是两个分开的过程,而且认证过程不属于Identity ...

  9. windows环境变量PATH顺序的重要性

    PATH是路径的意思,PATH环境变量中存放的值,就是一连串的路径.不同的路径之间,用英文的分号间隔开.系统在执行用户命令时,若用户未给出绝对路径,则首先在当前目录下寻找相应的可执行文件.批处理文件等 ...

  10. windows系统中搭建Jenkins服务器

    1       须知 100.126.36.232等Jenkins服务器是通过设置代理访问外网,管理Jenkins和插件升级站点的,本地安装受黄区网络限制需要特殊配置,且有些插件无法下载. 前提条件: ...