1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-34703 LOAD DATA INFILE using Innodb bulk load aborts

problem:
=======
- During load statement, InnoDB bulk operation relies on temporary
directory and it got crash when tmpdir is exhausted.

Solution:
========
During bulk insert, LOAD statement is building the clustered
index one record at a time instead of page. By doing this,
InnoDB does the following
1) Avoids creation of temporary file for clustered index.
2) Writes the undo log for first insert operation alone
This commit is contained in:
Thirunarayanan Balathandayuthapani
2025-01-15 18:30:03 +05:30
parent f4e999d753
commit 2d42e9ff7d
10 changed files with 203 additions and 20 deletions

View File

@@ -0,0 +1,50 @@
CREATE TABLE t1(f1 INT NOT NULL,f2 INT NOT NULL)ENGINE=InnoDB;
INSERT INTO t1 SELECT seq, seq from seq_1_to_131072;
INSERT INTO t1 VALUES(131073, 131073), (131074, 131073);
SELECT * INTO OUTFILE "VARDIR/tmp/t1.outfile" FROM t1;
# successful load statement using bulk insert
CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY,
f2 INT NOT NULL)ENGINE=InnoDB;
SET unique_checks=0, foreign_key_checks=0;
LOAD DATA INFILE 'VARDIR/tmp/t1.outfile' INTO TABLE t2;
SELECT COUNT(*) FROM t2;
COUNT(*)
131074
CHECK TABLE t2 EXTENDED;
Table Op Msg_type Msg_text
test.t2 check status OK
DROP TABLE t2;
CREATE TABLE t2(f1 INT NOT NULL, PRIMARY KEY(f1 DESC),
f2 INT NOT NULL)ENGINE=InnoDB;
LOAD DATA INFILE 'VARDIR/tmp/t1.outfile' INTO TABLE t2;
SELECT COUNT(*) FROM t2;
COUNT(*)
131074
CHECK TABLE t2 EXTENDED;
Table Op Msg_type Msg_text
test.t2 check status OK
DROP TABLE t2;
# load statement using bulk insert fails during secondary index
CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY,
f2 INT NOT NULL UNIQUE KEY)ENGINE=InnoDB;
LOAD DATA INFILE 'VARDIR/tmp/t1.outfile' INTO TABLE t2;
ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
SELECT COUNT(*) FROM t2;
COUNT(*)
0
CHECK TABLE t2 EXTENDED;
Table Op Msg_type Msg_text
test.t2 check status OK
DROP TABLE t2;
# load statement using bulk insert fails during primary index
CREATE TABLE t2(f1 INT NOT NULL,
f2 INT NOT NULL PRIMARY KEY)ENGINE=InnoDB;
LOAD DATA INFILE 'VARDIR/tmp/t1.outfile' INTO TABLE t2;
ERROR 23000: Duplicate entry '131073' for key 'PRIMARY'
SELECT COUNT(*) FROM t2;
COUNT(*)
0
CHECK TABLE t2 EXTENDED;
Table Op Msg_type Msg_text
test.t2 check status OK
DROP TABLE t2, t1;

View File

@@ -0,0 +1 @@
--innodb_sort_buffer_size=65536

View File

@@ -0,0 +1,52 @@
--source include/have_innodb.inc
--source include/have_sequence.inc
--source include/big_test.inc
CREATE TABLE t1(f1 INT NOT NULL,f2 INT NOT NULL)ENGINE=InnoDB;
INSERT INTO t1 SELECT seq, seq from seq_1_to_131072;
INSERT INTO t1 VALUES(131073, 131073), (131074, 131073);
--replace_result $MYSQLTEST_VARDIR VARDIR
--disable_cursor_protocol
--disable_ps2_protocol
eval SELECT * INTO OUTFILE "$MYSQLTEST_VARDIR/tmp/t1.outfile" FROM t1;
--enable_ps2_protocol
--enable_cursor_protocol
--echo # successful load statement using bulk insert
CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY,
f2 INT NOT NULL)ENGINE=InnoDB;
SET unique_checks=0, foreign_key_checks=0;
--replace_result $MYSQLTEST_VARDIR VARDIR
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.outfile' INTO TABLE t2;
SELECT COUNT(*) FROM t2;
CHECK TABLE t2 EXTENDED;
DROP TABLE t2;
CREATE TABLE t2(f1 INT NOT NULL, PRIMARY KEY(f1 DESC),
f2 INT NOT NULL)ENGINE=InnoDB;
--replace_result $MYSQLTEST_VARDIR VARDIR
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.outfile' INTO TABLE t2;
SELECT COUNT(*) FROM t2;
CHECK TABLE t2 EXTENDED;
DROP TABLE t2;
--echo # load statement using bulk insert fails during secondary index
CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY,
f2 INT NOT NULL UNIQUE KEY)ENGINE=InnoDB;
--replace_result $MYSQLTEST_VARDIR VARDIR
--error ER_ERROR_DURING_COMMIT
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.outfile' INTO TABLE t2;
SELECT COUNT(*) FROM t2;
CHECK TABLE t2 EXTENDED;
DROP TABLE t2;
--echo # load statement using bulk insert fails during primary index
CREATE TABLE t2(f1 INT NOT NULL,
f2 INT NOT NULL PRIMARY KEY)ENGINE=InnoDB;
--replace_result $MYSQLTEST_VARDIR VARDIR
--error ER_DUP_ENTRY
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.outfile' INTO TABLE t2;
SELECT COUNT(*) FROM t2;
CHECK TABLE t2 EXTENDED;
--remove_file $MYSQLTEST_VARDIR/tmp/t1.outfile
DROP TABLE t2, t1;