MYSQL 导入出错从指定行号截取文件(C语言写的)及注意事项

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 今天同事导入MYSQL的时候遇到错误 导出文件大约200G,在大约1.8w行出错。文件太大用SED读取指定行的时候命令报错, sed -n '18032,$p' sql.sql >sqlnew.sql 如果查看任何信息都非常麻烦,但是 MYSQL报错的时候出现了一个行号,然后大概推算了一下得出了开始的行号,所以使用C写了一个小程序,记录下来 i==18031 是你确定的行号-1 开始。
今天同事导入MYSQL的时候遇到错误 导出文件大约200G,在大约1.8w行出错。文件太大用SED读取指定行的时候命令报错,
sed -n ' 18032,$p' sql.sql >sqlnew.sql

如果查看任何信息都非常麻烦,但是
MYSQL报错的时候出现了一个行号,然后大概推算了一下得出了开始的行号,所以使用C写了一个小程序,记录下来

i==18031 是你确定的行号-1 开始。

点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include <string.h>


  4. int main(void)
  5. {
  6.         FILE* fd1;
  7.         FILE* fd2;
  8.         int i=0;
  9.         char m;

  10.         char test[4096];

  11.         if(!(fd1=fopen("reslut.sql","r")))
  12.         {
  13.                 printf("file 1 open error!\n");
  14.                 exit(10);
  15.         }
  16.         if(!(fd2=fopen("reslutnew.sql","w+")))
  17.         {
  18.                 printf("file 2 open error!\n");
  19.                 exit(10);
  20.         }
  21.         while(1)
  22.         {
  23.         if(fgetc(fd1) == '\n')
  24.          {
  25.                 i++;
  26.                 if(i==18031)
  27.                 {
  28.                         break;
  29.                 }
  30.          }
  31.         }
  32.         while(!(feof(fd1)))
  33.         {
  34.                 memset(test,0,4096);
  35.                 fread(test,1000,4,fd1);
  36.                 fwrite(test,strlen(test),1,fd2);
  37.         }

  38.         fclose(fd1);
  39.         fclose(fd2);

  40. }
速度还行。
实际上就是根据换行符确定行号然后接着写入。
写入完成后使用sed替换了某些字符
sed -i 's/\*\/\;\;/\*\/\$\$/g'  reslutnew.sql
可以完成,sed取行的时候应该是OOM了。

注意:
1、这样截取没有 use database信息需要自己写一下然后source
2、这样截取MYSQLDUMP语句的头信息肯定没有了要自己写一下
3、注意关闭binlog set sql_bin_log=0;
4、注意设置 innodb_flush_log_at_trx_commit  = 0

关于分开导出表结构和数据 注意事项:
1、表结构中使用--skip-triggers不要导出trigger,因为触发器可能导致数据变化,同时trigger是随表导出的一定要--skip-triggers
       在某些跨版本的情况下routine都不要导出,只要建表建库等语句,注意导出表结构和导出表数据都要--skip-trigger 因为不管
        导出数据还是表结构trigger都会导出
2、MYSQL库会在导入结构的时候插入字典信息,导出数据同样包含了MYSQL的信息,这个时候再往MYSQL插入数据就会报错
     处理就是删除MYSQL数据库
3、在存储过程和触发替换 ;;为使sedis/\*\//\*\/$$/g/;;/

sed -i 's/DELIMITER ;;/DELIMITER /gDELIMITER;;DELIMITER

sed -i 's/end ;;/end /gend;;end

4、如果截断了行进行再次导入一定注意加上MYSQLDUMP文件的一些初始的变量设置如:

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

5、如果用MYSQL界面导入设置一个 --tee log.log 用于记录插入日志

关于trigger 还有一点要说明:
trigger本生是随表导出的。
也就是不管是after还是before的trigger某个表的触发器都是在
这个表数据insert以后建立,这样既保证了trigger的建立也保证了
数据不会变化,但是如果先导入的是表结构带了trigger那么就打破了
这个原则导致数据乱掉。
看如下dump:
LOCK TABLES `mmmm` WRITE;
/*!40000 ALTER TABLE `mmmm` DISABLE KEYS */;
INSERT INTO `mmmm` VALUES (1);
/*!40000 ALTER TABLE `mmmm` ENABLE KEYS */;
UNLOCK TABLES;
/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client  = utf8 */ ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection  = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
/*!50003 SET sql_mode              = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger tri_bb after insert on mmmm
for each row
begin
insert into mmmm1 select count(*) from mmmm;
end */;;
DELIMITER ;
/*!50003 SET sql_mode              = @saved_sql_mode */ ;
/*!50003 SET character_set_client  = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection  = @saved_col_connection */ ;


