From a47d16907d089a33f95c64361b016009e7a20691 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 19 Sep 2017 13:08:24 +0400 Subject: [PATCH 01/11] MDEV-13137 MySQL 5.6.23 Crashes when SET GLOBAL server_audit_logging=OFF; The MySQL 5.6 doesn't always send the MYSQL_AUDIT_GENERAL_LOG notification. So we have to suppress the log_current_query() in this case. --- plugin/server_audit/server_audit.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index c9f478662fd..ad2a4618514 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -15,7 +15,7 @@ #define PLUGIN_VERSION 0x104 -#define PLUGIN_STR_VERSION "1.4.1" +#define PLUGIN_STR_VERSION "1.4.2" #define _my_thread_var loc_thread_var @@ -1090,6 +1090,7 @@ static void setup_connection_connect(struct connection_info *cn, const struct mysql_event_connection *event) { cn->query_id= 0; + cn->query_length= 0; cn->log_always= 0; cn->thread_id= event->thread_id; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), @@ -1131,6 +1132,7 @@ static void setup_connection_initdb(struct connection_info *cn, cn->thread_id= event->general_thread_id; cn->query_id= 0; + cn->query_length= 0; cn->log_always= 0; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), event->general_query, event->general_query_length); @@ -1163,6 +1165,7 @@ static void setup_connection_table(struct connection_info *cn, cn->thread_id= event->thread_id; cn->query_id= query_counter++; cn->log_always= 0; + cn->query_length= 0; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), event->database, event->database_length); get_str_n(cn->user, &cn->user_length, sizeof(cn->db), @@ -1184,6 +1187,7 @@ static void setup_connection_query(struct connection_info *cn, cn->thread_id= event->general_thread_id; cn->query_id= query_counter++; cn->log_always= 0; + cn->query_length= 0; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), "", 0); if (get_user_host(event->general_user, event->general_user_length, @@ -2008,6 +2012,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) event_query_command(event)) { log_statement(cn, event, "QUERY"); + cn->query_length= 0; /* So the log_current_query() won't log this again. */ } } else if (event_class == MYSQL_AUDIT_TABLE_CLASS && FILTER(EVENT_TABLE) && cn) @@ -2523,7 +2528,8 @@ static void log_current_query(MYSQL_THD thd) if (!thd) return; cn= get_loc_info(thd); - if (!ci_needs_setup(cn) && FILTER(EVENT_QUERY) && do_log_user(cn->user)) + if (!ci_needs_setup(cn) && cn->query_length && + FILTER(EVENT_QUERY) && do_log_user(cn->user)) { log_statement_ex(cn, cn->query_time, thd_get_thread_id(thd), cn->query, cn->query_length, 0, "QUERY"); From e3dee8376885c79350d447a5f99ddc5bf03188d8 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 25 Sep 2017 13:41:20 -0400 Subject: [PATCH 02/11] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index b44db15ffd8..3d1d889a5c1 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=1 -MYSQL_VERSION_PATCH=27 +MYSQL_VERSION_PATCH=28 From 0627929f626482508cc999d854e20f3a120f927a Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Wed, 27 Sep 2017 10:06:44 +0530 Subject: [PATCH 03/11] MDEV-13787 Crash in persistent stats wsrep_on (thd=0x0) Problem:- This crash happens because of thd = NULL , and while checking for wsrep_on , we no longer check for thd != NULL (MDEV-7955). So this problem is regression of MDEV-7955. However this patch not only solves this regression , It solves all regression caused by MDEV-7955 patch. To get all possible cases when thd can be null , assert(thd)/ assert(trx->mysql_thd) is place just before all wsrep_on and innodb test suite is run. And the assert which caused failure are removed with a physical check for thd != NULL. Rest assert are removed. Hopefully this method will remove all current/potential regression of MDEV-7955. --- mysql-test/suite/galera/r/galera_mdev_13787.result | 3 +++ mysql-test/suite/galera/t/galera_mdev_13787.opt | 1 + mysql-test/suite/galera/t/galera_mdev_13787.test | 6 ++++++ sql/wsrep_mysqld.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 2 +- storage/innobase/include/lock0lock.h | 5 +++++ storage/innobase/lock/lock0lock.cc | 12 ++++++++++-- storage/innobase/lock/lock0wait.cc | 4 ++-- storage/innobase/row/row0upd.cc | 7 +++---- storage/xtradb/handler/ha_innodb.cc | 2 +- storage/xtradb/include/lock0lock.h | 8 ++++++++ storage/xtradb/lock/lock0lock.cc | 12 ++++++++++-- storage/xtradb/lock/lock0wait.cc | 4 ++-- storage/xtradb/row/row0upd.cc | 7 +++---- 14 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 mysql-test/suite/galera/r/galera_mdev_13787.result create mode 100644 mysql-test/suite/galera/t/galera_mdev_13787.opt create mode 100644 mysql-test/suite/galera/t/galera_mdev_13787.test diff --git a/mysql-test/suite/galera/r/galera_mdev_13787.result b/mysql-test/suite/galera/r/galera_mdev_13787.result new file mode 100644 index 00000000000..e3133f60b0c --- /dev/null +++ b/mysql-test/suite/galera/r/galera_mdev_13787.result @@ -0,0 +1,3 @@ +create table t(a int); +insert into t select 1; +DROP TABLE t; diff --git a/mysql-test/suite/galera/t/galera_mdev_13787.opt b/mysql-test/suite/galera/t/galera_mdev_13787.opt new file mode 100644 index 00000000000..27ec1e3f00e --- /dev/null +++ b/mysql-test/suite/galera/t/galera_mdev_13787.opt @@ -0,0 +1 @@ +--innodb-stats-persistent=1 diff --git a/mysql-test/suite/galera/t/galera_mdev_13787.test b/mysql-test/suite/galera/t/galera_mdev_13787.test new file mode 100644 index 00000000000..940cffb8b65 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_mdev_13787.test @@ -0,0 +1,6 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc +--connection node_1 +create table t(a int); +insert into t select 1; +DROP TABLE t; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 33689a91661..061f877da6e 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2293,7 +2293,7 @@ static int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len) } -extern int wsrep_on(THD *thd) +extern inline int wsrep_on(THD *thd) { return (int)(WSREP(thd)); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index afc320de517..e50f9fc9774 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4122,7 +4122,7 @@ innobase_commit_low( trx_commit_for_mysql(trx); } #ifdef WITH_WSREP - if (wsrep_on(thd)) { thd_proc_info(thd, tmp); } + if (thd && wsrep_on(thd)) { thd_proc_info(thd, tmp); } #endif /* WITH_WSREP */ } diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 8c63157ea8e..62bbd572068 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -1024,6 +1024,11 @@ std::string lock_get_info( const lock_t*); +/*******************************************************************//** +@return whether wsrep_on is true on trx->mysql_thd*/ +bool +wsrep_on_trx(const trx_t* trx); + #endif /* WITH_WSREP */ #ifndef UNIV_NONINL #include "lock0lock.ic" diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 3f5489fbc19..cedf08322b7 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1825,7 +1825,7 @@ lock_rec_other_has_conflicting( #ifdef WITH_WSREP if (lock_rec_has_to_wait(TRUE, trx, mode, lock, is_supremum)) { - if (wsrep_on(trx->mysql_thd)) { + if (wsrep_on_trx(trx)) { trx_mutex_enter(lock->trx); wsrep_kill_victim(trx, lock); trx_mutex_exit(lock->trx); @@ -2151,7 +2151,7 @@ lock_rec_create( #ifdef WITH_WSREP if (c_lock && - wsrep_on(trx->mysql_thd) && + wsrep_on_trx(trx) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { lock_t *hash = (lock_t *)c_lock->hash; lock_t *prev = NULL; @@ -8213,3 +8213,11 @@ lock_get_info( return info; } + +#ifdef WITH_WSREP +bool inline +wsrep_on_trx(const trx_t* trx) +{ + return trx->mysql_thd && wsrep_on(trx->mysql_thd); +} +#endif /* WITH_WSREP */ diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc index a447027e336..ca9d05a4829 100644 --- a/storage/innobase/lock/lock0wait.cc +++ b/storage/innobase/lock/lock0wait.cc @@ -197,7 +197,7 @@ wsrep_is_BF_lock_timeout( /*====================*/ trx_t* trx) /* in: trx to check for lock priority */ { - if (wsrep_on(trx->mysql_thd) && + if (wsrep_on_trx(trx) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { fprintf(stderr, "WSREP: BF lock wait long\n"); srv_print_innodb_monitor = TRUE; @@ -402,7 +402,7 @@ lock_wait_suspend_thread( if (lock_wait_timeout < 100000000 && wait_time > (double) lock_wait_timeout) { #ifdef WITH_WSREP - if (!wsrep_on(trx->mysql_thd) || + if (!wsrep_on_trx(trx) || (!wsrep_is_BF_lock_timeout(trx) && trx->error_state != DB_DEADLOCK)) { #endif /* WITH_WSREP */ diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 85a4b0bdf19..ba874ac6dec 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1983,7 +1983,7 @@ row_upd_sec_index_entry( } #ifdef WITH_WSREP if (err == DB_SUCCESS && !referenced && - wsrep_on(trx->mysql_thd) && + wsrep_on_trx(trx) && !wsrep_thd_is_BF(trx->mysql_thd, FALSE) && !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE && @@ -2270,7 +2270,7 @@ err_exit: } } #ifdef WITH_WSREP - if (!referenced && wsrep_on(trx->mysql_thd) && + if (!referenced && wsrep_on_trx(trx) && !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE && ((upd_node_t*)parent)->cascade_node == node) && foreign @@ -2536,8 +2536,7 @@ row_upd_del_mark_clust_rec( } #ifdef WITH_WSREP trx_t* trx = thr_get_trx(thr) ; - - if (err == DB_SUCCESS && !referenced && trx && wsrep_on(trx->mysql_thd) && + if (err == DB_SUCCESS && !referenced && wsrep_on_trx(trx) && !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE && ((upd_node_t*)parent)->cascade_node == node) && foreign diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 3517eee0380..8763fab5a85 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -4633,7 +4633,7 @@ innobase_commit_low( trx_commit_for_mysql(trx); } #ifdef WITH_WSREP - if (wsrep_on(thd)) { thd_proc_info(thd, tmp); } + if (thd && wsrep_on(thd)) { thd_proc_info(thd, tmp); } #endif /* WITH_WSREP */ } diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h index 923c463aa22..5f8e7b1c878 100644 --- a/storage/xtradb/include/lock0lock.h +++ b/storage/xtradb/include/lock0lock.h @@ -1028,6 +1028,14 @@ Get lock mode and table/index name std::string lock_get_info( const lock_t*); +#ifdef WITH_WSREP + +/*******************************************************************//** +@return whether wsrep_on is true on trx->mysql_thd*/ +bool +wsrep_on_trx(const trx_t* trx); + +#endif /* WITH_WSREP */ #ifndef UNIV_NONINL #include "lock0lock.ic" diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 40ab9d9403c..40511b60f49 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -1835,7 +1835,7 @@ lock_rec_other_has_conflicting( #ifdef WITH_WSREP if (lock_rec_has_to_wait(TRUE, trx, mode, lock, is_supremum)) { - if (wsrep_on(trx->mysql_thd)) { + if (wsrep_on_trx(trx)) { trx_mutex_enter(lock->trx); wsrep_kill_victim(trx, lock); trx_mutex_exit(lock->trx); @@ -2290,7 +2290,7 @@ lock_rec_create( #ifdef WITH_WSREP if (c_lock && - wsrep_on(trx->mysql_thd) && + wsrep_on_trx(trx) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { lock_t *hash = (lock_t *)c_lock->hash; lock_t *prev = NULL; @@ -8336,3 +8336,11 @@ lock_get_info( return info; } + +#ifdef WITH_WSREP +bool inline +wsrep_on_trx(const trx_t* trx) +{ + return trx->mysql_thd && wsrep_on(trx->mysql_thd); +} +#endif /* WITH_WSREP */ diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc index a447027e336..ca9d05a4829 100644 --- a/storage/xtradb/lock/lock0wait.cc +++ b/storage/xtradb/lock/lock0wait.cc @@ -197,7 +197,7 @@ wsrep_is_BF_lock_timeout( /*====================*/ trx_t* trx) /* in: trx to check for lock priority */ { - if (wsrep_on(trx->mysql_thd) && + if (wsrep_on_trx(trx) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { fprintf(stderr, "WSREP: BF lock wait long\n"); srv_print_innodb_monitor = TRUE; @@ -402,7 +402,7 @@ lock_wait_suspend_thread( if (lock_wait_timeout < 100000000 && wait_time > (double) lock_wait_timeout) { #ifdef WITH_WSREP - if (!wsrep_on(trx->mysql_thd) || + if (!wsrep_on_trx(trx) || (!wsrep_is_BF_lock_timeout(trx) && trx->error_state != DB_DEADLOCK)) { #endif /* WITH_WSREP */ diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc index 91dbc5252bc..91f7fb30e81 100644 --- a/storage/xtradb/row/row0upd.cc +++ b/storage/xtradb/row/row0upd.cc @@ -1989,7 +1989,7 @@ row_upd_sec_index_entry( } #ifdef WITH_WSREP if (err == DB_SUCCESS && !referenced && - wsrep_on(trx->mysql_thd) && + wsrep_on_trx(trx) && !wsrep_thd_is_BF(trx->mysql_thd, FALSE) && !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE && @@ -2279,7 +2279,7 @@ err_exit: } } #ifdef WITH_WSREP - if (!referenced && wsrep_on(trx->mysql_thd) && + if (!referenced && wsrep_on_trx(trx) && !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE && ((upd_node_t*)parent)->cascade_node == node) && foreign @@ -2548,8 +2548,7 @@ row_upd_del_mark_clust_rec( } #ifdef WITH_WSREP trx_t* trx = thr_get_trx(thr) ; - - if (err == DB_SUCCESS && !referenced && trx && wsrep_on(trx->mysql_thd) && + if (err == DB_SUCCESS && !referenced && wsrep_on_trx(trx) && !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE && ((upd_node_t*)parent)->cascade_node == node) && foreign From 7dc1815d5c5cd14f8a49ae47e9b22a849c43ad74 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 26 Sep 2017 18:36:19 +0200 Subject: [PATCH 04/11] cleanup: reduce code duplication remove copy-pasted code, fix meaningless comparison. followup for ea2162b6aae --- storage/maria/ma_create.c | 57 ++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c index ba4a70a4c51..f3af97014f0 100644 --- a/storage/maria/ma_create.c +++ b/storage/maria/ma_create.c @@ -33,6 +33,27 @@ static int compare_columns(MARIA_COLUMNDEF **a, MARIA_COLUMNDEF **b); + +static ulonglong update_tot_length(ulonglong tot_length, ulonglong max_rows, uint length) +{ + ulonglong tot_length_part; + + if (tot_length == ULONGLONG_MAX) + return ULONGLONG_MAX; + + tot_length_part= (max_rows/(ulong) ((maria_block_size - + MAX_KEYPAGE_HEADER_SIZE - KEYPAGE_CHECKSUM_SIZE)/ + (length*2))); + if (tot_length_part >= ULONGLONG_MAX / maria_block_size) + return ULONGLONG_MAX; + + if (tot_length > ULONGLONG_MAX - tot_length_part * maria_block_size) + return ULONGLONG_MAX; + + return tot_length + tot_length_part * maria_block_size; +} + + /* Old options is used when recreating database, from maria_chk */ @@ -661,23 +682,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, if (length > max_key_length) max_key_length= length; - if (tot_length == ULLONG_MAX) - continue; - - ulonglong tot_length_part= (max_rows/(ulong) (((uint) maria_block_size - - MAX_KEYPAGE_HEADER_SIZE - - KEYPAGE_CHECKSUM_SIZE)/ - (length*2))); - if (tot_length_part >= (ULLONG_MAX / maria_block_size + - ULLONG_MAX % maria_block_size)) - tot_length= ULLONG_MAX; - else - { - if (tot_length > ULLONG_MAX - tot_length_part * maria_block_size) - tot_length= ULLONG_MAX; - else - tot_length+= tot_length_part * maria_block_size; - } + tot_length= update_tot_length(tot_length, max_rows, length); } unique_key_parts=0; @@ -687,23 +692,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, unique_key_parts+=uniquedef->keysegs; share.state.key_root[keys+i]= HA_OFFSET_ERROR; - if (tot_length == ULLONG_MAX) - continue; - ulonglong tot_length_part= (max_rows/(ulong) (((uint) maria_block_size - - MAX_KEYPAGE_HEADER_SIZE - - KEYPAGE_CHECKSUM_SIZE) / - ((MARIA_UNIQUE_HASH_LENGTH + pointer)*2))); - - if (tot_length_part >= (ULLONG_MAX / maria_block_size + - ULLONG_MAX % maria_block_size)) - tot_length= ULLONG_MAX; - else - { - if (tot_length > ULLONG_MAX - tot_length_part * maria_block_size) - tot_length= ULLONG_MAX; - else - tot_length+= tot_length_part * maria_block_size; - } + tot_length= update_tot_length(tot_length, max_rows, MARIA_UNIQUE_HASH_LENGTH + pointer); } keys+=uniques; /* Each unique has 1 key */ key_segs+=uniques; /* Each unique has 1 key seg */ From f7628ca3c203ea7642a3abe14bd205012f8d4ec5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 27 Sep 2017 10:22:00 +0200 Subject: [PATCH 05/11] cleanup: remove useless "inline" keywords avoid a function call for a commonly used one-liner. followup for 0627929f626 --- sql/wsrep_mysqld.cc | 2 +- storage/innobase/include/lock0lock.h | 3 +-- storage/innobase/lock/lock0lock.cc | 8 -------- storage/xtradb/include/lock0lock.h | 8 +------- storage/xtradb/lock/lock0lock.cc | 8 -------- 5 files changed, 3 insertions(+), 26 deletions(-) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 061f877da6e..33689a91661 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2293,7 +2293,7 @@ static int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len) } -extern inline int wsrep_on(THD *thd) +extern int wsrep_on(THD *thd) { return (int)(WSREP(thd)); } diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 62bbd572068..b4259cd4851 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -1026,8 +1026,7 @@ lock_get_info( /*******************************************************************//** @return whether wsrep_on is true on trx->mysql_thd*/ -bool -wsrep_on_trx(const trx_t* trx); +#define wsrep_on_trx(trx) ((trx)->mysql_thd && wsrep_on((trx)->mysql_thd)) #endif /* WITH_WSREP */ #ifndef UNIV_NONINL diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index cedf08322b7..fb6caf2691e 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -8213,11 +8213,3 @@ lock_get_info( return info; } - -#ifdef WITH_WSREP -bool inline -wsrep_on_trx(const trx_t* trx) -{ - return trx->mysql_thd && wsrep_on(trx->mysql_thd); -} -#endif /* WITH_WSREP */ diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h index 5f8e7b1c878..5aff67db0ee 100644 --- a/storage/xtradb/include/lock0lock.h +++ b/storage/xtradb/include/lock0lock.h @@ -1028,14 +1028,8 @@ Get lock mode and table/index name std::string lock_get_info( const lock_t*); -#ifdef WITH_WSREP -/*******************************************************************//** -@return whether wsrep_on is true on trx->mysql_thd*/ -bool -wsrep_on_trx(const trx_t* trx); - -#endif /* WITH_WSREP */ +#define wsrep_on_trx(trx) ((trx)->mysql_thd && wsrep_on((trx)->mysql_thd)) #ifndef UNIV_NONINL #include "lock0lock.ic" diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 40511b60f49..ce51effbab0 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -8336,11 +8336,3 @@ lock_get_info( return info; } - -#ifdef WITH_WSREP -bool inline -wsrep_on_trx(const trx_t* trx) -{ - return trx->mysql_thd && wsrep_on(trx->mysql_thd); -} -#endif /* WITH_WSREP */ From 5b01b88e2ba6a51a5e9112badb45210e3b2e3dc4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 26 Sep 2017 20:16:06 +0200 Subject: [PATCH 06/11] update test results on 32-bit --- mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff index 8638fd00be6..5c7e310ce08 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff @@ -1222,7 +1222,7 @@ VARIABLE_NAME INNODB_VERSION SESSION_VALUE NULL -GLOBAL_VALUE 5.6.37 -+GLOBAL_VALUE 5.6.36-82.1 ++GLOBAL_VALUE 5.6.36-82.2 GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE NULL VARIABLE_SCOPE GLOBAL From f0e9bebd278b27e05d9c66746420b48535f2b86e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 26 Sep 2017 16:43:54 +0200 Subject: [PATCH 07/11] MDEV-13897 SELECT @a := MAX(col) FROM t requires full index scan fix some old bad merge --- mysql-test/r/join_cache.result | 2 +- mysql-test/r/user_var.result | 16 +++++++++------- mysql-test/r/variables.result | 4 ++-- mysql-test/t/user_var.test | 10 +++++++--- sql/item_func.h | 6 ------ 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index a5a24455d9b..7a11cb95715 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5880,7 +5880,7 @@ where c1 = c2-0 and c2 <= (select max(c3) from t3 where c3 = 2 and @counter:=@co id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -2 UNCACHEABLE SUBQUERY t3 system NULL NULL NULL NULL 1 +2 UNCACHEABLE SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE set @counter=0; select count(*) from t1 straight_join t2 where c1 = c2-0 and c2 <= (select max(c3) from t3 where c3 = 2 and @counter:=@counter+1); diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 178f9fb7db4..ec19f922b05 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2; set @a := foo; ERROR 42S22: Unknown column 'foo' in 'field list' set @a := connection_id() + 3; @@ -126,14 +125,14 @@ select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i; set @a=0; select @a,@a:="hello",@a,@a:=3,@a,@a:="hello again" from t1 group by i; @a @a:="hello" @a @a:=3 @a @a:="hello again" -0 hello 0 3 3 hello again -0 hello 0 3 3 hello again -0 hello 0 3 3 hello again +0 hello 0 3 0 hello again +0 hello 0 3 0 hello again +0 hello 0 3 0 hello again select @a,@a:="hello",@a,@a:=3,@a,@a:="hello again" from t1 group by i; @a @a:="hello" @a @a:=3 @a @a:="hello again" -hello again hello hello 3 3 hello again -hello again hello hello 3 3 hello again -hello again hello hello 3 3 hello again +hello again hello hello again 3 hello again hello again +hello again hello hello again 3 hello again hello again +hello again hello hello again 3 hello again hello again drop table t1; set @a=_latin2'test'; select charset(@a),collation(@a),coercibility(@a); @@ -570,3 +569,6 @@ End of 5.5 tests # set @var= repeat('a',20000); 1 +explain select @a:=max(seq) from seq_1_to_1000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index fef3e4a3e9e..b621fc13ee4 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1544,7 +1544,7 @@ one 1 explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0); one @@ -1555,7 +1555,7 @@ one set sql_buffer_result=1; explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary 2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0); one diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 2c889c2cc0c..1e9b6a7bb14 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -1,7 +1,5 @@ # Initialise ---disable_warnings -drop table if exists t1,t2; ---enable_warnings +source include/have_sequence.inc; --error 1054 set @a := foo; @@ -501,3 +499,9 @@ eval select $tmp < $tmp2; --enable_column_names --enable_query_log +# +# MDEV-13897 SELECT @a := MAX(col) FROM t requires full index scan +# +explain select @a:=max(seq) from seq_1_to_1000000; + +# End of 10.1 tests diff --git a/sql/item_func.h b/sql/item_func.h index 38d5d0aa873..ec8ec6fca74 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1773,12 +1773,6 @@ public: create_tmp_field(false, table, MY_INT32_NUM_DECIMAL_DIGITS) : tmp_table_field_from_field_type(table, false, true); } - table_map used_tables() const - { - return used_tables_cache | RAND_TABLE_BIT; - } - bool const_item() const { return 0; } - bool is_expensive() { return 1; } virtual void print(String *str, enum_query_type query_type); void print_as_stmt(String *str, enum_query_type query_type); const char *func_name() const { return "set_user_var"; } From 4aeec7275f8bb72d716a76ece5c5edbcf8c0966b Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Wed, 27 Sep 2017 18:27:39 -0400 Subject: [PATCH 08/11] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3d1d889a5c1..dce8bbe23fc 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=1 -MYSQL_VERSION_PATCH=28 +MYSQL_VERSION_PATCH=29 From 4d01dd79a102599d2e996e5acf77ea9c54f8c644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 28 Sep 2017 12:38:51 +0300 Subject: [PATCH 09/11] MDEV-12634: Uninitialised ROW_MERGE_RESERVE_SIZE bytes written to temporary file After review cleanup. --- storage/innobase/log/log0crypt.cc | 2 +- storage/innobase/row/row0log.cc | 29 +++++++++++++---------------- storage/innobase/row/row0merge.cc | 19 +++---------------- storage/xtradb/log/log0crypt.cc | 2 +- storage/xtradb/row/row0log.cc | 29 +++++++++++++---------------- storage/xtradb/row/row0merge.cc | 19 +++---------------- 6 files changed, 34 insertions(+), 66 deletions(-) diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc index fe1b41202ea..13d69118779 100644 --- a/storage/innobase/log/log0crypt.cc +++ b/storage/innobase/log/log0crypt.cc @@ -246,7 +246,7 @@ next: ENCRYPTION_FLAG_DECRYPT @param[in] offs offset to block @param[in] space_id tablespace id -@return true if successfull, false in case of failure +@return true if successful, false in case of failure */ static bool diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index ec6b4a60680..9107ad6236c 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -182,7 +182,6 @@ struct row_log_t { dict_table_t* table; /*!< table that is being rebuilt, or NULL when this is a secondary index that is being created online */ - dict_index_t* index; /*!< index to be build */ bool same_pk;/*!< whether the definition of the PRIMARY KEY has remained the same */ const dtuple_t* add_cols; @@ -385,7 +384,7 @@ row_log_online_op( byte_offset, index->table->space)) { log->error = DB_DECRYPTION_FAILED; - goto err_exit; + goto write_failed; } srv_stats.n_rowlog_blocks_encrypted.inc(); @@ -479,13 +478,15 @@ static MY_ATTRIBUTE((nonnull)) void row_log_table_close_func( /*=====================*/ - row_log_t* log, /*!< in/out: online rebuild log */ + dict_index_t* index, /*!< in/out: online rebuilt index */ #ifdef UNIV_DEBUG const byte* b, /*!< in: end of log record */ #endif /* UNIV_DEBUG */ ulint size, /*!< in: size of log record */ ulint avail) /*!< in: available size for log record */ { + row_log_t* log = index->online_log; + ut_ad(mutex_own(&log->mutex)); if (size >= avail) { @@ -520,7 +521,7 @@ row_log_table_close_func( srv_sort_buf_size, log->crypt_tail, byte_offset, - log->index->table->space)) { + index->table->space)) { log->error = DB_DECRYPTION_FAILED; goto err_exit; } @@ -559,11 +560,11 @@ err_exit: } #ifdef UNIV_DEBUG -# define row_log_table_close(log, b, size, avail) \ - row_log_table_close_func(log, b, size, avail) +# define row_log_table_close(index, b, size, avail) \ + row_log_table_close_func(index, b, size, avail) #else /* UNIV_DEBUG */ # define row_log_table_close(log, b, size, avail) \ - row_log_table_close_func(log, size, avail) + row_log_table_close_func(index, size, avail) #endif /* UNIV_DEBUG */ /******************************************************//** @@ -735,8 +736,7 @@ row_log_table_delete( b += ext_size; } - row_log_table_close( - index->online_log, b, mrec_size, avail_size); + row_log_table_close(index, b, mrec_size, avail_size); } func_exit: @@ -859,8 +859,7 @@ row_log_table_low_redundant( b + extra_size, index, tuple->fields, tuple->n_fields); b += size; - row_log_table_close( - index->online_log, b, mrec_size, avail_size); + row_log_table_close(index, b, mrec_size, avail_size); } mem_heap_free(heap); @@ -969,8 +968,7 @@ row_log_table_low( memcpy(b, rec, rec_offs_data_size(offsets)); b += rec_offs_data_size(offsets); - row_log_table_close( - index->online_log, b, mrec_size, avail_size); + row_log_table_close(index, b, mrec_size, avail_size); } } @@ -2678,7 +2676,7 @@ all_done: /* If encryption is enabled decrypt buffer after reading it from file system. */ - if (log_tmp_is_encrypted()) { + if (success && log_tmp_is_encrypted()) { if (!log_tmp_block_decrypt(buf, srv_sort_buf_size, index->online_log->crypt_head, @@ -2999,7 +2997,6 @@ row_log_allocate( log->head.total = 0; log->path = path; log->crypt_tail = log->crypt_head = NULL; - log->index = index; dict_index_set_online_status(index, ONLINE_INDEX_CREATION); index->online_log = log; @@ -3548,7 +3545,7 @@ all_done: /* If encryption is enabled decrypt buffer after reading it from file system. */ - if (log_tmp_is_encrypted()) { + if (success && log_tmp_is_encrypted()) { if (!log_tmp_block_decrypt(buf, srv_sort_buf_size, index->online_log->crypt_head, diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 62dc98a3e30..27fc5c6ff63 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -880,8 +880,8 @@ row_merge_read( success = os_file_read_no_error_handling_int_fd(fd, buf, ofs, srv_sort_buf_size); - /* For encrypted tables, decrypt data after reading and copy data */ - if (log_tmp_is_encrypted()) { + /* If encryption is enabled decrypt buffer */ + if (success && log_tmp_is_encrypted()) { if (!log_tmp_block_decrypt(buf, srv_sort_buf_size, crypt_buf, ofs, space)) { return (FALSE); @@ -3915,22 +3915,13 @@ row_merge_build_indexes( DBUG_RETURN(DB_OUT_OF_MEMORY); } - /* Get crypt data from tablespace if present. We should be protected - from concurrent DDL (e.g. drop table) by MDL-locks. */ - fil_space_t* space = fil_space_acquire(new_table->space); - - if (!space) { - DBUG_RETURN(DB_TABLESPACE_NOT_FOUND); - } - - /* If tablespace is encrypted, allocate additional buffer for + /* If temporal log file is encrypted allocate memory for encryption/decryption. */ if (log_tmp_is_encrypted()) { crypt_block = static_cast( os_mem_alloc_large(&block_size)); if (crypt_block == NULL) { - fil_space_release(space); DBUG_RETURN(DB_OUT_OF_MEMORY); } } @@ -4310,9 +4301,5 @@ func_exit: } } - if (space) { - fil_space_release(space); - } - DBUG_RETURN(error); } diff --git a/storage/xtradb/log/log0crypt.cc b/storage/xtradb/log/log0crypt.cc index 9509797dde3..a5fbbab17ef 100644 --- a/storage/xtradb/log/log0crypt.cc +++ b/storage/xtradb/log/log0crypt.cc @@ -245,7 +245,7 @@ next: ENCRYPTION_FLAG_DECRYPT @param[in] offs offset to block @param[in] space_id tablespace id -@return true if successfull, false in case of failure +@return true if successful, false in case of failure */ static bool diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc index f49ff2f1530..e15a4f4f5d8 100644 --- a/storage/xtradb/row/row0log.cc +++ b/storage/xtradb/row/row0log.cc @@ -182,7 +182,6 @@ struct row_log_t { dict_table_t* table; /*!< table that is being rebuilt, or NULL when this is a secondary index that is being created online */ - dict_index_t* index; /*!< index to be build */ bool same_pk;/*!< whether the definition of the PRIMARY KEY has remained the same */ const dtuple_t* add_cols; @@ -385,7 +384,7 @@ row_log_online_op( byte_offset, index->table->space)) { log->error = DB_DECRYPTION_FAILED; - goto err_exit; + goto write_failed; } srv_stats.n_rowlog_blocks_encrypted.inc(); @@ -479,13 +478,15 @@ static MY_ATTRIBUTE((nonnull)) void row_log_table_close_func( /*=====================*/ - row_log_t* log, /*!< in/out: online rebuild log */ + dict_index_t* index, /*!< in/out: online rebuilt index */ #ifdef UNIV_DEBUG const byte* b, /*!< in: end of log record */ #endif /* UNIV_DEBUG */ ulint size, /*!< in: size of log record */ ulint avail) /*!< in: available size for log record */ { + row_log_t* log = index->online_log; + ut_ad(mutex_own(&log->mutex)); if (size >= avail) { @@ -520,7 +521,7 @@ row_log_table_close_func( srv_sort_buf_size, log->crypt_tail, byte_offset, - log->index->table->space)) { + index->table->space)) { log->error = DB_DECRYPTION_FAILED; goto err_exit; } @@ -559,11 +560,11 @@ err_exit: } #ifdef UNIV_DEBUG -# define row_log_table_close(log, b, size, avail) \ - row_log_table_close_func(log, b, size, avail) +# define row_log_table_close(index, b, size, avail) \ + row_log_table_close_func(index, b, size, avail) #else /* UNIV_DEBUG */ # define row_log_table_close(log, b, size, avail) \ - row_log_table_close_func(log, size, avail) + row_log_table_close_func(index, size, avail) #endif /* UNIV_DEBUG */ /******************************************************//** @@ -735,8 +736,7 @@ row_log_table_delete( b += ext_size; } - row_log_table_close( - index->online_log, b, mrec_size, avail_size); + row_log_table_close(index, b, mrec_size, avail_size); } func_exit: @@ -859,8 +859,7 @@ row_log_table_low_redundant( b + extra_size, index, tuple->fields, tuple->n_fields); b += size; - row_log_table_close( - index->online_log, b, mrec_size, avail_size); + row_log_table_close(index, b, mrec_size, avail_size); } mem_heap_free(heap); @@ -969,8 +968,7 @@ row_log_table_low( memcpy(b, rec, rec_offs_data_size(offsets)); b += rec_offs_data_size(offsets); - row_log_table_close( - index->online_log, b, mrec_size, avail_size); + row_log_table_close(index, b, mrec_size, avail_size); } } @@ -2675,7 +2673,7 @@ all_done: /* If encryption is enabled decrypt buffer after reading it from file system. */ - if (log_tmp_is_encrypted()) { + if (success && log_tmp_is_encrypted()) { if (!log_tmp_block_decrypt(buf, srv_sort_buf_size, index->online_log->crypt_head, @@ -2996,7 +2994,6 @@ row_log_allocate( log->head.total = 0; log->path = path; log->crypt_tail = log->crypt_head = NULL; - log->index = index; dict_index_set_online_status(index, ONLINE_INDEX_CREATION); index->online_log = log; @@ -3542,7 +3539,7 @@ all_done: /* If encryption is enabled decrypt buffer after reading it from file system. */ - if (log_tmp_is_encrypted()) { + if (success && log_tmp_is_encrypted()) { if (!log_tmp_block_decrypt(buf, srv_sort_buf_size, index->online_log->crypt_head, diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index 5db2ab6c2b7..6e48f21c2dd 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -887,8 +887,8 @@ row_merge_read( success = os_file_read_no_error_handling_int_fd(fd, buf, ofs, srv_sort_buf_size); - /* For encrypted tables, decrypt data after reading and copy data */ - if (log_tmp_is_encrypted()) { + /* If encryption is enabled decrypt buffer */ + if (success && log_tmp_is_encrypted()) { if (!log_tmp_block_decrypt(buf, srv_sort_buf_size, crypt_buf, ofs, space)) { return (FALSE); @@ -3918,22 +3918,13 @@ row_merge_build_indexes( DBUG_RETURN(DB_OUT_OF_MEMORY); } - /* Get crypt data from tablespace if present. We should be protected - from concurrent DDL (e.g. drop table) by MDL-locks. */ - fil_space_t* space = fil_space_acquire(new_table->space); - - if (!space) { - DBUG_RETURN(DB_TABLESPACE_NOT_FOUND); - } - - /* If temporal log file is encrypted allocate memory for + /* If temporary log file is encrypted allocate memory for encryption/decryption. */ if (log_tmp_is_encrypted()) { crypt_block = static_cast( os_mem_alloc_large(&block_size)); if (crypt_block == NULL) { - fil_space_release(space); DBUG_RETURN(DB_OUT_OF_MEMORY); } } @@ -4313,9 +4304,5 @@ func_exit: } } - if (space) { - fil_space_release(space); - } - DBUG_RETURN(error); } From b8488e5cf56cece22ae324a652d7ce8042739971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 29 Sep 2017 14:12:38 +0300 Subject: [PATCH 10/11] MDEV-13932: fil0pagecompress.cc fails to compile with lzo 2.10 Patch contibuted by Gordon Fisher. Thank you for your contribution! --- storage/innobase/fil/fil0pagecompress.cc | 12 ++++++++++-- storage/xtradb/fil/fil0pagecompress.cc | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc index 7a61f17836b..edc932f36f5 100644 --- a/storage/innobase/fil/fil0pagecompress.cc +++ b/storage/innobase/fil/fil0pagecompress.cc @@ -106,6 +106,9 @@ fil_compress_page( int comp_level = level; ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE; ulint write_size = 0; +#if HAVE_LZO + lzo_uint write_size_lzo = write_size; +#endif /* Cache to avoid change during function execution */ ulint comp_method = innodb_compression_algorithm; bool allocated = false; @@ -207,7 +210,9 @@ fil_compress_page( #ifdef HAVE_LZO case PAGE_LZO_ALGORITHM: err = lzo1x_1_15_compress( - buf, len, out_buf+header_len, &write_size, out_buf+UNIV_PAGE_SIZE); + buf, len, out_buf+header_len, &write_size_lzo, out_buf+UNIV_PAGE_SIZE); + + write_size = write_size_lzo; if (err != LZO_E_OK || write_size > UNIV_PAGE_SIZE-header_len) { if (space && !space->printed_compression_failure) { @@ -604,8 +609,11 @@ fil_decompress_page( #ifdef HAVE_LZO case PAGE_LZO_ALGORITHM: { ulint olen = 0; + lzo_uint olen_lzo = olen; err = lzo1x_decompress((const unsigned char *)buf+header_len, - actual_size,(unsigned char *)in_buf, &olen, NULL); + actual_size,(unsigned char *)in_buf, &olen_lzo, NULL); + + olen = olen_lzo; if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) { ib_logf(IB_LOG_LEVEL_ERROR, diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc index 7a61f17836b..edc932f36f5 100644 --- a/storage/xtradb/fil/fil0pagecompress.cc +++ b/storage/xtradb/fil/fil0pagecompress.cc @@ -106,6 +106,9 @@ fil_compress_page( int comp_level = level; ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE; ulint write_size = 0; +#if HAVE_LZO + lzo_uint write_size_lzo = write_size; +#endif /* Cache to avoid change during function execution */ ulint comp_method = innodb_compression_algorithm; bool allocated = false; @@ -207,7 +210,9 @@ fil_compress_page( #ifdef HAVE_LZO case PAGE_LZO_ALGORITHM: err = lzo1x_1_15_compress( - buf, len, out_buf+header_len, &write_size, out_buf+UNIV_PAGE_SIZE); + buf, len, out_buf+header_len, &write_size_lzo, out_buf+UNIV_PAGE_SIZE); + + write_size = write_size_lzo; if (err != LZO_E_OK || write_size > UNIV_PAGE_SIZE-header_len) { if (space && !space->printed_compression_failure) { @@ -604,8 +609,11 @@ fil_decompress_page( #ifdef HAVE_LZO case PAGE_LZO_ALGORITHM: { ulint olen = 0; + lzo_uint olen_lzo = olen; err = lzo1x_decompress((const unsigned char *)buf+header_len, - actual_size,(unsigned char *)in_buf, &olen, NULL); + actual_size,(unsigned char *)in_buf, &olen_lzo, NULL); + + olen = olen_lzo; if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) { ib_logf(IB_LOG_LEVEL_ERROR, From 028d253dd7401fa564bcf817fe81c7034f2512d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 2 Oct 2017 10:22:42 +0300 Subject: [PATCH 11/11] MDEV-13980 InnoDB fails to discard record lock when discarding an index page btr_cur_pessimistic_delete(): Discard a possible record lock also in the case when the record was the only one in the page. Failure to do this would corrupt the record lock data structures in a partial rollback (ROLLBACK TO SAVEPOINT or rolling back a row operation due to some error, such as a duplicate key in a unique secondary index). --- storage/innobase/btr/btr0cur.c | 10 +++++----- storage/xtradb/btr/btr0cur.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 2c1ab4bffae..e8c467409b2 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -2,6 +2,7 @@ Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -3193,7 +3194,6 @@ btr_cur_pessimistic_delete( ulint n_reserved; ibool success; ibool ret = FALSE; - ulint level; mem_heap_t* heap; ulint* offsets; @@ -3240,6 +3240,8 @@ btr_cur_pessimistic_delete( #endif /* UNIV_ZIP_DEBUG */ } + lock_update_delete(block, rec); + if (UNIV_UNLIKELY(page_get_n_recs(page) < 2) && UNIV_UNLIKELY(dict_index_get_page(index) != buf_block_get_page_no(block))) { @@ -3255,10 +3257,7 @@ btr_cur_pessimistic_delete( goto return_after_reservations; } - lock_update_delete(block, rec); - level = btr_page_get_level(page, mtr); - - if (level > 0 + if (!page_is_leaf(page) && UNIV_UNLIKELY(rec == page_rec_get_next( page_get_infimum_rec(page)))) { @@ -3281,6 +3280,7 @@ btr_cur_pessimistic_delete( on a page, we have to change the father node pointer so that it is equal to the new leftmost node pointer on the page */ + ulint level = btr_page_get_level(page, mtr); btr_node_ptr_delete(index, block, mtr); diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c index d9c1a2ef7a8..0d015111d81 100644 --- a/storage/xtradb/btr/btr0cur.c +++ b/storage/xtradb/btr/btr0cur.c @@ -2,6 +2,7 @@ Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -3376,7 +3377,6 @@ btr_cur_pessimistic_delete( ulint n_reserved; ibool success; ibool ret = FALSE; - ulint level; mem_heap_t* heap; ulint* offsets; @@ -3425,6 +3425,8 @@ btr_cur_pessimistic_delete( #endif /* UNIV_ZIP_DEBUG */ } + lock_update_delete(block, rec); + if (UNIV_UNLIKELY(page_get_n_recs(page) < 2) && UNIV_UNLIKELY(dict_index_get_page(index) != buf_block_get_page_no(block))) { @@ -3440,10 +3442,7 @@ btr_cur_pessimistic_delete( goto return_after_reservations; } - lock_update_delete(block, rec); - level = btr_page_get_level(page, mtr); - - if (level > 0 + if (!page_is_leaf(page) && UNIV_UNLIKELY(rec == page_rec_get_next( page_get_infimum_rec(page)))) { @@ -3466,6 +3465,7 @@ btr_cur_pessimistic_delete( on a page, we have to change the father node pointer so that it is equal to the new leftmost node pointer on the page */ + ulint level = btr_page_get_level(page, mtr); btr_node_ptr_delete(index, block, mtr);