超大文本文件解析、数据库备份还原

背景
事故背景

因为运维人员的失误,误将生产数据库清空了,幸好操作前做了备份,但38G的超大sql文件导入耗时将近1个小时,还出现了两次导入失败,其中一次导入进度约等于99%时发生了主键冲突而停止,几乎浪费了3个多小时的宝贵时间,虽然最终还原完成上线成功,但对于这种超大数据库文件的导入确实欠缺应对策略,故此复现问题。

首先数据还原中文件导入至99%时发生了唯一索引冲突造成了导入停止,定位发现有一程序仍在运行插入数据,因此可行的情况下,将服务停止再做还原,另外导入的方式,直接使用mysql导入遇到错误会终止,而source导入方式遇到错误会继续,很不幸运维人员使用的mysql命令进行导入的,导入错误提示为37000行左右,假设不想再浪费一个小时的时间,如何解决冲突如何继续导入呢?

思路,首先定位文件总行数,然后根据出错行数将剩余部分截取至新文件中,删除冲突的sql行,使用source继续进行导入。

数据准备

文件大小:39GB, 行数:38912行, 每行:约1MB字符, 文件名称:bigtext.txt。

行数统计
wc -l 文件名称
grep -c '\n' 文件名称
#其他不建议
sed -n '$='  文件名称
awk 'END { print NR }' 文件名称
效率对比
time wc -l bigtext.txt
38912 bigtext.txt
real    9m58.965s
user    0m9.455s
sys     0m50.827s

time grep -c '\n' bigtext.txt
38912
real    5m22.045s
user    0m11.758s
sys     0m16.724s

#sed awk 时间过长,未作统计

结论 建议使用grep -c的方式统计行数

文件截取
#从结尾截取文件 
tail -c 字符大小 文件名称 > 新文件名称
tail -n 行数 文件名称 > 新文件名称

#从开头截取文件
head -c 字符大小 文件名称 > 新文件名称
head -n 行数 文件名称 > 新文件名称
数据导入
#mysql导入
mysql -uusername -ppassword scheme < scheme.sql

#source导入
mysql -uusername -ppassword
> source import.sql

区别 mysql遇到错误会终止,source遇到错误会继续

加速导入

未作详细验证,感觉实际影响并不大

set sql_log_bin=off;
set autocommit=0;
start transaction;
source 文件.sql;
commit;

#改回配置
set sql_log_bin=on;
set autocommit=1;

#其他加速配置
# 进入mysql中执行如下
SET GLOBAL foreign_key_checks=0;
SET GLOBAL unique_checks=0;
SET GLOBAL innodb_flush_log_at_trx_commit=0;
SET GLOBAL sync_binlog=0;
 
-- 你的sql语句

SET GLOBAL foreign_key_checks=1;
SET GLOBAL unique_checks=1;
SET GLOBAL innodb_flush_log_at_trx_commit=1;
SET GLOBAL sync_binlog=1;

还是要根据实际情况正确处理问题,生产无小事。

参考链接 linux - Count lines in large files - Stack Overflow

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值