Skip to content

Commit

Permalink
Add support for aborting query
Browse files Browse the repository at this point in the history
GitHub: fix #344

MySQL uses max_execution_time.

MariaDB uses max_statement_time.

Reported by Kazuhiko. Thanks!!!
  • Loading branch information
kou committed Oct 6, 2022
1 parent 406b48b commit e7987d8
Show file tree
Hide file tree
Showing 14 changed files with 337 additions and 10 deletions.
53 changes: 53 additions & 0 deletions ha_mroonga.cpp
Expand Up @@ -315,7 +315,12 @@ static mysql_mutex_t *mrn_LOCK_open;
#endif

#ifdef MRN_MARIADB_P
# define MRN_HANDLERTON_HAVE_KILL_QUERY
# define MRN_HANDLERTON_HAVE_ALTER_TABLE_FLAGS
#else
# if MYSQL_VERSION_ID >= 50700
# define MRN_HANDLERTON_HAVE_KILL_CONNECTION
# endif
#endif

Rpl_filter *mrn_binlog_filter;
Expand Down Expand Up @@ -1539,6 +1544,40 @@ static int mrn_hton_close_connection(handlerton *hton, THD *thd)
DBUG_RETURN(0);
}

#ifdef MRN_HANDLERTON_HAVE_KILL_QUERY
static void mrn_hton_kill_query(handlerton *hton,
THD *thd,
enum thd_kill_levels level)
{
MRN_DBUG_ENTER_FUNCTION();
auto slot_data = mrn_get_slot_data(thd, false);
if (slot_data) {
for (auto ctx : slot_data->associated_grn_ctxs) {
if (ctx->rc == GRN_SUCCESS) {
ctx->rc = GRN_CANCEL;
}
}
}
DBUG_VOID_RETURN;
}
#endif

#ifdef MRN_HANDLERTON_HAVE_KILL_CONNECTION
static void mrn_hton_kill_connection(handlerton *hton, THD *thd)
{
MRN_DBUG_ENTER_FUNCTION();
auto slot_data = mrn_get_slot_data(thd, false);
if (slot_data) {
for (auto ctx : slot_data->associated_grn_ctxs) {
if (ctx->rc == GRN_SUCCESS) {
ctx->rc = GRN_CANCEL;
}
}
}
DBUG_VOID_RETURN;
}
#endif

#ifdef MRN_FLUSH_LOGS_HAVE_BINLOG_GROUP_FLUSH
static bool mrn_flush_logs(handlerton *hton, bool binlog_group_flush)
#else
Expand Down Expand Up @@ -2247,6 +2286,12 @@ static int mrn_init(void *p)
#endif
hton->drop_database = mrn_hton_drop_database;
hton->close_connection = mrn_hton_close_connection;
#ifdef MRN_HANDLERTON_HAVE_KILL_QUERY
hton->kill_query = mrn_hton_kill_query;
#endif
#ifdef MRN_HANDLERTON_HAVE_KILL_CONNECTION
hton->kill_connection = mrn_hton_kill_connection;
#endif
hton->flush_logs = mrn_flush_logs;
#ifdef MRN_HANDLERTON_HAVE_ALTER_TABLE_FLAGS
hton->alter_table_flags = mrn_hton_alter_table_flags;
Expand Down Expand Up @@ -3123,6 +3168,10 @@ ha_mroonga::ha_mroonga(handlerton *hton, TABLE_SHARE *share_arg)
grn_ctx_init(ctx, 0);
mrn_change_encoding(ctx, system_charset_info);
grn_ctx_use(ctx, mrn_db);
mrn::SlotData *slot_data = mrn_get_slot_data(ha_thd(), true);
if (slot_data) {
slot_data->add_associated_grn_ctx(ctx);
}
GRN_WGS84_GEO_POINT_INIT(&top_left_point, 0);
GRN_WGS84_GEO_POINT_INIT(&bottom_right_point, 0);
GRN_WGS84_GEO_POINT_INIT(&source_point, 0);
Expand Down Expand Up @@ -3161,6 +3210,10 @@ ha_mroonga::~ha_mroonga()
grn_obj_unlink(ctx, &encoded_key_buffer);
grn_obj_unlink(ctx, &old_value_buffer);
grn_obj_unlink(ctx, &new_value_buffer);
mrn::SlotData *slot_data = mrn_get_slot_data(ha_thd(), false);
if (slot_data) {
slot_data->remove_associated_grn_ctx(ctx);
}
grn_ctx_fin(ctx);
DBUG_VOID_RETURN;
}
Expand Down
22 changes: 22 additions & 0 deletions mrn_mysql_compat.h
Expand Up @@ -1052,3 +1052,25 @@ typedef uint mrn_srid;
#if (MYSQL_VERSION_ID >= 80000 && !defined(MRN_MARIADB_P))
# define MRN_HAVE_UDF_METADATA
#endif

