diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-06-01 10:38:09 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-06-01 10:38:09 +0300 |
commit | 9c7a456a92262bdb44b85a05aa9f87369c5b063c (patch) | |
tree | ae2354c36aa3220a6ca5e8becc41491b52b9881c /sql | |
parent | 2a4f72b7d2ac30a771a14d097608b0ce282e021c (diff) | |
parent | 77d8da57d744505838a7830afbc437e54cc03c50 (diff) | |
download | mariadb-git-9c7a456a92262bdb44b85a05aa9f87369c5b063c.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_partition.cc | 19 | ||||
-rw-r--r-- | sql/ha_partition.h | 5 | ||||
-rw-r--r-- | sql/handler.cc | 42 | ||||
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/mdl.h | 6 | ||||
-rw-r--r-- | sql/sql_admin.cc | 9 | ||||
-rw-r--r-- | sql/sql_base.cc | 25 | ||||
-rw-r--r-- | sql/sql_base.h | 2 | ||||
-rw-r--r-- | sql/sql_delete.cc | 2 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 11 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 |
11 files changed, 85 insertions, 40 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 18c6ca5a63c..6b7f6a880d9 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -2385,25 +2385,6 @@ void ha_partition::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) } } -/* - Change comments specific to handler - - SYNOPSIS - update_table_comment() - comment Original comment - - RETURN VALUE - new comment - - DESCRIPTION - No comment changes so far -*/ - -char *ha_partition::update_table_comment(const char *comment) -{ - return (char*) comment; /* Nothing to change */ -} - /** Handle delete and rename table diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 60a2d7f6762..b77e20f3e9c 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -525,10 +525,6 @@ public: Meta data routines to CREATE, DROP, RENAME table and often used at ALTER TABLE (update_create_info used from ALTER TABLE and SHOW ..). - update_table_comment is used in SHOW TABLE commands to provide a - chance for the handler to add any interesting comments to the table - comments not provided by the users comment. - create_partitioning_metadata is called before opening a new handler object with openfrm to call create. It is used to create any local handler object needed in opening the object in openfrm @@ -544,7 +540,6 @@ public: override; bool check_if_updates_are_ignored(const char *op) const override; void update_create_info(HA_CREATE_INFO *create_info) override; - char *update_table_comment(const char *comment) override; int change_partitions(HA_CREATE_INFO *create_info, const char *path, ulonglong * const copied, ulonglong * const deleted, const uchar *pack_frm_data, size_t pack_frm_len) diff --git a/sql/handler.cc b/sql/handler.cc index c6031e252a6..112ed23939e 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7217,10 +7217,24 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data) error= binlog_log_row(table, old_data, new_data, log_func); } #ifdef WITH_WSREP - if (WSREP_NNULL(ha_thd()) && table_share->tmp_table == NO_TMP_TABLE && - ht->flags & HTON_WSREP_REPLICATION && - !error && (error= wsrep_after_row(ha_thd()))) - return error; + THD *thd= ha_thd(); + if (WSREP_NNULL(thd)) + { + /* for streaming replication, the following wsrep_after_row() + may replicate a fragment, so we have to declare potential PA + unsafe before that */ + if (table->s->primary_key == MAX_KEY && wsrep_thd_is_local(thd)) + { + WSREP_DEBUG("marking trx as PA unsafe pk %d", table->s->primary_key); + if (thd->wsrep_cs().mark_transaction_pa_unsafe()) + WSREP_DEBUG("session does not have active transaction," + " can not mark as PA unsafe"); + } + + if (!error && table_share->tmp_table == NO_TMP_TABLE && + ht->flags & HTON_WSREP_REPLICATION) + error= wsrep_after_row(thd); + } #endif /* WITH_WSREP */ } return error; @@ -7281,11 +7295,23 @@ int handler::ha_delete_row(const uchar *buf) error= binlog_log_row(table, buf, 0, log_func); } #ifdef WITH_WSREP - if (WSREP_NNULL(ha_thd()) && table_share->tmp_table == NO_TMP_TABLE && - ht->flags & HTON_WSREP_REPLICATION && - !error && (error= wsrep_after_row(ha_thd()))) + THD *thd= ha_thd(); + if (WSREP_NNULL(thd)) { - return error; + /* for streaming replication, the following wsrep_after_row() + may replicate a fragment, so we have to declare potential PA + unsafe before that */ + if (table->s->primary_key == MAX_KEY && wsrep_thd_is_local(thd)) + { + WSREP_DEBUG("marking trx as PA unsafe pk %d", table->s->primary_key); + if (thd->wsrep_cs().mark_transaction_pa_unsafe()) + WSREP_DEBUG("session does not have active transaction," + " can not mark as PA unsafe"); + } + + if (!error && table_share->tmp_table == NO_TMP_TABLE && + ht->flags & HTON_WSREP_REPLICATION) + error= wsrep_after_row(thd); } #endif /* WITH_WSREP */ } diff --git a/sql/handler.h b/sql/handler.h index 9ae115c59a7..4e98560a869 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -4055,8 +4055,6 @@ public: /* end of the list of admin commands */ virtual int indexes_are_disabled(void) {return 0;} - virtual char *update_table_comment(const char * comment) - { return (char*) comment;} virtual void append_create_info(String *packet) {} /** If index == MAX_KEY then a check for table is made and if index < diff --git a/sql/mdl.h b/sql/mdl.h index 45d28cc3068..52c48768329 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -1,7 +1,7 @@ #ifndef MDL_H #define MDL_H /* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. - Copyright (c) 2020, MariaDB + Copyright (c) 2020, 2021, MariaDB 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 @@ -905,6 +905,10 @@ public: m_tickets[MDL_TRANSACTION].is_empty() && m_tickets[MDL_EXPLICIT].is_empty()); } + bool has_explicit_locks() const + { + return !m_tickets[MDL_EXPLICIT].is_empty(); + } inline bool has_transactional_locks() const { return !m_tickets[MDL_TRANSACTION].is_empty(); diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 94381d1bee1..227116a82b2 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -565,8 +565,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str)); DEBUG_SYNC(thd, "admin_command_kill_before_modify"); - if (thd->is_killed()) - break; strxmov(table_name, db, ".", table->table_name.str, NullS); thd->open_options|= extra_open_options; table->lock_type= lock_type; @@ -581,6 +579,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, : lock_type >= TL_WRITE_ALLOW_WRITE ? MDL_SHARED_WRITE : MDL_SHARED_READ); + if (thd->check_killed()) + { + fatal_error= true; + result_code= HA_ADMIN_FAILED; + goto send_result; + } + /* open only one table from local list of command */ while (1) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f9f9856f4c0..1476d708d75 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2554,7 +2554,17 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count) /* If no tables left, do an automatic UNLOCK TABLES */ if (thd->lock && thd->lock->table_count == 0) + { + /* + We have to rollback any open transactions here. + This is required in the case where the server has been killed + but some transations are still open (as part of locked tables). + If we don't do this, we will get an assert in unlock_locked_tables(). + */ + ha_rollback_trans(thd, FALSE); + ha_rollback_trans(thd, TRUE); unlock_locked_tables(thd); + } } @@ -9207,6 +9217,21 @@ int dynamic_column_error_message(enum_dyncol_func_result rc) return rc; } + +/** + Turn on the SELECT_DESCRIBE flag for the primary SELECT_LEX of the statement + being processed in case the statement is EXPLAIN UPDATE/DELETE. + + @param lex current LEX +*/ + +void promote_select_describe_flag_if_needed(LEX *lex) +{ + if (lex->describe) + lex->first_select_lex()->options|= SELECT_DESCRIBE; +} + + /** @} (end of group Data_Dictionary) */ diff --git a/sql/sql_base.h b/sql/sql_base.h index ccfacaf9086..0c90a95b5b0 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -516,6 +516,8 @@ bool extend_table_list(THD *thd, TABLE_LIST *tables, Prelocking_strategy *prelocking_strategy, bool has_prelocking_list); +void promote_select_describe_flag_if_needed(LEX *lex); + /** A context of open_tables() function, used to recover from a failed open_table() or open_routine() attempt. diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index cf411d01f38..870eecdd494 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -365,6 +365,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, query_plan.select_lex= thd->lex->first_select_lex(); query_plan.table= table; + promote_select_describe_flag_if_needed(thd->lex); + if (mysql_prepare_delete(thd, table_list, &conds, &delete_while_scanning)) DBUG_RETURN(TRUE); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index b8042a90872..a99078362d6 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2004, 2012, Oracle and/or its affiliates. - Copyright (c) 2010, 2018, MariaDB + Copyright (c) 2010, 2021, MariaDB 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 @@ -647,8 +647,13 @@ end: thd->lex->spname->m_name.str, static_cast<uint>(thd->lex->spname->m_name.length)); } - if (mdl_request_for_trn.ticket) - thd->mdl_context.release_lock(mdl_request_for_trn.ticket); + /* In Locked_tables_list::reopen_tables(), + MDL_context::set_transaction_duration_for_all_locks() may have been invoked, + converting our explicit MDL to transaction scope. In that case, we will not + release the lock, to avoid a debug assertion failure. */ + if (MDL_ticket *ticket= mdl_request_for_trn.ticket) + if (thd->mdl_context.has_explicit_locks()) + thd->mdl_context.release_lock(ticket); DBUG_RETURN(result); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 578a05d18ae..c14585f44c5 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -468,6 +468,8 @@ int mysql_update(THD *thd, want_privilege= (table_list->view ? UPDATE_ACL : table_list->grant.want_privilege); #endif + promote_select_describe_flag_if_needed(thd->lex); + if (mysql_prepare_update(thd, table_list, &conds, order_num, order)) DBUG_RETURN(1); |