SHOW V..."/>
您好,登錄后才能下訂單哦!
MySQL中導(dǎo)入數(shù)據(jù)的方法主要有兩種: LOAD和SOURCE, 下面看看兩者的特點(diǎn).
測(cè)試過程中二進(jìn)制日志格式, 和用到的表結(jié)構(gòu)如下:
(root@localhost) [(none)]> SHOW VARIABLES LIKE 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)
(root@localhost) [stage]> SHOW CREATE TABLE st1\G
*************************** 1. row***************************
Table: st1
Create Table: CREATE TABLE `st1` (
`a`int(10) unsigned NOT NULL DEFAULT '0',
`b`varchar(4) NOT NULL DEFAULT '',
`c`int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
使用LOAD導(dǎo)入數(shù)據(jù).
(root@localhost) [stage]> LOAD DATA INFILE '/tmp/st1.txt' INTO TABLE st1;
Query OK, 4 rows affected (0.00 sec)
Records: 4 Deleted: 0 Skipped: 0 Warnings: 0
分析其產(chǎn)生的二進(jìn)制日志, 可以發(fā)現(xiàn)LOAD將該過程作為一個(gè)事物了.
BEGIN
/*!*/;
# at 193
# at 263
#170904 15:36:07 server id 1683316 end_log_pos 314 CRC32 0xffbd6789 Table_map: `stage`.`st1` mapped to number76
# at 314
#170904 15:36:07 server id 1683316 end_log_pos 397 CRC32 0xb3c288aa Write_rows: table id 76 flags: STMT_END_F
### INSERT INTO `stage`.`st1`
### SET
### @1=1
### @2='aa'
### @3=2
### INSERT INTO `stage`.`st1`
### SET
### @1=2
### @2='bb'
### @3=4
### INSERT INTO `stage`.`st1`
### SET
### @1=3
### @2='cc'
### @3=6
### INSERT INTO `stage`.`st1`
### SET
### @1=4
### @2='dd'
### @3=8
# at 397
#170904 15:36:07 server id 1683316 end_log_pos 428 CRC32 0x67fed44c Xid = 29
COMMIT/*!*/;
上面的過程, 其實(shí)和下面的語句是等價(jià)的.
START TRANSACTION;
INSERT INTO st1 VALUES(…);
INSERT INTO st1 VALUES(…);
…
COMMIT;
若LOAD遇到錯(cuò)誤, 如數(shù)據(jù)類型不對(duì), 或數(shù)據(jù)列不匹配等, 整個(gè)過程就會(huì)回滾. 下面是實(shí)際數(shù)據(jù)導(dǎo)入中遇到的一個(gè)報(bào)錯(cuò):
(root@localhost) [product]> LOAD DATA INFILE '/tmp/pro1.txt' INTO TABLE pro1;
ERROR 1261 (01000): Row 4999999 doesn'tcontain data for all columns
(root@localhost) [product]>system perror 1261;
MySQL error code 1261(ER_WARN_TOO_FEW_RECORDS): Row %ld doesn't contain data for all columns
如上報(bào)錯(cuò), 在導(dǎo)入第499999條記錄時(shí), 遇到錯(cuò)誤, 整個(gè)事物進(jìn)行了回滾, 這樣的大事物運(yùn)行效率很低, 即使最后提交成功, 在主從復(fù)制環(huán)境下, 也極有可能造成延時(shí).
建議LOAD導(dǎo)入數(shù)據(jù)時(shí), 可先用命令split將數(shù)據(jù)文件分成若干小文件, 然后多次導(dǎo)入; 也可借助PT工具pt-fifo-split分割文件, 其具體使用見說明文檔.
其實(shí)上面拆分導(dǎo)入的方式, 正是命令SOURCE的思路, 其一般導(dǎo)入INSERT語句, 格式如INSERT INTO st1 VALUES(…), (…), (…) …
下面是實(shí)際數(shù)據(jù)導(dǎo)入中摘出來的日志:
Query OK, 8690 rows affected (0.19 sec)
Records: 8690 Duplicates: 0 Warnings: 0
Query OK, 8800 rows affected (0.24 sec)
Records: 8800 Duplicates: 0 Warnings: 0
可見SOURCE每8000行記錄左右提交一次, 也可在二進(jìn)制日志中得到印證. 若某條記錄出錯(cuò), 其所在分組會(huì)進(jìn)行回滾. 至于為什么是8000, 暫且理解為內(nèi)部機(jī)制了.
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。