#ifdef MRN_MARIADB_P
# define MRN_ERROR_CANCEL ER_STATEMENT_TIMEOUT
#else
# if MYSQL_VERSION_ID >= 50700
# define MRN_ERROR_CANCEL ER_QUERY_TIMEOUT
# endif
#endif

#ifdef MRN_ERROR_CANCEL
# define MRN_SET_MESSAGE_FROM_CTX(ctx, error_code) \
do { \
if ((ctx)->rc == GRN_CANCEL) { \
my_error(MRN_ERROR_CANCEL, MYF(0)); \
} else { \
my_message((error_code), (ctx)->errbuf, MYF(0)); \
} \
} while (false)
#else
# define MRN_SET_MESSAGE_FROM_CTX(ctx, error_code) \
my_message(error_code, ctx->errbuf, MYF(0))
#endif
20 changes: 19 additions & 1 deletion mrn_table.hpp
Expand Up @@ -20,6 +20,7 @@

#pragma once

#include <vector>

#include "mrn_mysql.h"

Expand Down Expand Up @@ -103,7 +104,8 @@ namespace mrn {
alter_create_info(NULL),
disable_keys_create_info(NULL),
alter_connect_string(NULL),
alter_comment(NULL) {
alter_comment(NULL),
associated_grn_ctxs() {
}

~SlotData() {
Expand Down Expand Up @@ -134,6 +136,21 @@ namespace mrn {
}
}

void add_associated_grn_ctx(grn_ctx *ctx) {
associated_grn_ctxs.push_back(ctx);
}

void remove_associated_grn_ctx(grn_ctx *ctx) {
for (std::vector<grn_ctx *>::iterator it = associated_grn_ctxs.begin();
it != associated_grn_ctxs.end();
++it) {
if (*it == ctx) {
associated_grn_ctxs.erase(it);
break;
}
}
}

grn_id last_insert_record_id;
#ifdef MRN_ENABLE_WRAPPER_MODE
st_mrn_wrap_hton *first_wrap_hton;
Expand All @@ -142,6 +159,7 @@ namespace mrn {
HA_CREATE_INFO *disable_keys_create_info;
char *alter_connect_string;
char *alter_comment;
std::vector<grn_ctx *> associated_grn_ctxs;
};
};

Expand Down
4 changes: 4 additions & 0 deletions mysql-test/mroonga/include/mroonga/check_groonga_version.inc
Expand Up @@ -52,4 +52,8 @@ let $groonga_version_12_0_2_or_later =
`SELECT (($groonga_version_major * 100) +
($groonga_version_minor * 10) +
($groonga_version_micro)) >= 1202;`;
let $groonga_version_12_0_9_or_later =
`SELECT (($groonga_version_major * 100) +
($groonga_version_minor * 10) +
($groonga_version_micro)) >= 1209;`;
--enable_query_log
@@ -0,0 +1,24 @@
# -*- mode: sql; sql-product: mysql -*-
#
# Copyright(C) 2022 Sutou Kouhei <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

--source ../../include/mroonga/check_groonga_version.inc

if (!$groonga_version_12_0_9_or_later) {
--source ../../include/mroonga/have_mroonga_deinit.inc
--skip This test is for Groonga version 12.0.9 or later
}
@@ -0,0 +1,9 @@
DROP TABLE IF EXISTS diaries;
SET NAMES utf8mb4;
CREATE TABLE diaries(
title TEXT
) DEFAULT CHARSET=utf8mb4;
SELECT /*+ MAX_EXECUTION_TIME(1) */
mroonga_command('sleep', 'second', '1');
ERROR HY000: Query execution was interrupted, maximum statement execution time exceeded
DROP TABLE diaries;
@@ -0,0 +1,9 @@
DROP TABLE IF EXISTS diaries;
SET NAMES utf8mb4;
CREATE TABLE diaries(
title TEXT
) DEFAULT CHARSET=utf8mb4;
SET STATEMENT max_statement_time = 0.001 FOR
SELECT mroonga_command('sleep', 'second', '1');
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
DROP TABLE diaries;
@@ -0,0 +1,41 @@
# -*- mode: sql; sql-product: mysql -*-
#
# Copyright(C) 2022 Sutou Kouhei <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

--source ../../../../include/mroonga/have_mysql.inc
--source ../../../../include/mroonga/not_embedded.inc
--source ../../../../include/mroonga/have_mroonga.inc
# --source ../../../../include/mroonga/have_groonga_12_0_9_or_later.inc
--source ../../../../include/mroonga/load_mroonga_functions.inc

--disable_warnings
DROP TABLE IF EXISTS diaries;
--enable_warnings

SET NAMES utf8mb4;
CREATE TABLE diaries(
title TEXT
) DEFAULT CHARSET=utf8mb4;

--error ER_QUERY_TIMEOUT
SELECT /*+ MAX_EXECUTION_TIME(1) */
mroonga_command('sleep', 'second', '1');

DROP TABLE diaries;

--source ../../../../include/mroonga/unload_mroonga_functions.inc
--source ../../../../include/mroonga/have_mroonga_deinit.inc
@@ -0,0 +1,41 @@
# -*- mode: sql; sql-product: mysql -*-
#
# Copyright(C) 2022 Sutou Kouhei <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

--source ../../../../include/mroonga/have_mariadb.inc
--source ../../../../include/mroonga/not_embedded.inc
--source ../../../../include/mroonga/have_mroonga.inc
# --source ../../../../include/mroonga/have_groonga_12_0_9_or_later.inc
--source ../../../../include/mroonga/load_mroonga_functions.inc

--disable_warnings
DROP TABLE IF EXISTS diaries;
--enable_warnings

SET NAMES utf8mb4;
CREATE TABLE diaries(
title TEXT
) DEFAULT CHARSET=utf8mb4;

--error ER_STATEMENT_TIMEOUT
SET STATEMENT max_statement_time = 0.001 FOR
SELECT mroonga_command('sleep', 'second', '1');

DROP TABLE diaries;

--source ../../../../include/mroonga/unload_mroonga_functions.inc
--source ../../../../include/mroonga/have_mroonga_deinit.inc
8 changes: 8 additions & 0 deletions mysql-test/mroonga/storage/r/max_execution_time.result
@@ -0,0 +1,8 @@
DROP TABLE IF EXISTS diaries;
SET NAMES utf8mb4;
CREATE TABLE diaries(
title TEXT
) DEFAULT CHARSET=utf8mb4;
SELECT /*+ MAX_EXECUTION_TIME(1) */ title, sleep(1) FROM diaries;
ERROR HY000: Query execution was interrupted, maximum statement execution time exceeded
DROP TABLE diaries;
9 changes: 9 additions & 0 deletions mysql-test/mroonga/storage/r/max_statement_time.result
@@ -0,0 +1,9 @@
DROP TABLE IF EXISTS diaries;
SET NAMES utf8mb4;
CREATE TABLE diaries(
title TEXT
) DEFAULT CHARSET=utf8mb4;
SET STATEMENT max_statement_time = 0.001 FOR
SELECT title, sleep(1) FROM diaries;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
DROP TABLE diaries;
38 changes: 38 additions & 0 deletions mysql-test/mroonga/storage/t/max_execution_time.test
@@ -0,0 +1,38 @@
# -*- mode: sql; sql-product: mysql -*-
#
# Copyright(C) 2022 Sutou Kouhei <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

--source ../../include/mroonga/have_mysql.inc
--source ../../include/mroonga/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
# --source ../../include/mroonga/have_groonga_12_0_9_or_later.inc

--disable_warnings
DROP TABLE IF EXISTS diaries;
--enable_warnings

SET NAMES utf8mb4;
CREATE TABLE diaries(
title TEXT
) DEFAULT CHARSET=utf8mb4;

--error ER_QUERY_TIMEOUT
SELECT /*+ MAX_EXECUTION_TIME(1) */ title, sleep(1) FROM diaries;

DROP TABLE diaries;

--source ../../include/mroonga/have_mroonga_deinit.inc
39 changes: 39 additions & 0 deletions mysql-test/mroonga/storage/t/max_statement_time.test
@@ -0,0 +1,39 @@
# -*- mode: sql; sql-product: mysql -*-
#
# Copyright(C) 2022 Sutou Kouhei <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

--source ../../include/mroonga/have_mariadb.inc
--source ../../include/mroonga/not_embedded.inc
--source ../../include/mroonga/have_mroonga.inc
# --source ../../include/mroonga/have_groonga_12_0_9_or_later.inc

--disable_warnings
DROP TABLE IF EXISTS diaries;
--enable_warnings

SET NAMES utf8mb4;
CREATE TABLE diaries(
title TEXT
) DEFAULT CHARSET=utf8mb4;

--error ER_STATEMENT_TIMEOUT
SET STATEMENT max_statement_time = 0.001 FOR
SELECT title, sleep(1) FROM diaries;

DROP TABLE diaries;

--source ../../include/mroonga/have_mroonga_deinit.inc

0 comments on commit e7987d8

Please sign in to comment.