当前位置: 首页 > article >正文

安全快速地删除 MySQL 大表数据并释放空间

一、需求

  1. 按业务逻辑删除大量表数据
  2. 操作不卡库,不能影响正常业务操作
  3. 操作不能造成 60 秒以上的复制延迟
  4. 满足以上条件的前提下,尽快删除数据并释放所占空间

        表结构如下:

create table `space_visit_av` (
  `userid` bigint(20) not null comment '用户id',
  `avid` bigint(20) not null comment '作品id',
  `touserid` bigint(20) not null comment '被访问用户d',
  `createtime` timestamp not null default current_timestamp comment '创建时间',
  `updatetime` timestamp not null default current_timestamp on update current_timestamp comment '收藏时间',
  primary key (`userid`,`avid`),
  key `index_1` (`touserid`,`updatetime`) using btree,
  key `index_2` (`avid`,`updatetime`) using btree,
  key `idx_updatetime` (`updatetime`)
) engine=innodb default charset=utf8 comment='用户访问作品表';

        表中现有约 50 亿条数据,只保留 2023-10-01 以后的数据(约占总量的 1/10),其它删除。

二、实现

1. 主库按原表创建删除关联表,只保留原表的主键

mysql -uwxy -p123456 -h10.10.10.1 -P18251 -Dspace -e "
create table del (
  userid bigint(20) not null comment '用户id',
  avid bigint(20) not null comment '作品id',
  primary key (userid,avid));"

2. 导出需要删除数据的主键到文件

-- 在从库执行查询
select userid, avid into outfile '/data/del.txt' from space_visit_av where updatetime < '2023-10-01';

3. 将文件分割成 10 万行一个的小文件

cd /data
split -l 100000 -d -a 6 del.txt

# 删除原文件
rm del.txt

4. 遍历文件执行删除

# 后台执行
nohup ~/del.sh > ~/del.log 2>&1 &

        del.sh 脚本文件内容如下:

#!/bin/bash
source ~/.bashrc

dir="/data/"
ls $dir | while read line
do
    file=${dir}${line}

    # 表关联删除数据
    mysql -wxy -p123456 -h10.10.10.1 -P18251 -Dspace --local-infile -e "
        delete from del;
        load data local infile '$file' into table del;
        analyze table del; analyze table space_visit_av;
        delete t1 from space_visit_av t1, del t2 where t1.userid=t2.userid and t1.avid=t2.avid;" -vvv

    echo ${line}
    
    # 取得所有从库的延迟秒数
    s1=`mysql -wxy -p123456 -h10.10.10.2 -P18251 -e "show slave status\G" 2>/dev/null | egrep 'Seconds_Behind_Master' | awk -F": " '{print $2}'`
    s2=`mysql -wxy -p123456 -h10.10.10.3 -P18251 -e "show slave status\G" 2>/dev/null | egrep 'Seconds_Behind_Master' | awk -F": " '{print $2}'`
    s3=`mysql -wxy -p123456 -h10.10.10.4 -P18251 -e "show slave status\G" 2>/dev/null | egrep 'Seconds_Behind_Master' | awk -F": " '{print $2}'`

    # 只有所有从库延迟小于等于 1 秒时继续执行删除,否则等待从库追赶
    while ((s1 > 1)) || ((s2 > 1)) || ((s3 > 1))
    do
        sleep 1;
        s1=`mysql -wxy -p123456 -h10.10.10.2 -P18251 -e "show slave status\G" 2>/dev/null | egrep 'Seconds_Behind_Master' | awk -F": " '{print $2}'`
        s2=`mysql -wxy -p123456 -h10.10.10.3 -P18251 -e "show slave status\G" 2>/dev/null | egrep 'Seconds_Behind_Master' | awk -F": " '{print $2}'`
        s3=`mysql -wxy -p123456 -h10.10.10.4 -P18251 -e "show slave status\G" 2>/dev/null | egrep 'Seconds_Behind_Master' | awk -F": " '{print $2}'`

        echo "$s1 $s2 $s3"
    done

done

# 删除完成后,分析原表,删除关联表
mysql -wxy -p123456 -h10.10.10.1 -P18251 -Dspace -e "
    analyze table space_visit_av;
    drop table del;"

5. 所有从库分析表

mysql -wxy -p123456 -h10.10.10.2 -P18251 -Dspace -e "analyze table space_visit_av;"
mysql -wxy -p123456 -h10.10.10.3 -P18251 -Dspace -e "analyze table space_visit_av;"
mysql -wxy -p123456 -h10.10.10.4 -P18251 -Dspace -e "analyze table space_visit_av;"

6. 使用 pt-online-schema-change 释放删除数据所占空间

# 后台执行
nohup ~/shrink.sh > ~/shrink.log 2>&1 &

        shrink.sh 脚本文件内容如下:

#!/bin/bash
source ~/.bashrc

# 连接主库执行
pt-online-schema-change \
--host="10.10.10.1" \
--port=18251 \
--user="wxy" \
--password="123456" \
--charset="utf8mb4" \
--chunk-size=10000 \
--recursion-method="processlist" \
--check-interval=10s \
--max-lag=60s \
--nocheck-replication-filters \
--critical-load="Threads_running=512" \
--max-load="Threads_running=256" \
D="space",t="space_visit_av" \
--progress=time,30 \
--execute


http://www.kler.cn/news/162332.html

相关文章:

  • 微信小程序 - 创建 ZIP 压缩包
  • Termux
  • VIT总结
  • 算法学习—排序
  • 用网安技术去合法挖漏洞,一个月能拿多少钱?想不到吧!
  • NVMe Over Fabrics with iRDMA总结 - 1
  • WT2605-24SS录放音语音芯片:便捷按键功能提升用户体验
  • linux下查看文件当下的所有文件的大小和查找大文件
  • 线性动态规划
  • 《使用ThinkPHP6开发项目》 - 设置项目环境变量
  • 在线教育小程序如何一键生成App
  • 使用微信虚拟支付后端请求API总是支付签名校验失败
  • 参加百度Apollo技术沙龙—感受自动驾驶的魅力
  • MySQL-日期时间函数详解及练习
  • VUE笔试题精讲1
  • VUE3给table的head添加popover筛选、时间去除时分秒、字符串替换某字符
  • macOS本地调试k8s源码
  • mac苹果笔记本电脑如何强力删除卸载app软件?
  • SQL进阶 | CASE表达式
  • 泽攸科技二维材料转移台的应用场景及优势
  • go-zero 开发入门-加法客服端示例
  • 一文详解设备维护管理软件:降本增效的关键利器
  • Java线程池—附阿里巴巴Java开发手册强制规范要求
  • 【CCF-B】中科院1区TOP,极速1天见刊,国人友好,基金申请必备之选!
  • navigationBar顶部导航栏,兼容适配所有机型(附完整案例)
  • 3接上篇 我的自定义GPTs的改进优化 与物理世界连接成功 GPTs的创建与使用定义和执行特定任务的功能模块 通过API与外部系统或服务的交互
  • git常用命令指南
  • android 13.0 去掉usb授权提示框 默认给予权限
  • 12月7日作业
  • pytorch学习入门之 Variable(变量)