--
-- Dumping data for table `mmmm2`
--


LOCK TABLES `mmmm2` WRITE;
/*!40000 ALTER TABLE `mmmm2` DISABLE KEYS */;
INSERT INTO `mmmm2` VALUES (1);
/*!40000 ALTER TABLE `mmmm2` ENABLE KEYS */;
UNLOCK TABLES;
/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client  = utf8 */ ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection  = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
/*!50003 SET sql_mode              = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger tri_bb1 after insert on mmmm2
for each row
begin
insert into mmmm3 select count(*) from mmmm;
end */;;
DELIMITER ;
/*!50003 SET sql_mode              = @saved_sql_mode */ ;
/*!50003 SET character_set_client  = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection  = @saved_col_connection */ ;


可以看到trigger的建立是在表insert后下一个表以前

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
打赏
0
0
0
0
91
分享
相关文章
MySQL底层概述—4.InnoDB数据文件
本文介绍了InnoDB表空间文件结构及其组成部分,包括表空间、段、区、页和行。表空间是最高逻辑层,包含多个段;段由若干个区组成,每个区包含64个连续的页,页用于存储多条行记录。文章还详细解析了Page结构,分为通用部分(文件头与文件尾)、数据记录部分和页目录部分。此外,文中探讨了行记录格式,包括四种行格式(Redundant、Compact、Dynamic和Compressed),重点介绍了Compact行记录格式及其溢出机制。最后,文章解释了不同行格式的特点及应用场景,帮助理解InnoDB存储引擎的工作原理。
MySQL底层概述—4.InnoDB数据文件
MySQL补充性文件
通过以上内容,您可以全面了解和掌握 MySQL 补充性文件的配置、查看及其作用,从而提升数据库管理的效率和质量。
70 36
【C语言程序设计——文件】文件操作(头歌实践教学平台习题)【合集】
本文介绍了C语言中的文件操作,分为两个关卡。第1关任务是将键盘输入的字符(以#结束)存入`file1.txt`并显示输出;第2关任务是从键盘输入若干行文本(每行不超过80个字符,用-1作为结束标志),写入`file2.txt`后再读取并显示。文中详细讲解了文件的打开、读取(使用`fgetc()`和`fgets()`)、写入(使用`fputc()`和`fputs()`)及关闭操作,并提供了示例代码和测试说明。
68 5
Linux下mysql数据库的导入与导出以及查看端口
本文详细介绍了在Linux下如何导入和导出MySQL数据库,以及查看MySQL运行端口的方法。通过这些操作,用户可以轻松进行数据库的备份与恢复,以及确认MySQL服务的运行状态和端口。掌握这些技能,对于日常数据库管理和维护非常重要。
155 8
数据库数据恢复—MYSQL数据库文件损坏的数据恢复案例
mysql数据库文件ibdata1、MYI、MYD损坏。 故障表现:1、数据库无法进行查询等操作;2、使用mysqlcheck和myisamchk无法修复数据库。
解决MySQL删除/var/lib/mysql下的所有文件后无法启动的问题
删除 `/var/lib/mysql` 下的所有文件后,需要重新初始化数据目录,确保正确的权限设置,并重新启动 MySQL 服务。通过按照上述步骤操作,可以解决 MySQL 无法启动的问题,并恢复数据库的正常运行。初始化数据目录后,别忘了配置安全设置,并根据需要恢复备份数据。这些步骤不仅能够恢复 MySQL 的正常运行,还能确保数据库的安全性和完整性。
212 2
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
201 4
C语言中的预处理器指令,涵盖其基本概念、常见指令(如`#define`、`#include`、条件编译指令等)、使用技巧及注意事项
本文深入解析C语言中的预处理器指令,涵盖其基本概念、常见指令(如`#define`、`#include`、条件编译指令等)、使用技巧及注意事项,并通过实际案例分析,展示预处理器指令在代码编写与处理中的重要性和灵活性。
107 2
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等