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

今天同事导入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、在存储过程和触发替换 ;;为$$的过程中因为担心数据中也有这种信息
我们使用如下几次替换:
sed -i 's/\*\/\;\;/\*\/\$\$/g'   替换*/;; 为*/$$
sed -i 's/DELIMITER ;;/DELIMITER $$/g' 替换 DELIMITER ;; 为 DELIMITER $$
sed -i 's/end ;;/end $$/g' 替换 end ;; 为 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后下一个表以前

时间: 2024-11-03 10:13:41

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

大数据量POI导出Excel出错及getRow(行号)返回空行的问题咨询

问题描述 本人最近有个需求.就是导出1个含3个Sheet的excel.其中有个sheet的数据量比较大(大有90W条).每个sheet都有汇总统计信息及分组统计信息.咱是用的SXSSFWorkbookwb=newSXSSFWorkbook(-1);方式创建工作表然后每5000条记录调用一次((SXSSFSheet)sheet).flushRows();刷一次缓存.现在咱遇到两个问题1,导出报错,错误日志为:Exceptioninthread"main"java.lang.OutOfMe

新人求助,写csdn博客的时候插入代码显示行号

问题描述 新人求助,写csdn博客的时候插入代码显示行号 这是我自己写博客时候插入的代码,但是不显示行号,请问怎么才能显示呢 解决方案 我明白了,原来保存之后就有行号了,被自己蠢哭了(┬_┬) 解决方案二: 解决方案三: markdown好像没有这个功能.

Mysql导入.sql文件出错

问题描述 Mysql导入.sql文件出错 mysql导入sql文件时老是提示错误,请问各位高手该怎么解决? 解决方案 那最长的串右侧没有单引号 '注意用括起来' 解决方案二: 单引号要成双成对.一一对应. 否则,SQL语句可能会因为错误的单引号导致语法错误. 解决方案三: 中文字符串后面缺少单引号 解决方案四: sql文件格式有问题,估计引号什么的被中文字符串影响了

MFC线程计算可以不从函数的开始的位置,而从指定的行号开始执行么

问题描述 MFC线程计算可以不从函数的开始的位置,而从指定的行号开始执行么 MFC线程计算可以不从函数的开始的位置,而从指定的行号开始执行么,怎么根据行号来执行函数? 解决方案 给需要用到的行加上标号,自己编号,在程序开头判断,用goto跳转执行

MySQL中在查询结果集中得到记录行号的方法

 如果需要在查询语句返回的列中包含一列表示该条记录在整个结果集中的行号, ISO SQL:2003 标准提出的方法是提供 ROW_NUMBER() / RANK() 函数. Oracle 中可以使用标准方法(8i版本以上),也可以使用非标准的 ROWNUM : MS SQL Server 则在 2005 版本中提供了 ROW_NUMBER() 函数:但在MySQL 中似乎还没有这样的系统自带功能.虽然 LIMIT 可以很方便的对返回的结果集数量和位置进行过滤,但过滤出来的记录的行号却没办法被 S

在Word文档中按指定的间隔显示行号的方法

  在Word文档中按指定的间隔显示行号的方法         1.启动Word 2013,打开需要添加行号的文档.在"页面布局"选项卡中单击"页面设置"按钮打开"页面设置"对话框,在"版式"选项卡中单击"行号"按钮,如图1所示. 图1 "页面设置"对话框 注意 在"页面设置"组中单击"行号"按钮 ,在打开的列表中选择"无"选项

mysql导入数据特殊符号出错问题

问题描述 mysql导入数据特殊符号出错问题 ,无论将编码都设成gbk还是utf8都出现同样的报错,就这有特殊符号的这一行.日志是服务器端自动记录的,偶尔还会出现其他的乱码特殊符号,替换的话,开销太大.有什么方法可以实现成功导入到数据库呢? 解决方案 统一一下你的项目编码,比如无论导入导出,都使用utf-8 解决方案二: 创建数据库时,将编码改为Latin2,就可以导入了.究竟该怎么解决这个问题呢.来人帮忙啊

MySQL中在查询结果集中得到记录行号的方法_Mysql

如果需要在查询语句返回的列中包含一列表示该条记录在整个结果集中的行号, ISO SQL:2003 标准提出的方法是提供 ROW_NUMBER() / RANK() 函数. Oracle 中可以使用标准方法(8i版本以上),也可以使用非标准的 ROWNUM : MS SQL Server 则在 2005 版本中提供了 ROW_NUMBER() 函数:但在 MySQL 中似乎还没有这样的系统自带功能.虽然 LIMIT 可以很方便的对返回的结果集数量和位置进行过滤,但过滤出来的记录的行号却没办法被 S

导入密钥时出错,指定了无效的提供程序类型

问题描述 win7系统重装后,安装vs2012需要重新导入密钥,导入时出错了,以为是.netframework3.5版本没安装导致不兼容,但是网上查了win7是自带.netframework3.5而且也有打开了就是导入出错求大神帮忙! 解决方案