summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-07-31 16:12:38 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-08-01 08:43:12 +0300
commita7f84f09bfec22e26b3bd54505a9c8e1d0faff40 (patch)
treef4d802bbc9dee6bf79da3709637d2213a906a928
parentb3e95086e1188dc86e67e44d0fe5a68ea2feca99 (diff)
downloadmariadb-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.result6
-rw-r--r--mysql-test/suite/innodb_fts/t/fts_kill_query.test30
-rw-r--r--storage/innobase/fts/fts0ast.cc9
-rw-r--r--storage/innobase/fts/fts0que.cc17
-rw-r--r--storage/innobase/include/fts0ast.h5
-rw-r--r--storage/xtradb/fts/fts0ast.cc9
-rw-r--r--storage/xtradb/fts/fts0que.cc17
-rw-r--r--storage/xtradb/include/fts0ast.h5
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 */