diff options
author | Sergei Golubchik <serg@mariadb.org> | 2017-03-30 12:48:42 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2017-03-30 12:48:42 +0200 |
commit | da4d71d10d23c1ac2d10b72baee14991ccb7a146 (patch) | |
tree | 7cdf3a8c8e72ca7c1c8105427c04123f025bd870 /sql | |
parent | 9ec85009985d644ce7ae797bc3572d0ad0f69bb0 (diff) | |
parent | a00517ac9707ffd51c092f5af5d198c5ee789bb4 (diff) | |
download | mariadb-git-da4d71d10d23c1ac2d10b72baee14991ccb7a146.tar.gz |
Merge branch '10.1' into 10.2
Diffstat (limited to 'sql')
110 files changed, 1327 insertions, 1037 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 243468e095a..fc41a31c3c4 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -81,7 +81,7 @@ SET (SQL_SOURCE ../sql-common/client.c compat56.cc derror.cc des_key_file.cc discover.cc ../sql-common/errmsg.c field.cc field_conv.cc filesort_utils.cc - filesort.cc gstream.cc sha2.cc + filesort.cc gstream.cc signal_handler.cc handler.cc hash_filo.h hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc diff --git a/sql/bounded_queue.h b/sql/bounded_queue.h index 88c2bbc238d..3573c5ceb27 100644 --- a/sql/bounded_queue.h +++ b/sql/bounded_queue.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #ifndef BOUNDED_QUEUE_INCLUDED #define BOUNDED_QUEUE_INCLUDED diff --git a/sql/contributors.h b/sql/contributors.h index 0359ec54022..3a771e2b493 100644 --- a/sql/contributors.h +++ b/sql/contributors.h @@ -37,16 +37,18 @@ struct show_table_contributors_st { struct show_table_contributors_st show_table_contributors[]= { /* MariaDB foundation sponsors, in contribution, size , time order */ - {"Booking.com", "http://www.booking.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"}, + {"Booking.com", "https://www.booking.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"}, + {"Alibaba Cloud", "https://intl.aliyun.com", "Platinum Sponsor of the MariaDB Foundation"}, {"MariaDB Corporation", "https://mariadb.com", "Founding member, Gold Sponsor of the MariaDB Foundation"}, - {"Visma", "http://visma.com", "Gold Sponsor of the MariaDB Foundation"}, - {"DBS", "http://dbs.com", "Gold Sponsor of the MariaDB Foundation"}, + {"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"}, + {"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"}, {"Nexedi", "https://www.nexedi.com", "Silver Sponsor of the MariaDB Foundation"}, {"Acronis", "http://www.acronis.com", "Silver Sponsor of the MariaDB Foundation"}, {"Auttomattic", "https://automattic.com", "Bronze Sponsor of the MariaDB Foundation"}, - {"Verkkokauppa.com", "https://virtuozzo.com", "Bronze Sponsor of the MariaDB Foundation"}, - {"Virtuozzo", "https://virtuozzo.com/", "Bronze Sponsor of the MariaDB Foundation"}, - {"Tencent Game DBA", "http://tencentdba.com/about/", "Bronze Sponsor of the MariaDB Foundation"}, + {"Verkkokauppa.com", "https://www.verkkokauppa.com", "Bronze Sponsor of the MariaDB Foundation"}, + {"Virtuozzo", "https://virtuozzo.com", "Bronze Sponsor of the MariaDB Foundation"}, + {"Tencent Game DBA", "http://tencentdba.com/about", "Bronze Sponsor of the MariaDB Foundation"}, + {"Tencent TDSQL", "http://tdsql.org", "Bronze Sponsor of the MariaDB Foundation"}, /* Sponsors of important features */ {"Google", "USA", "Sponsoring encryption, parallel replication and GTID"}, diff --git a/sql/create_options.cc b/sql/create_options.cc index 7edc2cb95f2..99562faa077 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file diff --git a/sql/create_options.h b/sql/create_options.h index 3e7f9ecfabf..191ec88750a 100644 --- a/sql/create_options.h +++ b/sql/create_options.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file diff --git a/sql/datadict.cc b/sql/datadict.cc index c1e1e85c377..103a33214ae 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -39,25 +39,27 @@ static int read_string(File file, uchar**to, size_t length) /** Check type of .frm if we are not going to parse it. - @param[in] thd The current session. - @param[in] path path to FRM file. - @param[out] dbt db_type of the table if FRMTYPE_TABLE, otherwise undefined. + @param[in] thd The current session. + @param[in] path path to FRM file. + @param[in/out] engine_name table engine name (length < NAME_CHAR_LEN) + + engine_name is a LEX_STRING, where engine_name->str must point to + a buffer of at least NAME_CHAR_LEN+1 bytes. @retval FRMTYPE_ERROR error @retval FRMTYPE_TABLE table @retval FRMTYPE_VIEW view */ -frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) +frm_type_enum dd_frm_type(THD *thd, char *path, LEX_STRING *engine_name) { File file; uchar header[10]; //"TYPE=VIEW\n" it is 10 characters size_t error; frm_type_enum type= FRMTYPE_ERROR; + uchar dbt; DBUG_ENTER("dd_frm_type"); - *dbt= DB_TYPE_UNKNOWN; - if ((file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0))) < 0) DBUG_RETURN(FRMTYPE_ERROR); error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP)); @@ -72,17 +74,24 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) type= FRMTYPE_TABLE; - /* - This is just a check for DB_TYPE. We'll return default unknown type - if the following test is true (arg #3). This should not have effect - on return value from this function (default FRMTYPE_TABLE) - */ - if (!is_binary_frm_header(header)) + if (!is_binary_frm_header(header) || !engine_name) goto err; - *dbt= (enum legacy_db_type) (uint) *(header + 3); + engine_name->length= 0; + dbt= header[3]; + + /* cannot use ha_resolve_by_legacy_type without a THD */ + if (thd && dbt < DB_TYPE_FIRST_DYNAMIC) + { + handlerton *ht= ha_resolve_by_legacy_type(thd, (enum legacy_db_type)dbt); + if (ht) + { + *engine_name= hton2plugin[ht->slot]->name; + goto err; + } + } - if (*dbt >= DB_TYPE_FIRST_DYNAMIC) /* read the true engine name */ + /* read the true engine name */ { MY_STAT state; uchar *frm_image= 0; @@ -110,15 +119,10 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) next_chunk+= connect_string_length + 2; if (next_chunk + 2 < buff_end) { - uint str_db_type_length= uint2korr(next_chunk); - LEX_STRING name; - name.str= (char*) next_chunk + 2; - name.length= str_db_type_length; - plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name, false); - if (tmp_plugin) - *dbt= plugin_data(tmp_plugin, handlerton *)->db_type; - else - *dbt= DB_TYPE_UNKNOWN; + uint len= uint2korr(next_chunk); + if (len <= NAME_CHAR_LEN) + strmake(engine_name->str, (char*)next_chunk + 2, + engine_name->length= len); } } diff --git a/sql/datadict.h b/sql/datadict.h index dd80942daca..9b180a882f9 100644 --- a/sql/datadict.h +++ b/sql/datadict.h @@ -35,12 +35,11 @@ enum frm_type_enum Prefer to use ha_table_exists() instead. To check whether it's an frm of a view, use dd_frm_is_view(). */ -frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt); +frm_type_enum dd_frm_type(THD *thd, char *path, LEX_STRING *engine_name); static inline bool dd_frm_is_view(THD *thd, char *path) { - enum legacy_db_type not_used; - return dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW; + return dd_frm_type(thd, path, NULL) == FRMTYPE_VIEW; } bool dd_recreate_table(THD *thd, const char *db, const char *table_name, diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 3450e60f85c..8ed5901b69a 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -133,9 +133,6 @@ post_init_event_thread(THD *thd) thd->cleanup(); return TRUE; } - - add_to_active_threads(thd); - inc_thread_running(); return FALSE; } @@ -153,8 +150,8 @@ deinit_event_thread(THD *thd) { thd->proc_info= "Clearing"; DBUG_PRINT("exit", ("Event thread finishing")); - - delete_running_thd(thd); + unlink_not_visible_thd(thd); + delete thd; } @@ -188,6 +185,7 @@ pre_init_event_thread(THD* thd) thd->net.read_timeout= slave_net_timeout; thd->variables.option_bits|= OPTION_AUTO_IS_NULL; thd->client_capabilities|= CLIENT_MULTI_RESULTS; + add_to_active_threads(thd); /* Guarantees that we will see the thread in SHOW PROCESSLIST though its @@ -234,13 +232,8 @@ event_scheduler_thread(void *arg) my_free(arg); if (!res) scheduler->run(thd); - else - { - thd->proc_info= "Clearing"; - net_end(&thd->net); - delete thd; - } + deinit_event_thread(thd); DBUG_LEAVE; // Against gcc warnings my_thread_end(); return 0; @@ -304,6 +297,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) DBUG_ENTER("Event_worker_thread::run"); DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd)); + inc_thread_running(); if (res) goto end; @@ -332,6 +326,7 @@ end: event->name.str)); delete event; + dec_thread_running(); deinit_event_thread(thd); DBUG_VOID_RETURN; @@ -436,13 +431,9 @@ Event_scheduler::start(int *err_no) " Can not create thread for event scheduler (errno=%d)", *err_no); - new_thd->proc_info= "Clearing"; - DBUG_ASSERT(new_thd->net.buff != 0); - net_end(&new_thd->net); - state= INITIALIZED; scheduler_thd= NULL; - delete new_thd; + deinit_event_thread(new_thd); delete scheduler_param_value; ret= true; @@ -509,7 +500,6 @@ Event_scheduler::run(THD *thd) } LOCK_DATA(); - deinit_event_thread(thd); scheduler_thd= NULL; state= INITIALIZED; DBUG_PRINT("info", ("Broadcasting COND_state back to the stoppers")); @@ -569,10 +559,7 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name) sql_print_error("Event_scheduler::execute_top: Can not create event worker" " thread (errno=%d). Stopping event scheduler", res); - new_thd->proc_info= "Clearing"; - DBUG_ASSERT(new_thd->net.buff != 0); - net_end(&new_thd->net); - + deinit_event_thread(new_thd); goto error; } @@ -584,9 +571,6 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name) error: DBUG_PRINT("error", ("Event_scheduler::execute_top() res: %d", res)); - if (new_thd) - delete new_thd; - delete event_name; DBUG_RETURN(TRUE); } diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc index 34110dcfc1f..a0bc5ee6aa2 100644 --- a/sql/filesort_utils.cc +++ b/sql/filesort_utils.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "filesort_utils.h" #include "sql_const.h" diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc index f62c413fd35..ab48542add6 100644 --- a/sql/gcalc_slicescan.cc +++ b/sql/gcalc_slicescan.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <my_global.h> diff --git a/sql/gcalc_slicescan.h b/sql/gcalc_slicescan.h index 4996287ca88..b9516fc8d8c 100644 --- a/sql/gcalc_slicescan.h +++ b/sql/gcalc_slicescan.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #ifndef GCALC_SLICESCAN_INCLUDED diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc index da0252c6b67..71118ae1c9f 100644 --- a/sql/gcalc_tools.cc +++ b/sql/gcalc_tools.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <my_global.h> diff --git a/sql/gcalc_tools.h b/sql/gcalc_tools.h index 9e9b580b359..8bda3c144a6 100644 --- a/sql/gcalc_tools.h +++ b/sql/gcalc_tools.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #ifndef GCALC_TOOLS_INCLUDED diff --git a/sql/group_by_handler.cc b/sql/group_by_handler.cc index e3420b8d48d..c1b5cfbe254 100644 --- a/sql/group_by_handler.cc +++ b/sql/group_by_handler.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* This file implements the group_by_handler code. This interface diff --git a/sql/group_by_handler.h b/sql/group_by_handler.h index b05b7fd39ae..d3f48a15c24 100644 --- a/sql/group_by_handler.h +++ b/sql/group_by_handler.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* This file implements the group_by_handler interface. This interface diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index d1a5a7bb0ea..7f156c80205 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -7275,6 +7275,7 @@ int ha_partition::reset(void) result= tmp; } bitmap_clear_all(&m_partitions_to_reset); + m_extra_prepare_for_update= FALSE; DBUG_RETURN(result); } diff --git a/sql/handler.cc b/sql/handler.cc index fb5d1699419..e07d656c986 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3385,6 +3385,8 @@ void handler::print_error(int error, myf errflag) textno=ER_FILE_USED; break; case ENOENT: + case ENOTDIR: + case ELOOP: textno=ER_FILE_NOT_FOUND; break; case ENOSPC: @@ -3862,7 +3864,6 @@ int handler::delete_table(const char *name) int saved_error= 0; int error= 0; int enoent_or_zero; - char buff[FN_REFLEN]; if (ht->discover_table) enoent_or_zero= 0; // the table may not exist in the engine, it's ok @@ -3871,8 +3872,7 @@ int handler::delete_table(const char *name) for (const char **ext=bas_ext(); *ext ; ext++) { - fn_format(buff, name, "", *ext, MY_UNPACK_FILENAME|MY_APPEND_EXT); - if (mysql_file_delete_with_symlink(key_file_misc, buff, MYF(0))) + if (mysql_file_delete_with_symlink(key_file_misc, name, *ext, 0)) { if (my_errno != ENOENT) { @@ -4229,7 +4229,7 @@ enum_alter_inplace_result handler::check_if_supported_inplace_alter(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { - DBUG_ENTER("check_if_supported_alter"); + DBUG_ENTER("handler::check_if_supported_inplace_alter"); HA_CREATE_INFO *create_info= ha_alter_info->create_info; @@ -5056,14 +5056,16 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name, bool exists= true; if (hton) { - enum legacy_db_type db_type; - if (dd_frm_type(thd, path, &db_type) != FRMTYPE_VIEW) + char engine_buf[NAME_CHAR_LEN + 1]; + LEX_STRING engine= { engine_buf, 0 }; + + if (dd_frm_type(thd, path, &engine) != FRMTYPE_VIEW) { - handlerton *ht= ha_resolve_by_legacy_type(thd, db_type); - if ((*hton= ht)) + plugin_ref p= plugin_lock_by_name(thd, &engine, MYSQL_STORAGE_ENGINE_PLUGIN); + *hton= p ? plugin_hton(p) : NULL; + if (*hton) // verify that the table really exists - exists= discover_existence(thd, - plugin_int_to_ref(hton2plugin[ht->slot]), &args); + exists= discover_existence(thd, p, &args); } else *hton= view_pseudo_hton; diff --git a/sql/item.h b/sql/item.h index 67640ce5f4d..6d69e3b60de 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4930,6 +4930,11 @@ public: virtual double val_real() = 0; virtual longlong val_int() = 0; virtual int save_in_field(Field *field, bool no_conversions) = 0; + bool walk(Item_processor processor, bool walk_subquery, void *args) + { + return (item->walk(processor, walk_subquery, args)) || + (this->*processor)(args); + } }; /** diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index a3b9041aed4..689ce656d60 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -645,6 +645,22 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg, return 0; } + if (m_compare_type == REAL_RESULT && + (((*a)->result_type() == DECIMAL_RESULT && !(*a)->const_item() && + (*b)->result_type() == STRING_RESULT && (*b)->const_item()) || + ((*b)->result_type() == DECIMAL_RESULT && !(*b)->const_item() && + (*a)->result_type() == STRING_RESULT && (*a)->const_item()))) + { + /* + <non-const decimal expression> <cmp> <const string expression> + or + <const string expression> <cmp> <non-const decimal expression> + + Do comparison as decimal rather than float, in order not to lose precision. + */ + m_compare_type= DECIMAL_RESULT; + } + if (m_compare_type == INT_RESULT && (*a)->field_type() == MYSQL_TYPE_YEAR && (*b)->field_type() == MYSQL_TYPE_YEAR) @@ -5171,6 +5187,18 @@ bool Item_func_like::with_sargable_pattern() const } +SEL_TREE *Item_func_like::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr) +{ + MEM_ROOT *tmp_root= param->mem_root; + param->thd->mem_root= param->old_root; + bool sargable_pattern= with_sargable_pattern(); + param->thd->mem_root= tmp_root; + return sargable_pattern ? + Item_bool_func2::get_mm_tree(param, cond_ptr) : + Item_func::get_mm_tree(param, cond_ptr); +} + + bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str, bool escape_used_in_parsing, CHARSET_INFO *cmp_cs, int *escape) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index cb51b1dda82..1a2cc3a6c81 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1948,12 +1948,7 @@ public: } void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables); - SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr) - { - return with_sargable_pattern() ? - Item_bool_func2::get_mm_tree(param, cond_ptr) : - Item_func::get_mm_tree(param, cond_ptr); - } + SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr); Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) { /* diff --git a/sql/item_func.cc b/sql/item_func.cc index 2e0596da2d1..ed527cda218 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3890,12 +3890,7 @@ longlong Item_master_pos_wait::val_int() else connection_name= thd->variables.default_master_connection; - mysql_mutex_lock(&LOCK_active_mi); - if (master_info_index) // master_info_index is set to NULL on shutdown. - mi= master_info_index->get_master_info(&connection_name, - Sql_condition::WARN_LEVEL_WARN); - mysql_mutex_unlock(&LOCK_active_mi); - if (!mi) + if (!(mi= get_master_info(&connection_name, Sql_condition::WARN_LEVEL_WARN))) goto err; if ((event_count = mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2) @@ -3903,6 +3898,7 @@ longlong Item_master_pos_wait::val_int() null_value = 1; event_count=0; } + mi->release(); #endif return event_count; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 21f8ccb4348..b34f9fd1b58 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -33,9 +33,6 @@ #include <my_global.h> // HAVE_* -/* May include caustic 3rd-party defs. Use early, so it can override nothing */ -#include "sha2.h" - #include "sql_priv.h" /* It is necessary to include set_var.h instead of item.h because there @@ -51,9 +48,7 @@ #include "password.h" // my_make_scrambled_password, // my_make_scrambled_password_323 #include <m_ctype.h> -#include <base64.h> #include <my_md5.h> -#include "sha1.h" C_MODE_START #include "../mysys/my_static.h" // For soundex_map C_MODE_END @@ -171,14 +166,14 @@ String *Item_func_sha::val_str_ascii(String *str) if (sptr) /* If we got value different from NULL */ { /* Temporary buffer to store 160bit digest */ - uint8 digest[SHA1_HASH_SIZE]; - compute_sha1_hash(digest, (const char *) sptr->ptr(), sptr->length()); + uint8 digest[MY_SHA1_HASH_SIZE]; + my_sha1(digest, (const char *) sptr->ptr(), sptr->length()); /* Ensure that memory is free and we got result */ - if (!str->alloc(SHA1_HASH_SIZE*2)) + if (!str->alloc(MY_SHA1_HASH_SIZE*2)) { - array_to_hex((char *) str->ptr(), digest, SHA1_HASH_SIZE); + array_to_hex((char *) str->ptr(), digest, MY_SHA1_HASH_SIZE); str->set_charset(&my_charset_numeric); - str->length((uint) SHA1_HASH_SIZE*2); + str->length((uint) MY_SHA1_HASH_SIZE*2); null_value=0; return str; } @@ -190,18 +185,16 @@ String *Item_func_sha::val_str_ascii(String *str) void Item_func_sha::fix_length_and_dec() { // size of hex representation of hash - fix_length_and_charset(SHA1_HASH_SIZE * 2, default_charset()); + fix_length_and_charset(MY_SHA1_HASH_SIZE * 2, default_charset()); } String *Item_func_sha2::val_str_ascii(String *str) { DBUG_ASSERT(fixed == 1); -#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) - unsigned char digest_buf[SHA512_DIGEST_LENGTH]; + unsigned char digest_buf[512/8]; // enough for SHA512 String *input_string; - unsigned char *input_ptr; + const char *input_ptr; size_t input_len; - uint digest_length= 0; str->set_charset(&my_charset_bin); @@ -216,31 +209,26 @@ String *Item_func_sha2::val_str_ascii(String *str) if (null_value) return (String *) NULL; - input_ptr= (unsigned char *) input_string->ptr(); + input_ptr= input_string->ptr(); input_len= input_string->length(); - switch ((uint) args[1]->val_int()) { -#ifndef OPENSSL_NO_SHA512 + longlong digest_length= args[1]->val_int(); + switch (digest_length) { case 512: - digest_length= SHA512_DIGEST_LENGTH; - (void) SHA512(input_ptr, input_len, digest_buf); + my_sha512(digest_buf, input_ptr, input_len); break; case 384: - digest_length= SHA384_DIGEST_LENGTH; - (void) SHA384(input_ptr, input_len, digest_buf); + my_sha384(digest_buf, input_ptr, input_len); break; -#endif -#ifndef OPENSSL_NO_SHA256 case 224: - digest_length= SHA224_DIGEST_LENGTH; - (void) SHA224(input_ptr, input_len, digest_buf); + my_sha224(digest_buf, input_ptr, input_len); break; - case 256: case 0: // SHA-256 is the default - digest_length= SHA256_DIGEST_LENGTH; - (void) SHA256(input_ptr, input_len, digest_buf); + digest_length= 256; + /* fall trough */ + case 256: + my_sha256(digest_buf, input_ptr, input_len); break; -#endif default: if (!args[1]->const_item()) { @@ -254,6 +242,7 @@ String *Item_func_sha2::val_str_ascii(String *str) null_value= TRUE; return NULL; } + digest_length/= 8; /* bits to bytes */ /* Since we're subverting the usual String methods, we must make sure that @@ -269,17 +258,6 @@ String *Item_func_sha2::val_str_ascii(String *str) null_value= FALSE; return str; - -#else - THD *thd= current_thd; - push_warning_printf(thd, - Sql_condition::WARN_LEVEL_WARN, - ER_FEATURE_DISABLED, - ER_THD(thd, ER_FEATURE_DISABLED), - "sha2", "--with-ssl"); - null_value= TRUE; - return (String *) NULL; -#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */ } @@ -288,27 +266,18 @@ void Item_func_sha2::fix_length_and_dec() maybe_null= 1; max_length = 0; -#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) int sha_variant= args[1]->const_item() ? args[1]->val_int() : 512; switch (sha_variant) { -#ifndef OPENSSL_NO_SHA512 + case 0: // SHA-256 is the default + sha_variant= 256; + /* fall trough */ case 512: - fix_length_and_charset(SHA512_DIGEST_LENGTH * 2, default_charset()); - break; case 384: - fix_length_and_charset(SHA384_DIGEST_LENGTH * 2, default_charset()); - break; -#endif -#ifndef OPENSSL_NO_SHA256 case 256: - case 0: // SHA-256 is the default - fix_length_and_charset(SHA256_DIGEST_LENGTH * 2, default_charset()); - break; case 224: - fix_length_and_charset(SHA224_DIGEST_LENGTH * 2, default_charset()); + fix_length_and_charset(sha_variant/8 * 2, default_charset()); break; -#endif default: THD *thd= current_thd; push_warning_printf(thd, @@ -317,15 +286,6 @@ void Item_func_sha2::fix_length_and_dec() ER_THD(thd, ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2"); } - -#else - THD *thd= current_thd; - push_warning_printf(thd, - Sql_condition::WARN_LEVEL_WARN, - ER_FEATURE_DISABLED, - ER_THD(thd, ER_FEATURE_DISABLED), - "sha2", "--with-ssl"); -#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */ } /* Implementation of AES encryption routines */ @@ -5203,4 +5163,3 @@ null: my_free(names); return NULL; } - diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 94bc71ca889..76c754d5627 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -934,7 +934,7 @@ void Item_subselect::update_used_tables() if (!forced_const) { recalc_used_tables(parent_select, FALSE); - if (!engine->uncacheable()) + if (!(engine->uncacheable() & ~UNCACHEABLE_EXPLAIN)) { // did all used tables become static? if (!(used_tables_cache & ~engine->upper_select_const_tables())) @@ -2113,6 +2113,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, We can encounter "NULL IN (SELECT ...)". Wrap the added condition within a trig_cond. */ + disable_cond_guard_for_const_null_left_expr(0); item= new (thd->mem_root) Item_func_trig_cond(thd, item, get_cond_guard(0)); } @@ -2137,6 +2138,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, having= new (thd->mem_root) Item_is_not_null_test(thd, this, having); if (left_expr->maybe_null) { + disable_cond_guard_for_const_null_left_expr(0); if (!(having= new (thd->mem_root) Item_func_trig_cond(thd, having, get_cond_guard(0)))) DBUG_RETURN(true); @@ -2155,6 +2157,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, */ if (!abort_on_null && left_expr->maybe_null) { + disable_cond_guard_for_const_null_left_expr(0); if (!(item= new (thd->mem_root) Item_func_trig_cond(thd, item, get_cond_guard(0)))) DBUG_RETURN(true); @@ -2184,6 +2187,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, (char *)"<result>")); if (!abort_on_null && left_expr->maybe_null) { + disable_cond_guard_for_const_null_left_expr(0); if (!(new_having= new (thd->mem_root) Item_func_trig_cond(thd, new_having, get_cond_guard(0)))) DBUG_RETURN(true); @@ -2383,6 +2387,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, Item_cond_or(thd, item_eq, item_isnull); if (!abort_on_null && left_expr->element_index(i)->maybe_null) { + disable_cond_guard_for_const_null_left_expr(i); if (!(col_item= new (thd->mem_root) Item_func_trig_cond(thd, col_item, get_cond_guard(i)))) DBUG_RETURN(true); @@ -2400,6 +2405,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, (char *)"<list ref>")); if (!abort_on_null && left_expr->element_index(i)->maybe_null) { + disable_cond_guard_for_const_null_left_expr(i); if (!(item_nnull_test= new (thd->mem_root) Item_func_trig_cond(thd, item_nnull_test, get_cond_guard(i)))) @@ -2460,6 +2466,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join, item= new (thd->mem_root) Item_cond_or(thd, item, item_isnull); if (left_expr->element_index(i)->maybe_null) { + disable_cond_guard_for_const_null_left_expr(i); if (!(item= new (thd->mem_root) Item_func_trig_cond(thd, item, get_cond_guard(i)))) DBUG_RETURN(true); diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 805e8958246..aa01f571a3d 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -633,6 +633,15 @@ public: bool expr_cache_is_needed(THD *thd); inline bool left_expr_has_null(); + void disable_cond_guard_for_const_null_left_expr(int i) + { + if (left_expr->const_item() && !left_expr->is_expensive()) + { + if (left_expr->element_index(i)->is_null()) + set_cond_guard_var(i,FALSE); + } + } + int optimize(double *out_rows, double *cost); /* Return the identifier that we could use to identify the subquery for the diff --git a/sql/log.cc b/sql/log.cc index 7ad9790bb13..64c7698e2a2 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2793,16 +2793,16 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name, void MYSQL_QUERY_LOG::reopen_file() { char *save_name; - DBUG_ENTER("MYSQL_LOG::reopen_file"); + + mysql_mutex_lock(&LOCK_log); if (!is_open()) { DBUG_PRINT("info",("log is closed")); + mysql_mutex_unlock(&LOCK_log); DBUG_VOID_RETURN; } - mysql_mutex_lock(&LOCK_log); - save_name= name; name= 0; // Don't free name close(LOG_CLOSE_TO_BE_OPENED); @@ -2960,13 +2960,6 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, DBUG_ENTER("MYSQL_QUERY_LOG::write"); mysql_mutex_lock(&LOCK_log); - - if (!is_open()) - { - mysql_mutex_unlock(&LOCK_log); - DBUG_RETURN(0); - } - if (is_open()) { // Safety agains reopen int tmp_errno= 0; @@ -3216,7 +3209,9 @@ void MYSQL_BIN_LOG::cleanup() stop_background_thread(); inited= 0; + mysql_mutex_lock(&LOCK_log); close(LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT); + mysql_mutex_unlock(&LOCK_log); delete description_event_for_queue; delete description_event_for_exec; @@ -3383,6 +3378,8 @@ bool MYSQL_BIN_LOG::open(const char *log_name, DBUG_ENTER("MYSQL_BIN_LOG::open"); DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg)); + mysql_mutex_assert_owner(&LOCK_log); + if (!is_relay_log) { if (!binlog_state_recover_done) @@ -4342,7 +4339,7 @@ void MYSQL_BIN_LOG::wait_for_last_checkpoint_event() int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) { - int error; + int error, errcode; char *to_purge_if_included= NULL; inuse_relaylog *ir; ulonglong log_space_reclaimed= 0; @@ -4412,7 +4409,8 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) } /* Store where we are in the new file for the execution thread */ - rli->flush(); + if (rli->flush()) + error= LOG_INFO_IO; DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE();); @@ -4428,10 +4426,10 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) * Need to update the log pos because purge logs has been called * after fetching initially the log pos at the beginning of the method. */ - if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0))) + if ((errcode= find_log_pos(&rli->linfo, rli->event_relay_log_name, 0))) { sql_print_error("next log error: %d offset: %llu log: %s included: %d", - error, rli->linfo.index_file_offset, + errcode, rli->linfo.index_file_offset, rli->group_relay_log_name, included); goto err; } @@ -5055,19 +5053,19 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) File UNINIT_VAR(old_file); DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl"); + if (need_lock) + mysql_mutex_lock(&LOCK_log); + mysql_mutex_assert_owner(&LOCK_log); + if (!is_open()) { DBUG_PRINT("info",("log is closed")); + mysql_mutex_unlock(&LOCK_log); DBUG_RETURN(error); } - if (need_lock) - mysql_mutex_lock(&LOCK_log); mysql_mutex_lock(&LOCK_index); - mysql_mutex_assert_owner(&LOCK_log); - mysql_mutex_assert_owner(&LOCK_index); - /* Reuse old name if not binlog and not update log */ new_name_ptr= name; @@ -5202,9 +5200,9 @@ end: new_name_ptr, errno); } + mysql_mutex_unlock(&LOCK_index); if (need_lock) mysql_mutex_unlock(&LOCK_log); - mysql_mutex_unlock(&LOCK_index); DBUG_RETURN(error); } @@ -8145,9 +8143,11 @@ int MYSQL_BIN_LOG::wait_for_update_binlog_end_pos(THD* thd, void MYSQL_BIN_LOG::close(uint exiting) { // One can't set log_type here! bool failed_to_save_state= false; - DBUG_ENTER("MYSQL_BIN_LOG::close"); DBUG_PRINT("enter",("exiting: %d", (int) exiting)); + + mysql_mutex_assert_owner(&LOCK_log); + if (log_state == LOG_OPENED) { #ifdef HAVE_REPLICATION diff --git a/sql/log_event.cc b/sql/log_event.cc index 69d0f52d211..3aea3eaf2f1 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -46,7 +46,6 @@ #include "wsrep_mysqld.h" #endif /* MYSQL_CLIENT */ -#include <base64.h> #include <my_bitmap.h> #include "rpl_utility.h" #include "rpl_constants.h" @@ -7219,9 +7218,11 @@ bool Rotate_log_event::write() @retval 0 ok + 1 error */ int Rotate_log_event::do_update_pos(rpl_group_info *rgi) { + int error= 0; Relay_log_info *rli= rgi->rli; DBUG_ENTER("Rotate_log_event::do_update_pos"); @@ -7270,7 +7271,7 @@ int Rotate_log_event::do_update_pos(rpl_group_info *rgi) (ulong) rli->group_master_log_pos)); mysql_mutex_unlock(&rli->data_lock); rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi); - rli->flush(); + error= rli->flush(); /* Reset thd->variables.option_bits and sql_mode etc, because this could @@ -7288,8 +7289,7 @@ int Rotate_log_event::do_update_pos(rpl_group_info *rgi) else rgi->inc_event_relay_log_pos(); - - DBUG_RETURN(0); + DBUG_RETURN(error); } @@ -9053,6 +9053,7 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) int Stop_log_event::do_update_pos(rpl_group_info *rgi) { + int error= 0; Relay_log_info *rli= rgi->rli; DBUG_ENTER("Stop_log_event::do_update_pos"); /* @@ -9068,9 +9069,10 @@ int Stop_log_event::do_update_pos(rpl_group_info *rgi) { rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi); rli->inc_group_relay_log_pos(0, rgi); - rli->flush(); + if (rli->flush()) + error= 1; } - DBUG_RETURN(0); + DBUG_RETURN(error); } #endif /* !MYSQL_CLIENT */ @@ -11154,8 +11156,8 @@ int Rows_log_event::do_update_pos(rpl_group_info *rgi) { Relay_log_info *rli= rgi->rli; - DBUG_ENTER("Rows_log_event::do_update_pos"); int error= 0; + DBUG_ENTER("Rows_log_event::do_update_pos"); DBUG_PRINT("info", ("flags: %s", get_flags(STMT_END_F) ? "STMT_END_F " : "")); @@ -11167,7 +11169,7 @@ Rows_log_event::do_update_pos(rpl_group_info *rgi) Step the group log position if we are not in a transaction, otherwise increase the event log position. */ - rli->stmt_done(log_pos, thd, rgi); + error= rli->stmt_done(log_pos, thd, rgi); /* Clear any errors in thd->net.last_err*. It is not known if this is needed or not. It is believed that any errors that may exist in diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 552221ee68a..381f4129321 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1745,8 +1745,8 @@ int Old_rows_log_event::do_update_pos(rpl_group_info *rgi) { Relay_log_info *rli= rgi->rli; - DBUG_ENTER("Old_rows_log_event::do_update_pos"); int error= 0; + DBUG_ENTER("Old_rows_log_event::do_update_pos"); DBUG_PRINT("info", ("flags: %s", get_flags(STMT_END_F) ? "STMT_END_F " : "")); @@ -1758,7 +1758,7 @@ Old_rows_log_event::do_update_pos(rpl_group_info *rgi) Step the group log position if we are not in a transaction, otherwise increase the event log position. */ - rli->stmt_done(log_pos, thd, rgi); + error= rli->stmt_done(log_pos, thd, rgi); /* Clear any errors in thd->net.last_err*. It is not known if this is needed or not. It is believed that any errors that may exist in diff --git a/sql/log_slow.h b/sql/log_slow.h index c641d2be87d..c52722f0cd7 100644 --- a/sql/log_slow.h +++ b/sql/log_slow.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* Defining what to log to slow log */ diff --git a/sql/mdl.cc b/sql/mdl.cc index c05fdc0157b..f1a505f3d84 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -2126,7 +2126,8 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) find_deadlock(); struct timespec abs_timeout, abs_shortwait; - set_timespec(abs_timeout, (ulonglong) lock_wait_timeout); + set_timespec_nsec(abs_timeout, + (ulonglong)(lock_wait_timeout * 1000000000ULL)); set_timespec(abs_shortwait, 1); wait_status= MDL_wait::EMPTY; diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 5de9b4a9eec..53d0c3204a1 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "sql_parse.h" #include <my_bit.h> diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h index ffae6d63124..b8234998f74 100644 --- a/sql/multi_range_read.h +++ b/sql/multi_range_read.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @defgroup DS-MRR declarations diff --git a/sql/my_apc.cc b/sql/my_apc.cc index dcb8503b880..b165a801ce5 100644 --- a/sql/my_apc.cc +++ b/sql/my_apc.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #ifndef MY_APC_STANDALONE diff --git a/sql/my_apc.h b/sql/my_apc.h index 20b1ee4c4ec..46c6fbd549d 100644 --- a/sql/my_apc.h +++ b/sql/my_apc.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* Interface diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc index 135ce353552..390123fbba9 100644 --- a/sql/my_json_writer.cc +++ b/sql/my_json_writer.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <my_global.h> #include "sql_priv.h" diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index 8ab20b10d73..c4b528ae10d 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ class Json_writer; diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index 58f19c427aa..5960346c60e 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* mysql_install_db creates a new database instance (optionally as service) @@ -393,8 +393,8 @@ static int register_service() CloseServiceHandle(sc_manager); die("CreateService failed (%u)", GetLastError()); } - - SERVICE_DESCRIPTION sd= { "MariaDB database server" }; + char description[] = "MariaDB database server"; + SERVICE_DESCRIPTION sd= { description }; ChangeServiceConfig2(sc_service, SERVICE_CONFIG_DESCRIPTION, &sd); CloseServiceHandle(sc_service); CloseServiceHandle(sc_manager); diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc index db916101eb1..36de05e54e4 100644 --- a/sql/mysql_upgrade_service.cc +++ b/sql/mysql_upgrade_service.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* mysql_upgrade_service upgrades mysql service on Windows. diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7b8e3ee0ee6..6108ed6ffd4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -21,7 +21,7 @@ #ifndef __WIN__ #include <netdb.h> // getservbyname, servent #endif -#include "sql_parse.h" // test_if_data_home_dir +#include "sql_parse.h" // path_starts_from_data_home_dir #include "sql_cache.h" // query_cache, query_cache_* #include "sql_locale.h" // MY_LOCALES, my_locales, my_locale_by_name #include "sql_show.h" // free_status_vars, add_status_vars, @@ -750,12 +750,15 @@ mysql_mutex_t LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_global_system_variables, - LOCK_user_conn, LOCK_slave_list, LOCK_active_mi, + LOCK_user_conn, LOCK_slave_list, LOCK_connection_count, LOCK_error_messages, LOCK_slave_background; mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats, LOCK_global_table_stats, LOCK_global_index_stats; +/* This protects against changes in master_info_index */ +mysql_mutex_t LOCK_active_mi; + /** The below lock protects access to two global server variables: max_prepared_stmt_count and prepared_stmt_count. These variables @@ -913,7 +916,7 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_LOCK_system_variables_hash, key_LOCK_thd_data, key_LOCK_user_conn, key_LOCK_uuid_short_generator, key_LOG_LOCK_log, key_master_info_data_lock, key_master_info_run_lock, - key_master_info_sleep_lock, + key_master_info_sleep_lock, key_master_info_start_stop_lock, key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock, key_rpl_group_info_sleep_lock, key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, @@ -986,6 +989,7 @@ static PSI_mutex_info all_server_mutexes[]= { &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL}, { &key_LOG_LOCK_log, "LOG::LOCK_log", 0}, { &key_master_info_data_lock, "Master_info::data_lock", 0}, + { &key_master_info_start_stop_lock, "Master_info::start_stop_lock", 0}, { &key_master_info_run_lock, "Master_info::run_lock", 0}, { &key_master_info_sleep_lock, "Master_info::sleep_lock", 0}, { &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0}, @@ -1478,7 +1482,7 @@ ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE; Query_cache query_cache; #endif #ifdef HAVE_SMEM -char *shared_memory_base_name= default_shared_memory_base_name; +const char *shared_memory_base_name= default_shared_memory_base_name; my_bool opt_enable_shared_memory; HANDLE smem_event_connect_request= 0; #endif @@ -1719,7 +1723,7 @@ static void close_connections(void) mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list Events::deinit(); - end_slave(); + slave_prepare_for_shutdown(); mysql_bin_log.stop_background_thread(); /* @@ -1798,6 +1802,7 @@ static void close_connections(void) DBUG_PRINT("quit",("Unlocking LOCK_thread_count")); mysql_mutex_unlock(&LOCK_thread_count); } + end_slave(); /* All threads has now been aborted */ DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count)); mysql_mutex_lock(&LOCK_thread_count); @@ -2605,6 +2610,12 @@ static MYSQL_SOCKET activate_tcp_port(uint port) (char*)&arg, sizeof(arg)); } #endif + +#ifdef IP_FREEBIND + arg= 1; + (void) mysql_socket_setsockopt(ip_sock, IPPROTO_IP, IP_FREEBIND, (char*) &arg, + sizeof(arg)); +#endif /* Sometimes the port is not released fast enough when stopping and restarting the server. This happens quite often with the test suite @@ -2836,31 +2847,8 @@ void dec_connection_count(scheduler_functions *scheduler) /* - Delete THD and decrement thread counters, including thread_running - - This is mainly used to delete event threads which are not increasing - global counters. -*/ - -void delete_running_thd(THD *thd) -{ - thd->add_status_to_global(); - unlink_not_visible_thd(thd); - - delete thd; - dec_thread_running(); -} - -/* - Decrease number of threads. Signal when it reaches 0 - - SYNOPSIS - dec_thread_count() -*/ - -/* - Send a signal to unblock close_conneciton() / rpl_slave_init_thread() - if there is no more threads running with a THD attached + Send a signal to unblock close_conneciton() if there is no more + threads running with a THD attached It's safe to check for thread_count and service_thread_count outside of a mutex as we are only interested to see if they where decremented @@ -5404,15 +5392,13 @@ static int init_server_components() if (opt_bin_log) { - /** - * mutex lock is not needed here. - * but to be able to have mysql_mutex_assert_owner() in code, - * we do it anyway */ - mysql_mutex_lock(mysql_bin_log.get_log_lock()); - int r= mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, 0, + int error; + mysql_mutex_t *log_lock= mysql_bin_log.get_log_lock(); + mysql_mutex_lock(log_lock); + error= mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, 0, WRITE_CACHE, max_binlog_size, 0, TRUE); - mysql_mutex_unlock(mysql_bin_log.get_log_lock()); - if (r) + mysql_mutex_unlock(log_lock); + if (error) unireg_abort(1); } @@ -7722,17 +7708,14 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff, var->type= SHOW_MY_BOOL; var->value= buff; - mysql_mutex_lock(&LOCK_active_mi); - if (master_info_index) + + if ((mi= get_master_info(&thd->variables.default_master_connection, + Sql_condition::WARN_LEVEL_NOTE))) { - mi= master_info_index-> - get_master_info(&thd->variables.default_master_connection, - Sql_condition::WARN_LEVEL_NOTE); - if (mi) - tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING && - mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN); + tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING && + mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN); + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); if (mi) *((my_bool *)buff)= tmp; else @@ -7764,14 +7747,9 @@ static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONGLONG; var->value= buff; - mysql_mutex_lock(&LOCK_active_mi); - if (master_info_index) - *((longlong *)buff)= master_info_index->any_slave_sql_running(); - else - *((longlong *)buff)= 0; + *((longlong *)buff)= any_slave_sql_running(); - mysql_mutex_unlock(&LOCK_active_mi); return 0; } @@ -7779,23 +7757,17 @@ static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff) static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff, enum enum_var_type scope) { - Master_info *mi= NULL; - longlong UNINIT_VAR(tmp); + Master_info *mi; var->type= SHOW_LONGLONG; var->value= buff; - mysql_mutex_lock(&LOCK_active_mi); - if (master_info_index) + + if ((mi= get_master_info(&thd->variables.default_master_connection, + Sql_condition::WARN_LEVEL_NOTE))) { - mi= master_info_index-> - get_master_info(&thd->variables.default_master_connection, - Sql_condition::WARN_LEVEL_NOTE); - if (mi) - tmp= mi->received_heartbeats; + *((longlong *)buff)= mi->received_heartbeats; + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); - if (mi) - *((longlong *)buff)= tmp; else var->type= SHOW_UNDEF; return 0; @@ -7805,23 +7777,17 @@ static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff, static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff, enum enum_var_type scope) { - Master_info *mi= NULL; - float UNINIT_VAR(tmp); + Master_info *mi; var->type= SHOW_CHAR; var->value= buff; - mysql_mutex_lock(&LOCK_active_mi); - if (master_info_index) + + if ((mi= get_master_info(&thd->variables.default_master_connection, + Sql_condition::WARN_LEVEL_NOTE))) { - mi= master_info_index-> - get_master_info(&thd->variables.default_master_connection, - Sql_condition::WARN_LEVEL_NOTE); - if (mi) - tmp= mi->heartbeat_period; + sprintf(buff, "%.3f", mi->heartbeat_period); + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); - if (mi) - sprintf(buff, "%.3f", tmp); else var->type= SHOW_UNDEF; return 0; @@ -8712,7 +8678,7 @@ static int mysql_init_variables(void) mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0; #if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH) /* We can only test for sub paths if my_symlink.c is using realpath */ - myisam_test_invalid_symlink= test_if_data_home_dir; + mysys_test_invalid_symlink= path_starts_from_data_home_dir; #endif opt_log= 0; opt_bin_log= opt_bin_log_used= 0; diff --git a/sql/mysqld.h b/sql/mysqld.h index 8f74194181a..613b57b133d 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -85,7 +85,6 @@ void kill_mysql(THD *thd= 0); void close_connection(THD *thd, uint sql_errno= 0); void handle_connection_in_main_thread(CONNECT *thd); void create_thread_to_handle_connection(CONNECT *connect); -void delete_running_thd(THD *thd); void signal_thd_deleted(); void unlink_thd(THD *thd); bool one_thread_per_connection_end(THD *thd, bool put_in_cache); @@ -146,7 +145,8 @@ extern my_bool sp_automatic_privileges, opt_noacl; extern ulong use_stat_tables; extern my_bool opt_old_style_user_limits, trust_function_creators; extern uint opt_crash_binlog_innodb; -extern char *shared_memory_base_name, *mysqld_unix_port; +extern const char *shared_memory_base_name; +extern char *mysqld_unix_port; extern my_bool opt_enable_shared_memory; extern ulong opt_replicate_events_marked_for_skip; extern char *default_tz_name; @@ -295,7 +295,7 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_LOCK_thd_data, key_LOCK_user_conn, key_LOG_LOCK_log, key_master_info_data_lock, key_master_info_run_lock, - key_master_info_sleep_lock, + key_master_info_sleep_lock, key_master_info_start_stop_lock, key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock, key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, key_rpl_group_info_sleep_lock, diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index d6a8eac7ed5..e05e43a0a59 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -508,7 +508,7 @@ BOOL NTService::IsService(LPCSTR ServiceName) } /* ------------------------------------------------------------------------ -------------------------------------------------------------------------- */ -BOOL NTService::got_service_option(char **argv, char *service_option) +BOOL NTService::got_service_option(char **argv, const char *service_option) { char *option; for (option= argv[1]; *option; option++) diff --git a/sql/nt_servc.h b/sql/nt_servc.h index 949499d8d7f..6781fe0ddfa 100644 --- a/sql/nt_servc.h +++ b/sql/nt_servc.h @@ -61,7 +61,7 @@ class NTService BOOL SeekStatus(LPCSTR szInternName, int OperationType); BOOL Remove(LPCSTR szInternName); BOOL IsService(LPCSTR ServiceName); - BOOL got_service_option(char **argv, char *service_option); + BOOL got_service_option(char **argv, const char *service_option); BOOL is_super_user(); /* diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc index a6707d458df..1dde5228263 100644 --- a/sql/opt_index_cond_pushdown.cc +++ b/sql/opt_index_cond_pushdown.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "sql_select.h" #include "sql_test.h" diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 397ce6f7ecc..6d088cad91e 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -9297,6 +9297,13 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) if (!tmp->next_key_part) { + if (key2->use_count) + { + SEL_ARG *key2_cpy= new SEL_ARG(*key2); + if (key2_cpy) + return 0; + key2= key2_cpy; + } /* tmp->next_key_part is empty: cut the range that is covered by tmp from key2. @@ -9328,13 +9335,6 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) key2: [---] tmp: [---------] */ - if (key2->use_count) - { - SEL_ARG *key2_cpy= new SEL_ARG(*key2); - if (key2_cpy) - return 0; - key2= key2_cpy; - } key2->copy_max_to_min(tmp); continue; } diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc index fbccb7c4e1d..b3350191d13 100644 --- a/sql/opt_range_mrr.cc +++ b/sql/opt_range_mrr.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /**************************************************************************** MRR Range Sequence Interface implementation that walks a SEL_ARG* tree. diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index dc0caa32998..15b803ac49a 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h index 8daa973f825..7954becfad4 100644 --- a/sql/opt_subselect.h +++ b/sql/opt_subselect.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* Semi-join subquery optimization code definitions diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc index b4131093f0f..b7010d1f8ed 100644 --- a/sql/opt_table_elimination.cc +++ b/sql/opt_table_elimination.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 74c09b8a3c6..24506434a76 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -27,7 +27,7 @@ #include "sql_partition.h" // partition_info.h: LIST_PART_ENTRY // NOT_A_PARTITION_ID #include "partition_info.h" -#include "sql_parse.h" // test_if_data_home_dir +#include "sql_parse.h" #include "sql_acl.h" // *_ACL #include "sql_base.h" // fill_record diff --git a/sql/password.c b/sql/password.c index 37d06136d80..1f0a55a10fe 100644 --- a/sql/password.c +++ b/sql/password.c @@ -38,7 +38,7 @@ The new authentication is performed in following manner: - SERVER: public_seed=create_random_string() + SERVER: public_seed=thd_create_random_password() send(public_seed) CLIENT: recv(public_seed) @@ -66,7 +66,6 @@ #include <password.h> #include <mysql.h> #include <my_rnd.h> -#include <sha1.h> /************ MySQL 3.23-4.0 authentication routines: untouched ***********/ @@ -279,25 +278,6 @@ void make_password_from_salt_323(char *to, const ulong *salt) **************** MySQL 4.1.1 authentication routines ************* */ -/** - Generate string of printable random characters of requested length. - - @param to[out] Buffer for generation; must be at least length+1 bytes - long; result string is always null-terminated - length[in] How many random characters to put in buffer - rand_st Structure used for number generation -*/ - -void create_random_string(char *to, uint length, - struct my_rnd_struct *rand_st) -{ - char *end= to + length; - /* Use pointer arithmetics as it is faster way to do so. */ - for (; to < end; to++) - *to= (char) (my_rnd(rand_st)*94+33); - *to= '\0'; -} - /* Character to use as version identifier for version 4.1 */ @@ -389,10 +369,10 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len, uint8 *hash_stage1, uint8 *hash_stage2) { /* Stage 1: hash password */ - compute_sha1_hash(hash_stage1, password, pass_len); + my_sha1(hash_stage1, password, pass_len); /* Stage 2 : hash first stage's output. */ - compute_sha1_hash(hash_stage2, (const char *) hash_stage1, SHA1_HASH_SIZE); + my_sha1(hash_stage2, (const char *) hash_stage1, MY_SHA1_HASH_SIZE); } @@ -404,7 +384,7 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len, is stored in the database. SYNOPSIS my_make_scrambled_password() - buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string + buf OUT buffer of size 2*MY_SHA1_HASH_SIZE + 2 to store hex string password IN password string pass_len IN length of password string */ @@ -412,14 +392,14 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len, void my_make_scrambled_password(char *to, const char *password, size_t pass_len) { - uint8 hash_stage2[SHA1_HASH_SIZE]; + uint8 hash_stage2[MY_SHA1_HASH_SIZE]; /* Two stage SHA1 hash of the password. */ compute_two_stage_sha1_hash(password, pass_len, (uint8 *) to, hash_stage2); /* convert hash_stage2 to hex string */ *to++= PVERSION41_CHAR; - octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE); + octet2hex(to, (const char*) hash_stage2, MY_SHA1_HASH_SIZE); } @@ -430,7 +410,7 @@ void my_make_scrambled_password(char *to, const char *password, avoid strlen(). SYNOPSIS make_scrambled_password() - buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string + buf OUT buffer of size 2*MY_SHA1_HASH_SIZE + 2 to store hex string password IN NULL-terminated password string */ @@ -451,7 +431,7 @@ void make_scrambled_password(char *to, const char *password) SYNOPSIS scramble() buf OUT store scrambled string here. The buf must be at least - SHA1_HASH_SIZE bytes long. + MY_SHA1_HASH_SIZE bytes long. message IN random message, must be exactly SCRAMBLE_LENGTH long and NULL-terminated. password IN users' password @@ -460,16 +440,16 @@ void make_scrambled_password(char *to, const char *password) void scramble(char *to, const char *message, const char *password) { - uint8 hash_stage1[SHA1_HASH_SIZE]; - uint8 hash_stage2[SHA1_HASH_SIZE]; + uint8 hash_stage1[MY_SHA1_HASH_SIZE]; + uint8 hash_stage2[MY_SHA1_HASH_SIZE]; /* Two stage SHA1 hash of the password. */ compute_two_stage_sha1_hash(password, strlen(password), hash_stage1, hash_stage2); /* create crypt string as sha1(message, hash_stage2) */; - compute_sha1_hash_multi((uint8 *) to, message, SCRAMBLE_LENGTH, - (const char *) hash_stage2, SHA1_HASH_SIZE); + my_sha1_multi((uint8 *) to, message, SCRAMBLE_LENGTH, + (const char *) hash_stage2, MY_SHA1_HASH_SIZE, NULL); my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); } @@ -478,7 +458,7 @@ scramble(char *to, const char *message, const char *password) Check that scrambled message corresponds to the password; the function is used by server to check that received reply is authentic. This function does not check lengths of given strings: message must be - null-terminated, reply and hash_stage2 must be at least SHA1_HASH_SIZE + null-terminated, reply and hash_stage2 must be at least MY_SHA1_HASH_SIZE long (if not, something fishy is going on). SYNOPSIS check_scramble() @@ -498,19 +478,19 @@ my_bool check_scramble(const uchar *scramble_arg, const char *message, const uint8 *hash_stage2) { - uint8 buf[SHA1_HASH_SIZE]; - uint8 hash_stage2_reassured[SHA1_HASH_SIZE]; + uint8 buf[MY_SHA1_HASH_SIZE]; + uint8 hash_stage2_reassured[MY_SHA1_HASH_SIZE]; /* create key to encrypt scramble */ - compute_sha1_hash_multi(buf, message, SCRAMBLE_LENGTH, - (const char *) hash_stage2, SHA1_HASH_SIZE); + my_sha1_multi(buf, message, SCRAMBLE_LENGTH, + (const char *) hash_stage2, MY_SHA1_HASH_SIZE, NULL); /* encrypt scramble */ my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH); /* now buf supposedly contains hash_stage1: so we can get hash_stage2 */ - compute_sha1_hash(hash_stage2_reassured, (const char *) buf, SHA1_HASH_SIZE); + my_sha1(hash_stage2_reassured, (const char *) buf, MY_SHA1_HASH_SIZE); - return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE)); + return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, MY_SHA1_HASH_SIZE)); } /* @@ -518,27 +498,27 @@ check_scramble(const uchar *scramble_arg, const char *message, SYNOPSIS get_salt_from_password() - res OUT buf to hold password. Must be at least SHA1_HASH_SIZE + res OUT buf to hold password. Must be at least MY_SHA1_HASH_SIZE bytes long. password IN 4.1.1 version value of user.password */ void get_salt_from_password(uint8 *hash_stage2, const char *password) { - hex2octet(hash_stage2, password+1 /* skip '*' */, SHA1_HASH_SIZE * 2); + hex2octet(hash_stage2, password+1 /* skip '*' */, MY_SHA1_HASH_SIZE * 2); } /* Convert scrambled password from binary form to asciiz hex string. SYNOPSIS make_password_from_salt() - to OUT store resulting string here, 2*SHA1_HASH_SIZE+2 bytes + to OUT store resulting string here, 2*MY_SHA1_HASH_SIZE+2 bytes salt IN password in salt format */ void make_password_from_salt(char *to, const uint8 *hash_stage2) { *to++= PVERSION41_CHAR; - octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE); + octet2hex(to, (const char*) hash_stage2, MY_SHA1_HASH_SIZE); } diff --git a/sql/plistsort.c b/sql/plistsort.c index 71d287e7b45..99657410fe0 100644 --- a/sql/plistsort.c +++ b/sql/plistsort.c @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index a141d238f78..f30b7e161f2 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -40,7 +40,9 @@ Master_info::Master_info(LEX_STRING *connection_name_arg, sync_counter(0), heartbeat_period(0), received_heartbeats(0), master_id(0), prev_master_id(0), using_gtid(USE_GTID_NO), events_queued_since_last_gtid(0), - gtid_reconnect_event_skip_count(0), gtid_event_seen(false) + gtid_reconnect_event_skip_count(0), gtid_event_seen(false), + in_start_all_slaves(0), in_stop_all_slaves(0), + users(0), killed(0) { host[0] = 0; user[0] = 0; password[0] = 0; ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0; @@ -81,6 +83,8 @@ Master_info::Master_info(LEX_STRING *connection_name_arg, bzero((char*) &file, sizeof(file)); mysql_mutex_init(key_master_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_master_info_data_lock, &data_lock, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_master_info_start_stop_lock, &start_stop_lock, + MY_MUTEX_INIT_SLOW); mysql_mutex_setflags(&run_lock, MYF_NO_DEADLOCK_DETECTION); mysql_mutex_setflags(&data_lock, MYF_NO_DEADLOCK_DETECTION); mysql_mutex_init(key_master_info_sleep_lock, &sleep_lock, MY_MUTEX_INIT_FAST); @@ -90,8 +94,27 @@ Master_info::Master_info(LEX_STRING *connection_name_arg, mysql_cond_init(key_master_info_sleep_cond, &sleep_cond, NULL); } + +/** + Wait until no one is using Master_info +*/ + +void Master_info::wait_until_free() +{ + mysql_mutex_lock(&sleep_lock); + killed= 1; + while (users) + mysql_cond_wait(&sleep_cond, &sleep_lock); + mysql_mutex_unlock(&sleep_lock); +} + +/** + Delete master_info +*/ + Master_info::~Master_info() { + wait_until_free(); #ifdef WITH_WSREP /* Do not free "wsrep" rpl_filter. It will eventually be freed by @@ -106,6 +129,7 @@ Master_info::~Master_info() mysql_mutex_destroy(&run_lock); mysql_mutex_destroy(&data_lock); mysql_mutex_destroy(&sleep_lock); + mysql_mutex_destroy(&start_stop_lock); mysql_cond_destroy(&data_cond); mysql_cond_destroy(&start_cond); mysql_cond_destroy(&stop_cond); @@ -841,12 +865,28 @@ uchar *get_key_master_info(Master_info *mi, size_t *length, return (uchar*) mi->cmp_connection_name.str; } +/* + Delete a master info + + Called from my_hash_delete(&master_info_hash) + Stops associated slave threads and frees master_info +*/ + void free_key_master_info(Master_info *mi) { DBUG_ENTER("free_key_master_info"); + mysql_mutex_unlock(&LOCK_active_mi); + + /* Ensure that we are not in reset_slave while this is done */ + mi->lock_slave_threads(); terminate_slave_threads(mi,SLAVE_FORCE_ALL); + /* We use 2 here instead of 1 just to make it easier when debugging */ + mi->killed= 2; end_master_info(mi); + mi->unlock_slave_threads(); delete mi; + + mysql_mutex_lock(&LOCK_active_mi); DBUG_VOID_RETURN; } @@ -1002,9 +1042,28 @@ Master_info_index::Master_info_index() index_file.file= -1; } + +/** + Free all connection threads + + This is done during early stages of shutdown + to give connection threads and slave threads time + to die before ~Master_info_index is called +*/ + +void Master_info_index::free_connections() +{ + mysql_mutex_assert_owner(&LOCK_active_mi); + my_hash_reset(&master_info_hash); +} + + +/** + Free all connection threads and free structures +*/ + Master_info_index::~Master_info_index() { - /* This will close connection for all objects in the cache */ my_hash_free(&master_info_hash); end_io_cache(&index_file); if (index_file.file >= 0) @@ -1025,9 +1084,9 @@ bool Master_info_index::init_all_master_info() int err_num= 0, succ_num= 0; // The number of success read Master_info char sign[MAX_CONNECTION_NAME+1]; File index_file_nr; + THD *thd; DBUG_ENTER("init_all_master_info"); - mysql_mutex_assert_owner(&LOCK_active_mi); DBUG_ASSERT(master_info_index); if ((index_file_nr= my_open(index_file_name, @@ -1057,6 +1116,10 @@ bool Master_info_index::init_all_master_info() DBUG_RETURN(1); } + thd= new THD(next_thread_id()); /* Needed by start_slave_threads */ + thd->thread_stack= (char*) &thd; + thd->store_globals(); + reinit_io_cache(&index_file, READ_CACHE, 0L,0,0); while (!init_strvar_from_file(sign, sizeof(sign), &index_file, NULL)) @@ -1072,10 +1135,9 @@ bool Master_info_index::init_all_master_info() mi->error()) { delete mi; - DBUG_RETURN(1); + goto error; } - lock_slave_threads(mi); init_thread_mask(&thread_mask,mi,0 /*not inverse*/); create_logfile_name_with_suffix(buf_master_info_file, @@ -1090,6 +1152,7 @@ bool Master_info_index::init_all_master_info() sql_print_information("Reading Master_info: '%s' Relay_info:'%s'", buf_master_info_file, buf_relay_log_info_file); + mi->lock_slave_threads(); if (init_master_info(mi, buf_master_info_file, buf_relay_log_info_file, 0, thread_mask)) { @@ -1101,17 +1164,18 @@ bool Master_info_index::init_all_master_info() { /* Master_info is not in HASH; Add it */ if (master_info_index->add_master_info(mi, FALSE)) - DBUG_RETURN(1); + goto error; succ_num++; - unlock_slave_threads(mi); + mi->unlock_slave_threads(); } else { /* Master_info already in HASH */ sql_print_error(ER_THD_OR_DEFAULT(current_thd, ER_CONNECTION_ALREADY_EXISTS), + (int) connection_name.length, connection_name.str, (int) connection_name.length, connection_name.str); - unlock_slave_threads(mi); + mi->unlock_slave_threads(); delete mi; } continue; @@ -1128,23 +1192,23 @@ bool Master_info_index::init_all_master_info() /* Master_info was already registered */ sql_print_error(ER_THD_OR_DEFAULT(current_thd, ER_CONNECTION_ALREADY_EXISTS), + (int) connection_name.length, connection_name.str, (int) connection_name.length, connection_name.str); - unlock_slave_threads(mi); + mi->unlock_slave_threads(); delete mi; continue; } /* Master_info was not registered; add it */ if (master_info_index->add_master_info(mi, FALSE)) - DBUG_RETURN(1); + goto error; succ_num++; - unlock_slave_threads(mi); if (!opt_skip_slave_start) { if (start_slave_threads(current_thd, 1 /* need mutex */, - 0 /* no wait for start*/, + 1 /* wait for start*/, mi, buf_master_info_file, buf_relay_log_info_file, @@ -1160,8 +1224,11 @@ bool Master_info_index::init_all_master_info() (int) connection_name.length, connection_name.str); } + mi->unlock_slave_threads(); } } + thd->reset_globals(); + delete thd; if (!err_num) // No Error on read Master_info { @@ -1169,16 +1236,19 @@ bool Master_info_index::init_all_master_info() sql_print_information("Reading of all Master_info entries succeded"); DBUG_RETURN(0); } - else if (succ_num) // Have some Error and some Success + if (succ_num) // Have some Error and some Success { sql_print_warning("Reading of some Master_info entries failed"); DBUG_RETURN(1); } - else // All failed - { - sql_print_error("Reading of all Master_info entries failed!"); - DBUG_RETURN(1); - } + + sql_print_error("Reading of all Master_info entries failed!"); + DBUG_RETURN(1); + +error: + thd->reset_globals(); + delete thd; + DBUG_RETURN(1); } @@ -1211,6 +1281,71 @@ bool Master_info_index::write_master_name_to_index_file(LEX_STRING *name, /** + Get Master_info for a connection and lock the object from deletion + + @param + connection_name Connection name + warning WARN_LEVEL_NOTE -> Don't print anything + WARN_LEVEL_WARN -> Issue warning if not exists + WARN_LEVEL_ERROR-> Issue error if not exists +*/ + +Master_info *get_master_info(const LEX_STRING *connection_name, + Sql_condition::enum_warning_level warning) +{ + Master_info *mi; + DBUG_ENTER("get_master_info"); + + /* Protect against inserts into hash */ + mysql_mutex_lock(&LOCK_active_mi); + /* + The following can only be true during shutdown when slave has been killed + but some other threads are still trying to access slave statistics. + */ + if (unlikely(!master_info_index)) + { + if (warning != Sql_condition::WARN_LEVEL_NOTE) + my_error(WARN_NO_MASTER_INFO, + MYF(warning == Sql_condition::WARN_LEVEL_WARN ? + ME_JUST_WARNING : 0), + (int) connection_name->length, connection_name->str); + mysql_mutex_unlock(&LOCK_active_mi); + DBUG_RETURN(0); + } + if ((mi= master_info_index->get_master_info(connection_name, warning))) + { + /* + We have to use sleep_lock here. If we would use LOCK_active_mi + then we would take locks in wrong order in Master_info::release() + */ + mysql_mutex_lock(&mi->sleep_lock); + mi->users++; + DBUG_PRINT("info",("users: %d", mi->users)); + mysql_mutex_unlock(&mi->sleep_lock); + } + mysql_mutex_unlock(&LOCK_active_mi); + DBUG_RETURN(mi); +} + + +/** + Release master info. + Signals ~Master_info that it's now safe to delete it +*/ + +void Master_info::release() +{ + mysql_mutex_lock(&sleep_lock); + if (!--users && killed) + { + /* Signal ~Master_info that it's ok to now free it */ + mysql_cond_signal(&sleep_cond); + } + mysql_mutex_unlock(&sleep_lock); +} + + +/** Get Master_info for a connection @param @@ -1232,8 +1367,6 @@ Master_info_index::get_master_info(const LEX_STRING *connection_name, ("connection_name: '%.*s'", (int) connection_name->length, connection_name->str)); - mysql_mutex_assert_owner(&LOCK_active_mi); - /* Make name lower case for comparison */ res= strmake(buff, connection_name->str, connection_name->length); my_casedn_str(system_charset_info, buff); @@ -1299,7 +1432,12 @@ bool Master_info_index::check_duplicate_master_info(LEX_STRING *name_arg, /* Add a Master_info class to Hash Table */ bool Master_info_index::add_master_info(Master_info *mi, bool write_to_file) { - if (!my_hash_insert(&master_info_hash, (uchar*) mi)) + /* + We have to protect against shutdown to ensure we are not calling + my_hash_insert() while my_hash_free() is in progress + */ + if (unlikely(shutdown_in_progress) || + !my_hash_insert(&master_info_hash, (uchar*) mi)) { if (global_system_variables.log_warnings > 1) sql_print_information("Added new Master_info '%.*s' to hash table", @@ -1325,105 +1463,131 @@ bool Master_info_index::add_master_info(Master_info *mi, bool write_to_file) atomic */ -bool Master_info_index::remove_master_info(LEX_STRING *name) +bool Master_info_index::remove_master_info(Master_info *mi) { - Master_info* mi; DBUG_ENTER("remove_master_info"); + mysql_mutex_assert_owner(&LOCK_active_mi); - if ((mi= get_master_info(name, Sql_condition::WARN_LEVEL_WARN))) + // Delete Master_info and rewrite others to file + if (!my_hash_delete(&master_info_hash, (uchar*) mi)) { - // Delete Master_info and rewrite others to file - if (!my_hash_delete(&master_info_hash, (uchar*) mi)) + File index_file_nr; + + // Close IO_CACHE and FILE handler fisrt + end_io_cache(&index_file); + my_close(index_file.file, MYF(MY_WME)); + + // Reopen File and truncate it + if ((index_file_nr= my_open(index_file_name, + O_RDWR | O_CREAT | O_TRUNC | O_BINARY , + MYF(MY_WME))) < 0 || + init_io_cache(&index_file, index_file_nr, + IO_SIZE, WRITE_CACHE, + my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)), + 0, MYF(MY_WME | MY_WAIT_IF_FULL))) { - File index_file_nr; - - // Close IO_CACHE and FILE handler fisrt - end_io_cache(&index_file); - my_close(index_file.file, MYF(MY_WME)); - - // Reopen File and truncate it - if ((index_file_nr= my_open(index_file_name, - O_RDWR | O_CREAT | O_TRUNC | O_BINARY , - MYF(MY_WME))) < 0 || - init_io_cache(&index_file, index_file_nr, - IO_SIZE, WRITE_CACHE, - my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)), - 0, MYF(MY_WME | MY_WAIT_IF_FULL))) - { - int error= my_errno; - if (index_file_nr >= 0) - my_close(index_file_nr,MYF(0)); - - sql_print_error("Create of Master Info Index file '%s' failed with " - "error: %M", - index_file_name, error); - DBUG_RETURN(TRUE); - } + int error= my_errno; + if (index_file_nr >= 0) + my_close(index_file_nr,MYF(0)); - // Rewrite Master_info.index - for (uint i= 0; i< master_info_hash.records; ++i) - { - Master_info *tmp_mi; - tmp_mi= (Master_info *) my_hash_element(&master_info_hash, i); - write_master_name_to_index_file(&tmp_mi->connection_name, 0); - } - my_sync(index_file_nr, MYF(MY_WME)); + sql_print_error("Create of Master Info Index file '%s' failed with " + "error: %M", + index_file_name, error); + DBUG_RETURN(TRUE); + } + + // Rewrite Master_info.index + for (uint i= 0; i< master_info_hash.records; ++i) + { + Master_info *tmp_mi; + tmp_mi= (Master_info *) my_hash_element(&master_info_hash, i); + write_master_name_to_index_file(&tmp_mi->connection_name, 0); } + if (my_sync(index_file_nr, MYF(MY_WME))) + DBUG_RETURN(TRUE); } DBUG_RETURN(FALSE); } /** - Master_info_index::give_error_if_slave_running() + give_error_if_slave_running() + + @param + already_locked 0 if we need to lock, 1 if we have LOCK_active_mi_locked @return TRUE If some slave is running. An error is printed FALSE No slave is running */ -bool Master_info_index::give_error_if_slave_running() +bool give_error_if_slave_running(bool already_locked) { + bool ret= 0; DBUG_ENTER("give_error_if_slave_running"); - mysql_mutex_assert_owner(&LOCK_active_mi); - for (uint i= 0; i< master_info_hash.records; ++i) + if (!already_locked) + mysql_mutex_lock(&LOCK_active_mi); + if (!master_info_index) { - Master_info *mi; - mi= (Master_info *) my_hash_element(&master_info_hash, i); - if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN) + my_error(ER_SERVER_SHUTDOWN, MYF(0)); + ret= 1; + } + else + { + HASH *hash= &master_info_index->master_info_hash; + for (uint i= 0; i< hash->records; ++i) { - my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length, - mi->connection_name.str); - DBUG_RETURN(TRUE); + Master_info *mi; + mi= (Master_info *) my_hash_element(hash, i); + if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN) + { + my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length, + mi->connection_name.str); + ret= 1; + break; + } } } - DBUG_RETURN(FALSE); + if (!already_locked) + mysql_mutex_unlock(&LOCK_active_mi); + DBUG_RETURN(ret); } /** - Master_info_index::any_slave_sql_running() - - The LOCK_active_mi must be held while calling this function. + any_slave_sql_running() @return 0 No Slave SQL thread is running # Number of slave SQL thread running + + Note that during shutdown we return 1. This is needed to ensure we + don't try to resize thread pool during shutdown as during shutdown + master_info_hash may be freeing the hash and during that time + hash entries can't be accessed. */ -uint Master_info_index::any_slave_sql_running() +uint any_slave_sql_running() { uint count= 0; + HASH *hash; DBUG_ENTER("any_slave_sql_running"); - mysql_mutex_assert_owner(&LOCK_active_mi); - for (uint i= 0; i< master_info_hash.records; ++i) + mysql_mutex_lock(&LOCK_active_mi); + if (unlikely(shutdown_in_progress || !master_info_index)) { - Master_info *mi= (Master_info *)my_hash_element(&master_info_hash, i); + mysql_mutex_unlock(&LOCK_active_mi); + DBUG_RETURN(1); + } + hash= &master_info_index->master_info_hash; + for (uint i= 0; i< hash->records; ++i) + { + Master_info *mi= (Master_info *)my_hash_element(hash, i); if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN) count++; } + mysql_mutex_unlock(&LOCK_active_mi); DBUG_RETURN(count); } @@ -1436,15 +1600,25 @@ uint Master_info_index::any_slave_sql_running() @return TRUE Error FALSE Everything ok. + + This code is written so that we don't keep LOCK_active_mi active + while we are starting a slave. */ bool Master_info_index::start_all_slaves(THD *thd) { bool result= FALSE; - DBUG_ENTER("warn_if_slave_running"); + DBUG_ENTER("start_all_slaves"); mysql_mutex_assert_owner(&LOCK_active_mi); - for (uint i= 0; i< master_info_hash.records; ++i) + for (uint i= 0; i< master_info_hash.records; i++) + { + Master_info *mi; + mi= (Master_info *) my_hash_element(&master_info_hash, i); + mi->in_start_all_slaves= 0; + } + + for (uint i= 0; i< master_info_hash.records; ) { int error; Master_info *mi; @@ -1454,25 +1628,40 @@ bool Master_info_index::start_all_slaves(THD *thd) Try to start all slaves that are configured (host is defined) and are not already running */ - if ((mi->slave_running == MYSQL_SLAVE_NOT_RUN || - !mi->rli.slave_running) && *mi->host) + if (!((mi->slave_running == MYSQL_SLAVE_NOT_RUN || + !mi->rli.slave_running) && *mi->host) || + mi->in_start_all_slaves) { - if ((error= start_slave(thd, mi, 1))) - { - my_error(ER_CANT_START_STOP_SLAVE, MYF(0), - "START", - (int) mi->connection_name.length, - mi->connection_name.str); - result= 1; - if (error < 0) // fatal error - break; - } - else if (thd) - push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_SLAVE_STARTED, ER_THD(thd, ER_SLAVE_STARTED), - (int) mi->connection_name.length, - mi->connection_name.str); + i++; + continue; + } + mi->in_start_all_slaves= 1; + + mysql_mutex_lock(&mi->sleep_lock); + mi->users++; // Mark used + mysql_mutex_unlock(&mi->sleep_lock); + mysql_mutex_unlock(&LOCK_active_mi); + error= start_slave(thd, mi, 1); + mi->release(); + mysql_mutex_lock(&LOCK_active_mi); + if (error) + { + my_error(ER_CANT_START_STOP_SLAVE, MYF(0), + "START", + (int) mi->connection_name.length, + mi->connection_name.str); + result= 1; + if (error < 0) // fatal error + break; } + else if (thd) + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_SLAVE_STARTED, ER_THD(thd, ER_SLAVE_STARTED), + (int) mi->connection_name.length, + mi->connection_name.str); + /* Restart from first element as master_info_hash may have changed */ + i= 0; + continue; } DBUG_RETURN(result); } @@ -1488,39 +1677,64 @@ bool Master_info_index::start_all_slaves(THD *thd) @return TRUE Error FALSE Everything ok. + + This code is written so that we don't keep LOCK_active_mi active + while we are stopping a slave. */ bool Master_info_index::stop_all_slaves(THD *thd) { bool result= FALSE; - DBUG_ENTER("warn_if_slave_running"); + DBUG_ENTER("stop_all_slaves"); mysql_mutex_assert_owner(&LOCK_active_mi); DBUG_ASSERT(thd); - for (uint i= 0; i< master_info_hash.records; ++i) + for (uint i= 0; i< master_info_hash.records; i++) + { + Master_info *mi; + mi= (Master_info *) my_hash_element(&master_info_hash, i); + mi->in_stop_all_slaves= 0; + } + + for (uint i= 0; i< master_info_hash.records ;) { int error; Master_info *mi; mi= (Master_info *) my_hash_element(&master_info_hash, i); - if ((mi->slave_running != MYSQL_SLAVE_NOT_RUN || - mi->rli.slave_running)) + if (!(mi->slave_running != MYSQL_SLAVE_NOT_RUN || + mi->rli.slave_running) || + mi->in_stop_all_slaves) { - if ((error= stop_slave(thd, mi, 1))) - { - my_error(ER_CANT_START_STOP_SLAVE, MYF(0), - "STOP", - (int) mi->connection_name.length, - mi->connection_name.str); - result= 1; - if (error < 0) // Fatal error - break; - } - else - push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_SLAVE_STOPPED, ER_THD(thd, ER_SLAVE_STOPPED), - (int) mi->connection_name.length, - mi->connection_name.str); + i++; + continue; } + mi->in_stop_all_slaves= 1; // Protection for loops + + mysql_mutex_lock(&mi->sleep_lock); + mi->users++; // Mark used + mysql_mutex_unlock(&mi->sleep_lock); + mysql_mutex_unlock(&LOCK_active_mi); + error= stop_slave(thd, mi, 1); + mi->release(); + mysql_mutex_lock(&LOCK_active_mi); + if (error) + { + my_error(ER_CANT_START_STOP_SLAVE, MYF(0), + "STOP", + (int) mi->connection_name.length, + mi->connection_name.str); + result= 1; + if (error < 0) // Fatal error + break; + } + else + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_SLAVE_STOPPED, ER_THD(thd, ER_SLAVE_STOPPED), + (int) mi->connection_name.length, + mi->connection_name.str); + /* Restart from first element as master_info_hash may have changed */ + i= 0; + continue; } DBUG_RETURN(result); } diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 9365c065ea9..31c0f280ac1 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -187,6 +187,10 @@ class Master_info : public Slave_reporting_capability return opt_slave_parallel_threads > 0 && parallel_mode > SLAVE_PARALLEL_NONE; } + void release(); + void wait_until_free(); + void lock_slave_threads(); + void unlock_slave_threads(); /* the variables below are needed because we can change masters on the fly */ char master_log_name[FN_REFLEN+6]; /* Room for multi-*/ @@ -205,7 +209,7 @@ class Master_info : public Slave_reporting_capability File fd; // we keep the file open, so we need to remember the file pointer IO_CACHE file; - mysql_mutex_t data_lock, run_lock, sleep_lock; + mysql_mutex_t data_lock, run_lock, sleep_lock, start_stop_lock; mysql_cond_t data_cond, start_cond, stop_cond, sleep_cond; THD *io_thd; MYSQL* mysql; @@ -297,6 +301,9 @@ class Master_info : public Slave_reporting_capability uint64 gtid_reconnect_event_skip_count; /* gtid_event_seen is false until we receive first GTID event from master. */ bool gtid_event_seen; + bool in_start_all_slaves, in_stop_all_slaves; + uint users; /* Active user for object */ + uint killed; /* domain-id based filter */ Domain_id_filter domain_id_filter; @@ -341,13 +348,12 @@ public: bool check_duplicate_master_info(LEX_STRING *connection_name, const char *host, uint port); bool add_master_info(Master_info *mi, bool write_to_file); - bool remove_master_info(LEX_STRING *connection_name); + bool remove_master_info(Master_info *mi); Master_info *get_master_info(const LEX_STRING *connection_name, Sql_condition::enum_warning_level warning); - bool give_error_if_slave_running(); - uint any_slave_sql_running(); bool start_all_slaves(THD *thd); bool stop_all_slaves(THD *thd); + void free_connections(); }; @@ -360,6 +366,8 @@ public: }; +Master_info *get_master_info(const LEX_STRING *connection_name, + Sql_condition::enum_warning_level warning); bool check_master_connection_name(LEX_STRING *name); void create_logfile_name_with_suffix(char *res_file_name, size_t length, const char *info_file, @@ -369,5 +377,8 @@ void create_logfile_name_with_suffix(char *res_file_name, size_t length, uchar *get_key_master_info(Master_info *mi, size_t *length, my_bool not_used __attribute__((unused))); void free_key_master_info(Master_info *mi); +uint any_slave_sql_running(); +bool give_error_if_slave_running(bool already_lock); + #endif /* HAVE_REPLICATION */ #endif /* RPL_MI_H */ diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index f7aab704c43..6788f422cbd 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -1320,39 +1320,16 @@ handle_rpl_parallel_thread(void *arg) */ rpt->batch_free(); - for (;;) + if ((events= rpt->event_queue) != NULL) { - if ((events= rpt->event_queue) != NULL) - { - /* - Take next group of events from the replication pool. - This is faster than having to wakeup the pool manager thread to give - us a new event. - */ - rpt->dequeue1(events); - mysql_mutex_unlock(&rpt->LOCK_rpl_thread); - goto more_events; - } - if (!rpt->pause_for_ftwrl || - (in_event_group && !group_rgi->parallel_entry->force_abort)) - break; /* - We are currently in the delicate process of pausing parallel - replication while FLUSH TABLES WITH READ LOCK is starting. We must - not de-allocate the thread (setting rpt->current_owner= NULL) until - rpl_unpause_after_ftwrl() has woken us up. + Take next group of events from the replication pool. + This is faster than having to wakeup the pool manager thread to give + us a new event. */ - mysql_mutex_lock(&rpt->current_entry->LOCK_parallel_entry); + rpt->dequeue1(events); mysql_mutex_unlock(&rpt->LOCK_rpl_thread); - if (rpt->pause_for_ftwrl) - mysql_cond_wait(&rpt->current_entry->COND_parallel_entry, - &rpt->current_entry->LOCK_parallel_entry); - mysql_mutex_unlock(&rpt->current_entry->LOCK_parallel_entry); - mysql_mutex_lock(&rpt->LOCK_rpl_thread); - /* - Now loop to check again for more events available, since we released - and re-aquired the LOCK_rpl_thread mutex. - */ + goto more_events; } rpt->inuse_relaylog_refcount_update(); @@ -1379,11 +1356,35 @@ handle_rpl_parallel_thread(void *arg) } if (!in_event_group) { + /* If we are in a FLUSH TABLES FOR READ LOCK, wait for it */ + while (rpt->current_entry && rpt->pause_for_ftwrl) + { + /* + We are currently in the delicate process of pausing parallel + replication while FLUSH TABLES WITH READ LOCK is starting. We must + not de-allocate the thread (setting rpt->current_owner= NULL) until + rpl_unpause_after_ftwrl() has woken us up. + */ + rpl_parallel_entry *e= rpt->current_entry; + /* + Wait for rpl_unpause_after_ftwrl() to wake us up. + Note that rpl_pause_for_ftwrl() may wait for 'e->pause_sub_id' + to change. This should happen eventually in finish_event_group() + */ + mysql_mutex_lock(&e->LOCK_parallel_entry); + mysql_mutex_unlock(&rpt->LOCK_rpl_thread); + if (rpt->pause_for_ftwrl) + mysql_cond_wait(&e->COND_parallel_entry, &e->LOCK_parallel_entry); + mysql_mutex_unlock(&e->LOCK_parallel_entry); + mysql_mutex_lock(&rpt->LOCK_rpl_thread); + } + rpt->current_owner= NULL; /* Tell wait_for_done() that we are done, if it is waiting. */ if (likely(rpt->current_entry) && unlikely(rpt->current_entry->force_abort)) mysql_cond_broadcast(&rpt->COND_rpl_thread_stop); + rpt->current_entry= NULL; if (!rpt->stop) rpt->pool->release_thread(rpt); @@ -1422,10 +1423,24 @@ dealloc_gco(group_commit_orderer *gco) my_free(gco); } +/** + Change thread count for global parallel worker threads + + @param pool parallel thread pool + @param new_count Number of threads to be in pool. 0 in shutdown + @param force Force thread count to new_count even if slave + threads are running + + By default we don't resize pool of there are running threads. + However during shutdown we will always do it. + This is needed as any_slave_sql_running() returns 1 during shutdown + as we don't want to access master_info while + Master_info_index::free_connections are running. +*/ static int rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool, - uint32 new_count) + uint32 new_count, bool force) { uint32 i; rpl_parallel_thread **old_list= NULL; @@ -1437,6 +1452,28 @@ rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool, if ((res= pool_mark_busy(pool, current_thd))) return res; + /* Protect against parallel pool resizes */ + if (pool->count == new_count) + { + pool_mark_not_busy(pool); + return 0; + } + + /* + If we are about to delete pool, do an extra check that there are no new + slave threads running since we marked pool busy + */ + if (!new_count && !force) + { + if (any_slave_sql_running()) + { + DBUG_PRINT("warning", + ("SQL threads running while trying to reset parallel pool")); + pool_mark_not_busy(pool); + return 0; // Ok to not resize pool + } + } + /* Allocate the new list of threads up-front. That way, if we fail half-way, we only need to free whatever we managed @@ -1450,7 +1487,7 @@ rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool, { my_error(ER_OUTOFMEMORY, MYF(0), (int(new_count*sizeof(*new_list) + new_count*sizeof(*rpt_array)))); - goto err;; + goto err; } for (i= 0; i < new_count; ++i) @@ -1575,12 +1612,26 @@ err: return 1; } +/* + Deactivate the parallel replication thread pool, if there are now no more + SQL threads running. +*/ + +int rpl_parallel_resize_pool_if_no_slaves(void) +{ + /* master_info_index is set to NULL on shutdown */ + if (opt_slave_parallel_threads > 0 && !any_slave_sql_running()) + return rpl_parallel_inactivate_pool(&global_rpl_thread_pool); + return 0; +} + int rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool) { if (!pool->count) - return rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads); + return rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads, + 0); return 0; } @@ -1588,7 +1639,7 @@ rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool) int rpl_parallel_inactivate_pool(rpl_parallel_thread_pool *pool) { - return rpl_parallel_change_thread_count(pool, 0); + return rpl_parallel_change_thread_count(pool, 0, 0); } @@ -1866,7 +1917,7 @@ rpl_parallel_thread_pool::destroy() { if (!inited) return; - rpl_parallel_change_thread_count(this, 0); + rpl_parallel_change_thread_count(this, 0, 1); mysql_mutex_destroy(&LOCK_rpl_thread_pool); mysql_cond_destroy(&COND_rpl_thread_pool); inited= false; @@ -1885,6 +1936,7 @@ rpl_parallel_thread_pool::get_thread(rpl_parallel_thread **owner, { rpl_parallel_thread *rpt; + DBUG_ASSERT(count > 0); mysql_mutex_lock(&LOCK_rpl_thread_pool); while (unlikely(busy) || !(rpt= free_list)) mysql_cond_wait(&COND_rpl_thread_pool, &LOCK_rpl_thread_pool); @@ -2113,6 +2165,11 @@ rpl_parallel::find(uint32 domain_id) return e; } +/** + Wait until all sql worker threads has stopped processing + + This is called when sql thread has been killed/stopped +*/ void rpl_parallel::wait_for_done(THD *thd, Relay_log_info *rli) diff --git a/sql/rpl_parallel.h b/sql/rpl_parallel.h index c6f77b0144c..a0faeae815c 100644 --- a/sql/rpl_parallel.h +++ b/sql/rpl_parallel.h @@ -365,6 +365,7 @@ struct rpl_parallel { extern struct rpl_parallel_thread_pool global_rpl_thread_pool; +extern int rpl_parallel_resize_pool_if_no_slaves(void); extern int rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool); extern int rpl_parallel_inactivate_pool(rpl_parallel_thread_pool *pool); extern bool process_gtid_for_restart_pos(Relay_log_info *rli, rpl_gtid *gtid); diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index cd189b4ab2d..fda922c3e12 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -207,6 +207,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name); /* For multimaster, add connection name to relay log filenames */ char buf_relay_logname[FN_REFLEN], buf_relaylog_index_name_buff[FN_REFLEN]; char *buf_relaylog_index_name= opt_relaylog_index_name; + mysql_mutex_t *log_lock; create_logfile_name_with_suffix(buf_relay_logname, sizeof(buf_relay_logname), @@ -226,14 +227,18 @@ a file name for --relay-log-index option", opt_relaylog_index_name); note, that if open() fails, we'll still have index file open but a destructor will take care of that */ + log_lock= relay_log.get_log_lock(); + mysql_mutex_lock(log_lock); if (relay_log.open_index_file(buf_relaylog_index_name, ln, TRUE) || relay_log.open(ln, LOG_BIN, 0, 0, SEQ_READ_APPEND, max_relay_log_size, 1, TRUE)) { + mysql_mutex_unlock(log_lock); mysql_mutex_unlock(&data_lock); sql_print_error("Failed when trying to open logs for '%s' in Relay_log_info::init(). Error: %M", ln, my_errno); DBUG_RETURN(1); } + mysql_mutex_unlock(log_lock); } /* if file does not exist */ @@ -413,7 +418,7 @@ Failed to open the existing relay log info file '%s' (errno %d)", } inited= 1; mysql_mutex_unlock(&data_lock); - DBUG_RETURN(error); + DBUG_RETURN(0); err: sql_print_error("%s", msg); @@ -1312,9 +1317,10 @@ bool Relay_log_info::is_until_satisfied(my_off_t master_beg_pos) } -void Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd, +bool Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd, rpl_group_info *rgi) { + int error= 0; DBUG_ENTER("Relay_log_info::stmt_done"); DBUG_ASSERT(!belongs_to_client()); @@ -1367,10 +1373,11 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd, } DBUG_EXECUTE_IF("inject_crash_before_flush_rli", DBUG_SUICIDE();); if (mi->using_gtid == Master_info::USE_GTID_NO) - flush(); + if (flush()) + error= 1; DBUG_EXECUTE_IF("inject_crash_after_flush_rli", DBUG_SUICIDE();); } - DBUG_VOID_RETURN; + DBUG_RETURN(error); } diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 60a75859050..93e7b869be0 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -433,7 +433,7 @@ public: relay log info and used to produce information for <code>SHOW SLAVE STATUS</code>. */ - void stmt_done(my_off_t event_log_pos, THD *thd, rpl_group_info *rgi); + bool stmt_done(my_off_t event_log_pos, THD *thd, rpl_group_info *rgi); int alloc_inuse_relaylog(const char *name); void free_inuse_relaylog(inuse_relaylog *ir); void reset_inuse_relaylog(); diff --git a/sql/sha2.cc b/sql/sha2.cc deleted file mode 100644 index f2201974172..00000000000 --- a/sql/sha2.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - - 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 Foundation; version 2 of the License. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -/** - @file - A compatibility layer to our built-in SSL implementation, to mimic the - oft-used external library, OpenSSL. -*/ - -#include <my_global.h> -#include <sha2.h> - -#ifdef HAVE_YASSL - -/* - If TaoCrypt::SHA512 or ::SHA384 are not defined (but ::SHA256 is), it's - probably that neither of config.h's SIZEOF_LONG or SIZEOF_LONG_LONG are - 64 bits long. At present, both OpenSSL and YaSSL require 64-bit integers - for SHA-512. (The SIZEOF_* definitions come from autoconf's config.h .) -*/ - -# define GEN_YASSL_SHA2_BRIDGE(size) \ -unsigned char* SHA##size(const unsigned char *input_ptr, size_t input_length, \ - char unsigned *output_ptr) { \ - TaoCrypt::SHA##size hasher; \ - \ - hasher.Update(input_ptr, input_length); \ - hasher.Final(output_ptr); \ - return(output_ptr); \ -} - - -/** - @fn SHA512 - @fn SHA384 - @fn SHA256 - @fn SHA224 - - Instantiate an hash object, fill in the cleartext value, compute the digest, - and extract the result from the object. - - (Generate the functions. See similar .h code for the prototypes.) -*/ -# ifndef OPENSSL_NO_SHA512 -GEN_YASSL_SHA2_BRIDGE(512); -GEN_YASSL_SHA2_BRIDGE(384); -# else -# warning Some SHA2 functionality is missing. See OPENSSL_NO_SHA512. -# endif -GEN_YASSL_SHA2_BRIDGE(256); -GEN_YASSL_SHA2_BRIDGE(224); - -# undef GEN_YASSL_SHA2_BRIDGE - -#endif /* HAVE_YASSL */ diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 930cd2ceaa2..e1ed868c783 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -4839,7 +4839,7 @@ WARN_DATA_TRUNCATED 01000 spa "Datos truncados para columna '%s' en la línea %lu" ER_WARN_USING_OTHER_HANDLER eng "Using storage engine %s for table '%s'" - ger "Für Tabelle '%s' wird Speicher-Engine %s benutzt" + ger "Speicher-Engine %s wird für Tabelle '%s' benutzt" jpn "ストレージエンジン %s が表 '%s' に利用されています。" por "Usando engine de armazenamento %s para tabela '%s'" spa "Usando motor de almacenamiento %s para tabla '%s'" diff --git a/sql/slave.cc b/sql/slave.cc index e031a424ea6..fbdb78b5c5d 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -233,16 +233,14 @@ void init_thread_mask(int* mask,Master_info* mi,bool inverse) /* - lock_slave_threads() + lock_slave_threads() against other threads doing STOP, START or RESET SLAVE + */ -void lock_slave_threads(Master_info* mi) +void Master_info::lock_slave_threads() { DBUG_ENTER("lock_slave_threads"); - - //TODO: see if we can do this without dual mutex - mysql_mutex_lock(&mi->run_lock); - mysql_mutex_lock(&mi->rli.run_lock); + mysql_mutex_lock(&start_stop_lock); DBUG_VOID_RETURN; } @@ -251,13 +249,10 @@ void lock_slave_threads(Master_info* mi) unlock_slave_threads() */ -void unlock_slave_threads(Master_info* mi) +void Master_info::unlock_slave_threads() { DBUG_ENTER("unlock_slave_threads"); - - //TODO: see if we can do this without dual mutex - mysql_mutex_unlock(&mi->rli.run_lock); - mysql_mutex_unlock(&mi->run_lock); + mysql_mutex_unlock(&start_stop_lock); DBUG_VOID_RETURN; } @@ -470,7 +465,6 @@ int init_slave() accepted. However bootstrap may conflict with us if it does START SLAVE. So it's safer to take the lock. */ - mysql_mutex_lock(&LOCK_active_mi); if (pthread_key_create(&RPL_MASTER_INFO, NULL)) goto err; @@ -479,7 +473,6 @@ int init_slave() if (!master_info_index || master_info_index->init_all_master_info()) { sql_print_error("Failed to initialize multi master structures"); - mysql_mutex_unlock(&LOCK_active_mi); DBUG_RETURN(1); } if (!(active_mi= new Master_info(&default_master_connection_name, @@ -524,13 +517,22 @@ int init_slave() if (active_mi->host[0] && !opt_skip_slave_start) { - if (start_slave_threads(0, /* No active thd */ - 1 /* need mutex */, - 0 /* no wait for start*/, - active_mi, - master_info_file, - relay_log_info_file, - SLAVE_IO | SLAVE_SQL)) + int error; + THD *thd= new THD(next_thread_id()); + thd->thread_stack= (char*) &thd; + thd->store_globals(); + + error= start_slave_threads(0, /* No active thd */ + 1 /* need mutex */, + 1 /* wait for start*/, + active_mi, + master_info_file, + relay_log_info_file, + SLAVE_IO | SLAVE_SQL); + + thd->reset_globals(); + delete thd; + if (error) { sql_print_error("Failed to create slave threads"); goto err; @@ -538,7 +540,6 @@ int init_slave() } end: - mysql_mutex_unlock(&LOCK_active_mi); DBUG_RETURN(error); err: @@ -711,6 +712,7 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock) if (!mi->inited) DBUG_RETURN(0); /* successfully do nothing */ int error,force_all = (thread_mask & SLAVE_FORCE_ALL); + int retval= 0; mysql_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock; mysql_mutex_t *log_lock= mi->rli.relay_log.get_log_lock(); @@ -730,24 +732,18 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock) skip_lock)) && !force_all) DBUG_RETURN(error); + retval= error; mysql_mutex_lock(log_lock); DBUG_PRINT("info",("Flushing relay-log info file.")); if (current_thd) THD_STAGE_INFO(current_thd, stage_flushing_relay_log_info_file); - if (mi->rli.flush()) - DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); - - if (my_sync(mi->rli.info_fd, MYF(MY_WME))) - DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); + if (mi->rli.flush() || my_sync(mi->rli.info_fd, MYF(MY_WME))) + retval= ER_ERROR_DURING_FLUSH_LOGS; mysql_mutex_unlock(log_lock); } - if (opt_slave_parallel_threads > 0 && - master_info_index &&// master_info_index is set to NULL on server shutdown - !master_info_index->any_slave_sql_running()) - rpl_parallel_inactivate_pool(&global_rpl_thread_pool); if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) { DBUG_PRINT("info",("Terminating IO thread")); @@ -758,25 +754,26 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock) skip_lock)) && !force_all) DBUG_RETURN(error); + if (!retval) + retval= error; mysql_mutex_lock(log_lock); DBUG_PRINT("info",("Flushing relay log and master info file.")); if (current_thd) THD_STAGE_INFO(current_thd, stage_flushing_relay_log_and_master_info_repository); - if (flush_master_info(mi, TRUE, FALSE)) - DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); - + if (likely(mi->fd >= 0)) + { + if (flush_master_info(mi, TRUE, FALSE) || my_sync(mi->fd, MYF(MY_WME))) + retval= ER_ERROR_DURING_FLUSH_LOGS; + } if (mi->rli.relay_log.is_open() && my_sync(mi->rli.relay_log.get_log_file()->file, MYF(MY_WME))) - DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); - - if (my_sync(mi->fd, MYF(MY_WME))) - DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); + retval= ER_ERROR_DURING_FLUSH_LOGS; mysql_mutex_unlock(log_lock); } - DBUG_RETURN(0); + DBUG_RETURN(retval); } @@ -939,6 +936,15 @@ int start_slave_thread( mysql_mutex_unlock(start_lock); DBUG_RETURN(ER_SLAVE_THREAD); } + + /* + In the following loop we can't check for thd->killed as we have to + wait until THD structures for the slave thread are created + before we can return. + This should be ok as there is no major work done in the slave + threads before they signal that we can stop waiting. + */ + if (start_cond && cond_lock) // caller has cond_lock { THD* thd = current_thd; @@ -956,16 +962,9 @@ int start_slave_thread( registered, we could otherwise go waiting though thd->killed is set. */ - if (!thd->killed) - mysql_cond_wait(start_cond, cond_lock); + mysql_cond_wait(start_cond, cond_lock); thd->EXIT_COND(& saved_stage); mysql_mutex_lock(cond_lock); // re-acquire it as exit_cond() released - if (thd->killed) - { - if (start_lock) - mysql_mutex_unlock(start_lock); - DBUG_RETURN(thd->killed_errno()); - } } } if (start_lock) @@ -1054,10 +1053,7 @@ int start_slave_threads(THD *thd, mi); if (!error && (thread_mask & SLAVE_SQL)) { - if (opt_slave_parallel_threads > 0) - error= rpl_parallel_activate_pool(&global_rpl_thread_pool); - if (!error) - error= start_slave_thread( + error= start_slave_thread( #ifdef HAVE_PSI_INTERFACE key_thread_slave_sql, #endif @@ -1073,10 +1069,19 @@ int start_slave_threads(THD *thd, /* - Release slave threads at time of executing shutdown. + Kill slaves preparing for shutdown +*/ - SYNOPSIS - end_slave() +void slave_prepare_for_shutdown() +{ + mysql_mutex_lock(&LOCK_active_mi); + master_info_index->free_connections(); + mysql_mutex_unlock(&LOCK_active_mi); + stop_slave_background_thread(); +} + +/* + Release slave threads at time of executing shutdown. */ void end_slave() @@ -1094,7 +1099,10 @@ void end_slave() startup parameter to the server was wrong. */ mysql_mutex_lock(&LOCK_active_mi); - /* This will call terminate_slave_threads() on all connections */ + /* + master_info_index should not have any threads anymore as they where + killed as part of slave_prepare_for_shutdown() + */ delete master_info_index; master_info_index= 0; active_mi= 0; @@ -2878,7 +2886,9 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, mysql_mutex_lock(&mi->data_lock); mysql_mutex_lock(&mi->rli.data_lock); + /* err_lock is to protect mi->last_error() */ mysql_mutex_lock(&mi->err_lock); + /* err_lock is to protect mi->rli.last_error() */ mysql_mutex_lock(&mi->rli.err_lock); protocol->store(mi->host, &my_charset_bin); protocol->store(mi->user, &my_charset_bin); @@ -4884,6 +4894,16 @@ pthread_handler_t handle_slave_sql(void *arg) rli->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT; pthread_detach_this_thread(); + + if (opt_slave_parallel_threads > 0 && + rpl_parallel_activate_pool(&global_rpl_thread_pool)) + { + mysql_cond_broadcast(&rli->start_cond); + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, + "Failed during parallel slave pool activation"); + goto err_during_init; + } + if (init_slave_thread(thd, mi, SLAVE_THD_SQL)) { /* @@ -5184,8 +5204,15 @@ pthread_handler_t handle_slave_sql(void *arg) if (rli->mi->using_gtid != Master_info::USE_GTID_NO) { ulong domain_count; + my_bool save_log_all_errors= thd->log_all_errors; + /* + We don't need to check return value for rli->flush() + as any errors should be logged to stderr + */ + thd->log_all_errors= 1; rli->flush(); + thd->log_all_errors= save_log_all_errors; if (mi->using_parallel()) { /* @@ -5296,17 +5323,7 @@ err_during_init: DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5);); mysql_mutex_unlock(&rli->run_lock); // tell the world we are done - /* - Deactivate the parallel replication thread pool, if there are now no more - SQL threads running. Do this here, when we have released all locks, but - while our THD (and current_thd) is still valid. - */ - mysql_mutex_lock(&LOCK_active_mi); - if (opt_slave_parallel_threads > 0 && - master_info_index &&// master_info_index is set to NULL on server shutdown - !master_info_index->any_slave_sql_running()) - rpl_parallel_inactivate_pool(&global_rpl_thread_pool); - mysql_mutex_unlock(&LOCK_active_mi); + rpl_parallel_resize_pool_if_no_slaves(); /* TODO: Check if this lock is needed */ mysql_mutex_lock(&LOCK_thread_count); @@ -6519,6 +6536,7 @@ err: void end_relay_log_info(Relay_log_info* rli) { + mysql_mutex_t *log_lock; DBUG_ENTER("end_relay_log_info"); if (!rli->inited) @@ -6536,8 +6554,11 @@ void end_relay_log_info(Relay_log_info* rli) rli->cur_log_fd = -1; } rli->inited = 0; + log_lock= rli->relay_log.get_log_lock(); + mysql_mutex_lock(log_lock); rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); rli->relay_log.harvest_bytes_written(&rli->log_space_total); + mysql_mutex_unlock(log_lock); /* Delete the slave's temporary tables from memory. In the future there will be other actions than this, to ensure persistance @@ -6688,7 +6709,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, suppress_warnings= 0; mi->report(ERROR_LEVEL, last_errno, NULL, "error %s to master '%s@%s:%d'" - " - retry-time: %d retries: %lu message: %s", + " - retry-time: %d maximum-retries: %lu message: %s", (reconnect ? "reconnecting" : "connecting"), mi->user, mi->host, mi->port, mi->connect_retry, master_retry_count, @@ -7181,9 +7202,12 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size) } rli->event_relay_log_pos = BIN_LOG_HEADER_SIZE; strmake_buf(rli->event_relay_log_name,rli->linfo.log_file_name); - rli->flush(); + if (rli->flush()) + { + errmsg= "error flushing relay log"; + goto err; + } } - /* Now we want to open this next log. To know if it's a hot log (the one being written by the I/O thread now) or a cold log, we can use diff --git a/sql/slave.h b/sql/slave.h index 38f3b7c8430..ded9d76e49d 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -230,13 +230,12 @@ bool rpl_master_erroneous_autoinc(THD* thd); const char *print_slave_db_safe(const char *db); void skip_load_data_infile(NET* net); +void slave_prepare_for_shutdown(); void end_slave(); /* release slave threads */ void close_active_mi(); /* clean up slave threads data */ void clear_until_condition(Relay_log_info* rli); void clear_slave_error(Relay_log_info* rli); void end_relay_log_info(Relay_log_info* rli); -void lock_slave_threads(Master_info* mi); -void unlock_slave_threads(Master_info* mi); void init_thread_mask(int* mask,Master_info* mi,bool inverse); Format_description_log_event * read_relay_log_description_event(IO_CACHE *cur_log, ulonglong start_pos, diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d18a5b4d503..5e3311d502a 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -9754,13 +9754,13 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, case USER_ACL: acl_user->user.str= strdup_root(&acl_memroot, user_to->user.str); acl_user->user.length= user_to->user.length; - acl_user->host.hostname= strdup_root(&acl_memroot, user_to->host.str); - acl_user->hostname_length= user_to->host.length; + update_hostname(&acl_user->host, strdup_root(&acl_memroot, user_to->host.str)); + acl_user->hostname_length= strlen(acl_user->host.hostname); break; case DB_ACL: acl_db->user= strdup_root(&acl_memroot, user_to->user.str); - acl_db->host.hostname= strdup_root(&acl_memroot, user_to->host.str); + update_hostname(&acl_db->host, strdup_root(&acl_memroot, user_to->host.str)); break; case COLUMN_PRIVILEGES_HASH: @@ -11927,7 +11927,6 @@ get_cached_table_access(GRANT_INTERNAL_INFO *grant_internal_info, struct MPVIO_EXT :public MYSQL_PLUGIN_VIO { MYSQL_SERVER_AUTH_INFO auth_info; - THD *thd; ACL_USER *acl_user; ///< a copy, independent from acl_users array plugin_ref plugin; ///< what plugin we're under LEX_STRING db; ///< db name from the handshake packet @@ -12007,7 +12006,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE); DBUG_ASSERT(data_len <= 255); - THD *thd= mpvio->thd; + THD *thd= mpvio->auth_info.thd; char *buff= (char *) my_alloca(1 + SERVER_VERSION_LENGTH + 1 + data_len + 64); char scramble_buf[SCRAMBLE_LENGTH]; char *end= buff; @@ -12057,14 +12056,14 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, native_password_plugin will have to send it in a separate packet, adding one more round trip. */ - create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); + thd_create_random_password(thd, thd->scramble, SCRAMBLE_LENGTH); data= thd->scramble; } data_len= SCRAMBLE_LENGTH; } end= strxnmov(end, SERVER_VERSION_LENGTH, RPL_VERSION_HACK, server_version, NullS) + 1; - int4store((uchar*) end, mpvio->thd->thread_id); + int4store((uchar*) end, mpvio->auth_info.thd->thread_id); end+= 4; /* @@ -12079,7 +12078,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, int2store(end, thd->client_capabilities); /* write server characteristics: up to 16 bytes allowed */ end[2]= (char) default_charset_info->number; - int2store(end+3, mpvio->thd->server_status); + int2store(end+3, mpvio->auth_info.thd->server_status); int2store(end+5, thd->client_capabilities >> 16); end[7]= data_len; DBUG_EXECUTE_IF("poison_srv_handshake_scramble_len", end[7]= -100;); @@ -12093,9 +12092,9 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, end= strmake(end, plugin_name(mpvio->plugin)->str, plugin_name(mpvio->plugin)->length); - int res= my_net_write(&mpvio->thd->net, (uchar*) buff, + int res= my_net_write(&mpvio->auth_info.thd->net, (uchar*) buff, (size_t) (end - buff + 1)) || - net_flush(&mpvio->thd->net); + net_flush(&mpvio->auth_info.thd->net); my_afree(buff); DBUG_RETURN (res); } @@ -12154,7 +12153,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, { DBUG_ASSERT(mpvio->packets_written == 1); DBUG_ASSERT(mpvio->packets_read == 1); - NET *net= &mpvio->thd->net; + NET *net= &mpvio->auth_info.thd->net; static uchar switch_plugin_request_buf[]= { 254 }; DBUG_ENTER("send_plugin_request_packet"); @@ -12179,7 +12178,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, client_auth_plugin == old_password_plugin_name.str; if (switch_from_long_to_short_scramble) - DBUG_RETURN (secure_auth(mpvio->thd) || + DBUG_RETURN (secure_auth(mpvio->auth_info.thd) || my_net_write(net, switch_plugin_request_buf, 1) || net_flush(net)); @@ -12195,8 +12194,8 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, if (switch_from_short_to_long_scramble) { my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); - general_log_print(mpvio->thd, COM_CONNECT, - ER_THD(mpvio->thd, ER_NOT_SUPPORTED_AUTH_MODE)); + general_log_print(mpvio->auth_info.thd, COM_CONNECT, + ER_THD(mpvio->auth_info.thd, ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN (1); } @@ -12220,7 +12219,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, */ static bool find_mpvio_user(MPVIO_EXT *mpvio) { - Security_context *sctx= mpvio->thd->security_ctx; + Security_context *sctx= mpvio->auth_info.thd->security_ctx; DBUG_ENTER("find_mpvio_user"); DBUG_ASSERT(mpvio->acl_user == 0); @@ -12228,7 +12227,7 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio) ACL_USER *user= find_user_or_anon(sctx->host, sctx->user, sctx->ip); if (user) - mpvio->acl_user= user->copy(mpvio->thd->mem_root); + mpvio->acl_user= user->copy(mpvio->auth_info.thd->mem_root); mysql_mutex_unlock(&acl_cache->lock); @@ -12252,12 +12251,12 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio) if (!acl_users.elements) { mysql_mutex_unlock(&acl_cache->lock); - login_failed_error(mpvio->thd); + login_failed_error(mpvio->auth_info.thd); DBUG_RETURN(1); } uint i= nr1 % acl_users.elements; ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*); - mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root); + mpvio->acl_user= acl_user_tmp->copy(mpvio->auth_info.thd->mem_root); mysql_mutex_unlock(&acl_cache->lock); mpvio->make_it_fail= true; @@ -12266,15 +12265,15 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio) /* user account requires non-default plugin and the client is too old */ if (mpvio->acl_user->plugin.str != native_password_plugin_name.str && mpvio->acl_user->plugin.str != old_password_plugin_name.str && - !(mpvio->thd->client_capabilities & CLIENT_PLUGIN_AUTH)) + !(mpvio->auth_info.thd->client_capabilities & CLIENT_PLUGIN_AUTH)) { DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, native_password_plugin_name.str)); DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, old_password_plugin_name.str)); my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); - general_log_print(mpvio->thd, COM_CONNECT, - ER_THD(mpvio->thd, ER_NOT_SUPPORTED_AUTH_MODE)); + general_log_print(mpvio->auth_info.thd, COM_CONNECT, + ER_THD(mpvio->auth_info.thd, ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN (1); } @@ -12331,7 +12330,7 @@ read_client_connect_attrs(char **ptr, char *end, CHARSET_INFO *from_cs) /* the packet format is described in send_change_user_packet() */ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) { - THD *thd= mpvio->thd; + THD *thd= mpvio->auth_info.thd; NET *net= &thd->net; Security_context *sctx= thd->security_ctx; @@ -12485,7 +12484,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, uchar **buff, ulong pkt_len) { #ifndef EMBEDDED_LIBRARY - THD *thd= mpvio->thd; + THD *thd= mpvio->auth_info.thd; NET *net= &thd->net; char *end; DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE); @@ -12695,7 +12694,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, if ((thd->client_capabilities & CLIENT_CONNECT_ATTRS) && read_client_connect_attrs(&next_field, ((char *)net->read_pos) + pkt_len, - mpvio->thd->charset())) + mpvio->auth_info.thd->charset())) return packet_error; /* @@ -12780,13 +12779,13 @@ static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param, We'll escape these bytes with \1. Consequently, we have to escape \1 byte too. */ - res= net_write_command(&mpvio->thd->net, 1, (uchar*)"", 0, + res= net_write_command(&mpvio->auth_info.thd->net, 1, (uchar*)"", 0, packet, packet_len); } else { - res= my_net_write(&mpvio->thd->net, packet, packet_len) || - net_flush(&mpvio->thd->net); + res= my_net_write(&mpvio->auth_info.thd->net, packet, packet_len) || + net_flush(&mpvio->auth_info.thd->net); } mpvio->packets_written++; DBUG_RETURN(res); @@ -12816,7 +12815,7 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) if (server_mpvio_write_packet(mpvio, 0, 0)) pkt_len= packet_error; else - pkt_len= my_net_read(&mpvio->thd->net); + pkt_len= my_net_read(&mpvio->auth_info.thd->net); } else if (mpvio->cached_client_reply.pkt) { @@ -12850,10 +12849,10 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) if (server_mpvio_write_packet(mpvio, 0, 0)) pkt_len= packet_error; else - pkt_len= my_net_read(&mpvio->thd->net); + pkt_len= my_net_read(&mpvio->auth_info.thd->net); } else - pkt_len= my_net_read(&mpvio->thd->net); + pkt_len= my_net_read(&mpvio->auth_info.thd->net); if (pkt_len == packet_error) goto err; @@ -12871,14 +12870,14 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) goto err; } else - *buf= mpvio->thd->net.read_pos; + *buf= mpvio->auth_info.thd->net.read_pos; DBUG_RETURN((int)pkt_len); err: if (mpvio->status == MPVIO_EXT::FAILURE) { - if (!mpvio->thd->is_error()) + if (!mpvio->auth_info.thd->is_error()) my_error(ER_HANDSHAKE_ERROR, MYF(0)); } DBUG_RETURN(-1); @@ -12892,7 +12891,7 @@ static void server_mpvio_info(MYSQL_PLUGIN_VIO *vio, MYSQL_PLUGIN_VIO_INFO *info) { MPVIO_EXT *mpvio= (MPVIO_EXT *) vio; - mpvio_info(mpvio->thd->net.vio, info); + mpvio_info(mpvio->auth_info.thd->net.vio, info); } static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) @@ -13027,11 +13026,11 @@ static int do_auth_once(THD *thd, const LEX_STRING *auth_plugin_name, if (plugin) { st_mysql_auth *auth= (st_mysql_auth *) plugin_decl(plugin)->info; - switch (auth->interface_version) { - case 0x0200: + switch (auth->interface_version >> 8) { + case 0x02: res= auth->authenticate_user(mpvio, &mpvio->auth_info); break; - case 0x0100: + case 0x01: { MYSQL_SERVER_AUTH_INFO_0x0100 compat; compat.downgrade(&mpvio->auth_info); @@ -13050,7 +13049,7 @@ static int do_auth_once(THD *thd, const LEX_STRING *auth_plugin_name, /* Server cannot load the required plugin. */ Host_errors errors; errors.m_no_auth_plugin= 1; - inc_host_errors(mpvio->thd->security_ctx->ip, &errors); + inc_host_errors(mpvio->auth_info.thd->security_ctx->ip, &errors); my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name->str); res= CR_ERROR; } @@ -13095,9 +13094,9 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) mpvio.read_packet= server_mpvio_read_packet; mpvio.write_packet= server_mpvio_write_packet; mpvio.info= server_mpvio_info; - mpvio.thd= thd; mpvio.status= MPVIO_EXT::FAILURE; mpvio.make_it_fail= false; + mpvio.auth_info.thd= thd; mpvio.auth_info.host_or_ip= thd->security_ctx->host_or_ip; mpvio.auth_info.host_or_ip_length= (unsigned int) strlen(thd->security_ctx->host_or_ip); @@ -13196,7 +13195,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) errors.m_auth_plugin= 1; break; } - inc_host_errors(mpvio.thd->security_ctx->ip, &errors); + inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors); if (!thd->is_error()) login_failed_error(thd); DBUG_RETURN(1); @@ -13223,7 +13222,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) { Host_errors errors; errors.m_proxy_user= 1; - inc_host_errors(mpvio.thd->security_ctx->ip, &errors); + inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors); if (!thd->is_error()) login_failed_error(thd); DBUG_RETURN(1); @@ -13243,7 +13242,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) Host_errors errors; errors.m_proxy_user_acl= 1; - inc_host_errors(mpvio.thd->security_ctx->ip, &errors); + inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors); if (!thd->is_error()) login_failed_error(thd); DBUG_RETURN(1); @@ -13273,7 +13272,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) { Host_errors errors; errors.m_ssl= 1; - inc_host_errors(mpvio.thd->security_ctx->ip, &errors); + inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors); login_failed_error(thd); DBUG_RETURN(1); } @@ -13410,13 +13409,13 @@ static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio, uchar *pkt; int pkt_len; MPVIO_EXT *mpvio= (MPVIO_EXT *) vio; - THD *thd=mpvio->thd; + THD *thd=info->thd; DBUG_ENTER("native_password_authenticate"); /* generate the scramble, or reuse the old one */ if (thd->scramble[SCRAMBLE_LENGTH]) { - create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); + thd_create_random_password(thd, thd->scramble, SCRAMBLE_LENGTH); /* and send it to the client */ if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) DBUG_RETURN(CR_AUTH_HANDSHAKE); @@ -13495,12 +13494,12 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio, uchar *pkt; int pkt_len; MPVIO_EXT *mpvio= (MPVIO_EXT *) vio; - THD *thd=mpvio->thd; + THD *thd=info->thd; /* generate the scramble, or reuse the old one */ if (thd->scramble[SCRAMBLE_LENGTH]) { - create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand); + thd_create_random_password(thd, thd->scramble, SCRAMBLE_LENGTH); /* and send it to the client */ if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1)) return CR_AUTH_HANDSHAKE; diff --git a/sql/sql_alter.h b/sql/sql_alter.h index faba3a14a1b..5668a0f52be 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -70,59 +70,56 @@ public: // Set for DISABLE KEYS | ENABLE KEYS static const uint ALTER_KEYS_ONOFF = 1L << 9; - // Set for CONVERT TO CHARACTER SET - static const uint ALTER_CONVERT = 1L << 10; - // Set for FORCE // Set for ENGINE(same engine) // Set by mysql_recreate_table() - static const uint ALTER_RECREATE = 1L << 11; + static const uint ALTER_RECREATE = 1L << 10; // Set for ADD PARTITION - static const uint ALTER_ADD_PARTITION = 1L << 12; + static const uint ALTER_ADD_PARTITION = 1L << 11; // Set for DROP PARTITION - static const uint ALTER_DROP_PARTITION = 1L << 13; + static const uint ALTER_DROP_PARTITION = 1L << 12; // Set for COALESCE PARTITION - static const uint ALTER_COALESCE_PARTITION = 1L << 14; + static const uint ALTER_COALESCE_PARTITION = 1L << 13; // Set for REORGANIZE PARTITION ... INTO - static const uint ALTER_REORGANIZE_PARTITION = 1L << 15; + static const uint ALTER_REORGANIZE_PARTITION = 1L << 14; // Set for partition_options - static const uint ALTER_PARTITION = 1L << 16; + static const uint ALTER_PARTITION = 1L << 15; // Set for LOAD INDEX INTO CACHE ... PARTITION // Set for CACHE INDEX ... PARTITION - static const uint ALTER_ADMIN_PARTITION = 1L << 17; + static const uint ALTER_ADMIN_PARTITION = 1L << 16; // Set for REORGANIZE PARTITION - static const uint ALTER_TABLE_REORG = 1L << 18; + static const uint ALTER_TABLE_REORG = 1L << 17; // Set for REBUILD PARTITION - static const uint ALTER_REBUILD_PARTITION = 1L << 19; + static const uint ALTER_REBUILD_PARTITION = 1L << 18; // Set for partitioning operations specifying ALL keyword - static const uint ALTER_ALL_PARTITION = 1L << 20; + static const uint ALTER_ALL_PARTITION = 1L << 19; // Set for REMOVE PARTITIONING - static const uint ALTER_REMOVE_PARTITIONING = 1L << 21; + static const uint ALTER_REMOVE_PARTITIONING = 1L << 20; // Set for ADD FOREIGN KEY - static const uint ADD_FOREIGN_KEY = 1L << 22; + static const uint ADD_FOREIGN_KEY = 1L << 21; // Set for DROP FOREIGN KEY - static const uint DROP_FOREIGN_KEY = 1L << 23; + static const uint DROP_FOREIGN_KEY = 1L << 22; // Set for EXCHANGE PARITION - static const uint ALTER_EXCHANGE_PARTITION = 1L << 24; + static const uint ALTER_EXCHANGE_PARTITION = 1L << 23; // Set by Sql_cmd_alter_table_truncate_partition::execute() - static const uint ALTER_TRUNCATE_PARTITION = 1L << 25; + static const uint ALTER_TRUNCATE_PARTITION = 1L << 24; // Set for ADD [COLUMN] FIRST | AFTER - static const uint ALTER_COLUMN_ORDER = 1L << 26; + static const uint ALTER_COLUMN_ORDER = 1L << 25; static const uint ALTER_ADD_CHECK_CONSTRAINT = 1L << 27; static const uint ALTER_DROP_CHECK_CONSTRAINT = 1L << 28; diff --git a/sql/sql_analyze_stmt.cc b/sql/sql_analyze_stmt.cc index 58f72d6b8de..cc6e0f89f75 100644 --- a/sql/sql_analyze_stmt.cc +++ b/sql/sql_analyze_stmt.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation diff --git a/sql/sql_analyze_stmt.h b/sql/sql_analyze_stmt.h index 2a08a842dfc..27fd7fb6d6a 100644 --- a/sql/sql_analyze_stmt.h +++ b/sql/sql_analyze_stmt.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 65cfe99649e..93511bb9188 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5811,7 +5811,7 @@ find_field_in_tables(THD *thd, Item_ident *item, if (!table_ref->belong_to_view && !table_ref->belong_to_derived) { - SELECT_LEX *current_sel= thd->lex->current_select; + SELECT_LEX *current_sel= item->context->select_lex; SELECT_LEX *last_select= table_ref->select_lex; bool all_merged= TRUE; for (SELECT_LEX *sl= current_sel; sl && sl!=last_select; diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index d92ac15822f..5f554a3cd92 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -20,7 +20,6 @@ #include "sql_parse.h" #include "sql_acl.h" #include "rpl_rli.h" -#include "base64.h" #include "slave.h" #include "log_event.h" diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c3bd40cf230..f8ba23298e0 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4408,6 +4408,28 @@ extern "C" int thd_is_connected(MYSQL_THD thd) } +extern "C" double thd_rnd(MYSQL_THD thd) +{ + return my_rnd(&thd->rand); +} + + +/** + Generate string of printable random characters of requested length. + + @param to[out] Buffer for generation; must be at least length+1 bytes + long; result string is always null-terminated + @param length[in] How many random characters to put in buffer +*/ +extern "C" void thd_create_random_password(MYSQL_THD thd, + char *to, size_t length) +{ + for (char *end= to + length; to < end; to++) + *to= (char) (my_rnd(&thd->rand)*94 + 33); + *to= '\0'; +} + + #ifdef INNODB_COMPATIBILITY_HOOKS /** open a table and add it to thd->open_tables @@ -4481,7 +4503,10 @@ MYSQL_THD create_thd() void destroy_thd(MYSQL_THD thd) { - delete_running_thd(thd); + thd->add_status_to_global(); + unlink_not_visible_thd(thd); + delete thd; + dec_thread_running(); } void reset_thd(MYSQL_THD thd) @@ -4533,6 +4558,15 @@ extern "C" int thd_rpl_is_parallel(const MYSQL_THD thd) return thd->rgi_slave && thd->rgi_slave->is_parallel_exec; } + +/* Returns high resolution timestamp for the start + of the current query. */ +extern "C" unsigned long long thd_start_utime(const MYSQL_THD thd) +{ + return thd->start_utime; +} + + /* This function can optionally be called to check if thd_rpl_deadlock_check() needs to be called for waits done by a given transaction. @@ -6979,7 +7013,13 @@ wait_for_commit::reinit() So in this case, do a re-init of the mutex. In release builds, we want to avoid the overhead of a re-init though. + + To ensure that no one is locking the mutex, we take a lock of it first. + For full explanation, see wait_for_commit::~wait_for_commit() */ + mysql_mutex_lock(&LOCK_wait_commit); + mysql_mutex_unlock(&LOCK_wait_commit); + mysql_mutex_destroy(&LOCK_wait_commit); mysql_mutex_init(key_LOCK_wait_commit, &LOCK_wait_commit, MY_MUTEX_INIT_FAST); #endif diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 157e59c2446..5cb4cd87296 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -832,11 +832,7 @@ bool init_new_connection_handler_thread() statistic_increment(connection_errors_internal, &LOCK_status); return 1; } - DBUG_EXECUTE_IF("simulate_failed_connection_1", - { - DBUG_SET("-d,simulate_failed_connection_1"); - return(1); - }); + DBUG_EXECUTE_IF("simulate_failed_connection_1", return(1); ); return 0; } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 8b7d4ee5ed2..813a17cdfdb 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -846,7 +846,8 @@ mysql_rm_db_internal(THD *thd,char *db, bool if_exists, bool silent) if there exists a table with the name 'db', so let's just do it separately. We know this file exists and needs to be deleted anyway. */ - if (my_delete_with_symlink(path, MYF(0)) && my_errno != ENOENT) + if (mysql_file_delete_with_symlink(key_file_misc, path, "", MYF(0)) && + my_errno != ENOENT) { my_error(EE_DELETE, MYF(0), path, my_errno); DBUG_RETURN(true); @@ -1153,9 +1154,9 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, strxmov(filePath, path, "/", file->name, NullS); /* We ignore ENOENT error in order to skip files that was deleted - by concurrently running statement like REAPIR TABLE ... + by concurrently running statement like REPAIR TABLE ... */ - if (my_delete_with_symlink(filePath, MYF(0)) && + if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(0)) && my_errno != ENOENT) { my_error(EE_DELETE, MYF(0), filePath, my_errno); @@ -1271,7 +1272,7 @@ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path) continue; } strxmov(filePath, org_path, "/", file->name, NullS); - if (mysql_file_delete_with_symlink(key_file_misc, filePath, MYF(MY_WME))) + if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(MY_WME))) { goto err; } diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index faf6dd790a6..90b6dad313a 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -449,6 +449,9 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) { Item *expr= derived->on_expr; expr= and_conds(thd, expr, dt_select->join ? dt_select->join->conds : 0); + if (expr) + expr->top_level_item(); + if (expr && (derived->prep_on_expr || expr != derived->on_expr)) { derived->on_expr= expr; diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 131c5a3bcfa..6b5db7e923b 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 5793599f4e1..bfddf40ff33 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc index 3ed33d97094..c79783bf561 100644 --- a/sql/sql_expression_cache.cc +++ b/sql/sql_expression_cache.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <my_global.h> #include "sql_base.h" diff --git a/sql/sql_expression_cache.h b/sql/sql_expression_cache.h index 87be6ddb4f4..05ac51f81f2 100644 --- a/sql/sql_expression_cache.h +++ b/sql/sql_expression_cache.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #ifndef SQL_EXPRESSION_CACHE_INCLUDED #define SQL_EXPRESSION_CACHE_INCLUDED diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 27820c16543..8e5dfb4f69c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -330,7 +330,7 @@ static bool has_no_default_value(THD *thd, Field *field, TABLE_LIST *table_list) push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NO_DEFAULT_FOR_FIELD, ER_THD(thd, ER_NO_DEFAULT_FOR_FIELD), field->field_name); } - return true; + return thd->really_abort_on_warning(); } return false; } @@ -904,7 +904,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (fields.elements || !value_count || table_list->view != 0) { - if (check_that_all_fields_are_given_values(thd, table, table_list)) + if (table->triggers && + table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE)) + { + /* BEFORE INSERT triggers exist, the check will be done later, per row */ + } + else if (check_that_all_fields_are_given_values(thd, table, table_list)) { error= 1; goto values_loop_end; @@ -3870,8 +3875,8 @@ bool select_insert::prepare_eof() bool select_insert::send_ok_packet() { char message[160]; /* status message */ - ulong row_count; /* rows affected */ - ulong id; /* last insert-id */ + ulonglong row_count; /* rows affected */ + ulonglong id; /* last insert-id */ DBUG_ENTER("select_insert::send_ok_packet"); diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 8a293956da7..12c64caa225 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h index fa00e309623..4ae843ebfc2 100644 --- a/sql/sql_join_cache.h +++ b/sql/sql_join_cache.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* This file contains declarations for implementations diff --git a/sql/sql_lifo_buffer.h b/sql/sql_lifo_buffer.h index feec4aeb4c2..8fa13c66dd9 100644 --- a/sql/sql_lifo_buffer.h +++ b/sql/sql_lifo_buffer.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @defgroup Bi-directional LIFO buffers used by DS-MRR implementation diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b41f6ffd0f0..590d2dfe681 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2542,12 +2542,12 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, #endif case SCH_COLUMNS: case SCH_STATISTICS: - { #ifdef DONT_ALLOW_SHOW_COMMANDS my_message(ER_NOT_ALLOWED_COMMAND, ER_THD(thd, ER_NOT_ALLOWED_COMMAND), MYF(0)); DBUG_RETURN(1); #else + { DBUG_ASSERT(table_ident); TABLE_LIST **query_tables_last= lex->query_tables_last; schema_select_lex= new (thd->mem_root) SELECT_LEX(); @@ -2914,7 +2914,7 @@ static bool do_execute_sp(THD *thd, sp_head *sp) int mysql_execute_command(THD *thd) { - int res= FALSE; + int res= 0; int up_result= 0; LEX *lex= thd->lex; /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ @@ -3593,10 +3593,17 @@ mysql_execute_command(THD *thd) if (check_global_access(thd, SUPER_ACL)) goto error; + /* + In this code it's ok to use LOCK_active_mi as we are adding new things + into master_info_index + */ mysql_mutex_lock(&LOCK_active_mi); - if (!master_info_index) + { + mysql_mutex_unlock(&LOCK_active_mi); + my_error(ER_SERVER_SHUTDOWN, MYF(0)); goto error; + } mi= master_info_index->get_master_info(&lex_mi->connection_name, Sql_condition::WARN_LEVEL_NOTE); @@ -3625,7 +3632,7 @@ mysql_execute_command(THD *thd) If new master was not added, we still need to free mi. */ if (master_info_added) - master_info_index->remove_master_info(&lex_mi->connection_name); + master_info_index->remove_master_info(mi); else delete mi; } @@ -3643,22 +3650,24 @@ mysql_execute_command(THD *thd) /* Accept one of two privileges */ if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL)) goto error; - mysql_mutex_lock(&LOCK_active_mi); if (lex->verbose) + { + mysql_mutex_lock(&LOCK_active_mi); res= show_all_master_info(thd); + mysql_mutex_unlock(&LOCK_active_mi); + } else { LEX_MASTER_INFO *lex_mi= &thd->lex->mi; Master_info *mi; - mi= master_info_index->get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR); - if (mi != NULL) + if ((mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR))) { res= show_master_info(thd, mi, 0); + mi->release(); } } - mysql_mutex_unlock(&LOCK_active_mi); break; } case SQLCOM_SHOW_MASTER_STAT: @@ -4009,22 +4018,23 @@ end_with_restore_list: load_error= rpl_load_gtid_slave_state(thd); - mysql_mutex_lock(&LOCK_active_mi); - - if ((mi= (master_info_index-> - get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR)))) + /* + We don't need to ensure that only one user is using master_info + as start_slave is protected against simultaneous usage + */ + if ((mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR))) { if (load_error) { /* - We cannot start a slave using GTID if we cannot load the GTID position - from the mysql.gtid_slave_pos table. But we can allow non-GTID - replication (useful eg. during upgrade). + We cannot start a slave using GTID if we cannot load the + GTID position from the mysql.gtid_slave_pos table. But we + can allow non-GTID replication (useful eg. during upgrade). */ if (mi->using_gtid != Master_info::USE_GTID_NO) { - mysql_mutex_unlock(&LOCK_active_mi); + mi->release(); break; } else @@ -4032,8 +4042,8 @@ end_with_restore_list: } if (!start_slave(thd, mi, 1 /* net report*/)) my_ok(thd); + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); break; } case SQLCOM_SLAVE_STOP: @@ -4063,13 +4073,17 @@ end_with_restore_list: } lex_mi= &thd->lex->mi; - mysql_mutex_lock(&LOCK_active_mi); - if ((mi= (master_info_index-> - get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR)))) - if (!stop_slave(thd, mi, 1/* net report*/)) + if ((mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR))) + { + if (stop_slave(thd, mi, 1/* net report*/)) + res= 1; + mi->release(); + if (rpl_parallel_resize_pool_if_no_slaves()) + res= 1; + if (!res) my_ok(thd); - mysql_mutex_unlock(&LOCK_active_mi); + } break; } case SQLCOM_SLAVE_ALL_START: @@ -5395,11 +5409,13 @@ end_with_restore_list: reload_acl_and_cache binlog interactions failed */ res= 1; - } + } if (!res) my_ok(thd); } + else + res= 1; // reload_acl_and_cache failed #ifdef HAVE_REPLICATION if (lex->type & REFRESH_READ_LOCK) rpl_unpause_after_ftwrl(thd); @@ -7755,7 +7771,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, } /* - When you modify mysql_parse(), you may need to mofify + When you modify mysql_parse(), you may need to modify mysql_test_parse_for_slave() in this same file. */ @@ -9696,48 +9712,24 @@ bool check_ident_length(LEX_STRING *ident) } -C_MODE_START - /* Check if path does not contain mysql data home directory SYNOPSIS - test_if_data_home_dir() - dir directory + path_starts_from_data_home_dir() + dir directory, with all symlinks resolved RETURN VALUES 0 ok 1 error ; Given path contains data directory */ +extern "C" { -int test_if_data_home_dir(const char *dir) +int path_starts_from_data_home_dir(const char *path) { - char path[FN_REFLEN]; - int dir_len; - DBUG_ENTER("test_if_data_home_dir"); - - if (!dir) - DBUG_RETURN(0); + int dir_len= strlen(path); + DBUG_ENTER("path_starts_from_data_home_dir"); - /* - data_file_name and index_file_name include the table name without - extension. Mostly this does not refer to an existing file. When - comparing data_file_name or index_file_name against the data - directory, we try to resolve all symbolic links. On some systems, - we use realpath(3) for the resolution. This returns ENOENT if the - resolved path does not refer to an existing file. my_realpath() - does then copy the requested path verbatim, without symlink - resolution. Thereafter the comparison can fail even if the - requested path is within the data directory. E.g. if symlinks to - another file system are used. To make realpath(3) return the - resolved path, we strip the table name and compare the directory - path only. If the directory doesn't exist either, table creation - will fail anyway. - */ - - (void) fn_format(path, dir, "", "", - (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); - dir_len= strlen(path); if (mysql_unpacked_real_data_home_len<= dir_len) { if (dir_len > mysql_unpacked_real_data_home_len && @@ -9765,7 +9757,31 @@ int test_if_data_home_dir(const char *dir) DBUG_RETURN(0); } -C_MODE_END +} + +/* + Check if path does not contain mysql data home directory + + SYNOPSIS + test_if_data_home_dir() + dir directory + + RETURN VALUES + 0 ok + 1 error ; Given path contains data directory +*/ + +int test_if_data_home_dir(const char *dir) +{ + char path[FN_REFLEN]; + DBUG_ENTER("test_if_data_home_dir"); + + if (!dir) + DBUG_RETURN(0); + + (void) fn_format(path, dir, "", "", MY_RETURN_REAL_PATH); + DBUG_RETURN(path_starts_from_data_home_dir(path)); +} int error_if_data_home_dir(const char *path, const char *what) diff --git a/sql/sql_parse.h b/sql/sql_parse.h index d669f36acef..eedb74df959 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -33,7 +33,8 @@ enum enum_mysql_completiontype { COMMIT_RELEASE=-1, COMMIT=0, COMMIT_AND_CHAIN=6 }; -extern "C" int test_if_data_home_dir(const char *dir); +extern "C" int path_starts_from_data_home_dir(const char *dir); +int test_if_data_home_dir(const char *dir); int error_if_data_home_dir(const char *path, const char *what); my_bool net_allocate_new_packet(NET *net, void *thd, uint my_flags); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 31d59ea47ef..101ea3fd3c7 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -724,7 +724,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) { #ifdef HAVE_DLOPEN char dlpath[FN_REFLEN]; - uint plugin_dir_len, dummy_errors, dlpathlen, i; + uint plugin_dir_len, dummy_errors, i; struct st_plugin_dl *tmp= 0, plugin_dl; void *sym; st_ptr_backup tmp_backup[array_elements(list_of_services)]; @@ -760,15 +760,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) /* Open new dll handle */ if (!(plugin_dl.handle= dlopen(dlpath, RTLD_NOW))) { - const char *errmsg=dlerror(); - dlpathlen= strlen(dlpath); - if (!strncmp(dlpath, errmsg, dlpathlen)) - { // if errmsg starts from dlpath, trim this prefix. - errmsg+=dlpathlen; - if (*errmsg == ':') errmsg++; - if (*errmsg == ' ') errmsg++; - } - report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg); + report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, my_dlerror(dlpath)); goto ret; } dlopen_count++; @@ -1569,8 +1561,8 @@ int plugin_init(int *argc, char **argv, int flags) } /* prepare debug_sync service */ - DBUG_ASSERT(strcmp(list_of_services[4].name, "debug_sync_service") == 0); - list_of_services[4].service= *(void**)&debug_sync_C_callback_ptr; + DBUG_ASSERT(strcmp(list_of_services[1].name, "debug_sync_service") == 0); + list_of_services[1].service= *(void**)&debug_sync_C_callback_ptr; /* prepare encryption_keys service */ finalize_encryption_plugin(0); @@ -1657,10 +1649,11 @@ int plugin_init(int *argc, char **argv, int flags) { char path[FN_REFLEN + 1]; build_table_filename(path, sizeof(path) - 1, "mysql", "plugin", reg_ext, 0); - enum legacy_db_type db_type; - frm_type_enum frm_type= dd_frm_type(NULL, path, &db_type); + char engine_name_buf[NAME_CHAR_LEN + 1]; + LEX_STRING maybe_myisam= { engine_name_buf, 0 }; + frm_type_enum frm_type= dd_frm_type(NULL, path, &maybe_myisam); /* if mysql.plugin table is MyISAM - load it right away */ - if (frm_type == FRMTYPE_TABLE && db_type == DB_TYPE_MYISAM) + if (frm_type == FRMTYPE_TABLE && !strcasecmp(maybe_myisam.str, "MyISAM")) { plugin_load(&tmp_root); flags|= PLUGIN_INIT_SKIP_PLUGIN_TABLE; @@ -3302,14 +3295,14 @@ uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type) { switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) { case PLUGIN_VAR_BOOL: - thd->sys_var_tmp.my_bool_value= (my_bool)option.def_value; + thd->sys_var_tmp.my_bool_value= option.def_value; return (uchar*) &thd->sys_var_tmp.my_bool_value; case PLUGIN_VAR_INT: - thd->sys_var_tmp.int_value= (int)option.def_value; + thd->sys_var_tmp.int_value= option.def_value; return (uchar*) &thd->sys_var_tmp.int_value; case PLUGIN_VAR_LONG: case PLUGIN_VAR_ENUM: - thd->sys_var_tmp.long_value= (long)option.def_value; + thd->sys_var_tmp.long_value= option.def_value; return (uchar*) &thd->sys_var_tmp.long_value; case PLUGIN_VAR_LONGLONG: case PLUGIN_VAR_SET: diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic index c3dfde18ab6..2e71fac50be 100644 --- a/sql/sql_plugin_services.ic +++ b/sql/sql_plugin_services.ic @@ -60,6 +60,33 @@ static struct thd_timezone_service_st thd_timezone_handler= { thd_gmt_sec_to_TIME }; +static struct my_sha2_service_st my_sha2_handler = { + my_sha224, + my_sha224_multi, + my_sha224_context_size, + my_sha224_init, + my_sha224_input, + my_sha224_result, + my_sha256, + my_sha256_multi, + my_sha256_context_size, + my_sha256_init, + my_sha256_input, + my_sha256_result, + my_sha384, + my_sha384_multi, + my_sha384_context_size, + my_sha384_init, + my_sha384_input, + my_sha384_result, + my_sha512, + my_sha512_multi, + my_sha512_context_size, + my_sha512_init, + my_sha512_input, + my_sha512_result, +}; + static struct my_sha1_service_st my_sha1_handler = { my_sha1, my_sha1_multi, @@ -92,6 +119,20 @@ static struct thd_autoinc_service_st thd_autoinc_handler= { thd_get_autoinc }; +static struct thd_rnd_service_st thd_rnd_handler= { + thd_rnd, + thd_create_random_password +}; + +static struct base64_service_st base64_handler= { + my_base64_needed_encoded_length, + my_base64_encode_max_arg_length, + my_base64_needed_decoded_length, + my_base64_decode_max_arg_length, + my_base64_encode, + my_base64_decode +}; + static struct thd_error_context_service_st thd_error_conext_handler= { thd_get_error_message, thd_get_error_number, @@ -157,21 +198,24 @@ static struct encryption_scheme_service_st encryption_scheme_handler= static struct st_service_ref list_of_services[]= { + { "base64_service", VERSION_base64, &base64_handler }, + { "debug_sync_service", VERSION_debug_sync, 0 }, // updated in plugin_init() + { "encryption_scheme_service", VERSION_encryption_scheme, &encryption_scheme_handler }, + { "encryption_service", VERSION_encryption, &encryption_handler }, + { "logger_service", VERSION_logger, &logger_service_handler }, + { "my_md5_service", VERSION_my_md5, &my_md5_handler}, + { "my_sha1_service", VERSION_my_sha1, &my_sha1_handler}, + { "my_sha2_service", VERSION_my_sha2, &my_sha2_handler}, { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler }, - { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler }, - { "thd_wait_service", VERSION_thd_wait, &thd_wait_handler }, { "progress_report_service", VERSION_progress_report, &progress_report_handler }, - { "debug_sync_service", VERSION_debug_sync, 0 }, // updated in plugin_init() + { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler }, + { "thd_autoinc_service", VERSION_thd_autoinc, &thd_autoinc_handler }, + { "thd_error_context_service", VERSION_thd_error_context, &thd_error_conext_handler }, { "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler }, + { "thd_rnd_service", VERSION_thd_rnd, &thd_rnd_handler }, + { "thd_specifics_service", VERSION_thd_specifics, &thd_specifics_handler }, { "thd_timezone_service", VERSION_thd_timezone, &thd_timezone_handler }, - { "my_sha1_service", VERSION_my_sha1, &my_sha1_handler}, - { "my_md5_service", VERSION_my_md5, &my_md5_handler}, - { "logger_service", VERSION_logger, &logger_service_handler }, - { "thd_autoinc_service", VERSION_thd_autoinc, &thd_autoinc_handler }, + { "thd_wait_service", VERSION_thd_wait, &thd_wait_handler }, { "wsrep_service", VERSION_wsrep, &wsrep_handler }, - { "encryption_service", VERSION_encryption, &encryption_handler }, - { "encryption_scheme_service", VERSION_encryption_scheme, &encryption_scheme_handler }, - { "thd_specifics_service", VERSION_thd_specifics, &thd_specifics_handler }, - { "thd_error_context_service", VERSION_thd_error_context, &thd_error_conext_handler }, }; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index c8765f45273..4b2d8b5fb36 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2258,7 +2258,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt, THD *thd= stmt->thd; LEX *lex= stmt->lex; SQL_HANDLER *ha_table; - DBUG_ENTER("mysql_test_select"); + DBUG_ENTER("mysql_test_handler_read"); lex->select_lex.context.resolve_in_select_list= TRUE; diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 2d72d1052d2..463989b3805 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -181,24 +181,20 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, slave is not likely to have the same connection names. */ tmp_write_to_binlog= 0; - mysql_mutex_lock(&LOCK_active_mi); - if (master_info_index) + + if (!(mi= (get_master_info(&connection_name, + Sql_condition::WARN_LEVEL_ERROR)))) { - if (!(mi= (master_info_index-> - get_master_info(&connection_name, - Sql_condition::WARN_LEVEL_ERROR)))) - { - result= 1; - } - else - { - mysql_mutex_lock(&mi->data_lock); - if (rotate_relay_log(mi)) - *write_to_binlog= -1; - mysql_mutex_unlock(&mi->data_lock); - } + result= 1; + } + else + { + mysql_mutex_lock(&mi->data_lock); + if (rotate_relay_log(mi)) + *write_to_binlog= -1; + mysql_mutex_unlock(&mi->data_lock); + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); #endif } #ifdef HAVE_QUERY_CACHE @@ -375,27 +371,33 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, LEX_MASTER_INFO* lex_mi= &thd->lex->mi; Master_info *mi; tmp_write_to_binlog= 0; - mysql_mutex_lock(&LOCK_active_mi); - if (master_info_index) + + if (!(mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR))) { - if (!(mi= (master_info_index-> - get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR)))) - { - result= 1; - } - else if (reset_slave(thd, mi)) + result= 1; + } + else + { + /* The following will fail if slave is running */ + if (reset_slave(thd, mi)) { + mi->release(); /* NOTE: my_error() has been already called by reset_slave(). */ result= 1; } else if (mi->connection_name.length && thd->lex->reset_slave_info.all) { /* If not default connection and 'all' is used */ - master_info_index->remove_master_info(&mi->connection_name); + mi->release(); + mysql_mutex_lock(&LOCK_active_mi); + if (master_info_index->remove_master_info(mi)) + result= 1; + mysql_mutex_unlock(&LOCK_active_mi); } + else + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); } #endif if (options & REFRESH_USER_RESOURCES) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 0180671977c..7c30aa38f1a 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3040,7 +3040,16 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) relay_log_info_file, 0, &mi->cmp_connection_name); - lock_slave_threads(mi); // this allows us to cleanly read slave_running + mi->lock_slave_threads(); + if (mi->killed) + { + /* connection was deleted while we waited for lock_slave_threads */ + mi->unlock_slave_threads(); + my_error(WARN_NO_MASTER_INFO, mi->connection_name.length, + mi->connection_name.str); + DBUG_RETURN(-1); + } + // Get a mask of _stopped_ threads init_thread_mask(&thread_mask,mi,1 /* inverse */); @@ -3169,7 +3178,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) if (!slave_errno) slave_errno = start_slave_threads(thd, - 0 /*no mutex */, + 1, 1 /* wait for start */, mi, master_info_file_tmp, @@ -3185,7 +3194,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) } err: - unlock_slave_threads(mi); + mi->unlock_slave_threads(); thd_proc_info(thd, 0); if (slave_errno) @@ -3226,8 +3235,12 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report ) DBUG_RETURN(-1); THD_STAGE_INFO(thd, stage_killing_slave); int thread_mask; - lock_slave_threads(mi); - // Get a mask of _running_ threads + mi->lock_slave_threads(); + /* + Get a mask of _running_ threads. + We don't have to test for mi->killed as the thread_mask will take care + of checking if threads exists + */ init_thread_mask(&thread_mask,mi,0 /* not inverse*/); /* Below we will stop all running threads. @@ -3240,8 +3253,7 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report ) if (thread_mask) { - slave_errno= terminate_slave_threads(mi,thread_mask, - 1 /*skip lock */); + slave_errno= terminate_slave_threads(mi,thread_mask, 0 /* get lock */); } else { @@ -3250,7 +3262,8 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report ) push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_WAS_NOT_RUNNING, ER_THD(thd, ER_SLAVE_WAS_NOT_RUNNING)); } - unlock_slave_threads(mi); + + mi->unlock_slave_threads(); if (slave_errno) { @@ -3285,11 +3298,20 @@ int reset_slave(THD *thd, Master_info* mi) char relay_log_info_file_tmp[FN_REFLEN]; DBUG_ENTER("reset_slave"); - lock_slave_threads(mi); + mi->lock_slave_threads(); + if (mi->killed) + { + /* connection was deleted while we waited for lock_slave_threads */ + mi->unlock_slave_threads(); + my_error(WARN_NO_MASTER_INFO, mi->connection_name.length, + mi->connection_name.str); + DBUG_RETURN(-1); + } + init_thread_mask(&thread_mask,mi,0 /* not inverse */); if (thread_mask) // We refuse if any slave thread is running { - unlock_slave_threads(mi); + mi->unlock_slave_threads(); my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length, mi->connection_name.str); DBUG_RETURN(ER_SLAVE_MUST_STOP); @@ -3353,7 +3375,7 @@ int reset_slave(THD *thd, Master_info* mi) RUN_HOOK(binlog_relay_io, after_reset_slave, (thd, mi)); err: - unlock_slave_threads(mi); + mi->unlock_slave_threads(); if (error) my_error(sql_errno, MYF(0), errmsg); DBUG_RETURN(error); @@ -3466,8 +3488,8 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added) DBUG_ENTER("change_master"); - mysql_mutex_assert_owner(&LOCK_active_mi); DBUG_ASSERT(master_info_index); + mysql_mutex_assert_owner(&LOCK_active_mi); *master_info_added= false; /* @@ -3487,7 +3509,16 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added) lex_mi->port)) DBUG_RETURN(TRUE); - lock_slave_threads(mi); + mi->lock_slave_threads(); + if (mi->killed) + { + /* connection was deleted while we waited for lock_slave_threads */ + mi->unlock_slave_threads(); + my_error(WARN_NO_MASTER_INFO, mi->connection_name.length, + mi->connection_name.str); + DBUG_RETURN(TRUE); + } + init_thread_mask(&thread_mask,mi,0 /*not inverse*/); if (thread_mask) // We refuse if any slave thread is running { @@ -3811,12 +3842,13 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added) in-memory value at restart (thus causing errors, as the old relay log does not exist anymore). */ - mi->rli.flush(); + if (mi->rli.flush()) + ret= 1; mysql_cond_broadcast(&mi->data_cond); mysql_mutex_unlock(&mi->rli.data_lock); err: - unlock_slave_threads(mi); + mi->unlock_slave_threads(); if (ret == FALSE) my_ok(thd); DBUG_RETURN(ret); @@ -3896,13 +3928,9 @@ bool mysql_show_binlog_events(THD* thd) { if (!lex_mi->connection_name.str) lex_mi->connection_name= thd->variables.default_master_connection; - mysql_mutex_lock(&LOCK_active_mi); - if (!master_info_index || - !(mi= master_info_index-> - get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR))) + if (!(mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR))) { - mysql_mutex_unlock(&LOCK_active_mi); DBUG_RETURN(TRUE); } binary_log= &(mi->rli.relay_log); @@ -3921,7 +3949,7 @@ bool mysql_show_binlog_events(THD* thd) if (mi) { /* We can unlock the mutex as we have a lock on the file */ - mysql_mutex_unlock(&LOCK_active_mi); + mi->release(); mi= 0; } @@ -4054,7 +4082,7 @@ bool mysql_show_binlog_events(THD* thd) mysql_mutex_unlock(log_lock); } else if (mi) - mysql_mutex_unlock(&LOCK_active_mi); + mi->release(); // Check that linfo is still on the function scope. DEBUG_SYNC(thd, "after_show_binlog_events"); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6f84b4a5762..54b0b01559b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6017,7 +6017,7 @@ double matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint, { TABLE *table= s->table; double sel= table->cond_selectivity; - double table_records= (double)table->stat_records(); + double table_records= table->stat_records(); dbl_records= table_records * sel; return dbl_records; } @@ -6043,7 +6043,7 @@ double matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint, if (s->table->quick_condition_rows != s->found_records) records= s->table->quick_condition_rows; - dbl_records= (double)records; + dbl_records= records; return dbl_records; } @@ -8799,8 +8799,6 @@ bool JOIN::get_best_combination() form= table[tablenr]= j->table; used_tables|= form->map; form->reginfo.join_tab=j; - if (!*j->on_expr_ref) - form->reginfo.not_exists_optimize=0; // Only with LEFT JOIN DBUG_PRINT("info",("type: %d", j->type)); if (j->type == JT_CONST) goto loop_end; // Handled in make_join_stat.. @@ -9363,8 +9361,6 @@ static void add_not_null_conds(JOIN *join) UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1); not_null_item is the t1.f1, but it's referred_tab is 0. */ - if (!referred_tab) - continue; if (!(notnull= new (join->thd->mem_root) Item_func_isnotnull(join->thd, item))) DBUG_VOID_RETURN; @@ -9376,16 +9372,19 @@ static void add_not_null_conds(JOIN *join) */ if (notnull->fix_fields(join->thd, ¬null)) DBUG_VOID_RETURN; + DBUG_EXECUTE("where",print_where(notnull, - referred_tab->table->alias.c_ptr(), - QT_ORDINARY);); + (referred_tab ? + referred_tab->table->alias.c_ptr() : + "outer_ref_cond"), + QT_ORDINARY);); if (!tab->first_inner) - { - COND *new_cond= referred_tab->join == join ? + { + COND *new_cond= (referred_tab && referred_tab->join == join) ? referred_tab->select_cond : join->outer_ref_cond; add_cond_and_fix(join->thd, &new_cond, notnull); - if (referred_tab->join == join) + if (referred_tab && referred_tab->join == join) referred_tab->set_select_cond(new_cond, __LINE__); else join->outer_ref_cond= new_cond; @@ -9537,7 +9536,10 @@ make_outerjoin_info(JOIN *join) tab->cond_equal= tbl->cond_equal; if (embedding && !embedding->is_active_sjm()) tab->first_upper= embedding->nested_join->first_nested; - } + } + else if (!embedding) + tab->table->reginfo.not_exists_optimize= 0; + for ( ; embedding ; embedding= embedding->embedding) { if (embedding->is_active_sjm()) @@ -9547,7 +9549,10 @@ make_outerjoin_info(JOIN *join) } /* Ignore sj-nests: */ if (!(embedding->on_expr && embedding->outer_join)) + { + tab->table->reginfo.not_exists_optimize= 0; continue; + } NESTED_JOIN *nested_join= embedding->nested_join; if (!nested_join->counter) { @@ -9563,17 +9568,10 @@ make_outerjoin_info(JOIN *join) } if (!tab->first_inner) tab->first_inner= nested_join->first_nested; - if (tab->table->reginfo.not_exists_optimize) - tab->first_inner->table->reginfo.not_exists_optimize= 1; if (++nested_join->counter < nested_join->n_tables) break; /* Table tab is the last inner table for nested join. */ nested_join->first_nested->last_inner= tab; - if (tab->first_inner->table->reginfo.not_exists_optimize) - { - for (JOIN_TAB *join_tab= tab->first_inner; join_tab <= tab; join_tab++) - join_tab->table->reginfo.not_exists_optimize= 1; - } } } DBUG_RETURN(FALSE); @@ -10348,7 +10346,7 @@ void JOIN::drop_unused_derived_keys() continue; if (!tmp_tbl->pos_in_table_list->is_materialized_derived()) continue; - if (tmp_tbl->max_keys > 1) + if (tmp_tbl->max_keys > 1 && !tab->is_ref_for_hash_join()) tmp_tbl->use_index(tab->ref.key); if (tmp_tbl->s->keys) { @@ -15934,7 +15932,9 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, DBUG_ASSERT(thd == table->in_use); new_field= item->Item::create_tmp_field(false, table); - if (copy_func && item->real_item()->is_result_field()) + if (copy_func && + (item->is_result_field() || + (item->real_item()->is_result_field()))) *((*copy_func)++) = item; // Save for copy_funcs if (modify_item) item->set_result_field(new_field); @@ -18540,32 +18540,41 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, first_unmatched->found= 1; for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++) { + /* + Check whether 'not exists' optimization can be used here. + If tab->table->reginfo.not_exists_optimize is set to true + then WHERE contains a conjunctive predicate IS NULL over + a non-nullable field of tab. When activated this predicate + will filter out all records with matches for the left part + of the outer join whose inner tables start from the + first_unmatched table and include table tab. To safely use + 'not exists' optimization we have to check that the + IS NULL predicate is really activated, i.e. all guards + that wrap it are in the 'open' state. + */ + bool not_exists_opt_is_applicable= + tab->table->reginfo.not_exists_optimize; + for (JOIN_TAB *first_upper= first_unmatched->first_upper; + not_exists_opt_is_applicable && first_upper; + first_upper= first_upper->first_upper) + { + if (!first_upper->found) + not_exists_opt_is_applicable= false; + } /* Check all predicates that has just been activated. */ /* Actually all predicates non-guarded by first_unmatched->found will be re-evaluated again. It could be fixed, but, probably, it's not worth doing now. */ - /* - not_exists_optimize has been created from a - select_cond containing 'is_null'. This 'is_null' - predicate is still present on any 'tab' with - 'not_exists_optimize'. Furthermore, the usual rules - for condition guards also applies for - 'not_exists_optimize' -> When 'is_null==false' we - know all cond. guards are open and we can apply - the 'not_exists_optimize'. - */ - DBUG_ASSERT(!(tab->table->reginfo.not_exists_optimize && - !tab->select_cond)); - if (tab->select_cond && !tab->select_cond->val_int()) { /* The condition attached to table tab is false */ - if (tab == join_tab) { found= 0; + if (not_exists_opt_is_applicable) + DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); } else { @@ -18574,21 +18583,10 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, not to the last table of the current nest level. */ join->return_tab= tab; - } - - if (tab->table->reginfo.not_exists_optimize) - { - /* - When not_exists_optimize is set: No need to further - explore more rows of 'tab' for this partial result. - Any found 'tab' matches are known to evaluate to 'false'. - Returning .._NO_MORE_ROWS will skip rem. 'tab' rows. - */ - DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); - } - else if (tab != join_tab) - { - DBUG_RETURN(NESTED_LOOP_OK); + if (not_exists_opt_is_applicable) + DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); + else + DBUG_RETURN(NESTED_LOOP_OK); } } } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index adba7ab4d33..18bc19bb85e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4133,6 +4133,22 @@ make_table_name_list(THD *thd, Dynamic_array<LEX_STRING*> *table_names, } +static void get_table_engine_for_i_s(THD *thd, char *buf, TABLE_LIST *tl, + LEX_STRING *db, LEX_STRING *table) +{ + LEX_STRING engine_name= { buf, 0 }; + + if (thd->get_stmt_da()->sql_errno() == ER_UNKNOWN_STORAGE_ENGINE) + { + char path[FN_REFLEN]; + build_table_filename(path, sizeof(path) - 1, + db->str, table->str, reg_ext, 0); + if (dd_frm_type(thd, path, &engine_name) == FRMTYPE_TABLE) + tl->option= engine_name.str; + } +} + + /** Fill I_S table with data obtained by performing full-blown table open. @@ -4203,9 +4219,9 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, /* Since make_table_list() might change database and table name passed - to it we create copies of orig_db_name and orig_table_name here. - These copies are used for make_table_list() while unaltered values - are passed to process_table() functions. + to it (if lower_case_table_names) we create copies of orig_db_name and + orig_table_name here. These copies are used for make_table_list() + while unaltered values are passed to process_table() functions. */ if (!thd->make_lex_string(&db_name, orig_db_name->str, orig_db_name->length) || @@ -4292,6 +4308,10 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, } else { + char buf[NAME_CHAR_LEN + 1]; + if (thd->is_error()) + get_table_engine_for_i_s(thd, buf, table_list, &db_name, &table_name); + result= schema_table->process_table(thd, table_list, table, result, orig_db_name, @@ -4508,15 +4528,13 @@ try_acquire_high_prio_shared_mdl_lock(THD *thd, TABLE_LIST *table, open_tables function for this table */ -static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, +static int fill_schema_table_from_frm(THD *thd, TABLE *table, ST_SCHEMA_TABLE *schema_table, LEX_STRING *db_name, LEX_STRING *table_name, - enum enum_schema_tables schema_table_idx, Open_tables_backup *open_tables_state_backup, bool can_deadlock) { - TABLE *table= tables->table; TABLE_SHARE *share; TABLE tbl; TABLE_LIST table_list; @@ -4598,7 +4616,19 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, share= tdc_acquire_share(thd, &table_list, GTS_TABLE | GTS_VIEW); if (!share) { - res= 0; + if (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE || + thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT) + { + res= 0; + } + else + { + char buf[NAME_CHAR_LEN + 1]; + get_table_engine_for_i_s(thd, buf, &table_list, db_name, table_name); + + res= schema_table->process_table(thd, &table_list, table, + true, db_name, table_name); + } goto end; } @@ -4874,9 +4904,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) if (!(table_open_method & ~OPEN_FRM_ONLY) && db_name != &INFORMATION_SCHEMA_NAME) { - if (!fill_schema_table_from_frm(thd, tables, schema_table, + if (!fill_schema_table_from_frm(thd, table, schema_table, db_name, table_name, - schema_table_idx, &open_tables_state_backup, can_deadlock)) continue; @@ -5010,6 +5039,11 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, else table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs); + if (tables->option) + { + table->field[4]->store(tables->option, strlen(tables->option), cs); + table->field[4]->set_notnull(); + } goto err; } diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 979852e2f6b..ad71f634265 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 07af3b891ea..baab8e320a0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6607,6 +6607,9 @@ static bool fill_alter_inplace_info(THD *thd, new_key->user_defined_key_parts)) goto index_changed; + if (table_key->block_size != new_key->block_size) + goto index_changed; + if (engine_options_differ(table_key->option_struct, new_key->option_struct, table->file->ht->index_options)) goto index_changed; diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 394fa713445..05698ce82cc 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -228,14 +228,13 @@ void udf_init() if (dl == NULL) { char dlpath[FN_REFLEN]; - strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl, - NullS); + strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl, NullS); (void) unpack_filename(dlpath, dlpath); if (!(dl= dlopen(dlpath, RTLD_NOW))) { /* Print warning to log */ sql_print_error(ER_THD(new_thd, ER_CANT_OPEN_LIBRARY), - tmp->dl, errno, dlerror()); + tmp->dl, errno, my_dlerror(dlpath)); /* Keep the udf in the hash so that we can remove it later */ continue; } @@ -539,10 +538,10 @@ int mysql_create_function(THD *thd,udf_func *udf) if (!(dl = dlopen(dlpath, RTLD_NOW))) { + my_error(ER_CANT_OPEN_LIBRARY, MYF(0), + udf->dl, errno, my_dlerror(dlpath)); DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", udf->dl, errno, dlerror())); - my_error(ER_CANT_OPEN_LIBRARY, MYF(0), - udf->dl, errno, dlerror()); goto err; } new_dl=1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index fe387ed80f2..412fcce8625 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1017,7 +1017,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %} -%pure_parser /* We have threads */ +%pure-parser /* We have threads */ %parse-param { THD *thd } %lex-param { THD *thd } /* @@ -7748,7 +7748,7 @@ alter_list_item: $5->name, $4->csname)); if (Lex->create_info.add_alter_list_item_convert_to_charset($5)) MYSQL_YYABORT; - Lex->alter_info.flags|= Alter_info::ALTER_CONVERT; + Lex->alter_info.flags|= Alter_info::ALTER_OPTIONS; } | create_table_options_space_separated { diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index fd724bc7dd1..a3bc3f6d9cf 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1596,7 +1596,6 @@ bool Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var) { String str, *res; - bool running; DBUG_ASSERT(var->type == OPT_GLOBAL); @@ -1607,11 +1606,7 @@ Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var) return true; } - mysql_mutex_lock(&LOCK_active_mi); - running= (!master_info_index || - master_info_index->give_error_if_slave_running()); - mysql_mutex_unlock(&LOCK_active_mi); - if (running) + if (give_error_if_slave_running(0)) return true; if (!(res= var->value->val_str(&str))) return true; @@ -1649,7 +1644,7 @@ Sys_var_gtid_slave_pos::global_update(THD *thd, set_var *var) mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_lock(&LOCK_active_mi); - if (!master_info_index || master_info_index->give_error_if_slave_running()) + if (give_error_if_slave_running(1)) err= true; else err= rpl_gtid_pos_update(thd, var->save_result.string_value.str, @@ -1835,16 +1830,7 @@ Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_STRING *base) static bool check_slave_parallel_threads(sys_var *self, THD *thd, set_var *var) { - bool running; - - mysql_mutex_lock(&LOCK_active_mi); - running= (!master_info_index || - master_info_index->give_error_if_slave_running()); - mysql_mutex_unlock(&LOCK_active_mi); - if (running) - return true; - - return false; + return give_error_if_slave_running(0); } static bool @@ -1853,10 +1839,7 @@ fix_slave_parallel_threads(sys_var *self, THD *thd, enum_var_type type) bool err; mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - err= (!master_info_index || - master_info_index->give_error_if_slave_running()); - mysql_mutex_unlock(&LOCK_active_mi); + err= give_error_if_slave_running(0); mysql_mutex_lock(&LOCK_global_system_variables); return err; @@ -1888,16 +1871,7 @@ static Sys_var_ulong Sys_slave_parallel_workers( static bool check_slave_domain_parallel_threads(sys_var *self, THD *thd, set_var *var) { - bool running; - - mysql_mutex_lock(&LOCK_active_mi); - running= (!master_info_index || - master_info_index->give_error_if_slave_running()); - mysql_mutex_unlock(&LOCK_active_mi); - if (running) - return true; - - return false; + return give_error_if_slave_running(0); } static bool @@ -1906,13 +1880,10 @@ fix_slave_domain_parallel_threads(sys_var *self, THD *thd, enum_var_type type) bool running; mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - running= (!master_info_index || - master_info_index->give_error_if_slave_running()); - mysql_mutex_unlock(&LOCK_active_mi); + running= give_error_if_slave_running(0); mysql_mutex_lock(&LOCK_global_system_variables); - return running ? true : false; + return running; } @@ -2055,16 +2026,7 @@ static Sys_var_bit Sys_skip_parallel_replication( static bool check_gtid_ignore_duplicates(sys_var *self, THD *thd, set_var *var) { - bool running; - - mysql_mutex_lock(&LOCK_active_mi); - running= (!master_info_index || - master_info_index->give_error_if_slave_running()); - mysql_mutex_unlock(&LOCK_active_mi); - if (running) - return true; - - return false; + return give_error_if_slave_running(0); } static bool @@ -2073,13 +2035,10 @@ fix_gtid_ignore_duplicates(sys_var *self, THD *thd, enum_var_type type) bool running; mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - running= (!master_info_index || - master_info_index->give_error_if_slave_running()); - mysql_mutex_unlock(&LOCK_active_mi); + running= give_error_if_slave_running(0); mysql_mutex_lock(&LOCK_global_system_variables); - return running ? true : false; + return running; } @@ -2980,10 +2939,8 @@ Sys_var_replicate_events_marked_for_skip::global_update(THD *thd, set_var *var) DBUG_ENTER("Sys_var_replicate_events_marked_for_skip::global_update"); mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - if (master_info_index && !master_info_index->give_error_if_slave_running()) + if (!give_error_if_slave_running(0)) result= Sys_var_enum::global_update(thd, var); - mysql_mutex_unlock(&LOCK_active_mi); mysql_mutex_lock(&LOCK_global_system_variables); DBUG_RETURN(result); } @@ -4379,35 +4336,31 @@ static Sys_var_mybool Sys_relay_log_recovery( bool Sys_var_rpl_filter::global_update(THD *thd, set_var *var) { bool result= true; // Assume error - Master_info *mi; LEX_STRING *base_name= &var->base; if (!base_name->length) base_name= &thd->variables.default_master_connection; mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - - mi= master_info_index-> - get_master_info(base_name, !base_name->length ? - Sql_condition::WARN_LEVEL_ERROR : - Sql_condition::WARN_LEVEL_WARN); - if (mi) + + if (Master_info *mi= get_master_info(base_name, !var->base.length ? + Sql_condition::WARN_LEVEL_ERROR : + Sql_condition::WARN_LEVEL_WARN)) { if (mi->rli.slave_running) { my_error(ER_SLAVE_MUST_STOP, MYF(0), - mi->connection_name.length, - mi->connection_name.str); + mi->connection_name.length, + mi->connection_name.str); result= true; } else { result= set_filter_value(var->save_result.string_value.str, mi); } + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); mysql_mutex_lock(&LOCK_global_system_variables); return result; } @@ -4417,6 +4370,8 @@ bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi) bool status= true; Rpl_filter* rpl_filter= mi->rpl_filter; + /* Proctect against other threads */ + mysql_mutex_lock(&LOCK_active_mi); switch (opt_id) { case OPT_REPLICATE_DO_DB: status= rpl_filter->set_do_db(value); @@ -4437,7 +4392,7 @@ bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi) status= rpl_filter->set_wild_ignore_table(value); break; } - + mysql_mutex_unlock(&LOCK_active_mi); return status; } @@ -4451,23 +4406,20 @@ uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd, Rpl_filter *rpl_filter; mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - - mi= master_info_index-> - get_master_info(base_name, !base_name->length ? - Sql_condition::WARN_LEVEL_ERROR : - Sql_condition::WARN_LEVEL_WARN); - - mysql_mutex_lock(&LOCK_global_system_variables); + mi= get_master_info(base_name, !base_name->length ? + Sql_condition::WARN_LEVEL_ERROR : + Sql_condition::WARN_LEVEL_WARN); if (!mi) { - mysql_mutex_unlock(&LOCK_active_mi); + mysql_mutex_lock(&LOCK_global_system_variables); return 0; } + rpl_filter= mi->rpl_filter; tmp.length(0); + mysql_mutex_lock(&LOCK_active_mi); switch (opt_id) { case OPT_REPLICATE_DO_DB: rpl_filter->get_do_db(&tmp); @@ -4488,9 +4440,12 @@ uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd, rpl_filter->get_wild_ignore_table(&tmp); break; } + mysql_mutex_unlock(&LOCK_active_mi); + mysql_mutex_lock(&LOCK_global_system_variables); + + mi->release(); ret= (uchar *) thd->strmake(tmp.ptr(), tmp.length()); - mysql_mutex_unlock(&LOCK_active_mi); return ret; } @@ -4559,17 +4514,12 @@ get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) Master_info *mi; ulonglong res= 0; // Default value mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - mi= master_info_index-> - get_master_info(&thd->variables.default_master_connection, - Sql_condition::WARN_LEVEL_WARN); - if (mi) + if ((mi= get_master_info(&thd->variables.default_master_connection, + Sql_condition::WARN_LEVEL_WARN))) { - mysql_mutex_lock(&mi->rli.data_lock); res= *((ulonglong*) (((uchar*) mi) + master_info_offset)); - mysql_mutex_unlock(&mi->rli.data_lock); + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); mysql_mutex_lock(&LOCK_global_system_variables); return res; } @@ -4584,19 +4534,16 @@ bool update_multi_source_variable(sys_var *self_var, THD *thd, if (type == OPT_GLOBAL) mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - mi= master_info_index-> - get_master_info(&thd->variables.default_master_connection, - Sql_condition::WARN_LEVEL_ERROR); - if (mi) + if ((mi= (get_master_info(&thd->variables.default_master_connection, + Sql_condition::WARN_LEVEL_ERROR)))) { mysql_mutex_lock(&mi->rli.run_lock); mysql_mutex_lock(&mi->rli.data_lock); result= self->update_variable(thd, mi); mysql_mutex_unlock(&mi->rli.data_lock); mysql_mutex_unlock(&mi->rli.run_lock); + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); if (type == OPT_GLOBAL) mysql_mutex_lock(&LOCK_global_system_variables); return result; diff --git a/sql/table.cc b/sql/table.cc index 6b15c06cb91..6d1a3a7f8d8 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -591,7 +591,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) { DBUG_ASSERT(flags & GTS_TABLE); DBUG_ASSERT(flags & GTS_USE_DISCOVERY); - mysql_file_delete_with_symlink(key_file_frm, path, MYF(0)); + mysql_file_delete_with_symlink(key_file_frm, path, "", MYF(0)); file= -1; } else diff --git a/sql/threadpool.h b/sql/threadpool.h index 17c8b6ea4ea..ba17dc042c2 100644 --- a/sql/threadpool.h +++ b/sql/threadpool.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #define MAX_THREAD_GROUPS 100000 diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc index 643ff80de2a..c6a3c7e44f8 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <my_global.h> #include <violite.h> diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc index 87c74d18aea..2ab874b2232 100644 --- a/sql/threadpool_generic.cc +++ b/sql/threadpool_generic.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <my_global.h> #include <violite.h> diff --git a/sql/threadpool_win.cc b/sql/threadpool_win.cc index dec898d92bb..855b9b38d78 100644 --- a/sql/threadpool_win.cc +++ b/sql/threadpool_win.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #ifdef _WIN32_WINNT #undef _WIN32_WINNT diff --git a/sql/winservice.c b/sql/winservice.c index 74e9e56acc6..efbbb527c9b 100644 --- a/sql/winservice.c +++ b/sql/winservice.c @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* Get Properties of an existing mysqld Windows service diff --git a/sql/winservice.h b/sql/winservice.h index c3e2bfe1b20..fe3fe526548 100644 --- a/sql/winservice.h +++ b/sql/winservice.h @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* Extract properties of a windows service binary path diff --git a/sql/wsrep_applier.h b/sql/wsrep_applier.h index d58d3cdc54e..f19d2d46d0c 100644 --- a/sql/wsrep_applier.h +++ b/sql/wsrep_applier.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #ifndef WSREP_APPLIER_H #define WSREP_APPLIER_H diff --git a/sql/wsrep_check_opts.cc b/sql/wsrep_check_opts.cc index bc77c434525..8da791b3429 100644 --- a/sql/wsrep_check_opts.cc +++ b/sql/wsrep_check_opts.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "mysqld.h" #include "sys_vars_shared.h" diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 2a93484002e..79dad571585 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <mysqld.h> #include "sql_base.h" diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index b0275fc2fd5..9a99dffc724 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <mysqld.h> #include <sql_class.h> diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 0332432a199..8c81367d12f 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <wsrep.h> diff --git a/sql/wsrep_notify.cc b/sql/wsrep_notify.cc index d1beb9c38d6..92c685ba485 100644 --- a/sql/wsrep_notify.cc +++ b/sql/wsrep_notify.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include <mysqld.h> #include "wsrep_priv.h" diff --git a/sql/wsrep_priv.h b/sql/wsrep_priv.h index e2dc526608f..97307fcc948 100644 --- a/sql/wsrep_priv.h +++ b/sql/wsrep_priv.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ //! @file declares symbols private to wsrep integration layer diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 03cd8674242..076da23967a 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "wsrep_sst.h" diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc index 9a9c2f84ac6..9c77cb49256 100644 --- a/sql/wsrep_utils.cc +++ b/sql/wsrep_utils.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ //! @file some utility functions and classes not directly related to replication diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index e6d4bbbc303..b34fdf8b7ed 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "wsrep_var.h" diff --git a/sql/wsrep_xid.cc b/sql/wsrep_xid.cc index 876f791da69..2ff6ea0b32e 100644 --- a/sql/wsrep_xid.cc +++ b/sql/wsrep_xid.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ //! @file some utility functions and classes not directly related to replication |