MYSQL 匯入出錯從指定行號擷取檔案(C語言寫的)及注意事項
今天同事匯入MYSQL的時候遇到錯誤 匯出檔案大約200G,在大約1.8w行出錯。檔案太大用SED讀取指定行的時候命令報錯,
sed -n '18032,$p' sql.sql >sqlnew.sql
如果檢視任何資訊都非常麻煩,但是
MYSQL報錯的時候出現了一個行號,然後大概推算了一下得出了開始的行號,所以使用C寫了一個小程式,記錄下來
i==18031 是你確定的行號-1 開始。
速度還行。
實際上就是根據換行符確定行號然後接著寫入。
寫入完成後使用sed替換了某些字元
sed -i 's/\*\/\;\;/\*\/\$\$/g' reslutnew.sql
可以完成,sed取行的時候應該是OOM了。
注意:
1、這樣擷取沒有 use database資訊需要自己寫一下然後source
2、這樣擷取MYSQLDUMP語句的頭資訊肯定沒有了要自己寫一下
3、注意關閉binlog set sql_bin_log=0;
4、注意設定 = 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後下一個表以前
sed -n '18032,$p' sql.sql >sqlnew.sql
如果檢視任何資訊都非常麻煩,但是
MYSQL報錯的時候出現了一個行號,然後大概推算了一下得出了開始的行號,所以使用C寫了一個小程式,記錄下來
i==18031 是你確定的行號-1 開始。
點選(此處)摺疊或開啟
-
#include<stdio.h>
-
#include<stdlib.h>
-
#include <string.h>
-
-
-
int main(void)
-
{
-
FILE* fd1;
-
FILE* fd2;
-
int i=0;
-
char m;
-
-
char test[4096];
-
-
if(!(fd1=fopen("reslut.sql","r")))
-
{
-
printf("file 1 open error!\n");
-
exit(10);
-
}
-
if(!(fd2=fopen("reslutnew.sql","w+")))
-
{
-
printf("file 2 open error!\n");
-
exit(10);
-
}
-
while(1)
-
{
-
if(fgetc(fd1) == '\n')
-
{
-
i++;
-
if(i==18031)
-
{
-
break;
-
}
-
}
-
}
-
while(!(feof(fd1)))
-
{
-
memset(test,0,4096);
-
fread(test,1000,4,fd1);
-
fwrite(test,strlen(test),1,fd2);
-
}
-
-
fclose(fd1);
-
fclose(fd2);
-
- }
實際上就是根據換行符確定行號然後接著寫入。
寫入完成後使用sed替換了某些字元
sed -i 's/\*\/\;\;/\*\/\$\$/g' reslutnew.sql
可以完成,sed取行的時候應該是OOM了。
注意:
1、這樣擷取沒有 use database資訊需要自己寫一下然後source
2、這樣擷取MYSQLDUMP語句的頭資訊肯定沒有了要自己寫一下
3、注意關閉binlog set sql_bin_log=0;
4、注意設定 = 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後下一個表以前
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2125234/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 用XML編寫EXCEL檔案,XML的寫法注意事項,可以C#+xslt匯出ExcelXMLExcelC#
- 用IDA匯出map檔案時的注意事項
- MySQL常用語句及注意事項MySql
- 奇怪的C語言——C51程式設計C語言注意事項C語言程式設計
- MySQL匯入匯出檔案檔案MySql
- fgets讀取檔案時的注意事項
- C 語言位域使用及其注意事項
- C語言讀取寫入CSV檔案 [一]基礎篇C語言
- C語言getpwnam()函式:從密碼檔案中取得指定賬號的資料C語言函式密碼
- 使用go語言對csv檔案進行解析處理,匯入匯出。Go
- mysql 匯入匯出 sql檔案MySql
- MySQL匯入匯出平面檔案MySql
- C語言putc()函式:寫檔案函式(將一指定字元寫入檔案中)C語言函式字元
- Python匯入包的注意事項Python
- Oracle 資料匯出注意事項Oracle
- C語言fputc()函式:寫檔案函式(將一指定字元寫入檔案流中)C語言函式字元
- C語言-檔案讀寫C語言
- sqoop匯入orcle注意事項OOP
- Oracle中exp,imp(匯入匯出)資料遷移注意事項Oracle
- 將WAV檔案做到EXE檔案的方法及注意事項 (轉)
- MySQL匯入CSV/TXT等資料來源中資料操作流程及注意事項MySql
- python相對匯入注意事項Python
- C語言setpwent()函式:從頭讀取密碼檔案中的賬號資料C語言函式密碼
- mysql索引使用技巧及注意事項MySql索引
- C語言/C++讀取檔案資訊C語言C++
- JAVA語言的開啟檔案和寫入檔案Java
- PHP獲取指定函式定義在哪個檔案中及行號PHP函式
- ubuntu 下mysql匯入和匯出.sql檔案UbuntuMySql
- MySQL 匯出匯入二進位制檔案MySql
- Mysql匯入大表檔案時注意修改引數MySql
- Mysql從指定位置擷取字串MySql字串
- php讀取excel檔案資料的匯入和匯出PHPExcel
- 快取注意事項快取
- R語言 - 讀取CSV檔案報錯R語言
- VirtualBox匯入虛擬機器注意事項虛擬機
- 關於mysql執行效率優化注意事項及要點MySql優化
- 從MySQL到ORACLE程式遷移的注意事項(轉)MySqlOracle
- php大檔案上傳注意事項PHP