From 95e99e12639f8cde87bba555dcb72cd8cc6542ad Mon Sep 17 00:00:00 2001 From: Praveenkumar Hulakund <praveenkumar.hulakund@oracle.com> Date: Wed, 19 Mar 2014 12:30:30 +0530 Subject: [PATCH] Bug#11759519 - INFINITE HANG WITH 100% CPU USAGE WITH LOAD DATA LOCAL AND IMPORT ERRORS Description: ----------- This bug happens due to the fact that current algorithm is designed that in the case of LOCAL load of data, in case of the error, the remaining part of the file is read in order to return the proper error message to the client side. But, the problem with current implementation is that data stream for the client side is cleared only in the case where line delimiters exist, which is not a case with, for example fixed width fields. Fix: ---- Ported patch provided by Sinisa Milivojevic n bug report for this issue to 5.5+ versions. As part of this patch code is changed to clear the data stream by calling new member function "READ_INFO::skip_data_till_eof". --- mysql-test/r/loaddata.result | 12 ++++++++++++ mysql-test/t/loaddata.test | 21 +++++++++++++++++++++ sql/sql_load.cc | 19 +++++++++++++------ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index 932c1c7602..2d67d24bed 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -520,3 +520,15 @@ LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug11735141.txt' INTO TABLE t1; ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field drop table t1; End of 5.1 tests +# +# Bug#11759519 INFINITE HANG WITH 100% CPU USAGE WITH LOAD DATA LOCAL AND IMPORT ERRORS +# +SET @old_mode= @@sql_mode; +CREATE TABLE t1 (fld1 INT); +SET sql_mode='strict_all_tables'; +# Without fix, load data hangs forever. +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/mysql' REPLACE INTO TABLE t1 +FIELDS TERMINATED BY 't' LINES TERMINATED BY ''; +Got one of the listed errors +SET @@sql_mode= @old_mode; +DROP TABLE t1; diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test index 80956aa2cb..aa7be52484 100644 --- a/mysql-test/t/loaddata.test +++ b/mysql-test/t/loaddata.test @@ -635,3 +635,24 @@ create table t1(a point); drop table t1; --echo End of 5.1 tests + +--echo # +--echo # Bug#11759519 INFINITE HANG WITH 100% CPU USAGE WITH LOAD DATA LOCAL AND IMPORT ERRORS +--echo # +SET @old_mode= @@sql_mode; +CREATE TABLE t1 (fld1 INT); +--copy_file $EXE_MYSQL $MYSQLTEST_VARDIR/mysql + +SET sql_mode='strict_all_tables'; + +--echo # Without fix, load data hangs forever. +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,1000 +eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/mysql' REPLACE INTO TABLE t1 + FIELDS TERMINATED BY 't' LINES TERMINATED BY ''; + +SET @@sql_mode= @old_mode; + +--remove_file $MYSQLTEST_VARDIR/mysql +DROP TABLE t1; + diff --git a/sql/sql_load.cc b/sql/sql_load.cc index b593412c55..7f962520dd 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -56,6 +56,9 @@ XML_TAG::XML_TAG(int l, String f, String v) } +#define GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache)) +#define PUSH(A) *(stack_pos++)=(A) + class READ_INFO { File file; uchar *buffer, /* Buffer for read text */ @@ -110,6 +113,15 @@ public: either the table or THD value */ void set_io_cache_arg(void* arg) { cache.arg = arg; } + + /** + skip all data till the eof. + */ + void skip_data_till_eof() + { + while (GET != my_b_EOF) + ; + } }; static int read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, @@ -534,8 +546,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if (error) { if (read_file_from_client) - while (!read_info.next_line()) - ; + read_info.skip_data_till_eof(); #ifndef EMBEDDED_LIBRARY if (mysql_bin_log.is_open()) @@ -1392,10 +1403,6 @@ READ_INFO::~READ_INFO() } -#define GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache)) -#define PUSH(A) *(stack_pos++)=(A) - - inline int READ_INFO::terminator(char *ptr,uint length) { int chr=0; // Keep gcc happy -- 2.30.9