diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-07-31 16:12:38 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-08-01 08:43:12 +0300 |
commit | a7f84f09bfec22e26b3bd54505a9c8e1d0faff40 (patch) | |
tree | f4d802bbc9dee6bf79da3709637d2213a906a928 | |
parent | b3e95086e1188dc86e67e44d0fe5a68ea2feca99 (diff) | |
download | mariadb-git-a7f84f09bfec22e26b3bd54505a9c8e1d0faff40.tar.gz |
MDEV-16865 InnoDB fts_query() ignores KILL
The functions fts_ast_visit() and fts_query() inside
InnoDB FULLTEXT INDEX query processing are not checking
for THD::killed (trx_is_interrupted()), like anything
that potentially takes a long time should do.
This is a port of the following change from MySQL 5.7.23,
with a completely rewritten test case.
commit c58c6f8f66ddd0357ecd0c99646aa6bf1dae49c8
Author: Aakanksha Verma <aakanksha.verma@oracle.com>
Date: Fri May 4 15:53:13 2018 +0530
Bug #27155294 MAX_EXECUTION_TIME NOT INTERUPTED WITH FULLTEXT SEARCH USING MECAB
-rw-r--r-- | mysql-test/suite/innodb_fts/r/fts_kill_query.result | 6 | ||||
-rw-r--r-- | mysql-test/suite/innodb_fts/t/fts_kill_query.test | 30 | ||||
-rw-r--r-- | storage/innobase/fts/fts0ast.cc | 9 | ||||
-rw-r--r-- | storage/innobase/fts/fts0que.cc | 17 | ||||
-rw-r--r-- | storage/innobase/include/fts0ast.h | 5 | ||||
-rw-r--r-- | storage/xtradb/fts/fts0ast.cc | 9 | ||||
-rw-r--r-- | storage/xtradb/fts/fts0que.cc | 17 | ||||
-rw-r--r-- | storage/xtradb/include/fts0ast.h | 5 |
8 files changed, 92 insertions, 6 deletions
diff --git a/mysql-test/suite/innodb_fts/r/fts_kill_query.result b/mysql-test/suite/innodb_fts/r/fts_kill_query.result new file mode 100644 index 00000000000..45623f96ab0 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/fts_kill_query.result @@ -0,0 +1,6 @@ +CREATE TABLE t1 (a VARCHAR(7), b text, FULLTEXT KEY idx (a,b)) ENGINE=InnoDB; +COMMIT; +SELECT COUNT(*) FROM t1 +WHERE MATCH (a,b) AGAINST ('foo bar' IN BOOLEAN MODE); +KILL QUERY @id; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/fts_kill_query.test b/mysql-test/suite/innodb_fts/t/fts_kill_query.test new file mode 100644 index 00000000000..3dda29a3876 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/fts_kill_query.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc + +CREATE TABLE t1 (a VARCHAR(7), b text, FULLTEXT KEY idx (a,b)) ENGINE=InnoDB; + +--disable_query_log +BEGIN; +let $n=1000; +while ($n) { +INSERT INTO t1 VALUES('foo bar','boo far'); +dec $n; +} +--enable_query_log +COMMIT; + +let $id = `SELECT CONNECTION_ID()`; +send SELECT COUNT(*) FROM t1 +WHERE MATCH (a,b) AGAINST ('foo bar' IN BOOLEAN MODE); + +connect (con1,localhost,root,,); +let $ignore= `SELECT @id := $ID`; +KILL QUERY @id; +disconnect con1; + +connection default; +# The following would return a result set if the KILL was not fast enough. +--disable_result_log +--error 0,ER_QUERY_INTERRUPTED,HA_ERR_ABORTED_BY_USER +reap; +--enable_result_log +DROP TABLE t1; diff --git a/storage/innobase/fts/fts0ast.cc b/storage/innobase/fts/fts0ast.cc index 030b972440f..4b36152cf62 100644 --- a/storage/innobase/fts/fts0ast.cc +++ b/storage/innobase/fts/fts0ast.cc @@ -1,6 +1,7 @@ /***************************************************************************** -Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -27,6 +28,7 @@ Created 2007/3/16 Sunny Bains. #include "fts0ast.h" #include "fts0pars.h" #include "fts0fts.h" +#include "row0sel.h" /* The FTS ast visit pass. */ enum fts_ast_visit_pass_t { @@ -498,6 +500,7 @@ fts_ast_visit( bool revisit = false; bool will_be_ignored = false; fts_ast_visit_pass_t visit_pass = FTS_PASS_FIRST; + const trx_t* trx = node->trx; start_node = node->list.head; @@ -596,6 +599,10 @@ fts_ast_visit( } } + if (trx_is_interrupted(trx)) { + return DB_INTERRUPTED; + } + if (revisit) { /* Exist pass processes the skipped FTS_EXIST operation. */ for (node = start_node; diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index 3a543836837..7d4cd7a3646 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -3970,6 +3970,7 @@ fts_query( /* Parse the input query string. */ if (fts_query_parse(&query, lc_query_str, result_len)) { fts_ast_node_t* ast = query.root; + ast->trx = trx; /* Optimize query to check if it's a single term */ fts_query_can_optimize(&query, flags); @@ -3983,6 +3984,11 @@ fts_query( query.error = fts_ast_visit( FTS_NONE, ast, fts_query_visitor, &query, &will_be_ignored); + if (query.error == DB_INTERRUPTED) { + error = DB_INTERRUPTED; + ut_free(lc_query_str); + goto func_exit; + } /* If query expansion is requested, extend the search with first search pass result */ @@ -4010,6 +4016,15 @@ fts_query( memset(*result, 0, sizeof(**result)); } + if (trx_is_interrupted(trx)) { + error = DB_INTERRUPTED; + ut_free(lc_query_str); + if (result != NULL) { + fts_query_free_result(*result); + } + goto func_exit; + } + ut_free(lc_query_str); if (fts_enable_diag_print && (*result)) { diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h index 50f62063893..25df2dd9156 100644 --- a/storage/innobase/include/fts0ast.h +++ b/storage/innobase/include/fts0ast.h @@ -1,6 +1,7 @@ /***************************************************************************** -Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -314,6 +315,8 @@ struct fts_ast_node_t { fts_ast_node_t* next_alloc; /*!< For tracking allocations */ bool visited; /*!< whether this node is already processed */ + /** current transaction */ + const trx_t* trx; }; /* To track state during parsing */ diff --git a/storage/xtradb/fts/fts0ast.cc b/storage/xtradb/fts/fts0ast.cc index 030b972440f..4b36152cf62 100644 --- a/storage/xtradb/fts/fts0ast.cc +++ b/storage/xtradb/fts/fts0ast.cc @@ -1,6 +1,7 @@ /***************************************************************************** -Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -27,6 +28,7 @@ Created 2007/3/16 Sunny Bains. #include "fts0ast.h" #include "fts0pars.h" #include "fts0fts.h" +#include "row0sel.h" /* The FTS ast visit pass. */ enum fts_ast_visit_pass_t { @@ -498,6 +500,7 @@ fts_ast_visit( bool revisit = false; bool will_be_ignored = false; fts_ast_visit_pass_t visit_pass = FTS_PASS_FIRST; + const trx_t* trx = node->trx; start_node = node->list.head; @@ -596,6 +599,10 @@ fts_ast_visit( } } + if (trx_is_interrupted(trx)) { + return DB_INTERRUPTED; + } + if (revisit) { /* Exist pass processes the skipped FTS_EXIST operation. */ for (node = start_node; diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc index 100dbcd70ca..50f198401f9 100644 --- a/storage/xtradb/fts/fts0que.cc +++ b/storage/xtradb/fts/fts0que.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -3989,6 +3989,7 @@ fts_query( /* Parse the input query string. */ if (fts_query_parse(&query, lc_query_str, result_len)) { fts_ast_node_t* ast = query.root; + ast->trx = trx; /* Optimize query to check if it's a single term */ fts_query_can_optimize(&query, flags); @@ -4002,6 +4003,11 @@ fts_query( query.error = fts_ast_visit( FTS_NONE, ast, fts_query_visitor, &query, &will_be_ignored); + if (query.error == DB_INTERRUPTED) { + error = DB_INTERRUPTED; + ut_free(lc_query_str); + goto func_exit; + } /* If query expansion is requested, extend the search with first search pass result */ @@ -4029,6 +4035,15 @@ fts_query( memset(*result, 0, sizeof(**result)); } + if (trx_is_interrupted(trx)) { + error = DB_INTERRUPTED; + ut_free(lc_query_str); + if (result != NULL) { + fts_query_free_result(*result); + } + goto func_exit; + } + ut_free(lc_query_str); if (fts_enable_diag_print && (*result)) { diff --git a/storage/xtradb/include/fts0ast.h b/storage/xtradb/include/fts0ast.h index 50f62063893..25df2dd9156 100644 --- a/storage/xtradb/include/fts0ast.h +++ b/storage/xtradb/include/fts0ast.h @@ -1,6 +1,7 @@ /***************************************************************************** -Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -314,6 +315,8 @@ struct fts_ast_node_t { fts_ast_node_t* next_alloc; /*!< For tracking allocations */ bool visited; /*!< whether this node is already processed */ + /** current transaction */ + const trx_t* trx; }; /* To track state during parsing */ |