From a47d16907d089a33f95c64361b016009e7a20691 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 19 Sep 2017 13:08:24 +0400 Subject: [PATCH 1/2] MDEV-13137 MySQL 5.6.23 Crashes when SET GLOBAL server_audit_logging=OFF; The MySQL 5.6 doesn't always send the MYSQL_AUDIT_GENERAL_LOG notification. So we have to suppress the log_current_query() in this case. --- plugin/server_audit/server_audit.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index c9f478662fd..ad2a4618514 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -15,7 +15,7 @@ #define PLUGIN_VERSION 0x104 -#define PLUGIN_STR_VERSION "1.4.1" +#define PLUGIN_STR_VERSION "1.4.2" #define _my_thread_var loc_thread_var @@ -1090,6 +1090,7 @@ static void setup_connection_connect(struct connection_info *cn, const struct mysql_event_connection *event) { cn->query_id= 0; + cn->query_length= 0; cn->log_always= 0; cn->thread_id= event->thread_id; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), @@ -1131,6 +1132,7 @@ static void setup_connection_initdb(struct connection_info *cn, cn->thread_id= event->general_thread_id; cn->query_id= 0; + cn->query_length= 0; cn->log_always= 0; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), event->general_query, event->general_query_length); @@ -1163,6 +1165,7 @@ static void setup_connection_table(struct connection_info *cn, cn->thread_id= event->thread_id; cn->query_id= query_counter++; cn->log_always= 0; + cn->query_length= 0; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), event->database, event->database_length); get_str_n(cn->user, &cn->user_length, sizeof(cn->db), @@ -1184,6 +1187,7 @@ static void setup_connection_query(struct connection_info *cn, cn->thread_id= event->general_thread_id; cn->query_id= query_counter++; cn->log_always= 0; + cn->query_length= 0; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), "", 0); if (get_user_host(event->general_user, event->general_user_length, @@ -2008,6 +2012,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) event_query_command(event)) { log_statement(cn, event, "QUERY"); + cn->query_length= 0; /* So the log_current_query() won't log this again. */ } } else if (event_class == MYSQL_AUDIT_TABLE_CLASS && FILTER(EVENT_TABLE) && cn) @@ -2523,7 +2528,8 @@ static void log_current_query(MYSQL_THD thd) if (!thd) return; cn= get_loc_info(thd); - if (!ci_needs_setup(cn) && FILTER(EVENT_QUERY) && do_log_user(cn->user)) + if (!ci_needs_setup(cn) && cn->query_length && + FILTER(EVENT_QUERY) && do_log_user(cn->user)) { log_statement_ex(cn, cn->query_time, thd_get_thread_id(thd), cn->query, cn->query_length, 0, "QUERY"); From 028d253dd7401fa564bcf817fe81c7034f2512d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 2 Oct 2017 10:22:42 +0300 Subject: [PATCH 2/2] MDEV-13980 InnoDB fails to discard record lock when discarding an index page btr_cur_pessimistic_delete(): Discard a possible record lock also in the case when the record was the only one in the page. Failure to do this would corrupt the record lock data structures in a partial rollback (ROLLBACK TO SAVEPOINT or rolling back a row operation due to some error, such as a duplicate key in a unique secondary index). --- storage/innobase/btr/btr0cur.c | 10 +++++----- storage/xtradb/btr/btr0cur.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 2c1ab4bffae..e8c467409b2 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -2,6 +2,7 @@ Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -3193,7 +3194,6 @@ btr_cur_pessimistic_delete( ulint n_reserved; ibool success; ibool ret = FALSE; - ulint level; mem_heap_t* heap; ulint* offsets; @@ -3240,6 +3240,8 @@ btr_cur_pessimistic_delete( #endif /* UNIV_ZIP_DEBUG */ } + lock_update_delete(block, rec); + if (UNIV_UNLIKELY(page_get_n_recs(page) < 2) && UNIV_UNLIKELY(dict_index_get_page(index) != buf_block_get_page_no(block))) { @@ -3255,10 +3257,7 @@ btr_cur_pessimistic_delete( goto return_after_reservations; } - lock_update_delete(block, rec); - level = btr_page_get_level(page, mtr); - - if (level > 0 + if (!page_is_leaf(page) && UNIV_UNLIKELY(rec == page_rec_get_next( page_get_infimum_rec(page)))) { @@ -3281,6 +3280,7 @@ btr_cur_pessimistic_delete( on a page, we have to change the father node pointer so that it is equal to the new leftmost node pointer on the page */ + ulint level = btr_page_get_level(page, mtr); btr_node_ptr_delete(index, block, mtr); diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c index d9c1a2ef7a8..0d015111d81 100644 --- a/storage/xtradb/btr/btr0cur.c +++ b/storage/xtradb/btr/btr0cur.c @@ -2,6 +2,7 @@ Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -3376,7 +3377,6 @@ btr_cur_pessimistic_delete( ulint n_reserved; ibool success; ibool ret = FALSE; - ulint level; mem_heap_t* heap; ulint* offsets; @@ -3425,6 +3425,8 @@ btr_cur_pessimistic_delete( #endif /* UNIV_ZIP_DEBUG */ } + lock_update_delete(block, rec); + if (UNIV_UNLIKELY(page_get_n_recs(page) < 2) && UNIV_UNLIKELY(dict_index_get_page(index) != buf_block_get_page_no(block))) { @@ -3440,10 +3442,7 @@ btr_cur_pessimistic_delete( goto return_after_reservations; } - lock_update_delete(block, rec); - level = btr_page_get_level(page, mtr); - - if (level > 0 + if (!page_is_leaf(page) && UNIV_UNLIKELY(rec == page_rec_get_next( page_get_infimum_rec(page)))) { @@ -3466,6 +3465,7 @@ btr_cur_pessimistic_delete( on a page, we have to change the father node pointer so that it is equal to the new leftmost node pointer on the page */ + ulint level = btr_page_get_level(page, mtr); btr_node_ptr_delete(index, block, mtr);