summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-11-15 08:59:30 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2022-11-15 08:59:30 +0200
commit3dd4bad4b3c7681eba3b16af888e8e82d772e826 (patch)
tree35a55475bfc7c992c4f455d586e27daff908a2a3
parent8d1c85a6dd8580f23709c21dfd008787315e2c9a (diff)
parentae6ebafd819d48c965d2615fc78f1f950e0fbf40 (diff)
downloadmariadb-git-bb-10.6-MDEV-25948-MDEV-25611.tar.gz
Interesting test failures: ./mtr --parallel=auto --mysqld=--debug-dbug=d,ib_log_checkpoint_avoid \ --max-test-fail=0 --big-test --force \ binlog{,_encryption}.binlog_incident rpl.rpl_skip_incident \ binlog.binlog_killed_simulate rpl.rpl_loaddata_fatal
-rw-r--r--VERSION2
-rw-r--r--client/mysqltest.cc69
-rw-r--r--cmake/abi_check.cmake1
-rwxr-xr-xdebian/autobake-deb.sh39
-rw-r--r--debian/mariadb-server-10.6.mariadb.init15
-rwxr-xr-xdebian/rules21
-rw-r--r--debian/salsa-ci.yml77
-rw-r--r--debian/source/lintian-overrides2
-rw-r--r--debian/tests/upstream24
-rw-r--r--extra/mariabackup/xtrabackup.cc4
-rw-r--r--include/mariadb_capi_rename.h57
-rw-r--r--include/my_alarm.h5
-rw-r--r--include/mysql.h1
-rw-r--r--include/mysql.h.pp797
-rw-r--r--man/mysqld_safe.119
-rw-r--r--mysql-test/include/rowid_filter_debug_kill.inc21
-rw-r--r--mysql-test/main/bad_startup_options.result2
-rw-r--r--mysql-test/main/bad_startup_options.test19
-rw-r--r--mysql-test/main/gis.result9
-rw-r--r--mysql-test/main/gis.test9
-rw-r--r--mysql-test/main/join_cache.result24
-rw-r--r--mysql-test/main/join_nested_jcl6.result2
-rw-r--r--mysql-test/main/long_unique_bugs.result9
-rw-r--r--mysql-test/main/long_unique_bugs.test11
-rw-r--r--mysql-test/main/mysql_upgrade.result4
-rw-r--r--mysql-test/main/order_by_innodb.result32
-rw-r--r--mysql-test/main/order_by_innodb.test37
-rw-r--r--mysql-test/main/partition_alter.result23
-rw-r--r--mysql-test/main/partition_alter.test26
-rw-r--r--mysql-test/main/partition_pruning.result2
-rw-r--r--mysql-test/main/range.result2
-rw-r--r--mysql-test/main/range_innodb.result15
-rw-r--r--mysql-test/main/range_innodb.test22
-rw-r--r--mysql-test/main/rowid_filter.result490
-rw-r--r--mysql-test/main/rowid_filter.test210
-rw-r--r--mysql-test/main/rowid_filter_innodb.result968
-rw-r--r--mysql-test/main/rowid_filter_innodb.test96
-rw-r--r--mysql-test/main/rowid_filter_innodb_debug.result19
-rw-r--r--mysql-test/main/rowid_filter_innodb_debug.test1
-rw-r--r--mysql-test/main/rowid_filter_myisam_debug.result18
-rw-r--r--mysql-test/main/select.result10
-rw-r--r--mysql-test/main/select_jcl6.result10
-rw-r--r--mysql-test/main/select_pkeycache.result10
-rw-r--r--mysql-test/main/selectivity.result18
-rw-r--r--mysql-test/main/selectivity.test6
-rw-r--r--mysql-test/main/selectivity_innodb.result18
-rw-r--r--mysql-test/main/subselect.result11
-rw-r--r--mysql-test/main/subselect.test14
-rw-r--r--mysql-test/main/subselect_no_exists_to_in.result11
-rw-r--r--mysql-test/main/subselect_no_mat.result11
-rw-r--r--mysql-test/main/subselect_no_opts.result11
-rw-r--r--mysql-test/main/subselect_no_scache.result11
-rw-r--r--mysql-test/main/subselect_no_semijoin.result11
-rw-r--r--mysql-test/main/type_time_hires.result13
-rw-r--r--mysql-test/main/type_time_hires.test15
-rw-r--r--mysql-test/std_data/mysql_upgrade/mdev28822_100427_innodb.frmbin0 -> 1443 bytes
-rw-r--r--mysql-test/suite/binlog/r/binlog_empty_xa_prepared.result109
-rw-r--r--mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_binary.result1
-rw-r--r--mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_ucs2.result1
-rw-r--r--mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_utf32.result1
-rw-r--r--mysql-test/suite/binlog/t/binlog_empty_xa_prepared.test54
-rw-r--r--mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_binary.test1
-rw-r--r--mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_ucs2.test1
-rw-r--r--mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_utf32.test1
-rw-r--r--mysql-test/suite/encryption/r/innochecksum,debug.rdiff10
-rw-r--r--mysql-test/suite/encryption/t/innochecksum.test14
-rw-r--r--mysql-test/suite/federated/federatedx_create_handlers.result94
-rw-r--r--mysql-test/suite/federated/federatedx_create_handlers.test105
-rw-r--r--mysql-test/suite/galera/disabled.def4
-rw-r--r--mysql-test/suite/galera/r/galera_many_rows.result14
-rw-r--r--mysql-test/suite/galera/t/galera_many_rows.test6
-rw-r--r--mysql-test/suite/innodb/r/innodb-fkcheck.result8
-rw-r--r--mysql-test/suite/innodb/r/innodb.result12
-rw-r--r--mysql-test/suite/innodb/r/insert_into_empty.result28
-rw-r--r--mysql-test/suite/innodb/r/insert_into_empty_notembedded.result30
-rw-r--r--mysql-test/suite/innodb/r/instant_alter.result11
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_crash.result16
-rw-r--r--mysql-test/suite/innodb/r/temporary_table.result12
-rw-r--r--mysql-test/suite/innodb/r/truncate_foreign.result10
-rw-r--r--mysql-test/suite/innodb/t/alter_dml_apply.test1
-rw-r--r--mysql-test/suite/innodb/t/import_corrupted.test1
-rw-r--r--mysql-test/suite/innodb/t/innodb-fkcheck.test13
-rw-r--r--mysql-test/suite/innodb/t/innodb.test12
-rw-r--r--mysql-test/suite/innodb/t/innodb_scrub.test1
-rw-r--r--mysql-test/suite/innodb/t/insert_into_empty.test31
-rw-r--r--mysql-test/suite/innodb/t/insert_into_empty_notembedded.test43
-rw-r--r--mysql-test/suite/innodb/t/instant_alter.test18
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_crash.test19
-rw-r--r--mysql-test/suite/innodb/t/temporary_table.test11
-rw-r--r--mysql-test/suite/innodb/t/truncate_foreign.test11
-rw-r--r--mysql-test/suite/innodb_fts/r/misc_debug.result1
-rw-r--r--mysql-test/suite/innodb_fts/t/misc_debug.test1
-rw-r--r--mysql-test/suite/innodb_gis/r/alter_spatial_index.result10
-rw-r--r--mysql-test/suite/innodb_gis/t/alter_spatial_index.test12
-rw-r--r--mysql-test/suite/innodb_zip/disabled.def1
-rw-r--r--mysql-test/suite/maria/rollback.result1
-rw-r--r--mysql-test/suite/maria/rollback.test2
-rw-r--r--mysql-test/suite/mariabackup/big_innodb_log.test1
-rw-r--r--mysql-test/suite/mariabackup/defer_space.result3
-rw-r--r--mysql-test/suite/mariabackup/defer_space.test19
-rw-r--r--mysql-test/suite/mariabackup/full_backup.opt1
-rw-r--r--mysql-test/suite/mariabackup/full_backup.result15
-rw-r--r--mysql-test/suite/mariabackup/full_backup.test24
-rw-r--r--mysql-test/suite/mariabackup/innodb_redo_log_overwrite.test1
-rw-r--r--mysql-test/suite/mariabackup/innodb_redo_overwrite.test1
-rw-r--r--mysql-test/suite/mariabackup/mdev-14447.combinations5
-rw-r--r--mysql-test/suite/plugins/t/false_dupes-6543.test1
-rw-r--r--mysql-test/suite/rpl/include/rpl_xa_empty_transaction.inc10
-rw-r--r--mysql-test/suite/rpl/include/rpl_xa_empty_transaction_test_case.inc131
-rw-r--r--mysql-test/suite/rpl/r/rpl_xa_empty_transaction.result1169
-rw-r--r--mysql-test/suite/rpl/t/rpl_xa_empty_transaction.cnf18
-rw-r--r--mysql-test/suite/rpl/t/rpl_xa_empty_transaction.test175
-rw-r--r--mysys/my_addr_resolve.c12
-rw-r--r--mysys/my_gethwaddr.c12
-rw-r--r--sql/derived_handler.cc5
-rw-r--r--sql/field.cc2
-rw-r--r--sql/field.h27
-rw-r--r--sql/ha_partition.cc29
-rw-r--r--sql/ha_partition.h12
-rw-r--r--sql/handler.cc9
-rw-r--r--sql/handler.h14
-rw-r--r--sql/item_geofunc.cc42
-rw-r--r--sql/log.cc54
-rw-r--r--sql/mysqld.cc11
-rw-r--r--sql/rowid_filter.h11
-rw-r--r--sql/spatial.cc41
-rw-r--r--sql/spatial.h2
-rw-r--r--sql/sql_analyze_stmt.h7
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_derived.cc5
-rw-r--r--sql/sql_explain.cc1
-rw-r--r--sql/sql_insert.cc10
-rw-r--r--sql/sql_select.cc94
-rw-r--r--sql/sql_select.h3
-rw-r--r--sql/sql_table.cc14
-rw-r--r--sql/sql_type_geom.h8
m---------storage/columnstore/columnstore0
-rw-r--r--storage/connect/bsonudf.cpp8
-rw-r--r--storage/connect/filamdbf.cpp2
-rw-r--r--storage/connect/mysql-test/connect/r/odbc_postgresql.result9
-rw-r--r--storage/connect/mysql-test/connect/t/odbc_postgresql.test9
-rw-r--r--storage/connect/odbconn.cpp2
-rw-r--r--storage/connect/tabext.cpp4
-rw-r--r--storage/federatedx/CMakeLists.txt3
-rw-r--r--storage/federatedx/federatedx_io_mysql.cc1
-rw-r--r--storage/federatedx/federatedx_pushdown.cc87
-rw-r--r--storage/federatedx/ha_federatedx.cc3
-rw-r--r--storage/federatedx/ha_federatedx.h1
-rw-r--r--storage/innobase/CMakeLists.txt3
-rw-r--r--storage/innobase/btr/btr0bulk.cc7
-rw-r--r--storage/innobase/btr/btr0cur.cc3
-rw-r--r--storage/innobase/buf/buf0buf.cc4
-rw-r--r--storage/innobase/buf/buf0flu.cc5
-rw-r--r--storage/innobase/dict/dict0dict.cc24
-rw-r--r--storage/innobase/dict/drop.cc3
-rw-r--r--storage/innobase/fts/fts0fts.cc7
-rw-r--r--storage/innobase/handler/ha_innodb.cc726
-rw-r--r--storage/innobase/handler/ha_innodb.h44
-rw-r--r--storage/innobase/handler/handler0alter.cc5
-rw-r--r--storage/innobase/handler/i_s.cc4
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc135
-rw-r--r--storage/innobase/include/dict0dict.h25
-rw-r--r--storage/innobase/include/dict0load.h2
-rw-r--r--storage/innobase/include/ibuf0ibuf.h57
-rw-r--r--storage/innobase/include/ibuf0ibuf.inl31
-rw-r--r--storage/innobase/include/ibuf0types.h31
-rw-r--r--storage/innobase/include/log0log.h7
-rw-r--r--storage/innobase/include/mtr0mtr.h4
-rw-r--r--storage/innobase/include/page0page.h22
-rw-r--r--storage/innobase/include/page0page.inl34
-rw-r--r--storage/innobase/include/trx0trx.h10
-rw-r--r--storage/innobase/lock/lock0lock.cc3
-rw-r--r--storage/innobase/log/log0log.cc27
-rw-r--r--storage/innobase/log/log0recv.cc64
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc48
-rw-r--r--storage/innobase/plugin_exports14
-rw-r--r--storage/innobase/que/que0que.cc75
-rw-r--r--storage/innobase/row/row0merge.cc165
-rw-r--r--storage/innobase/row/row0sel.cc19
-rw-r--r--storage/innobase/srv/srv0srv.cc73
-rw-r--r--storage/rocksdb/CMakeLists.txt4
-rw-r--r--storage/rocksdb/ha_rocksdb.cc10
-rw-r--r--storage/sphinx/CMakeLists.txt2
-rw-r--r--vio/viosslfactories.c11
184 files changed, 5552 insertions, 2404 deletions
diff --git a/VERSION b/VERSION
index 084adac9be3..0acffd643c8 100644
--- a/VERSION
+++ b/VERSION
@@ -1,4 +1,4 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=6
-MYSQL_VERSION_PATCH=11
+MYSQL_VERSION_PATCH=12
SERVER_MATURITY=stable
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 2c609bd9815..545e435e5cc 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1748,7 +1748,8 @@ int cat_file(DYNAMIC_STRING* ds, const char* filename)
len= (size_t) my_seek(fd, 0, SEEK_END, MYF(0));
my_seek(fd, 0, SEEK_SET, MYF(0));
if (len == (size_t)MY_FILEPOS_ERROR ||
- !(buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, len + 1, MYF(0))))
+ !(buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, len + 1,
+ MYF(MY_WME|MY_FAE))))
{
my_close(fd, MYF(0));
return 1;
@@ -2407,7 +2408,7 @@ VAR *var_init(VAR *v, const char *name, size_t name_len, const char *val, size_t
val_len= 0;
val_alloc_len = val_len + 16; /* room to grow */
if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(*tmp_var)
- + name_len+2, MYF(MY_WME))))
+ + name_len+2, MYF(MY_WME|MY_FAE))))
die("Out of memory");
if (name != NULL)
@@ -2421,7 +2422,8 @@ VAR *var_init(VAR *v, const char *name, size_t name_len, const char *val, size_t
tmp_var->alloced = (v == 0);
- if (!(tmp_var->str_val = (char*)my_malloc(PSI_NOT_INSTRUMENTED, val_alloc_len+1, MYF(MY_WME))))
+ if (!(tmp_var->str_val = (char*)my_malloc(PSI_NOT_INSTRUMENTED,
+ val_alloc_len+1, MYF(MY_WME|MY_FAE))))
die("Out of memory");
if (val)
@@ -2969,8 +2971,10 @@ void var_copy(VAR *dest, VAR *src)
/* Alloc/realloc data for str_val in dest */
if (dest->alloced_len < src->alloced_len &&
!(dest->str_val= dest->str_val
- ? (char*)my_realloc(PSI_NOT_INSTRUMENTED, dest->str_val, src->alloced_len, MYF(MY_WME))
- : (char*)my_malloc(PSI_NOT_INSTRUMENTED, src->alloced_len, MYF(MY_WME))))
+ ? (char*)my_realloc(PSI_NOT_INSTRUMENTED, dest->str_val, src->alloced_len,
+ MYF(MY_WME|MY_FAE))
+ : (char*)my_malloc(PSI_NOT_INSTRUMENTED, src->alloced_len,
+ MYF(MY_WME|MY_FAE))))
die("Out of memory");
else
dest->alloced_len= src->alloced_len;
@@ -3047,8 +3051,10 @@ void eval_expr(VAR *v, const char *p, const char **p_end,
MIN_VAR_ALLOC : new_val_len + 1;
if (!(v->str_val =
v->str_val ?
- (char*)my_realloc(PSI_NOT_INSTRUMENTED, v->str_val, v->alloced_len+1, MYF(MY_WME)) :
- (char*)my_malloc(PSI_NOT_INSTRUMENTED, v->alloced_len+1, MYF(MY_WME))))
+ (char*)my_realloc(PSI_NOT_INSTRUMENTED, v->str_val, v->alloced_len+1,
+ MYF(MY_WME|MY_FAE)) :
+ (char*)my_malloc(PSI_NOT_INSTRUMENTED, v->alloced_len+1,
+ MYF(MY_WME|MY_FAE))))
die("Out of memory");
}
v->str_val_len = new_val_len;
@@ -4784,7 +4790,8 @@ void do_sync_with_master(struct st_command *command)
p++;
while (*p && my_isspace(charset_info, *p))
p++;
- start= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(p)+1,MYF(MY_WME | MY_FAE));
+ start= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(p)+1,
+ MYF(MY_WME|MY_FAE));
get_string(&buff, &p, command);
}
command->last_argument= p;
@@ -6924,7 +6931,7 @@ int read_command(struct st_command** command_ptr)
}
if (!(*command_ptr= command=
(struct st_command*) my_malloc(PSI_NOT_INSTRUMENTED, sizeof(*command),
- MYF(MY_WME|MY_ZEROFILL))) ||
+ MYF(MY_WME|MY_FAE|MY_ZEROFILL))) ||
insert_dynamic(&q_lines, &command))
die("Out of memory");
command->type= Q_UNKNOWN;
@@ -7632,18 +7639,19 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
/* Allocate array with bind structs, lengths and NULL flags */
my_bind= (MYSQL_BIND*) my_malloc(PSI_NOT_INSTRUMENTED, num_fields * sizeof(MYSQL_BIND),
- MYF(MY_WME | MY_FAE | MY_ZEROFILL));
+ MYF(MY_WME|MY_FAE|MY_ZEROFILL));
length= (ulong*) my_malloc(PSI_NOT_INSTRUMENTED, num_fields * sizeof(ulong),
- MYF(MY_WME | MY_FAE));
+ MYF(MY_WME|MY_FAE));
is_null= (my_bool*) my_malloc(PSI_NOT_INSTRUMENTED, num_fields * sizeof(my_bool),
- MYF(MY_WME | MY_FAE));
+ MYF(MY_WME|MY_FAE));
/* Allocate data for the result of each field */
for (i= 0; i < num_fields; i++)
{
uint max_length= fields[i].max_length + 1;
my_bind[i].buffer_type= MYSQL_TYPE_STRING;
- my_bind[i].buffer= my_malloc(PSI_NOT_INSTRUMENTED, max_length, MYF(MY_WME | MY_FAE));
+ my_bind[i].buffer= my_malloc(PSI_NOT_INSTRUMENTED, max_length,
+ MYF(MY_WME|MY_FAE));
my_bind[i].buffer_length= max_length;
my_bind[i].is_null= &is_null[i];
my_bind[i].length= &length[i];
@@ -8667,7 +8675,7 @@ void run_bind_stmt(struct st_connection *cn, struct st_command *command,
cn->ps_params= ps_params = (MYSQL_BIND*)my_malloc(PSI_NOT_INSTRUMENTED,
sizeof(MYSQL_BIND) *
stmt->param_count,
- MYF(MY_WME));
+ MYF(MY_WME|MY_FAE));
bzero((char *) ps_params, sizeof(MYSQL_BIND) * stmt->param_count);
int i=0;
@@ -8682,7 +8690,8 @@ void run_bind_stmt(struct st_connection *cn, struct st_command *command,
if (!*c)
{
ps_params[i].buffer_type= MYSQL_TYPE_LONG;
- l= (long*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(long), MYF(MY_WME));
+ l= (long*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(long),
+ MYF(MY_WME|MY_FAE));
*l= strtol(p, &c, 10);
ps_params[i].buffer= (void*)l;
ps_params[i].buffer_length= 8;
@@ -8694,7 +8703,7 @@ void run_bind_stmt(struct st_connection *cn, struct st_command *command,
{
ps_params[i].buffer_type= MYSQL_TYPE_DECIMAL;
d= (double*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(double),
- MYF(MY_WME));
+ MYF(MY_WME|MY_FAE));
*d= strtod(p, &c);
ps_params[i].buffer= (void*)d;
ps_params[i].buffer_length= 8;
@@ -8702,7 +8711,8 @@ void run_bind_stmt(struct st_connection *cn, struct st_command *command,
else
{
ps_params[i].buffer_type= MYSQL_TYPE_STRING;
- ps_params[i].buffer= my_strdup(PSI_NOT_INSTRUMENTED, p, MYF(MY_WME));
+ ps_params[i].buffer= my_strdup(PSI_NOT_INSTRUMENTED, p,
+ MYF(MY_WME|MY_FAE));
ps_params[i].buffer_length= (unsigned long)strlen(p);
}
}
@@ -9740,7 +9750,7 @@ int main(int argc, char **argv)
/* Init connections, allocate 1 extra as buffer + 1 for default */
connections= (struct st_connection*)
my_malloc(PSI_NOT_INSTRUMENTED, (opt_max_connections+2) * sizeof(struct st_connection),
- MYF(MY_WME | MY_ZEROFILL));
+ MYF(MY_WME|MY_FAE|MY_ZEROFILL));
connections_end= connections + opt_max_connections +1;
next_con= connections + 1;
@@ -10462,7 +10472,8 @@ void do_get_replace_column(struct st_command *command)
die("Missing argument in %s", command->query);
/* Allocate a buffer for results */
- start= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(from)+1,MYF(MY_WME | MY_FAE));
+ start= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(from)+1,
+ MYF(MY_WME|MY_FAE));
while (*from)
{
char *to;
@@ -10475,7 +10486,8 @@ void do_get_replace_column(struct st_command *command)
command->query);
to= get_string(&buff, &from, command);
my_free(replace_column[column_number-1]);
- replace_column[column_number-1]= my_strdup(PSI_NOT_INSTRUMENTED, to, MYF(MY_WME | MY_FAE));
+ replace_column[column_number-1]= my_strdup(PSI_NOT_INSTRUMENTED, to,
+ MYF(MY_WME|MY_FAE));
set_if_bigger(max_replace_column, column_number);
}
my_free(start);
@@ -10542,7 +10554,8 @@ void do_get_replace(struct st_command *command)
bzero(&from_array,sizeof(from_array));
if (!*from)
die("Missing argument in %s", command->query);
- start= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(from)+1,MYF(MY_WME | MY_FAE));
+ start= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(from)+1,
+ MYF(MY_WME|MY_FAE));
while (*from)
{
char *to= buff;
@@ -11200,7 +11213,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
DBUG_RETURN(0);
found_sets=0;
if (!(found_set= (FOUND_SET*) my_malloc(PSI_NOT_INSTRUMENTED, sizeof(FOUND_SET)*max_length*count,
- MYF(MY_WME))))
+ MYF(MY_WME|MY_FAE))))
{
free_sets(&sets);
DBUG_RETURN(0);
@@ -11210,7 +11223,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
used_sets=-1;
word_states=make_new_set(&sets); /* Start of new word */
start_states=make_new_set(&sets); /* This is first state */
- if (!(follow=(FOLLOWS*) my_malloc(PSI_NOT_INSTRUMENTED, (states+2)*sizeof(FOLLOWS),MYF(MY_WME))))
+ if (!(follow=(FOLLOWS*) my_malloc(PSI_NOT_INSTRUMENTED, (states+2)*sizeof(FOLLOWS),MYF(MY_WME|MY_FAE))))
{
free_sets(&sets);
my_free(found_set);
@@ -11377,7 +11390,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
if ((replace=(REPLACE*) my_malloc(PSI_NOT_INSTRUMENTED, sizeof(REPLACE)*(sets.count)+
sizeof(REPLACE_STRING)*(found_sets+1)+
sizeof(char *)*count+result_len,
- MYF(MY_WME | MY_ZEROFILL))))
+ MYF(MY_WME|MY_FAE|MY_ZEROFILL))))
{
rep_str=(REPLACE_STRING*) (replace+sets.count);
to_array= (char **) (rep_str+found_sets+1);
@@ -11420,10 +11433,10 @@ int init_sets(REP_SETS *sets,uint states)
bzero(sets, sizeof(*sets));
sets->size_of_bits=((states+7)/8);
if (!(sets->set_buffer=(REP_SET*) my_malloc(PSI_NOT_INSTRUMENTED, sizeof(REP_SET)*SET_MALLOC_HUNC,
- MYF(MY_WME))))
+ MYF(MY_WME|MY_FAE))))
return 1;
if (!(sets->bit_buffer=(uint*) my_malloc(PSI_NOT_INSTRUMENTED, sizeof(uint)*sets->size_of_bits*
- SET_MALLOC_HUNC,MYF(MY_WME))))
+ SET_MALLOC_HUNC,MYF(MY_WME|MY_FAE))))
{
my_free(sets->set);
return 1;
@@ -11619,10 +11632,10 @@ int insert_pointer_name(POINTER_ARRAY *pa,char * name)
if (!(pa->typelib.type_names=(const char **)
my_malloc(PSI_NOT_INSTRUMENTED, ((PC_MALLOC-MALLOC_OVERHEAD)/
(sizeof(char *)+sizeof(*pa->flag))*
- (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
+ (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME|MY_FAE))))
DBUG_RETURN(-1);
if (!(pa->str= (uchar*) my_malloc(PSI_NOT_INSTRUMENTED, PS_MALLOC - MALLOC_OVERHEAD,
- MYF(MY_WME))))
+ MYF(MY_WME|MY_FAE))))
{
my_free(pa->typelib.type_names);
DBUG_RETURN (-1);
diff --git a/cmake/abi_check.cmake b/cmake/abi_check.cmake
index 98877be9351..e4a783f3de5 100644
--- a/cmake/abi_check.cmake
+++ b/cmake/abi_check.cmake
@@ -38,7 +38,6 @@ IF(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang" AND RUN_ABI_CHECK)
SET(API_PREPROCESSOR_HEADER
${CMAKE_SOURCE_DIR}/include/mysql/plugin_audit.h
${CMAKE_SOURCE_DIR}/include/mysql/plugin_ftparser.h
- ${CMAKE_SOURCE_DIR}/include/mysql.h
${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v1.h
${CMAKE_SOURCE_DIR}/include/mysql/psi/psi_abi_v2.h
${CMAKE_SOURCE_DIR}/include/mysql/client_plugin.h
diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh
index d76e19a03a9..1cc215f1c82 100755
--- a/debian/autobake-deb.sh
+++ b/debian/autobake-deb.sh
@@ -25,9 +25,9 @@ then
sed '/Add support for verbose builds/,/^$/d' -i debian/rules
elif [ -d storage/columnstore/columnstore/debian ]
then
- # ColumnStore is explicitly disabled in the native Debian build, so allow it
+ # ColumnStore is explicitly disabled in the native Debian build. Enable it
# now when build is triggered by autobake-deb.sh (MariaDB.org) and when the
- # build is not running on Travis or Gitlab-CI
+ # build is not running on Gitlab-CI.
sed '/-DPLUGIN_COLUMNSTORE=NO/d' -i debian/rules
# Take the files and part of control from MCS directory
if [ ! -f debian/mariadb-plugin-columnstore.install ]
@@ -58,26 +58,45 @@ replace_uring_with_aio()
{
sed 's/liburing-dev/libaio-dev/g' -i debian/control
sed -e '/-DIGNORE_AIO_CHECK=YES/d' \
- -e '/-DWITH_URING=yes/d' -i debian/rules
+ -e '/-DWITH_URING=YES/d' -i debian/rules
}
disable_pmem()
{
sed '/libpmem-dev/d' -i debian/control
- sed '/-DWITH_PMEM=yes/d' -i debian/rules
+ sed '/-DWITH_PMEM=YES/d' -i debian/rules
}
architecture=$(dpkg-architecture -q DEB_BUILD_ARCH)
+# Parse release name and number from Linux standard base release
+# Example:
+# $ lsb_release -a
+# No LSB modules are available.
+# Distributor ID: Debian
+# Description: Debian GNU/Linux bookworm/sid
+# Release: n/a
+# Codename: n/a
LSBID="$(lsb_release -si | tr '[:upper:]' '[:lower:]')"
LSBVERSION="$(lsb_release -sr | sed -e "s#\.##g")"
LSBNAME="$(lsb_release -sc)"
+# If 'n/a', assume 'sid'
+if [ "${LSBVERSION}" == "n/a" ] || [ "${LSBNAME}" == "n/a" ]
+then
+ LSBVERSION="sid"
+ LSBNAME="sid"
+fi
+
+# If not known, use 'unknown' in .deb version identifier
if [ -z "${LSBID}" ]
then
LSBID="unknown"
fi
-case "${LSBNAME}" in
+
+case "${LSBNAME}"
+in
+ # Debian
stretch)
# MDEV-16525 libzstd-dev-1.1.3 minimum version
sed -e '/libzstd-dev/d' \
@@ -105,10 +124,10 @@ case "${LSBNAME}" in
fi
;&
sid)
- # should always be empty here.
- # need to match here to avoid the default Error however
+ # The default packaging should always target Debian Sid, so in this case
+ # there is intentionally no customizations whatsoever.
;;
- # UBUNTU
+ # Ubuntu
bionic)
remove_rocksdb_tools
[ "$architecture" != amd64 ] && disable_pmem
@@ -134,7 +153,7 @@ case "${LSBNAME}" in
fi
;;
*)
- echo "Error - unknown release codename $LSBNAME" >&2
+ echo "Error: Unknown release '$LSBNAME'" >&2
exit 1
esac
@@ -153,7 +172,7 @@ LOGSTRING="MariaDB build"
EPOCH="1:"
VERSION="${EPOCH}${UPSTREAM}${PATCHLEVEL}~${LSBID:0:3}${LSBVERSION}"
-dch -b -D ${LSBNAME} -v "${VERSION}" "Automatic build with ${LOGSTRING}." --controlmaint
+dch -b -D "${LSBNAME}" -v "${VERSION}" "Automatic build with ${LOGSTRING}." --controlmaint
echo "Creating package version ${VERSION} ... "
diff --git a/debian/mariadb-server-10.6.mariadb.init b/debian/mariadb-server-10.6.mariadb.init
index a16e9f88edb..b92282dedce 100644
--- a/debian/mariadb-server-10.6.mariadb.init
+++ b/debian/mariadb-server-10.6.mariadb.init
@@ -21,9 +21,18 @@ test -x /usr/sbin/mariadbd || exit 0
. /lib/lsb/init-functions
-SELF=$(cd $(dirname $0); pwd -P)/$(basename $0)
-
-MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
+SELF=$(cd "$(dirname $0)"; pwd -P)/$(basename $0)
+
+if [ -f /usr/bin/mariadb-admin ]
+then
+ MYADMIN="/usr/bin/mariadb-admin --defaults-file=/etc/mysql/debian.cnf"
+elif [ -f /usr/bin/mysqladmin ]
+then
+ MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
+else
+ log_failure_msg "Command mariadb-admin/mysqladmin not found! This SysV init script depends on it."
+ exit -1
+fi
# priority can be overridden and "-s" adds output to stderr
ERR_LOGGER="logger -p daemon.err -t /etc/init.d/mariadb -i"
diff --git a/debian/rules b/debian/rules
index 15eadcbb590..7dcc9a2ba3c 100755
--- a/debian/rules
+++ b/debian/rules
@@ -5,7 +5,13 @@ export DEB_BUILD_HARDENING=1
# enable Debian Hardening
# see: https://wiki.debian.org/Hardening
-export DEB_BUILD_MAINT_OPTIONS = hardening=+all optimize=-lto
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+# Disable LTO on Ubuntu, see LP: #1970634 and https://jira.mariadb.org/browse/MDEV-25633
+ifeq ($(shell dpkg-vendor --derives-from Ubuntu && echo yes), yes)
+ export DEB_BUILD_MAINT_OPTIONS += optimize=-lto
+endif
+
DPKG_EXPORT_BUILDFLAGS = 1
# Include all defaults, including buildflags.mk
include /usr/share/dpkg/default.mk
@@ -46,11 +52,6 @@ ifeq (32,$(DEB_HOST_ARCH_BITS))
CMAKEFLAGS += -DPLUGIN_ROCKSDB=NO
endif
-# ColumnStore can build only on amd64 and arm64
-ifneq (,$(filter $(DEB_HOST_ARCH_CPU),amd64 arm64))
- CMAKEFLAGS += -DPLUGIN_COLUMNSTORE=NO
-endif
-
# Cross building requires stack direction instruction
ifneq ($(DEB_BUILD_ARCH),$(DEB_HOST_ARCH))
ifneq (,$(filter $(DEB_HOST_ARCH_CPU),alpha amd64 arm arm64 i386 ia64 m68k mips64el mipsel powerpc ppc64 ppc64el riscv64 s390x sh4 sparc64))
@@ -64,7 +65,7 @@ endif
# Only attempt to build with PMEM on archs that have package libpmem-dev available
# See https://packages.debian.org/search?searchon=names&keywords=libpmem-dev
ifneq (,$(filter $(DEB_HOST_ARCH_CPU),amd64 arm64 ppc64el riscv64))
- CMAKEFLAGS += -DWITH_PMEM=yes
+ CMAKEFLAGS += -DWITH_PMEM=YES
endif
# Add support for verbose builds
@@ -105,9 +106,9 @@ endif
-DBUILD_CONFIG=mysql_release \
-DCONC_DEFAULT_CHARSET=utf8mb4 \
-DPLUGIN_AWS_KEY_MANAGEMENT=NO \
- -DPLUGIN_COLUMNSTORE=NO \
+ -DPLUGIN_COLUMNSTORE=NO \
-DIGNORE_AIO_CHECK=YES \
- -DWITH_URING=yes \
+ -DWITH_URING=YES \
-DDEB=$(DEB_VENDOR)
# This is needed, otherwise 'make test' will run before binaries have been built
@@ -120,6 +121,7 @@ override_dh_auto_build:
override_dh_auto_test:
@echo "RULES.$@"
dh_testdir
+ # Ensure at least an empty file exists
touch mysql-test/unstable-tests
[ ! -f debian/unstable-tests.$(DEB_HOST_ARCH) ] || cat debian/unstable-tests.$(DEB_HOST_ARCH) >> mysql-test/unstable-tests
# Run testsuite
@@ -203,6 +205,7 @@ override_dh_installinit-arch:
dh_installinit --name=mariadb --no-start -- defaults 19 21
dh_systemd_start --restart-after-upgrade
+# Use custom server version string variable
override_dh_gencontrol:
dh_gencontrol -- -Tdebian/substvars
diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml
index 0a2203fabb9..1efde56d70d 100644
--- a/debian/salsa-ci.yml
+++ b/debian/salsa-ci.yml
@@ -16,12 +16,17 @@ variables:
GIT_SUBMODULE_STRATEGY: recursive
SALSA_CI_GBP_BUILDPACKAGE_ARGS: "--git-submodules" # did not apply to extract-sources
+# Extend Salsa-CI build jobs to have longer timeout as the default GitLab
+# timeout (1h) is often not enough
+.build-package:
+ timeout: 3h
+
stages:
- provisioning
- build
- test
- upgrade in Sid
- - upgrade from Bullseye/Buster
+ - upgrade from Bullseye
- upgrade extras
- test extras
- publish # Stage referenced by Salsa-CI template aptly stanza, so must exist even though not used
@@ -134,6 +139,17 @@ blhc:
apt-get update
apt-get install -y apt
+.test-enable-buster-backports-repos: &test-enable-buster-backports-repos |
+ # Enable buster-backports (assumes environment already Debian Buster)
+ echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/buster-backports.list
+ # Increase default backports priority policy from '100' to '500' so it can actually be used
+ cat << EOF > /etc/apt/preferences.d/enable-backports-to-satisfy-dependencies
+ Package: *
+ Pin: release n=buster-*
+ Pin-Priority: 500
+ EOF
+ apt-get update
+
.test-install: &test-install |
# Install MariaDB built in this commit
apt-get install -y ./*.deb
@@ -213,7 +229,7 @@ fresh install:
script:
- *test-prepare-container
- *test-install
- - service mariadb status # There is no init.d/mysql in MariaDB 10.6
+ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+
- *test-verify-final
variables:
GIT_STRATEGY: none
@@ -234,7 +250,7 @@ mariadb-10.6 Sid upgrade:
script:
- *test-prepare-container
- *test-install
- - service mariadb status # There is no init.d/mysql in MariaDB 10.6
+ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+
- *test-verify-final
variables:
GIT_STRATEGY: none
@@ -243,7 +259,7 @@ mariadb-10.6 Sid upgrade:
- $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/
mariadb-10.5 Bullseye to mariadb-10.6 upgrade:
- stage: upgrade from Bullseye/Buster
+ stage: upgrade from Bullseye
needs:
- job: build
image: debian:bullseye
@@ -268,10 +284,12 @@ mariadb-10.5 Bullseye to mariadb-10.6 upgrade:
variables:
- $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/
-mariadb-10.3 Buster to mariadb-10.6 upgrade:
- stage: upgrade from Bullseye/Buster
+# Upgrade of libcrypt.so.1 no longer possible from Buster to Sid,
+# so test upgrade only inside Buster (https://bugs.debian.org/993755)
+mariadb-10.3 to mariadb-10.6 upgrade in Buster:
+ stage: upgrade extras
needs:
- - job: build
+ - job: build buster-backports
image: debian:buster
artifacts:
when: always
@@ -284,7 +302,7 @@ mariadb-10.3 Buster to mariadb-10.6 upgrade:
- apt-get install -y 'default-mysql*' 'mariadb-*' 'libmariadb*'
# Verify installation of MariaDB from Buster
- *test-verify-initial
- - *test-enable-sid-repos
+ - *test-enable-buster-backports-repos
- *test-install
- service mysql status
- *test-verify-final
@@ -307,7 +325,7 @@ test basic features:
script:
- *test-prepare-container
- *test-install
- - service mariadb status # There is no init.d/mysql in MariaDB 10.6
+ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+
- *test-verify-final
- |
# Print info about server
@@ -452,7 +470,7 @@ default-libmysqlclient-dev Sid upgrade:
- $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/
default-libmysqlclient-dev Bullseye upgrade:
- stage: upgrade from Bullseye/Buster
+ stage: upgrade from Bullseye
needs:
- job: build
image: debian:bullseye
@@ -472,10 +490,12 @@ default-libmysqlclient-dev Bullseye upgrade:
variables:
- $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/
-default-libmysqlclient-dev Buster upgrade:
- stage: upgrade from Bullseye/Buster
+# Upgrade of libcrypt.so.1 no longer possible from Buster to Sid,
+# so test upgrade only inside Buster (https://bugs.debian.org/993755)
+default-libmysqlclient-dev upgrade in Buster:
+ stage: upgrade extras
needs:
- - job: build
+ - job: build buster-backports
image: debian:buster
artifacts:
when: always
@@ -486,7 +506,7 @@ default-libmysqlclient-dev Buster upgrade:
- *test-prepare-container
- apt-get install -y pkg-config default-libmysqlclient-dev
- pkg-config --list-all
- - *test-enable-sid-repos
+ - *test-enable-buster-backports-repos
- *test-install-all-libs
- *test-verify-libs
except:
@@ -511,8 +531,20 @@ mysql-8.0 Sid to mariadb-10.6 upgrade:
- apt-get install -y procps mysql-server 'libmysqlc*'
- *test-verify-initial
- *test-install
- - service mysql status
+ # The Debian version of MariaDB 10.6 still maintains compatibility and there
+ # running 'service mysql status' in Salsa-CI job 'mysql-8.0 Sid to
+ # mariadb-10.6 upgrade' still works.
+ #
+ # However, due to debian/control changes, the upstream MariaDB 10.6 when
+ # installed on a system with a previous installation of MySQL 8.0 will first
+ # fully remove MySQL, including the /etc/init.d/mysql file, so previous
+ # techniques in mariadb-server-10.6.postinst to maintain backwards
+ # compatibility with 'service mysql status' after installing MariaDB on top
+ # MySQL no longer works, and thus the step to test it now intentionally has
+ # a fallback to use the service name 'mariadb' instead, and the fallback is
+ # always used.
- sleep 5 # Give the mysql_upgrade a bit of time to complete before querying the server
+ - service mysql status || service mariadb status
- *test-verify-final
variables:
GIT_STRATEGY: none
@@ -522,7 +554,7 @@ mysql-8.0 Sid to mariadb-10.6 upgrade:
# Upgrading from MySQL 8.0 with datadir in place is not possible. Users need to do a data dump.
# The Debian maintainer scripts detect this situation and simply moves old datadir aside and start fresh.
-mysql-8.0 Focal to mariadb-10.6 upgrade:
+mysql-8.0 Focal to mariadb-10.6 upgrade in Buster:
stage: upgrade extras
needs:
- job: build buster-backports
@@ -582,18 +614,13 @@ mariadb.org-10.6 to mariadb-10.6 upgrade:
# Verify installation of MariaDB built in this commit
- dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed
- mariadb --version # Client version
- - service mariadb status # There is no init.d/mysql in MariaDB 10.6
+ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+
- *test-verify-final
variables:
GIT_STRATEGY: none
except:
variables:
- $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/
- allow_failure: true
- # Installation on Sid fails on missing liburing1 because upstream 10.6
- # MariaDB.org buildbot has not run 'apt upgrade' for a long time.
- # Remove this allow_failure once buildbot has built a new 10.6
- # release using latest liburing-dev in Debian Sid.
mariadb.org-10.5 to mariadb-10.6 upgrade:
stage: upgrade extras
@@ -617,7 +644,7 @@ mariadb.org-10.5 to mariadb-10.6 upgrade:
# Verify installation of MariaDB built in this commit
- dpkg -l | grep -iE 'maria|mysql|galera' || true # List installed
- mariadb --version # Client version
- - service mariadb status # There is no init.d/mysql in MariaDB 10.5
+ - service mariadb status # There is no init.d/mysql in MariaDB 10.5+
- *test-verify-final
variables:
GIT_STRATEGY: none
@@ -728,7 +755,7 @@ mariadb.org-10.2 to mariadb-10.6 upgrade:
variables:
- $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/
-mysql.com-5.7 to mariadb-10.6 upgrade:
+mysql.com-5.7 to mariadb-10.6 upgrade in Buster:
stage: upgrade extras
needs:
- job: build buster-backports
@@ -759,7 +786,7 @@ mysql.com-5.7 to mariadb-10.6 upgrade:
variables:
- $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/
-percona-xtradb-5.7 to mariadb-10.6 upgrade (MDEV-22679):
+percona-xtradb-5.7 to mariadb-10.6 upgrade in Buster (MDEV-22679):
stage: upgrade extras
needs:
- job: build buster-backports
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
index c570453b5be..4a4671e0c9e 100644
--- a/debian/source/lintian-overrides
+++ b/debian/source/lintian-overrides
@@ -48,7 +48,7 @@ very-long-line-length-in-source-file mysql-test/std_data/init_file_longline_3816
very-long-line-length-in-source-file scripts/fill_help_tables.sql *
very-long-line-length-in-source-file scripts/mysql_system_tables.sql *
very-long-line-length-in-source-file scripts/mysql_test_data_timezone.sql *
-# Machine formated HTML
+# Machine formatted HTML
very-long-line-length-in-source-file sql/share/charsets/languages.html *
very-long-line-length-in-source-file sql/share/errmsg-utf8.txt *
# Very long test string
diff --git a/debian/tests/upstream b/debian/tests/upstream
index f216df24371..c48701864b7 100644
--- a/debian/tests/upstream
+++ b/debian/tests/upstream
@@ -10,6 +10,8 @@ echo "Running test 'testsuite'"
set -e
SKIP_TEST_LST="/tmp/skip-test.lst"
+ARCH=$(dpkg --print-architecture)
+
WORKDIR=$(mktemp -d)
trap 'rm -rf $WORKDIR $SKIP_TEST_LST' 0 INT QUIT ABRT PIPE TERM
cd "$WORKDIR"
@@ -22,16 +24,15 @@ echo "using tmpdir: $WORKDIR/tmp"
echo "Setting up skip-tests-list"
-touch $SKIP_TEST_LST
+# Use unstable-tests list as base to skip all tests considered unstable
+# or create an empty file if that upstream file does not exists on this branch
+cp /usr/share/mysql/mysql-test/unstable-tests $SKIP_TEST_LST || touch $SKIP_TEST_LST
-# Also use arch specific skiplists if such files exist
-for filename in /usr/share/mysql/mysql-test/unstable-tests.*
-do
- # Check for case that no files matched and glob is returned
- [ -e "$filename" ] || continue
- # Append file to the main skip test list file
- cat "$filename" >> $SKIP_TEST_LST
-done
+# Also use the arch specific skiplists if exist
+if [ -f /usr/share/mysql/mysql-test/unstable-tests.$ARCH ]
+then
+ cat /usr/share/mysql/mysql-test/unstable-tests.$ARCH >> $SKIP_TEST_LST
+fi
# Skip tests that cannot run properly on ci.debian.net / autopkgtests.ubuntu.com
cat >> $SKIP_TEST_LST << EOF
@@ -48,7 +49,6 @@ main.mysqld--help : For unknown reason table-cache is 4000 instead of default 42
EOF
fi
-ARCH=$(dpkg --print-architecture)
if [ "$ARCH" = "s390x" ]
then
echo "main.func_regexp_pcre : recursion fails on s390x https://bugs.launchpad.net/ubuntu/+source/mariadb-10.1/+bug/1723947" >> $SKIP_TEST_LST
@@ -57,6 +57,10 @@ then
echo "main.failed_auth_unixsocket : Test returns wrong exit code on armhf and i386 (but only in debci) https://jira.mariadb.org/browse/MDEV-23933" >> $SKIP_TEST_LST
fi
+# Store skipped test list in artifacts so it can be viewed while debugging
+# failed autopkgtest runs
+cp -v $SKIP_TEST_LST $AUTOPKGTEST_ARTIFACTS
+
cd /usr/share/mysql/mysql-test
echo "starting mysql-test-tun.pl..."
eatmydata perl -I. ./mysql-test-run.pl --suite=main \
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 4d2da0082aa..cd1d21cdf75 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -3816,10 +3816,6 @@ static dberr_t xb_assign_undo_space_start()
int n_retries = 5;
ulint fsp_flags;
- if (srv_undo_tablespaces == 0) {
- return error;
- }
-
file = os_file_create(0, srv_sys_space.first_datafile()->filepath(),
OS_FILE_OPEN, OS_FILE_NORMAL, OS_DATA_FILE, true, &ret);
diff --git a/include/mariadb_capi_rename.h b/include/mariadb_capi_rename.h
new file mode 100644
index 00000000000..616a9142fe6
--- /dev/null
+++ b/include/mariadb_capi_rename.h
@@ -0,0 +1,57 @@
+/* Copyright (c) 2022, MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/* Renaming C API symbols inside server
+ * client.c defines a number of functions from the C API, that are used in replication, in number of storage engine plugins, mariadb-backup.
+ * That can cause a problem if a plugin loads libmariadb/libmysql or a library, that has dependency on them. The known case is ODBC driver.
+ * Thus the header re-names those functions for internal use.
+ */
+
+#ifndef MARIADB_CAPI_RENAME_INCLUDED
+#define MARIADB_CAPI_RENAME_INCLUDED
+
+#if !defined(EMBEDDED_LIBRARY)
+
+#define MARIADB_ADD_PREFIX(_SYMBOL) server_##_SYMBOL
+#define mysql_real_connect MARIADB_ADD_PREFIX(mysql_real_connect)
+#define mysql_init MARIADB_ADD_PREFIX(mysql_init)
+#define mysql_close MARIADB_ADD_PREFIX(mysql_close)
+#define mysql_options MARIADB_ADD_PREFIX(mysql_options)
+#define mysql_load_plugin MARIADB_ADD_PREFIX(mysql_load_plugin)
+#define mysql_load_plugin_v MARIADB_ADD_PREFIX(mysql_load_plugin_v)
+#define mysql_client_find_plugin MARIADB_ADD_PREFIX(mysql_client_find_plugin)
+#define mysql_real_query MARIADB_ADD_PREFIX(mysql_real_query)
+#define mysql_send_query MARIADB_ADD_PREFIX(mysql_send_query)
+#define mysql_free_result MARIADB_ADD_PREFIX(mysql_free_result)
+#define mysql_get_socket MARIADB_ADD_PREFIX(mysql_get_socket)
+#define mysql_set_character_set MARIADB_ADD_PREFIX(mysql_set_character_set)
+#define mysql_get_server_version MARIADB_ADD_PREFIX(mysql_get_server_version)
+#define mysql_error MARIADB_ADD_PREFIX(mysql_error)
+#define mysql_errno MARIADB_ADD_PREFIX(mysql_errno)
+#define mysql_num_fields MARIADB_ADD_PREFIX(mysql_num_fields)
+#define mysql_num_rows MARIADB_ADD_PREFIX(mysql_num_rows)
+#define mysql_options4 MARIADB_ADD_PREFIX(mysql_options4)
+#define mysql_fetch_lengths MARIADB_ADD_PREFIX(mysql_fetch_lengths)
+#define mysql_fetch_row MARIADB_ADD_PREFIX(mysql_fetch_row)
+#define mysql_affected_rows MARIADB_ADD_PREFIX(mysql_affected_rows)
+#define mysql_store_result MARIADB_ADD_PREFIX(mysql_store_result)
+#define mysql_select_db MARIADB_ADD_PREFIX(mysql_select_db)
+#define mysql_get_ssl_cipher MARIADB_ADD_PREFIX(mysql_get_ssl_cipher)
+#define mysql_ssl_set MARIADB_ADD_PREFIX(mysql_ssl_set)
+#define mysql_client_register_plugin MARIADB_ADD_PREFIX(mysql_client_register_plugin)
+
+#endif // !EMBEDDED_LIBRARY && !MYSQL_DYNAMIC_PLUGIN
+
+#endif // !MARIADB_CAPI_RENAME_INCLUDED
diff --git a/include/my_alarm.h b/include/my_alarm.h
index df5cb7f51de..652b460cba3 100644
--- a/include/my_alarm.h
+++ b/include/my_alarm.h
@@ -31,7 +31,10 @@ extern ulong my_time_to_wait_for_lock;
#include <signal.h>
#ifdef HAVE_SIGHANDLER_T
#define sig_return sighandler_t
-#elif defined(SOLARIS) || defined(__sun) || defined(__APPLE__) || defined(__FreeBSD__) || defined(_AIX)
+#elif defined(SOLARIS) || defined(__sun) || defined(__APPLE__) || \
+ defined(_AIX) || \
+ defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
+ defined(__DragonFly__)
typedef void (*sig_return)(int); /* Returns type from signal */
#else
typedef void (*sig_return)(void); /* Returns type from signal */
diff --git a/include/mysql.h b/include/mysql.h
index 87def05dc7e..5088d800f87 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -63,6 +63,7 @@ typedef int my_socket;
#endif /* my_socket_defined */
#endif /* MY_GLOBAL_INCLUDED */
+#include "mariadb_capi_rename.h"
#include "mysql_version.h"
#include "mysql_com.h"
#include "mysql_time.h"
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
deleted file mode 100644
index 584276a7a08..00000000000
--- a/include/mysql.h.pp
+++ /dev/null
@@ -1,797 +0,0 @@
-extern "C" {
-typedef char my_bool;
-typedef int my_socket;
-enum enum_server_command
-{
- COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST,
- COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS,
- COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING,
- COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP,
- COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE,
- COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE,
- COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON,
- COM_UNIMPLEMENTED,
- COM_RESET_CONNECTION,
- COM_MDB_GAP_BEG,
- COM_MDB_GAP_END=249,
- COM_STMT_BULK_EXECUTE=250,
- COM_SLAVE_WORKER=251,
- COM_SLAVE_IO=252,
- COM_SLAVE_SQL=253,
- COM_RESERVED_1=254,
- COM_END=255
-};
-enum enum_indicator_type
-{
- STMT_INDICATOR_NONE= 0,
- STMT_INDICATOR_NULL,
- STMT_INDICATOR_DEFAULT,
- STMT_INDICATOR_IGNORE
-};
-enum mariadb_field_attr_t
-{
- MARIADB_FIELD_ATTR_DATA_TYPE_NAME= 0,
- MARIADB_FIELD_ATTR_FORMAT_NAME= 1
-};
-struct st_vio;
-typedef struct st_vio Vio;
-typedef struct st_net {
- Vio *vio;
- unsigned char *buff,*buff_end,*write_pos,*read_pos;
- my_socket fd;
- unsigned long remain_in_buf,length, buf_length, where_b;
- unsigned long max_packet,max_packet_size;
- unsigned int pkt_nr,compress_pkt_nr;
- unsigned int write_timeout, read_timeout, retry_count;
- int fcntl;
- unsigned int *return_status;
- unsigned char reading_or_writing;
- char save_char;
- char net_skip_rest_factor;
- my_bool thread_specific_malloc;
- unsigned char compress;
- my_bool unused3;
- void *thd;
- unsigned int last_errno;
- unsigned char error;
- my_bool unused4;
- my_bool unused5;
- char last_error[512];
- char sqlstate[5 +1];
- void *extension;
-} NET;
-enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
- MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
- MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
- MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
- MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
- MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
- MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
- MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
- MYSQL_TYPE_BIT,
- MYSQL_TYPE_TIMESTAMP2,
- MYSQL_TYPE_DATETIME2,
- MYSQL_TYPE_TIME2,
- MYSQL_TYPE_BLOB_COMPRESSED= 140,
- MYSQL_TYPE_VARCHAR_COMPRESSED= 141,
- MYSQL_TYPE_NEWDECIMAL=246,
- MYSQL_TYPE_ENUM=247,
- MYSQL_TYPE_SET=248,
- MYSQL_TYPE_TINY_BLOB=249,
- MYSQL_TYPE_MEDIUM_BLOB=250,
- MYSQL_TYPE_LONG_BLOB=251,
- MYSQL_TYPE_BLOB=252,
- MYSQL_TYPE_VAR_STRING=253,
- MYSQL_TYPE_STRING=254,
- MYSQL_TYPE_GEOMETRY=255
-};
-enum mysql_enum_shutdown_level {
- SHUTDOWN_DEFAULT = 0,
- SHUTDOWN_WAIT_CONNECTIONS= (unsigned char)(1 << 0),
- SHUTDOWN_WAIT_TRANSACTIONS= (unsigned char)(1 << 1),
- SHUTDOWN_WAIT_UPDATES= (unsigned char)(1 << 3),
- SHUTDOWN_WAIT_ALL_BUFFERS= ((unsigned char)(1 << 3) << 1),
- SHUTDOWN_WAIT_CRITICAL_BUFFERS= ((unsigned char)(1 << 3) << 1) + 1
-};
-enum enum_cursor_type
-{
- CURSOR_TYPE_NO_CURSOR= 0,
- CURSOR_TYPE_READ_ONLY= 1,
- CURSOR_TYPE_FOR_UPDATE= 2,
- CURSOR_TYPE_SCROLLABLE= 4
-};
-enum enum_mysql_set_option
-{
- MYSQL_OPTION_MULTI_STATEMENTS_ON,
- MYSQL_OPTION_MULTI_STATEMENTS_OFF
-};
-enum enum_session_state_type
-{
- SESSION_TRACK_SYSTEM_VARIABLES,
- SESSION_TRACK_SCHEMA,
- SESSION_TRACK_STATE_CHANGE,
- SESSION_TRACK_GTIDS,
- SESSION_TRACK_TRANSACTION_CHARACTERISTICS,
- SESSION_TRACK_TRANSACTION_STATE,
- SESSION_TRACK_always_at_the_end
-};
-extern "C" {
-my_bool my_net_init(NET *net, Vio* vio, void *thd, unsigned int my_flags);
-void my_net_local_init(NET *net);
-void net_end(NET *net);
-void net_clear(NET *net, my_bool clear_buffer);
-my_bool net_realloc(NET *net, size_t length);
-my_bool net_flush(NET *net);
-my_bool my_net_write(NET *net,const unsigned char *packet, size_t len);
-my_bool net_write_command(NET *net,unsigned char command,
- const unsigned char *header, size_t head_len,
- const unsigned char *packet, size_t len);
-int net_real_write(NET *net,const unsigned char *packet, size_t len);
-unsigned long my_net_read_packet(NET *net, my_bool read_from_server);
-unsigned long my_net_read_packet_reallen(NET *net, my_bool read_from_server,
- unsigned long* reallen);
-struct sockaddr;
-int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
- unsigned int timeout);
-struct my_rnd_struct;
-}
-enum Item_result
-{
- STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT,
- TIME_RESULT
-};
-typedef struct st_udf_args
-{
- unsigned int arg_count;
- enum Item_result *arg_type;
- char **args;
- unsigned long *lengths;
- char *maybe_null;
- const char **attributes;
- unsigned long *attribute_lengths;
- void *extension;
-} UDF_ARGS;
-typedef struct st_udf_init
-{
- my_bool maybe_null;
- unsigned int decimals;
- unsigned long max_length;
- char *ptr;
- my_bool const_item;
- void *extension;
-} UDF_INIT;
-extern "C" {
-void create_random_string(char *to, unsigned int length,
- struct my_rnd_struct *rand_st);
-void hash_password(unsigned long *to, const char *password, unsigned int password_len);
-void make_scrambled_password_323(char *to, const char *password);
-void scramble_323(char *to, const char *message, const char *password);
-my_bool check_scramble_323(const unsigned char *reply, const char *message,
- unsigned long *salt);
-void get_salt_from_password_323(unsigned long *res, const char *password);
-void make_scrambled_password(char *to, const char *password);
-void scramble(char *to, const char *message, const char *password);
-my_bool check_scramble(const unsigned char *reply, const char *message,
- const unsigned char *hash_stage2);
-void get_salt_from_password(unsigned char *res, const char *password);
-char *octet2hex(char *to, const char *str, size_t len);
-char *get_tty_password(const char *opt_message);
-void get_tty_password_buff(const char *opt_message, char *to, size_t length);
-const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
-my_bool my_thread_init(void);
-void my_thread_end(void);
-}
-typedef long my_time_t;
-enum enum_mysql_timestamp_type
-{
- MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
- MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
-};
-typedef struct st_mysql_time
-{
- unsigned int year, month, day, hour, minute, second;
- unsigned long second_part;
- my_bool neg;
- enum enum_mysql_timestamp_type time_type;
-} MYSQL_TIME;
-extern "C" {
-typedef struct st_list {
- struct st_list *prev,*next;
- void *data;
-} LIST;
-typedef int (*list_walk_action)(void *,void *);
-extern LIST *list_add(LIST *root,LIST *element);
-extern LIST *list_delete(LIST *root,LIST *element);
-extern LIST *list_cons(void *data,LIST *root);
-extern LIST *list_reverse(LIST *root);
-extern void list_free(LIST *root,unsigned int free_data);
-extern unsigned int list_length(LIST *);
-extern int list_walk(LIST *,list_walk_action action,unsigned char * argument);
-}
-extern unsigned int mariadb_deinitialize_ssl;
-extern unsigned int mysql_port;
-extern char *mysql_unix_port;
-typedef struct st_mysql_const_lex_string MARIADB_CONST_STRING;
-typedef struct st_mysql_field {
- char *name;
- char *org_name;
- char *table;
- char *org_table;
- char *db;
- char *catalog;
- char *def;
- unsigned long length;
- unsigned long max_length;
- unsigned int name_length;
- unsigned int org_name_length;
- unsigned int table_length;
- unsigned int org_table_length;
- unsigned int db_length;
- unsigned int catalog_length;
- unsigned int def_length;
- unsigned int flags;
- unsigned int decimals;
- unsigned int charsetnr;
- enum enum_field_types type;
- void *extension;
-} MYSQL_FIELD;
-typedef char **MYSQL_ROW;
-typedef unsigned int MYSQL_FIELD_OFFSET;
-typedef unsigned long long my_ulonglong;
-extern "C" {
-}
-extern "C" {
-struct PSI_thread;
-typedef unsigned int PSI_memory_key;
-}
-extern "C" {
-typedef struct st_used_mem
-{
- struct st_used_mem *next;
- size_t left;
- size_t size;
-} USED_MEM;
-typedef struct st_mem_root
-{
- USED_MEM *free;
- USED_MEM *used;
- USED_MEM *pre_alloc;
- size_t min_malloc;
- size_t block_size;
- unsigned int block_num;
- unsigned int first_block_usage;
- void (*error_handler)(void);
- PSI_memory_key m_psi_key;
-} MEM_ROOT;
-}
-typedef struct st_typelib {
- unsigned int count;
- const char *name;
- const char **type_names;
- unsigned int *type_lengths;
-} TYPELIB;
-extern my_ulonglong find_typeset(const char *x, TYPELIB *typelib,
- int *error_position);
-extern int find_type_with_warning(const char *x, TYPELIB *typelib,
- const char *option);
-extern int find_type(const char *x, const TYPELIB *typelib, unsigned int flags);
-extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
-extern const char *get_type(TYPELIB *typelib,unsigned int nr);
-extern TYPELIB *copy_typelib(MEM_ROOT *root, const TYPELIB *from);
-extern TYPELIB sql_protocol_typelib;
-my_ulonglong find_set_from_flags(const TYPELIB *lib, unsigned int default_name,
- my_ulonglong cur_set, my_ulonglong default_set,
- const char *str, unsigned int length,
- char **err_pos, unsigned int *err_len);
-typedef struct st_mysql_rows {
- struct st_mysql_rows *next;
- MYSQL_ROW data;
- unsigned long length;
-} MYSQL_ROWS;
-typedef MYSQL_ROWS *MYSQL_ROW_OFFSET;
-typedef struct embedded_query_result EMBEDDED_QUERY_RESULT;
-typedef struct st_mysql_data {
- MYSQL_ROWS *data;
- struct embedded_query_result *embedded_info;
- MEM_ROOT alloc;
- my_ulonglong rows;
- unsigned int fields;
- void *extension;
-} MYSQL_DATA;
-enum mysql_option
-{
- MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
- MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
- MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
- MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
- MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
- MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
- MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
- MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,
- MYSQL_OPT_BIND,
- MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CERT,
- MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH, MYSQL_OPT_SSL_CIPHER,
- MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
- MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_CONNECT_ATTR_ADD,
- MYSQL_OPT_CONNECT_ATTR_DELETE,
- MYSQL_SERVER_PUBLIC_KEY,
- MYSQL_ENABLE_CLEARTEXT_PLUGIN,
- MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
- MYSQL_PROGRESS_CALLBACK=5999,
- MYSQL_OPT_NONBLOCK,
- MYSQL_OPT_USE_THREAD_SPECIFIC_MEMORY
-};
-struct st_mysql_options_extention;
-struct st_mysql_options {
- unsigned int connect_timeout, read_timeout, write_timeout;
- unsigned int port, protocol;
- unsigned long client_flag;
- char *host,*user,*password,*unix_socket,*db;
- struct st_dynamic_array *init_commands;
- char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
- char *ssl_key;
- char *ssl_cert;
- char *ssl_ca;
- char *ssl_capath;
- char *ssl_cipher;
- char *shared_memory_base_name;
- unsigned long max_allowed_packet;
- my_bool use_ssl;
- my_bool compress,named_pipe;
- my_bool use_thread_specific_memory;
- my_bool unused2;
- my_bool unused3;
- my_bool unused4;
- enum mysql_option methods_to_use;
- char *client_ip;
- my_bool secure_auth;
- my_bool report_data_truncation;
- int (*local_infile_init)(void **, const char *, void *);
- int (*local_infile_read)(void *, char *, unsigned int);
- void (*local_infile_end)(void *);
- int (*local_infile_error)(void *, char *, unsigned int);
- void *local_infile_userdata;
- struct st_mysql_options_extention *extension;
-};
-enum mysql_status
-{
- MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT,
- MYSQL_STATUS_STATEMENT_GET_RESULT
-};
-enum mysql_protocol_type
-{
- MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
- MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
-};
-typedef struct character_set
-{
- unsigned int number;
- unsigned int state;
- const char *csname;
- const char *name;
- const char *comment;
- const char *dir;
- unsigned int mbminlen;
- unsigned int mbmaxlen;
-} MY_CHARSET_INFO;
-struct st_mysql_methods;
-struct st_mysql_stmt;
-typedef struct st_mysql
-{
- NET net;
- unsigned char *connector_fd;
- char *host,*user,*passwd,*unix_socket,*server_version,*host_info;
- char *info, *db;
- const struct charset_info_st *charset;
- MYSQL_FIELD *fields;
- MEM_ROOT field_alloc;
- my_ulonglong affected_rows;
- my_ulonglong insert_id;
- my_ulonglong extra_info;
- unsigned long thread_id;
- unsigned long packet_length;
- unsigned int port;
- unsigned long client_flag,server_capabilities;
- unsigned int protocol_version;
- unsigned int field_count;
- unsigned int server_status;
- unsigned int server_language;
- unsigned int warning_count;
- struct st_mysql_options options;
- enum mysql_status status;
- my_bool free_me;
- my_bool reconnect;
- char scramble[20 +1];
- my_bool auto_local_infile;
- void *unused2, *unused3, *unused4, *unused5;
- LIST *stmts;
- const struct st_mysql_methods *methods;
- void *thd;
- my_bool *unbuffered_fetch_owner;
- char *info_buffer;
- void *extension;
-} MYSQL;
-typedef struct st_mysql_res {
- my_ulonglong row_count;
- MYSQL_FIELD *fields;
- MYSQL_DATA *data;
- MYSQL_ROWS *data_cursor;
- unsigned long *lengths;
- MYSQL *handle;
- const struct st_mysql_methods *methods;
- MYSQL_ROW row;
- MYSQL_ROW current_row;
- MEM_ROOT field_alloc;
- unsigned int field_count, current_field;
- my_bool eof;
- my_bool unbuffered_fetch_cancelled;
- void *extension;
-} MYSQL_RES;
-typedef struct st_mysql_parameters
-{
- unsigned long *p_max_allowed_packet;
- unsigned long *p_net_buffer_length;
- void *extension;
-} MYSQL_PARAMETERS;
-int mysql_server_init(int argc, char **argv, char **groups);
-void mysql_server_end(void);
-MYSQL_PARAMETERS * mysql_get_parameters(void);
-my_bool mysql_thread_init(void);
-void mysql_thread_end(void);
-my_ulonglong mysql_num_rows(MYSQL_RES *res);
-unsigned int mysql_num_fields(MYSQL_RES *res);
-my_bool mysql_eof(MYSQL_RES *res);
-MYSQL_FIELD * mysql_fetch_field_direct(MYSQL_RES *res,
- unsigned int fieldnr);
-MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES *res);
-MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *res);
-MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *res);
-int mariadb_field_attr(MARIADB_CONST_STRING *attr,
- const MYSQL_FIELD *field,
- enum mariadb_field_attr_t type);
-unsigned int mysql_field_count(MYSQL *mysql);
-my_ulonglong mysql_affected_rows(MYSQL *mysql);
-my_ulonglong mysql_insert_id(MYSQL *mysql);
-unsigned int mysql_errno(MYSQL *mysql);
-const char * mysql_error(MYSQL *mysql);
-const char * mysql_sqlstate(MYSQL *mysql);
-unsigned int mysql_warning_count(MYSQL *mysql);
-const char * mysql_info(MYSQL *mysql);
-unsigned long mysql_thread_id(MYSQL *mysql);
-const char * mysql_character_set_name(MYSQL *mysql);
-int mysql_set_character_set(MYSQL *mysql, const char *csname);
-int mysql_set_character_set_start(int *ret, MYSQL *mysql,
- const char *csname);
-int mysql_set_character_set_cont(int *ret, MYSQL *mysql,
- int status);
-MYSQL * mysql_init(MYSQL *mysql);
-my_bool mysql_ssl_set(MYSQL *mysql, const char *key,
- const char *cert, const char *ca,
- const char *capath, const char *cipher);
-const char * mysql_get_ssl_cipher(MYSQL *mysql);
-my_bool mysql_change_user(MYSQL *mysql, const char *user,
- const char *passwd, const char *db);
-int mysql_change_user_start(my_bool *ret, MYSQL *mysql,
- const char *user,
- const char *passwd,
- const char *db);
-int mysql_change_user_cont(my_bool *ret, MYSQL *mysql,
- int status);
-MYSQL * mysql_real_connect(MYSQL *mysql, const char *host,
- const char *user,
- const char *passwd,
- const char *db,
- unsigned int port,
- const char *unix_socket,
- unsigned long clientflag);
-int mysql_real_connect_start(MYSQL **ret, MYSQL *mysql,
- const char *host,
- const char *user,
- const char *passwd,
- const char *db,
- unsigned int port,
- const char *unix_socket,
- unsigned long clientflag);
-int mysql_real_connect_cont(MYSQL **ret, MYSQL *mysql,
- int status);
-int mysql_select_db(MYSQL *mysql, const char *db);
-int mysql_select_db_start(int *ret, MYSQL *mysql,
- const char *db);
-int mysql_select_db_cont(int *ret, MYSQL *mysql,
- int status);
-int mysql_query(MYSQL *mysql, const char *q);
-int mysql_query_start(int *ret, MYSQL *mysql,
- const char *q);
-int mysql_query_cont(int *ret, MYSQL *mysql,
- int status);
-int mysql_send_query(MYSQL *mysql, const char *q,
- unsigned long length);
-int mysql_send_query_start(int *ret, MYSQL *mysql,
- const char *q,
- unsigned long length);
-int mysql_send_query_cont(int *ret, MYSQL *mysql,
- int status);
-int mysql_real_query(MYSQL *mysql, const char *q,
- unsigned long length);
-int mysql_real_query_start(int *ret, MYSQL *mysql,
- const char *q,
- unsigned long length);
-int mysql_real_query_cont(int *ret, MYSQL *mysql,
- int status);
-MYSQL_RES * mysql_store_result(MYSQL *mysql);
-int mysql_store_result_start(MYSQL_RES **ret, MYSQL *mysql);
-int mysql_store_result_cont(MYSQL_RES **ret, MYSQL *mysql,
- int status);
-MYSQL_RES * mysql_use_result(MYSQL *mysql);
-void mysql_get_character_set_info(MYSQL *mysql,
- MY_CHARSET_INFO *charset);
-void
-mysql_set_local_infile_handler(MYSQL *mysql,
- int (*local_infile_init)(void **, const char *,
- void *),
- int (*local_infile_read)(void *, char *,
- unsigned int),
- void (*local_infile_end)(void *),
- int (*local_infile_error)(void *, char*,
- unsigned int),
- void *);
-void
-mysql_set_local_infile_default(MYSQL *mysql);
-int mysql_shutdown(MYSQL *mysql,
- enum mysql_enum_shutdown_level
- shutdown_level);
-int mysql_shutdown_start(int *ret, MYSQL *mysql,
- enum mysql_enum_shutdown_level
- shutdown_level);
-int mysql_shutdown_cont(int *ret, MYSQL *mysql,
- int status);
-int mysql_dump_debug_info(MYSQL *mysql);
-int mysql_dump_debug_info_start(int *ret, MYSQL *mysql);
-int mysql_dump_debug_info_cont(int *ret, MYSQL *mysql,
- int status);
-int mysql_refresh(MYSQL *mysql,
- unsigned int refresh_options);
-int mysql_refresh_start(int *ret, MYSQL *mysql,
- unsigned int refresh_options);
-int mysql_refresh_cont(int *ret, MYSQL *mysql, int status);
-int mysql_kill(MYSQL *mysql,unsigned long pid);
-int mysql_kill_start(int *ret, MYSQL *mysql,
- unsigned long pid);
-int mysql_kill_cont(int *ret, MYSQL *mysql, int status);
-int mysql_set_server_option(MYSQL *mysql,
- enum enum_mysql_set_option
- option);
-int mysql_set_server_option_start(int *ret, MYSQL *mysql,
- enum enum_mysql_set_option
- option);
-int mysql_set_server_option_cont(int *ret, MYSQL *mysql,
- int status);
-int mysql_ping(MYSQL *mysql);
-int mysql_ping_start(int *ret, MYSQL *mysql);
-int mysql_ping_cont(int *ret, MYSQL *mysql, int status);
-const char * mysql_stat(MYSQL *mysql);
-int mysql_stat_start(const char **ret, MYSQL *mysql);
-int mysql_stat_cont(const char **ret, MYSQL *mysql,
- int status);
-const char * mysql_get_server_info(MYSQL *mysql);
-const char * mysql_get_server_name(MYSQL *mysql);
-const char * mysql_get_client_info(void);
-unsigned long mysql_get_client_version(void);
-const char * mysql_get_host_info(MYSQL *mysql);
-unsigned long mysql_get_server_version(MYSQL *mysql);
-unsigned int mysql_get_proto_info(MYSQL *mysql);
-MYSQL_RES * mysql_list_dbs(MYSQL *mysql,const char *wild);
-int mysql_list_dbs_start(MYSQL_RES **ret, MYSQL *mysql,
- const char *wild);
-int mysql_list_dbs_cont(MYSQL_RES **ret, MYSQL *mysql,
- int status);
-MYSQL_RES * mysql_list_tables(MYSQL *mysql,const char *wild);
-int mysql_list_tables_start(MYSQL_RES **ret, MYSQL *mysql,
- const char *wild);
-int mysql_list_tables_cont(MYSQL_RES **ret, MYSQL *mysql,
- int status);
-MYSQL_RES * mysql_list_processes(MYSQL *mysql);
-int mysql_list_processes_start(MYSQL_RES **ret,
- MYSQL *mysql);
-int mysql_list_processes_cont(MYSQL_RES **ret, MYSQL *mysql,
- int status);
-int mysql_options(MYSQL *mysql,enum mysql_option option,
- const void *arg);
-int mysql_options4(MYSQL *mysql,enum mysql_option option,
- const void *arg1, const void *arg2);
-void mysql_free_result(MYSQL_RES *result);
-int mysql_free_result_start(MYSQL_RES *result);
-int mysql_free_result_cont(MYSQL_RES *result, int status);
-void mysql_data_seek(MYSQL_RES *result,
- my_ulonglong offset);
-MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result,
- MYSQL_ROW_OFFSET offset);
-MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result,
- MYSQL_FIELD_OFFSET offset);
-MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
-int mysql_fetch_row_start(MYSQL_ROW *ret,
- MYSQL_RES *result);
-int mysql_fetch_row_cont(MYSQL_ROW *ret, MYSQL_RES *result,
- int status);
-unsigned long * mysql_fetch_lengths(MYSQL_RES *result);
-MYSQL_FIELD * mysql_fetch_field(MYSQL_RES *result);
-MYSQL_RES * mysql_list_fields(MYSQL *mysql, const char *table,
- const char *wild);
-int mysql_list_fields_start(MYSQL_RES **ret, MYSQL *mysql,
- const char *table,
- const char *wild);
-int mysql_list_fields_cont(MYSQL_RES **ret, MYSQL *mysql,
- int status);
-unsigned long mysql_escape_string(char *to,const char *from,
- unsigned long from_length);
-unsigned long mysql_hex_string(char *to,const char *from,
- unsigned long from_length);
-unsigned long mysql_real_escape_string(MYSQL *mysql,
- char *to,const char *from,
- unsigned long length);
-void mysql_debug(const char *debug);
-void myodbc_remove_escape(MYSQL *mysql,char *name);
-unsigned int mysql_thread_safe(void);
-my_bool mysql_embedded(void);
-my_bool mariadb_connection(MYSQL *mysql);
-my_bool mysql_read_query_result(MYSQL *mysql);
-int mysql_read_query_result_start(my_bool *ret,
- MYSQL *mysql);
-int mysql_read_query_result_cont(my_bool *ret,
- MYSQL *mysql, int status);
-enum enum_mysql_stmt_state
-{
- MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
- MYSQL_STMT_FETCH_DONE
-};
-typedef struct st_mysql_bind
-{
- unsigned long *length;
- my_bool *is_null;
- void *buffer;
- my_bool *error;
- unsigned char *row_ptr;
- void (*store_param_func)(NET *net, struct st_mysql_bind *param);
- void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *,
- unsigned char **row);
- void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *,
- unsigned char **row);
- unsigned long buffer_length;
- unsigned long offset;
- unsigned long length_value;
- unsigned int param_number;
- unsigned int pack_length;
- enum enum_field_types buffer_type;
- my_bool error_value;
- my_bool is_unsigned;
- my_bool long_data_used;
- my_bool is_null_value;
- void *extension;
-} MYSQL_BIND;
-struct st_mysql_stmt_extension;
-typedef struct st_mysql_stmt
-{
- MEM_ROOT mem_root;
- LIST list;
- MYSQL *mysql;
- MYSQL_BIND *params;
- MYSQL_BIND *bind;
- MYSQL_FIELD *fields;
- MYSQL_DATA result;
- MYSQL_ROWS *data_cursor;
- int (*read_row_func)(struct st_mysql_stmt *stmt,
- unsigned char **row);
- my_ulonglong affected_rows;
- my_ulonglong insert_id;
- unsigned long stmt_id;
- unsigned long flags;
- unsigned long prefetch_rows;
- unsigned int server_status;
- unsigned int last_errno;
- unsigned int param_count;
- unsigned int field_count;
- enum enum_mysql_stmt_state state;
- char last_error[512];
- char sqlstate[5 +1];
- my_bool send_types_to_server;
- my_bool bind_param_done;
- unsigned char bind_result_done;
- my_bool unbuffered_fetch_cancelled;
- my_bool update_max_length;
- struct st_mysql_stmt_extension *extension;
-} MYSQL_STMT;
-enum enum_stmt_attr_type
-{
- STMT_ATTR_UPDATE_MAX_LENGTH,
- STMT_ATTR_CURSOR_TYPE,
- STMT_ATTR_PREFETCH_ROWS
-};
-MYSQL_STMT * mysql_stmt_init(MYSQL *mysql);
-int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
- unsigned long length);
-int mysql_stmt_prepare_start(int *ret, MYSQL_STMT *stmt,
- const char *query, unsigned long length);
-int mysql_stmt_prepare_cont(int *ret, MYSQL_STMT *stmt, int status);
-int mysql_stmt_execute(MYSQL_STMT *stmt);
-int mysql_stmt_execute_start(int *ret, MYSQL_STMT *stmt);
-int mysql_stmt_execute_cont(int *ret, MYSQL_STMT *stmt, int status);
-int mysql_stmt_fetch(MYSQL_STMT *stmt);
-int mysql_stmt_fetch_start(int *ret, MYSQL_STMT *stmt);
-int mysql_stmt_fetch_cont(int *ret, MYSQL_STMT *stmt, int status);
-int mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg,
- unsigned int column,
- unsigned long offset);
-int mysql_stmt_store_result(MYSQL_STMT *stmt);
-int mysql_stmt_store_result_start(int *ret, MYSQL_STMT *stmt);
-int mysql_stmt_store_result_cont(int *ret, MYSQL_STMT *stmt,
- int status);
-unsigned long mysql_stmt_param_count(MYSQL_STMT * stmt);
-my_bool mysql_stmt_attr_set(MYSQL_STMT *stmt,
- enum enum_stmt_attr_type attr_type,
- const void *attr);
-my_bool mysql_stmt_attr_get(MYSQL_STMT *stmt,
- enum enum_stmt_attr_type attr_type,
- void *attr);
-my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
-my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
-my_bool mysql_stmt_close(MYSQL_STMT * stmt);
-int mysql_stmt_close_start(my_bool *ret, MYSQL_STMT *stmt);
-int mysql_stmt_close_cont(my_bool *ret, MYSQL_STMT * stmt, int status);
-my_bool mysql_stmt_reset(MYSQL_STMT * stmt);
-int mysql_stmt_reset_start(my_bool *ret, MYSQL_STMT * stmt);
-int mysql_stmt_reset_cont(my_bool *ret, MYSQL_STMT *stmt, int status);
-my_bool mysql_stmt_free_result(MYSQL_STMT *stmt);
-int mysql_stmt_free_result_start(my_bool *ret, MYSQL_STMT *stmt);
-int mysql_stmt_free_result_cont(my_bool *ret, MYSQL_STMT *stmt,
- int status);
-my_bool mysql_stmt_send_long_data(MYSQL_STMT *stmt,
- unsigned int param_number,
- const char *data,
- unsigned long length);
-int mysql_stmt_send_long_data_start(my_bool *ret, MYSQL_STMT *stmt,
- unsigned int param_number,
- const char *data,
- unsigned long len);
-int mysql_stmt_send_long_data_cont(my_bool *ret, MYSQL_STMT *stmt,
- int status);
-MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT *stmt);
-MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT *stmt);
-unsigned int mysql_stmt_errno(MYSQL_STMT * stmt);
-const char * mysql_stmt_error(MYSQL_STMT * stmt);
-const char * mysql_stmt_sqlstate(MYSQL_STMT * stmt);
-MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT *stmt,
- MYSQL_ROW_OFFSET offset);
-MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT *stmt);
-void mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset);
-my_ulonglong mysql_stmt_num_rows(MYSQL_STMT *stmt);
-my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt);
-my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt);
-unsigned int mysql_stmt_field_count(MYSQL_STMT *stmt);
-my_bool mysql_commit(MYSQL * mysql);
-int mysql_commit_start(my_bool *ret, MYSQL * mysql);
-int mysql_commit_cont(my_bool *ret, MYSQL * mysql, int status);
-my_bool mysql_rollback(MYSQL * mysql);
-int mysql_rollback_start(my_bool *ret, MYSQL * mysql);
-int mysql_rollback_cont(my_bool *ret, MYSQL * mysql, int status);
-my_bool mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
-int mysql_autocommit_start(my_bool *ret, MYSQL * mysql,
- my_bool auto_mode);
-int mysql_autocommit_cont(my_bool *ret, MYSQL * mysql, int status);
-my_bool mysql_more_results(MYSQL *mysql);
-int mysql_next_result(MYSQL *mysql);
-int mysql_next_result_start(int *ret, MYSQL *mysql);
-int mysql_next_result_cont(int *ret, MYSQL *mysql, int status);
-int mysql_stmt_next_result(MYSQL_STMT *stmt);
-int mysql_stmt_next_result_start(int *ret, MYSQL_STMT *stmt);
-int mysql_stmt_next_result_cont(int *ret, MYSQL_STMT *stmt, int status);
-void mysql_close_slow_part(MYSQL *mysql);
-void mysql_close(MYSQL *sock);
-int mysql_close_start(MYSQL *sock);
-int mysql_close_cont(MYSQL *sock, int status);
-my_socket mysql_get_socket(const MYSQL *mysql);
-unsigned int mysql_get_timeout_value(const MYSQL *mysql);
-unsigned int mysql_get_timeout_value_ms(const MYSQL *mysql);
-unsigned long mysql_net_read_packet(MYSQL *mysql);
-unsigned long mysql_net_field_length(unsigned char **packet);
-}
diff --git a/man/mysqld_safe.1 b/man/mysqld_safe.1
index 11e2b3dcf25..da742dc65b7 100644
--- a/man/mysqld_safe.1
+++ b/man/mysqld_safe.1
@@ -340,7 +340,9 @@ program to set the server\'s scheduling priority to the given value\&.
.\}
.\" mysqld_safe: no-auto-restart option
.\" no-auto-restart option: mysqld_safe
-\fB\-\-no\-auto\-restart\fR
+\fB\-\-no\-auto\-restart\fR,
+\fB\-\-nowatch\fR,
+\fB\-\-no\-watch\fR
.sp
Exit after starting mysqld\&.
.RE
@@ -368,21 +370,6 @@ Do not read any option files\&. This must be the first option on the command lin
.sp -1
.IP \(bu 2.3
.\}
-.\" mysqld_safe: no-watch option
-.\" no-watch option: mysqld_safe
-\fB\-\-no\-auto\-restart\fR
-.sp
-Exit after starting mysqld\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
.\" mysqld_safe: numa-interleave option
.\" numa-interleave option: mysqld_safe
\fB\-\-numa\-interleave\fR
diff --git a/mysql-test/include/rowid_filter_debug_kill.inc b/mysql-test/include/rowid_filter_debug_kill.inc
index 6a8c5d3f70d..513efed8a4c 100644
--- a/mysql-test/include/rowid_filter_debug_kill.inc
+++ b/mysql-test/include/rowid_filter_debug_kill.inc
@@ -1,20 +1,14 @@
--source include/have_debug.inc
--source include/have_debug_sync.inc
+--source include/have_sequence.inc
--source include/count_sessions.inc
--echo #
--echo # MDEV-22761 KILL QUERY during rowid_filter, crashes
--echo #
-create table t0(a int);
-insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-
-create table t1(a int);
-insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
-
-# 100 rows
create table t2(a int);
-insert into t2 select A.a + B.a* 10 from t0 A, t0 B;
+insert into t2 select * from seq_0_to_99;
# 10K rows
CREATE TABLE t3 (
@@ -29,11 +23,10 @@ where table_schema=database() and table_name='t3';
insert into t3
select
- A.a,
- A.a,
+ A.seq,
+ B.seq,
'filler-data-filler-data'
-from
- t0 A, t1 B;
+from seq_0_to_99 A, seq_0_to_99 B;
analyze table t2,t3;
@@ -51,7 +44,6 @@ where
t3.key1=t2.a and t3.key2 in (2,3);
connect (con1, localhost, root,,);
-connection con1;
set debug_sync='now WAIT_FOR at_rowid_filter_check';
evalp kill query $target_id;
set debug_sync='now SIGNAL go';
@@ -63,6 +55,5 @@ disconnect con1;
reap;
set debug_sync='RESET';
-drop table t0,t1,t2,t3;
+drop table t2,t3;
--source include/wait_until_count_sessions.inc
-
diff --git a/mysql-test/main/bad_startup_options.result b/mysql-test/main/bad_startup_options.result
new file mode 100644
index 00000000000..b1eed54e172
--- /dev/null
+++ b/mysql-test/main/bad_startup_options.result
@@ -0,0 +1,2 @@
+FOUND 1 /\[ERROR\] SSL error: Unable to get certificate/ in errorlog.err
+# restart
diff --git a/mysql-test/main/bad_startup_options.test b/mysql-test/main/bad_startup_options.test
new file mode 100644
index 00000000000..bd0b6283854
--- /dev/null
+++ b/mysql-test/main/bad_startup_options.test
@@ -0,0 +1,19 @@
+--source include/not_embedded.inc
+--source include/have_ssl_communication.inc
+
+--source include/shutdown_mysqld.inc
+
+# Try to start the server, with bad values for some options.
+# Make sure, the starts fails, and expected message is in the error log
+
+--let errorlog=$MYSQL_TMP_DIR/errorlog.err
+--let SEARCH_FILE=$errorlog
+
+# Bad ssl-cert
+--error 1
+--exec $MYSQLD --defaults-group-suffix=.1 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --ssl-cert=bad --log-error=$errorlog
+--let SEARCH_PATTERN=\[ERROR\] SSL error: Unable to get certificate
+--source include/search_pattern_in_file.inc
+--remove_file $SEARCH_FILE
+
+--source include/start_mysqld.inc
diff --git a/mysql-test/main/gis.result b/mysql-test/main/gis.result
index b547f9f05cd..61deb087424 100644
--- a/mysql-test/main/gis.result
+++ b/mysql-test/main/gis.result
@@ -4977,6 +4977,15 @@ ERROR HY000: Illegal parameter data type point for operation 'is_free_lock'
SELECT IS_USED_LOCK(POINT(1,1));
ERROR HY000: Illegal parameter data type point for operation 'is_used_lock'
#
+# MDEV-26161 crash in Gis_point::calculate_haversine
+#
+select st_distance_sphere(x'01030000000400000004000000000000', multipoint(point(124,204)), 10);
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+select st_distance_sphere(x'010300000004000000040000', multipoint(point(124,204)), 10);
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+select st_distance_sphere(x'010300000001000000040000', multipoint(point(124,204)), 10);
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+#
# End of 10.3 tests
#
#
diff --git a/mysql-test/main/gis.test b/mysql-test/main/gis.test
index f0c9a69c503..2d3025308bc 100644
--- a/mysql-test/main/gis.test
+++ b/mysql-test/main/gis.test
@@ -3089,6 +3089,15 @@ SELECT IS_FREE_LOCK(POINT(1,1));
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT IS_USED_LOCK(POINT(1,1));
+--echo #
+--echo # MDEV-26161 crash in Gis_point::calculate_haversine
+--echo #
+--error ER_CANT_CREATE_GEOMETRY_OBJECT
+select st_distance_sphere(x'01030000000400000004000000000000', multipoint(point(124,204)), 10);
+--error ER_CANT_CREATE_GEOMETRY_OBJECT
+select st_distance_sphere(x'010300000004000000040000', multipoint(point(124,204)), 10);
+--error ER_CANT_CREATE_GEOMETRY_OBJECT
+select st_distance_sphere(x'010300000001000000040000', multipoint(point(124,204)), 10);
--echo #
--echo # End of 10.3 tests
diff --git a/mysql-test/main/join_cache.result b/mysql-test/main/join_cache.result
index 3ab6c1cf310..e93ae5055c8 100644
--- a/mysql-test/main/join_cache.result
+++ b/mysql-test/main/join_cache.result
@@ -853,7 +853,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country hash_ALL PRIMARY #hash#PRIMARY 3 world.City.Country 239 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE CountryLanguage hash_ALL|filter PRIMARY,Percentage #hash#PRIMARY|Percentage 3|4 world.City.Country 984 (19%) Using where; Using join buffer (flat, BNLH join); Using rowid filter
+1 SIMPLE CountryLanguage hash_ALL PRIMARY,Percentage #hash#PRIMARY 3 world.City.Country 984 Using where; Using join buffer (flat, BNLH join)
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -1053,7 +1053,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country hash_ALL PRIMARY #hash#PRIMARY 3 world.City.Country 239 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE CountryLanguage hash_ALL|filter PRIMARY,Percentage #hash#PRIMARY|Percentage 3|4 world.City.Country 984 (19%) Using where; Using join buffer (incremental, BNLH join); Using rowid filter
+1 SIMPLE CountryLanguage hash_ALL PRIMARY,Percentage #hash#PRIMARY 3 world.City.Country 984 Using where; Using join buffer (incremental, BNLH join)
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -1312,7 +1312,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE CountryLanguage ref|filter PRIMARY,Percentage PRIMARY|Percentage 3|4 world.City.Country 4 (19%) Using index condition(BKA); Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE CountryLanguage ref PRIMARY,Percentage PRIMARY 3 world.City.Country 4 Using index condition(BKA); Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -1509,7 +1509,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE CountryLanguage ref|filter PRIMARY,Percentage PRIMARY|Percentage 3|4 world.City.Country 4 (19%) Using index condition(BKA); Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE CountryLanguage ref PRIMARY,Percentage PRIMARY 3 world.City.Country 4 Using index condition(BKA); Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -1706,7 +1706,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
-1 SIMPLE CountryLanguage ref|filter PRIMARY,Percentage PRIMARY|Percentage 3|4 world.City.Country 4 (19%) Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE CountryLanguage ref PRIMARY,Percentage PRIMARY 3 world.City.Country 4 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -1903,7 +1903,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
-1 SIMPLE CountryLanguage ref|filter PRIMARY,Percentage PRIMARY|Percentage 3|4 world.City.Country 4 (19%) Using index condition(BKA); Using where; Using join buffer (incremental, BKAH join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE CountryLanguage ref PRIMARY,Percentage PRIMARY 3 world.City.Country 4 Using index condition(BKA); Using where; Using join buffer (incremental, BKAH join); Key-ordered Rowid-ordered scan
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -2104,7 +2104,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country hash_ALL PRIMARY #hash#PRIMARY 3 world.City.Country 239 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE CountryLanguage hash_ALL|filter PRIMARY,Percentage #hash#PRIMARY|Percentage 3|4 world.City.Country 984 (19%) Using where; Using join buffer (flat, BNLH join); Using rowid filter
+1 SIMPLE CountryLanguage hash_ALL PRIMARY,Percentage #hash#PRIMARY 3 world.City.Country 984 Using where; Using join buffer (flat, BNLH join)
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -2208,7 +2208,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country hash_ALL PRIMARY #hash#PRIMARY 3 world.City.Country 239 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE CountryLanguage hash_ALL|filter PRIMARY,Percentage #hash#PRIMARY|Percentage 3|4 world.City.Country 984 (19%) Using where; Using join buffer (incremental, BNLH join); Using rowid filter
+1 SIMPLE CountryLanguage hash_ALL PRIMARY,Percentage #hash#PRIMARY 3 world.City.Country 984 Using where; Using join buffer (incremental, BNLH join)
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -2312,7 +2312,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE CountryLanguage ref|filter PRIMARY,Percentage PRIMARY|Percentage 3|4 world.City.Country 4 (19%) Using index condition(BKA); Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE CountryLanguage ref PRIMARY,Percentage PRIMARY 3 world.City.Country 4 Using index condition(BKA); Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -2416,7 +2416,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE CountryLanguage ref|filter PRIMARY,Percentage PRIMARY|Percentage 3|4 world.City.Country 4 (19%) Using index condition(BKA); Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE CountryLanguage ref PRIMARY,Percentage PRIMARY 3 world.City.Country 4 Using index condition(BKA); Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -2520,7 +2520,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
-1 SIMPLE CountryLanguage ref|filter PRIMARY,Percentage PRIMARY|Percentage 3|4 world.City.Country 4 (19%) Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE CountryLanguage ref PRIMARY,Percentage PRIMARY 3 world.City.Country 4 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
@@ -2624,7 +2624,7 @@ LENGTH(Language) < LENGTH(City.Name) - 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE City ALL Country NULL NULL NULL 4079 Using where
1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
-1 SIMPLE CountryLanguage ref|filter PRIMARY,Percentage PRIMARY|Percentage 3|4 world.City.Country 4 (19%) Using index condition(BKA); Using where; Using join buffer (incremental, BKAH join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE CountryLanguage ref PRIMARY,Percentage PRIMARY 3 world.City.Country 4 Using index condition(BKA); Using where; Using join buffer (incremental, BKAH join); Key-ordered Rowid-ordered scan
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
diff --git a/mysql-test/main/join_nested_jcl6.result b/mysql-test/main/join_nested_jcl6.result
index 5db6d030965..221a3118b8a 100644
--- a/mysql-test/main/join_nested_jcl6.result
+++ b/mysql-test/main/join_nested_jcl6.result
@@ -2033,7 +2033,7 @@ ON t6.b >= 2 AND t5.b=t7.b AND
(t8.a > 0 OR t8.c IS NULL) AND t6.a>0 AND t7.a>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t5 ALL NULL NULL NULL NULL 3
-1 SIMPLE t7 ref|filter PRIMARY,b_i b_i|PRIMARY 5|4 test.t5.b 2 (29%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE t7 range PRIMARY,b_i PRIMARY 4 NULL 2 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
1 SIMPLE t6 range|filter PRIMARY,b_i PRIMARY|b_i 4|5 NULL 3 (86%) Using where; Rowid-ordered scan; Using join buffer (incremental, BNL join); Using rowid filter
1 SIMPLE t8 ref b_i b_i 5 test.t5.b 2 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result
index 31fa5f8c8d5..4c2fbcf1dd6 100644
--- a/mysql-test/main/long_unique_bugs.result
+++ b/mysql-test/main/long_unique_bugs.result
@@ -317,6 +317,15 @@ ERROR 23000: Duplicate entry '1' for key 'v2'
update t1,t2 set v1 = v2 , v5 = 0;
ERROR 23000: Duplicate entry '-128' for key 'v1'
drop table t1, t2;
+CREATE TABLE t1 (f TEXT UNIQUE);
+INSERT INTO t1 VALUES (NULL),(NULL);
+UPDATE t1 SET f = '';
+ERROR 23000: Duplicate entry '' for key 'f'
+SELECT * FROM t1;
+f
+
+NULL
+DROP TABLE t1;
#
# MDEV-21540 Initialization of already inited long unique index on reorganize partition
#
diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test
index e313d1d434e..f2160bb7f68 100644
--- a/mysql-test/main/long_unique_bugs.test
+++ b/mysql-test/main/long_unique_bugs.test
@@ -397,6 +397,17 @@ update t1 set v2 = 1, v3 = -128;
update t1,t2 set v1 = v2 , v5 = 0;
drop table t1, t2;
+#
+# MDEV-23264 Unique blobs allow duplicate values upon UPDATE
+#
+
+CREATE TABLE t1 (f TEXT UNIQUE);
+INSERT INTO t1 VALUES (NULL),(NULL);
+--error ER_DUP_ENTRY
+UPDATE t1 SET f = '';
+SELECT * FROM t1;
+DROP TABLE t1;
+
--echo #
--echo # MDEV-21540 Initialization of already inited long unique index on reorganize partition
--echo #
diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result
index 34af8eb6466..b6160bd3525 100644
--- a/mysql-test/main/mysql_upgrade.result
+++ b/mysql-test/main/mysql_upgrade.result
@@ -1319,10 +1319,6 @@ partition p2008 values less than (2009)
);
select length(table_name) from mysql.innodb_table_stats;
length(table_name)
-79
-79
-79
-79
drop table extralongname_extralongname_extralongname_extralongname_ext;
# End of 10.0 tests
set sql_mode=default;
diff --git a/mysql-test/main/order_by_innodb.result b/mysql-test/main/order_by_innodb.result
index 28922ef65f2..1d96a62e423 100644
--- a/mysql-test/main/order_by_innodb.result
+++ b/mysql-test/main/order_by_innodb.result
@@ -1,8 +1,8 @@
-drop table if exists t0,t1,t2,t3;
#
# MDEV-6434: Wrong result (extra rows) with ORDER BY, multiple-column index, InnoDB
#
-CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB;
+CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB
+STATS_PERSISTENT=0;
INSERT INTO t1 (a,c) VALUES
(8, 9),(8, 10),(13, 15),(16, 17),(16, 18),(16, 19),(20, 21),
(20, 22),(20, 24),(20, 25),(20, 26),(20, 27),(20, 28);
@@ -14,8 +14,6 @@ DROP TABLE t1;
#
# MDEV-9457: Poor query plan chosen for ORDER BY query by a recent 10.1
#
-create table t0 (a int);
-insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (
pk int primary key,
key1 int,
@@ -23,15 +21,9 @@ key2 int,
col1 char(255),
key(key1),
key(key2)
-) engine=innodb;
-set @a=-1;
+) engine=innodb stats_persistent=0;
insert into t1
-select
-@a:=@a+1,
-@a,
-@a,
-repeat('abcd', 63)
-from t0 A, t0 B, t0 C, t0 D;
+select seq,seq,seq,repeat('abcd', 63) from seq_0_to_9999;
# The following must NOT use 'index' on PK.
# It should use index_merge(key1,key2) + filesort
explain
@@ -47,7 +39,7 @@ from t1
where key1<3 or key2<3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL # Using sort_union(key1,key2); Using where
-drop table t0, t1;
+drop table t1;
#
# MDEV-18094: Query with order by limit picking index scan over filesort
#
@@ -78,9 +70,12 @@ drop table t1,t0;
# MDEV-14071: wrong results with orderby_uses_equalities=on
# (duplicate of MDEV-13994)
#
-CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB;
-CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB;
-CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB;
+CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB
+STATS_PERSISTENT=0;
+CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB
+STATS_PERSISTENT=0;
+CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB
+STATS_PERSISTENT=0;
INSERT INTO t1 VALUES
(127,0,1),(188,0,1),(206,0,1),(218,0,1),(292,0,1),(338,0,1),(375,0,1),
(381,0,1),(409,0,1),(466,0,1),(469,0,1),(498,0,1),(656,0,1);
@@ -150,7 +145,8 @@ DROP TABLE t1,t2,t3;
#
# MDEV-25858: Query results are incorrect when indexes are added
#
-CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb;
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb
+STATS_PERSISTENT=0;
insert into t1 values (1),(2),(3);
CREATE TABLE t2 (
id int NOT NULL PRIMARY KEY,
@@ -158,7 +154,7 @@ id2 int NOT NULL,
d1 datetime,
d2 timestamp NOT NULL,
KEY id2 (id2)
-) engine=innodb;
+) engine=innodb stats_persistent=0;
insert into t2 values
(1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
(2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
diff --git a/mysql-test/main/order_by_innodb.test b/mysql-test/main/order_by_innodb.test
index af12644c073..fbff825e26e 100644
--- a/mysql-test/main/order_by_innodb.test
+++ b/mysql-test/main/order_by_innodb.test
@@ -2,16 +2,14 @@
# ORDER BY handling (e.g. filesort) tests that require innodb
#
-- source include/have_innodb.inc
-
---disable_warnings
-drop table if exists t0,t1,t2,t3;
---enable_warnings
+-- source include/have_sequence.inc
--echo #
--echo # MDEV-6434: Wrong result (extra rows) with ORDER BY, multiple-column index, InnoDB
--echo #
-CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB;
+CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB
+STATS_PERSISTENT=0;
INSERT INTO t1 (a,c) VALUES
(8, 9),(8, 10),(13, 15),(16, 17),(16, 18),(16, 19),(20, 21),
@@ -24,9 +22,6 @@ DROP TABLE t1;
--echo #
--echo # MDEV-9457: Poor query plan chosen for ORDER BY query by a recent 10.1
--echo #
-create table t0 (a int);
-insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-
create table t1 (
pk int primary key,
key1 int,
@@ -34,16 +29,10 @@ create table t1 (
col1 char(255),
key(key1),
key(key2)
-) engine=innodb;
+) engine=innodb stats_persistent=0;
-set @a=-1;
insert into t1
-select
- @a:=@a+1,
- @a,
- @a,
- repeat('abcd', 63)
-from t0 A, t0 B, t0 C, t0 D;
+select seq,seq,seq,repeat('abcd', 63) from seq_0_to_9999;
--echo # The following must NOT use 'index' on PK.
--echo # It should use index_merge(key1,key2) + filesort
@@ -60,7 +49,7 @@ select *
from t1
where key1<3 or key2<3;
-drop table t0, t1;
+drop table t1;
--echo #
--echo # MDEV-18094: Query with order by limit picking index scan over filesort
@@ -93,9 +82,12 @@ drop table t1,t0;
--echo # (duplicate of MDEV-13994)
--echo #
-CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB;
-CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB;
-CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB;
+CREATE TABLE t1 (i int, j int, z int,PRIMARY KEY (i,j), KEY (z)) ENGINE=InnoDB
+STATS_PERSISTENT=0;
+CREATE TABLE t2 (i int, j int, PRIMARY KEY (i,j)) ENGINE=InnoDB
+STATS_PERSISTENT=0;
+CREATE TABLE t3 (j int, n varchar(5), PRIMARY KEY (j)) ENGINE=InnoDB
+STATS_PERSISTENT=0;
INSERT INTO t1 VALUES
(127,0,1),(188,0,1),(206,0,1),(218,0,1),(292,0,1),(338,0,1),(375,0,1),
@@ -139,7 +131,8 @@ DROP TABLE t1,t2,t3;
--echo # MDEV-25858: Query results are incorrect when indexes are added
--echo #
-CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb;
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb
+STATS_PERSISTENT=0;
insert into t1 values (1),(2),(3);
CREATE TABLE t2 (
@@ -148,7 +141,7 @@ CREATE TABLE t2 (
d1 datetime,
d2 timestamp NOT NULL,
KEY id2 (id2)
-) engine=innodb;
+) engine=innodb stats_persistent=0;
insert into t2 values
(1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
diff --git a/mysql-test/main/partition_alter.result b/mysql-test/main/partition_alter.result
index 539f896f54f..5bf8edea878 100644
--- a/mysql-test/main/partition_alter.result
+++ b/mysql-test/main/partition_alter.result
@@ -213,6 +213,29 @@ delete from t order by b limit 1;
drop table t;
# End of 10.3 tests
#
+# Start of 10.4 tests
+#
+#
+# MDEV-28545 MyISAM reorganize partition corrupt older table format
+#
+SET GLOBAL mysql56_temporal_format=OFF;
+CREATE TABLE t (ts timestamp, KEY (ts)) ENGINE=MyISAM
+PARTITION BY RANGE (unix_timestamp(ts)) (
+PARTITION p1 VALUES LESS THAN (1645398000),
+PARTITION pn VALUES LESS THAN MAXVALUE
+);
+SET GLOBAL mysql56_temporal_format=ON;
+FLUSH TABLES;
+ALTER TABLE t DROP PARTITION p1;
+CHECK TABLE t;
+Table Op Msg_type Msg_text
+test.t check status OK
+DROP TABLE t;
+SET GLOBAL mysql56_temporal_format=DEFAULT;
+#
+# End of 10.4 tests
+#
+#
# MDEV-28576 RENAME COLUMN with NOCOPY algorithm leads to corrupt partitioned table
#
create table t (a int)
diff --git a/mysql-test/main/partition_alter.test b/mysql-test/main/partition_alter.test
index 45fa8d280fe..593169d093d 100644
--- a/mysql-test/main/partition_alter.test
+++ b/mysql-test/main/partition_alter.test
@@ -199,6 +199,32 @@ drop table t;
--echo # End of 10.3 tests
--echo #
+--echo # Start of 10.4 tests
+--echo #
+
+--echo #
+--echo # MDEV-28545 MyISAM reorganize partition corrupt older table format
+--echo #
+
+SET GLOBAL mysql56_temporal_format=OFF;
+CREATE TABLE t (ts timestamp, KEY (ts)) ENGINE=MyISAM
+PARTITION BY RANGE (unix_timestamp(ts)) (
+ PARTITION p1 VALUES LESS THAN (1645398000),
+ PARTITION pn VALUES LESS THAN MAXVALUE
+);
+
+SET GLOBAL mysql56_temporal_format=ON;
+FLUSH TABLES;
+ALTER TABLE t DROP PARTITION p1;
+CHECK TABLE t;
+DROP TABLE t;
+SET GLOBAL mysql56_temporal_format=DEFAULT;
+
+--echo #
+--echo # End of 10.4 tests
+--echo #
+
+--echo #
--echo # MDEV-28576 RENAME COLUMN with NOCOPY algorithm leads to corrupt partitioned table
--echo #
create table t (a int)
diff --git a/mysql-test/main/partition_pruning.result b/mysql-test/main/partition_pruning.result
index 519bf590b9b..ec0cb144a51 100644
--- a/mysql-test/main/partition_pruning.result
+++ b/mysql-test/main/partition_pruning.result
@@ -2677,7 +2677,7 @@ select * from t1 X, t1 Y
where X.b = Y.b and (X.a=1 or X.a=2) and (Y.a=2 or Y.a=3);
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE X p1,p2 range a,b a 4 NULL 4 Using where
-1 SIMPLE Y p2,p3 ref|filter a,b b|a 4|4 test.X.b 2 (50%) Using where; Using rowid filter
+1 SIMPLE Y p2,p3 ref a,b b 4 test.X.b 2 Using where
explain partitions
select * from t1 X, t1 Y where X.a = Y.a and (X.a=1 or X.a=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result
index 81098118abd..145464896b3 100644
--- a/mysql-test/main/range.result
+++ b/mysql-test/main/range.result
@@ -281,7 +281,7 @@ INSERT INTO t1 VALUES
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref|filter a,b b|a 5|5 const 15 (5%) Using where; Using rowid filter
+1 SIMPLE t1 range|filter a,b a|b 5|5 NULL 2 (41%) Using index condition; Using where; Using rowid filter
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
a b
DROP TABLE t1;
diff --git a/mysql-test/main/range_innodb.result b/mysql-test/main/range_innodb.result
index 6cd1c133b93..eddfbfd0d62 100644
--- a/mysql-test/main/range_innodb.result
+++ b/mysql-test/main/range_innodb.result
@@ -1,15 +1,11 @@
#
# Range optimizer (and related) tests that need InnoDB.
#
-drop table if exists t0, t1, t2;
#
# MDEV-6735: Range checked for each record used with key
#
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-create table t1(a int);
-insert into t1 select A.a + B.a* 10 + C.a * 100 + D.a * 1000
-from t0 A, t0 B, t0 C, t0 D;
create table t2 (
a int,
b int,
@@ -22,12 +18,12 @@ key(b)
) engine=innodb;
insert into t2
select
-a,a,
+seq,seq,
repeat('0123456789', 10),
repeat('0123456789', 10),
repeat('0123456789', 10),
repeat('0123456789', 10)
-from t1;
+from seq_0_to_9999;
analyze table t2;
Table Op Msg_type Msg_text
test.t2 analyze status Engine-independent statistics collected
@@ -37,7 +33,7 @@ explain select * from t0 left join t2 on t2.a <t0.a and t2.b between 50 and 250;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10
1 SIMPLE t2 range a,b b 5 NULL 201 Using where; Using join buffer (flat, BNL join)
-drop table t0,t1,t2;
+drop table t0,t2;
#
# MDEV-10466: constructing an invalid SEL_ARG
#
@@ -89,15 +85,14 @@ drop table t1,t2;
#
set @optimizer_switch_save= @@optimizer_switch;
set optimizer_switch='index_merge_sort_intersection=off';
-create table t0 (a int)engine=innodb;
+create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (
a int, b int, c int,
key(a),key(b),key(c)
)engine=innodb;
insert into t1
-select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a
-from t0 A, t0 B, t0 C, t0 D where D.a<5;
+select a.seq/10, a.seq/10, a.seq from seq_0_to_499 a, seq_0_to_4 b;
SET @saved_dbug = @@GLOBAL.debug_dbug;
set @@global.debug_dbug="+d,ha_index_init_fail";
explain select * from t1 where a=10 and b=10;
diff --git a/mysql-test/main/range_innodb.test b/mysql-test/main/range_innodb.test
index b6dea2fbe06..276b9cea08f 100644
--- a/mysql-test/main/range_innodb.test
+++ b/mysql-test/main/range_innodb.test
@@ -4,12 +4,9 @@
--source include/have_innodb.inc
--source include/have_debug.inc
+--source include/have_sequence.inc
--source include/no_valgrind_without_big.inc
---disable_warnings
-drop table if exists t0, t1, t2;
---enable_warnings
-
--echo #
--echo # MDEV-6735: Range checked for each record used with key
--echo #
@@ -17,10 +14,6 @@ drop table if exists t0, t1, t2;
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-create table t1(a int);
-insert into t1 select A.a + B.a* 10 + C.a * 100 + D.a * 1000
-from t0 A, t0 B, t0 C, t0 D;
-
create table t2 (
a int,
b int,
@@ -34,18 +27,18 @@ create table t2 (
insert into t2
select
- a,a,
+ seq,seq,
repeat('0123456789', 10),
repeat('0123456789', 10),
repeat('0123456789', 10),
repeat('0123456789', 10)
-from t1;
+from seq_0_to_9999;
analyze table t2;
--echo # The following must not use "Range checked for each record":
explain select * from t0 left join t2 on t2.a <t0.a and t2.b between 50 and 250;
-drop table t0,t1,t2;
+drop table t0,t2;
--echo #
@@ -98,15 +91,14 @@ drop table t1,t2;
set @optimizer_switch_save= @@optimizer_switch;
set optimizer_switch='index_merge_sort_intersection=off';
-create table t0 (a int)engine=innodb;
+create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (
a int, b int, c int,
key(a),key(b),key(c)
)engine=innodb;
insert into t1
-select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a
-from t0 A, t0 B, t0 C, t0 D where D.a<5;
+select a.seq/10, a.seq/10, a.seq from seq_0_to_499 a, seq_0_to_4 b;
SET @saved_dbug = @@GLOBAL.debug_dbug;
set @@global.debug_dbug="+d,ha_index_init_fail";
explain select * from t1 where a=10 and b=10;
@@ -122,8 +114,6 @@ set @@optimizer_switch= @optimizer_switch_save;
--echo # MDEV-27262: Index intersection with full scan over an index
--echo #
---source include/have_sequence.inc
-
CREATE TABLE t1 (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
p char(32) DEFAULT NULL,
diff --git a/mysql-test/main/rowid_filter.result b/mysql-test/main/rowid_filter.result
index 63b43204861..f7a340b57c5 100644
--- a/mysql-test/main/rowid_filter.result
+++ b/mysql-test/main/rowid_filter.result
@@ -128,6 +128,7 @@ ANALYZE
"rows": 702,
"selectivity_pct": 11.69025812,
"r_rows": 605,
+ "r_lookups": 510,
"r_selectivity_pct": 11.76470588,
"r_buffer_size": "REPLACED",
"r_filling_time_ms": "REPLACED"
@@ -438,6 +439,7 @@ ANALYZE
"rows": 69,
"selectivity_pct": 4.6,
"r_rows": 71,
+ "r_lookups": 96,
"r_selectivity_pct": 10.41666667,
"r_buffer_size": "REPLACED",
"r_filling_time_ms": "REPLACED"
@@ -692,6 +694,7 @@ ANALYZE
"rows": 702,
"selectivity_pct": 11.69025812,
"r_rows": 605,
+ "r_lookups": 510,
"r_selectivity_pct": 11.76470588,
"r_buffer_size": "REPLACED",
"r_filling_time_ms": "REPLACED"
@@ -722,6 +725,7 @@ ANALYZE
"rows": 139,
"selectivity_pct": 9.266666667,
"r_rows": 144,
+ "r_lookups": 59,
"r_selectivity_pct": 25.42372881,
"r_buffer_size": "REPLACED",
"r_filling_time_ms": "REPLACED"
@@ -998,6 +1002,7 @@ ANALYZE
"rows": 509,
"selectivity_pct": 8.476269775,
"r_rows": 510,
+ "r_lookups": 476,
"r_selectivity_pct": 7.773109244,
"r_buffer_size": "REPLACED",
"r_filling_time_ms": "REPLACED"
@@ -2045,7 +2050,7 @@ EXPLAIN EXTENDED
SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+2 SUBQUERY t2 ref i1,i2 i1 5 const 1 100.00 Using index condition; Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` having 0
DROP TABLE t1,t2;
@@ -2054,7 +2059,7 @@ DROP TABLE t1,t2;
# that uses in expensive subquery
#
CREATE TABLE t1 (
-pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(b1)
+pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(a1), KEY(b1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES
(10,0,'z'),(11,3,'j'),(12,8,'f'),(13,8,'p'),(14,6,'w'),(15,0,'c'),(16,1,'j'),
@@ -2073,21 +2078,31 @@ INSERT INTO t1 VALUES
(101,0,'u'),(102,7,'r'),(103,2,'x'),(104,8,'e'),(105,8,'i'),(106,5,'q'),
(107,8,'z'),(108,3,'k'),(109,65,NULL);
CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 INT, b2 VARCHAR(1)) ENGINE=MyISAM;
-INSERT INTO t2 VALUES (1,1,'x');
+INSERT INTO t2 VALUES (1,1,'i');
INSERT INTO t2 SELECT * FROM t1;
-SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 )
+INSERT INTO t1 SELECT pk1+200, a1, b1 FROM t1;
+INSERT INTO t1 SELECT pk1+400, a1, b1 FROM t1;
+ANALYZE TABLE t1,t2 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 )
WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 );
pk1 a1 b1 pk2 a2 b2
-65 2 a 109 65 NULL
-EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 )
+17 1 f 16 1 j
+37 3 g 36 3 a
+105 8 i 104 8 e
+EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 )
WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 101 100.00 Using where
-1 PRIMARY t1 eq_ref|filter PRIMARY,b1 PRIMARY|b1 4|4 test.t2.a2 1 (87%) 87.00 Using where; Using rowid filter
+1 PRIMARY t1 ref|filter a1,b1 a1|b1 5|4 test.t2.a2 36 (29%) 28.75 Using where; Using rowid filter
2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 100.00 Using index condition
Warnings:
-Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`pk2` AS `pk2`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`pk1` = `test`.`t2`.`a2` and `test`.`t1`.`b1` <= (/* select#2 */ select max(`test`.`t2`.`b2`) from `test`.`t2` where `test`.`t2`.`pk2` <= 1) and `test`.`t2`.`a2` <> `test`.`t2`.`pk2`
-EXPLAIN FORMAT=JSON SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 )
+Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`pk2` AS `pk2`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a1` = `test`.`t2`.`a2` and `test`.`t1`.`b1` <= (/* select#2 */ select max(`test`.`t2`.`b2`) from `test`.`t2` where `test`.`t2`.`pk2` <= 1) and `test`.`t1`.`pk1` + 1 = `test`.`t2`.`pk2` + 2
+EXPLAIN FORMAT=JSON SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 )
WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 );
EXPLAIN
{
@@ -2098,27 +2113,27 @@ EXPLAIN
"access_type": "ALL",
"rows": 101,
"filtered": 100,
- "attached_condition": "t2.a2 <> t2.pk2 and t2.a2 is not null"
+ "attached_condition": "t2.a2 is not null"
},
"table": {
"table_name": "t1",
- "access_type": "eq_ref",
- "possible_keys": ["PRIMARY", "b1"],
- "key": "PRIMARY",
- "key_length": "4",
- "used_key_parts": ["pk1"],
+ "access_type": "ref",
+ "possible_keys": ["a1", "b1"],
+ "key": "a1",
+ "key_length": "5",
+ "used_key_parts": ["a1"],
"ref": ["test.t2.a2"],
"rowid_filter": {
"range": {
"key": "b1",
"used_key_parts": ["b1"]
},
- "rows": 87,
- "selectivity_pct": 87
+ "rows": 115,
+ "selectivity_pct": 28.75
},
- "rows": 1,
- "filtered": 87,
- "attached_condition": "t1.b1 <= (subquery#2)"
+ "rows": 36,
+ "filtered": 28.75,
+ "attached_condition": "t1.b1 <= (subquery#2) and t1.pk1 + 1 = t2.pk2 + 2"
},
"subqueries": [
{
@@ -2185,13 +2200,446 @@ set @save_optimizer_switch= @@optimizer_switch;
SET @@optimizer_switch="index_merge_sort_union=OFF";
CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b));
INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4);
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+ANALYZE table t1 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
explain
SELECT * FROM t1 WHERE a > 0 AND b=0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref|filter a,b b|a 5|5 const 2 (14%) Using where; Using rowid filter
+1 SIMPLE t1 range|filter a,b a|b 5|5 NULL 77 (34%) Using index condition; Using where; Using rowid filter
SELECT * FROM t1 WHERE a > 0 AND b=0;
a b
1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
drop table t1;
SET @@optimizer_switch=@save_optimizer_switch;
+#
+# MDEV-28846: Poor performance when rowid filter contains no elements
+#
+create table t1 (
+pk int primary key auto_increment,
+nm varchar(32),
+fl1 tinyint default 0,
+fl2 tinyint default 0,
+index idx1(nm, fl1),
+index idx2(fl2)
+) engine=myisam;
+create table name (
+pk int primary key auto_increment,
+nm bigint
+) engine=myisam;
+create table flag2 (
+pk int primary key auto_increment,
+fl2 tinyint
+) engine=myisam;
+insert into name(nm) select seq from seq_1_to_1000 order by rand(17);
+insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+select '500%' as a;
+a
+500%
+set optimizer_switch='rowid_filter=on';
+explain
+select * from t1 where nm like '500%' AND fl2 = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where
+analyze format=json
+select * from t1 where nm like '500%' AND fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx1",
+ "key_length": "35",
+ "used_key_parts": ["nm"],
+ "r_loops": 1,
+ "rows": 1,
+ "r_rows": 1,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 49.20000076,
+ "r_filtered": 100,
+ "index_condition": "t1.nm like '500%'",
+ "attached_condition": "t1.fl2 = 0"
+ }
+ }
+}
+select * from t1 where nm like '500%' AND fl2 = 0;
+pk nm fl1 fl2
+517 500 0 0
+truncate table name;
+truncate table flag2;
+truncate table t1;
+insert into name(nm) select seq from seq_1_to_1000 order by rand(17);
+insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+set optimizer_switch='rowid_filter=off';
+explain
+select * from t1 where nm like '500%' AND fl2 = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where
+analyze format=json
+select * from t1 where nm like '500%' AND fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx1",
+ "key_length": "35",
+ "used_key_parts": ["nm"],
+ "r_loops": 1,
+ "rows": 1,
+ "r_rows": 1,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 49.20000076,
+ "r_filtered": 100,
+ "index_condition": "t1.nm like '500%'",
+ "attached_condition": "t1.fl2 = 0"
+ }
+ }
+}
+select * from t1 where nm like '500%' AND fl2 = 0;
+pk nm fl1 fl2
+517 500 0 0
+truncate table name;
+truncate table flag2;
+truncate table t1;
+insert into name(nm) select seq from seq_1_to_1000 order by rand(17);
+insert into flag2(fl2) select seq mod 10 from seq_1_to_1000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+select '607%' as a;
+a
+607%
+set optimizer_switch='rowid_filter=on';
+explain
+select * from t1 where nm like '607%' AND fl2 = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where
+select * from t1 where nm like '607%' AND fl2 = 0;
+pk nm fl1 fl2
+721 607 0 0
+truncate table name;
+truncate table flag2;
+truncate table t1;
+insert into name(nm) select seq from seq_1_to_10000 order by rand(17);
+insert into flag2(fl2) select seq mod 100 from seq_1_to_10000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+select '75%' as a;
+a
+75%
+set optimizer_switch='rowid_filter=on';
+explain
+select * from t1 where nm like '75%' AND fl2 = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref|filter idx1,idx2 idx2|idx1 2|35 const 55 (1%) Using where; Using rowid filter
+analyze format=json
+select * from t1 where nm like '75%' AND fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ref",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx2",
+ "key_length": "2",
+ "used_key_parts": ["fl2"],
+ "ref": ["const"],
+ "rowid_filter": {
+ "range": {
+ "key": "idx1",
+ "used_key_parts": ["nm"]
+ },
+ "rows": 115,
+ "selectivity_pct": 1.15,
+ "r_rows": 111,
+ "r_lookups": 100,
+ "r_selectivity_pct": 2,
+ "r_buffer_size": "REPLACED",
+ "r_filling_time_ms": "REPLACED"
+ },
+ "r_loops": 1,
+ "rows": 55,
+ "r_rows": 2,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 1.149999976,
+ "r_filtered": 100,
+ "attached_condition": "t1.nm like '75%'"
+ }
+ }
+}
+select * from t1 where nm like '75%' AND fl2 = 0;
+pk nm fl1 fl2
+4543 7503 0 0
+7373 7518 0 0
+drop table name, flag2;
+drop table t1;
+create table t1 (
+pk int primary key auto_increment,
+nm char(255),
+fl1 tinyint default 0,
+fl2 int default 0,
+index idx1(nm, fl1),
+index idx2(fl2)
+) engine=myisam;
+create table name (
+pk int primary key auto_increment,
+nm bigint
+) engine=myisam;
+create table flag2 (
+pk int primary key auto_increment,
+fl2 int
+) engine=myisam;
+insert into name(nm) select seq from seq_1_to_10000 order by rand(17);
+insert into flag2(fl2) select seq mod 10 from seq_1_to_10000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+select * from t1
+where
+(
+nm like '3400%' or nm like '3402%' or nm like '3403%' or
+nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or
+nm like '3409%' or
+nm like '3411%' or nm like '3412%' or nm like '3413%' or
+nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or
+nm like '3418%' or nm like '3419%' or
+nm like '3421%' or nm like '3422%' or nm like '3423%' or
+nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or
+nm like '3428%' or nm like '3429%' or
+nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or
+nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or
+nm like '3439%' or
+nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or
+nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or
+nm like '3448%'
+) and fl2 = 0;
+pk nm fl1 fl2
+analyze format=json select * from t1
+where
+(
+nm like '3400%' or nm like '3402%' or nm like '3403%' or
+nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or
+nm like '3409%' or
+nm like '3411%' or nm like '3412%' or nm like '3413%' or
+nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or
+nm like '3418%' or nm like '3419%' or
+nm like '3421%' or nm like '3422%' or nm like '3423%' or
+nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or
+nm like '3428%' or nm like '3429%' or
+nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or
+nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or
+nm like '3439%' or
+nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or
+nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or
+nm like '3448%'
+) and fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ref",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx2",
+ "key_length": "5",
+ "used_key_parts": ["fl2"],
+ "ref": ["const"],
+ "rowid_filter": {
+ "range": {
+ "key": "idx1",
+ "used_key_parts": ["nm"]
+ },
+ "rows": 44,
+ "selectivity_pct": 0.44,
+ "r_rows": 44,
+ "r_lookups": 1000,
+ "r_selectivity_pct": 0,
+ "r_buffer_size": "REPLACED",
+ "r_filling_time_ms": "REPLACED"
+ },
+ "r_loops": 1,
+ "rows": 863,
+ "r_rows": 0,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 0.439999998,
+ "r_filtered": 100,
+ "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'"
+ }
+ }
+}
+create table t0 select * from t1 where nm like '34%';
+delete from t1 using t1,t0 where t1.nm=t0.nm;
+analyze format=json select * from t1
+where
+(
+nm like '3400%' or nm like '3402%' or nm like '3403%' or
+nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or
+nm like '3409%' or
+nm like '3411%' or nm like '3412%' or nm like '3413%' or
+nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or
+nm like '3418%' or nm like '3419%' or
+nm like '3421%' or nm like '3422%' or nm like '3423%' or
+nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or
+nm like '3428%' or nm like '3429%' or
+nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or
+nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or
+nm like '3439%' or
+nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or
+nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or
+nm like '3448%'
+) and fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ref",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx2",
+ "key_length": "5",
+ "used_key_parts": ["fl2"],
+ "ref": ["const"],
+ "rowid_filter": {
+ "range": {
+ "key": "idx1",
+ "used_key_parts": ["nm"]
+ },
+ "rows": 44,
+ "selectivity_pct": 0.44,
+ "r_rows": 0,
+ "r_lookups": 0,
+ "r_selectivity_pct": 0,
+ "r_buffer_size": "REPLACED",
+ "r_filling_time_ms": "REPLACED"
+ },
+ "r_loops": 1,
+ "rows": 853,
+ "r_rows": 0,
+ "filtered": 0.439999998,
+ "r_filtered": 100,
+ "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'"
+ }
+ }
+}
+drop table t0;
+set optimizer_switch='rowid_filter=default';
+drop table name, flag2;
+drop table t1;
set @@use_stat_tables=@save_use_stat_tables;
diff --git a/mysql-test/main/rowid_filter.test b/mysql-test/main/rowid_filter.test
index 163b71b6153..a2543e197ca 100644
--- a/mysql-test/main/rowid_filter.test
+++ b/mysql-test/main/rowid_filter.test
@@ -320,7 +320,7 @@ DROP TABLE t1,t2;
--echo #
CREATE TABLE t1 (
- pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(b1)
+ pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(a1), KEY(b1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES
(10,0,'z'),(11,3,'j'),(12,8,'f'),(13,8,'p'),(14,6,'w'),(15,0,'c'),(16,1,'j'),
@@ -340,11 +340,16 @@ INSERT INTO t1 VALUES
(107,8,'z'),(108,3,'k'),(109,65,NULL);
CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 INT, b2 VARCHAR(1)) ENGINE=MyISAM;
-INSERT INTO t2 VALUES (1,1,'x');
+INSERT INTO t2 VALUES (1,1,'i');
INSERT INTO t2 SELECT * FROM t1;
+INSERT INTO t1 SELECT pk1+200, a1, b1 FROM t1;
+INSERT INTO t1 SELECT pk1+400, a1, b1 FROM t1;
+
+ANALYZE TABLE t1,t2 PERSISTENT FOR ALL;
+
let $q=
-SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 )
+SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 )
WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 );
eval $q;
@@ -399,6 +404,15 @@ set @save_optimizer_switch= @@optimizer_switch;
SET @@optimizer_switch="index_merge_sort_union=OFF";
CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b));
INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4);
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+
+ANALYZE table t1 PERSISTENT FOR ALL;
+
explain
SELECT * FROM t1 WHERE a > 0 AND b=0;
SELECT * FROM t1 WHERE a > 0 AND b=0;
@@ -406,4 +420,194 @@ drop table t1;
SET @@optimizer_switch=@save_optimizer_switch;
+--echo #
+--echo # MDEV-28846: Poor performance when rowid filter contains no elements
+--echo #
+
+--source include/have_sequence.inc
+
+create table t1 (
+ pk int primary key auto_increment,
+ nm varchar(32),
+ fl1 tinyint default 0,
+ fl2 tinyint default 0,
+ index idx1(nm, fl1),
+ index idx2(fl2)
+) engine=myisam;
+
+create table name (
+ pk int primary key auto_increment,
+ nm bigint
+) engine=myisam;
+
+create table flag2 (
+ pk int primary key auto_increment,
+ fl2 tinyint
+) engine=myisam;
+
+insert into name(nm) select seq from seq_1_to_1000 order by rand(17);
+insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19);
+
+insert into t1(nm,fl2)
+ select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+
+analyze table t1 persistent for all;
+
+let $a=
+`select concat((select nm from t1 where fl2=0 order by RAND(13) limit 1),'%')`;
+eval select '$a' as a;
+
+set optimizer_switch='rowid_filter=on';
+eval
+explain
+select * from t1 where nm like '$a' AND fl2 = 0;
+--source include/analyze-format.inc
+eval
+analyze format=json
+select * from t1 where nm like '$a' AND fl2 = 0;
+eval
+select * from t1 where nm like '$a' AND fl2 = 0;
+
+truncate table name;
+truncate table flag2;
+truncate table t1;
+
+insert into name(nm) select seq from seq_1_to_1000 order by rand(17);
+insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19);
+
+insert into t1(nm,fl2)
+ select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+
+analyze table t1 persistent for all;
+
+set optimizer_switch='rowid_filter=off';
+eval
+explain
+select * from t1 where nm like '$a' AND fl2 = 0;
+--source include/analyze-format.inc
+eval
+analyze format=json
+select * from t1 where nm like '$a' AND fl2 = 0;
+eval
+select * from t1 where nm like '$a' AND fl2 = 0;
+
+truncate table name;
+truncate table flag2;
+truncate table t1;
+
+insert into name(nm) select seq from seq_1_to_1000 order by rand(17);
+insert into flag2(fl2) select seq mod 10 from seq_1_to_1000 order by rand(19);
+
+insert into t1(nm,fl2)
+ select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+
+analyze table t1 persistent for all;
+
+let $a=
+`select concat((select nm from t1 where fl2=0 order by RAND(13) limit 1),'%')`;
+eval select '$a' as a;
+
+set optimizer_switch='rowid_filter=on';
+eval
+explain
+select * from t1 where nm like '$a' AND fl2 = 0;
+eval
+select * from t1 where nm like '$a' AND fl2 = 0;
+
+truncate table name;
+truncate table flag2;
+truncate table t1;
+
+insert into name(nm) select seq from seq_1_to_10000 order by rand(17);
+insert into flag2(fl2) select seq mod 100 from seq_1_to_10000 order by rand(19);
+
+insert into t1(nm,fl2)
+ select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+
+analyze table t1 persistent for all;
+
+let $a=
+`select concat(left((select nm from t1 where fl2=0 order by RAND(13) limit 1),2),'%')`;
+eval select '$a' as a;
+
+set optimizer_switch='rowid_filter=on';
+eval
+explain
+select * from t1 where nm like '$a' AND fl2 = 0;
+--source include/analyze-format.inc
+eval
+analyze format=json
+select * from t1 where nm like '$a' AND fl2 = 0;
+eval
+select * from t1 where nm like '$a' AND fl2 = 0;
+
+drop table name, flag2;
+drop table t1;
+
+# This test shows that if the container is empty there are no lookups into it
+
+create table t1 (
+ pk int primary key auto_increment,
+ nm char(255),
+ fl1 tinyint default 0,
+ fl2 int default 0,
+ index idx1(nm, fl1),
+ index idx2(fl2)
+) engine=myisam;
+
+create table name (
+ pk int primary key auto_increment,
+ nm bigint
+) engine=myisam;
+
+create table flag2 (
+ pk int primary key auto_increment,
+ fl2 int
+) engine=myisam;
+
+insert into name(nm) select seq from seq_1_to_10000 order by rand(17);
+insert into flag2(fl2) select seq mod 10 from seq_1_to_10000 order by rand(19);
+
+insert into t1(nm,fl2)
+ select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+
+analyze table t1 persistent for all;
+
+let $q=
+select * from t1
+where
+(
+ nm like '3400%' or nm like '3402%' or nm like '3403%' or
+ nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or
+ nm like '3409%' or
+ nm like '3411%' or nm like '3412%' or nm like '3413%' or
+ nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or
+ nm like '3418%' or nm like '3419%' or
+ nm like '3421%' or nm like '3422%' or nm like '3423%' or
+ nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or
+ nm like '3428%' or nm like '3429%' or
+ nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or
+ nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or
+ nm like '3439%' or
+ nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or
+ nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or
+ nm like '3448%'
+) and fl2 = 0;
+
+eval $q;
+--source include/analyze-format.inc
+eval analyze format=json $q;
+
+create table t0 select * from t1 where nm like '34%';
+delete from t1 using t1,t0 where t1.nm=t0.nm;
+--source include/analyze-format.inc
+eval analyze format=json $q;
+
+drop table t0;
+
+set optimizer_switch='rowid_filter=default';
+
+drop table name, flag2;
+drop table t1;
+
set @@use_stat_tables=@save_use_stat_tables;
diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result
index 18d77ab70ce..936c688585c 100644
--- a/mysql-test/main/rowid_filter_innodb.result
+++ b/mysql-test/main/rowid_filter_innodb.result
@@ -131,6 +131,7 @@ ANALYZE
"rows": 605,
"selectivity_pct": 10.07493755,
"r_rows": 605,
+ "r_lookups": 510,
"r_selectivity_pct": 11.76470588,
"r_buffer_size": "REPLACED",
"r_filling_time_ms": "REPLACED"
@@ -671,6 +672,7 @@ ANALYZE
"rows": 605,
"selectivity_pct": 10.07493755,
"r_rows": 605,
+ "r_lookups": 510,
"r_selectivity_pct": 11.76470588,
"r_buffer_size": "REPLACED",
"r_filling_time_ms": "REPLACED"
@@ -1996,7 +1998,7 @@ EXPLAIN EXTENDED
SELECT * FROM t1 HAVING (7, 9) IN (SELECT t2.i1, t2.i2 FROM t2 WHERE t2.i1 = 3);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+2 SUBQUERY t2 ref i1,i2 i1 5 const 1 100.00 Using index condition; Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` having 0
DROP TABLE t1,t2;
@@ -2005,7 +2007,7 @@ DROP TABLE t1,t2;
# that uses in expensive subquery
#
CREATE TABLE t1 (
-pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(b1)
+pk1 INT PRIMARY KEY, a1 INT, b1 VARCHAR(1), KEY(a1), KEY(b1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES
(10,0,'z'),(11,3,'j'),(12,8,'f'),(13,8,'p'),(14,6,'w'),(15,0,'c'),(16,1,'j'),
@@ -2024,21 +2026,31 @@ INSERT INTO t1 VALUES
(101,0,'u'),(102,7,'r'),(103,2,'x'),(104,8,'e'),(105,8,'i'),(106,5,'q'),
(107,8,'z'),(108,3,'k'),(109,65,NULL);
CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 INT, b2 VARCHAR(1)) ENGINE=MyISAM;
-INSERT INTO t2 VALUES (1,1,'x');
+INSERT INTO t2 VALUES (1,1,'i');
INSERT INTO t2 SELECT * FROM t1;
-SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 )
+INSERT INTO t1 SELECT pk1+200, a1, b1 FROM t1;
+INSERT INTO t1 SELECT pk1+400, a1, b1 FROM t1;
+ANALYZE TABLE t1,t2 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 )
WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 );
pk1 a1 b1 pk2 a2 b2
-65 2 a 109 65 NULL
-EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 )
+17 1 f 16 1 j
+37 3 g 36 3 a
+105 8 i 104 8 e
+EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 )
WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 101 100.00 Using where
-1 PRIMARY t1 eq_ref|filter PRIMARY,b1 PRIMARY|b1 4|4 test.t2.a2 1 (87%) 87.00 Using where; Using rowid filter
+1 PRIMARY t1 ref|filter a1,b1 a1|b1 5|4 test.t2.a2 36 (29%) 28.75 Using where; Using rowid filter
2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 100.00 Using index condition
Warnings:
-Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`pk2` AS `pk2`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`pk1` = `test`.`t2`.`a2` and `test`.`t1`.`b1` <= (/* select#2 */ select max(`test`.`t2`.`b2`) from `test`.`t2` where `test`.`t2`.`pk2` <= 1) and `test`.`t2`.`a2` <> `test`.`t2`.`pk2`
-EXPLAIN FORMAT=JSON SELECT * FROM t1 INNER JOIN t2 ON ( pk1 <> pk2 AND pk1 = a2 )
+Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`pk2` AS `pk2`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a1` = `test`.`t2`.`a2` and `test`.`t1`.`b1` <= (/* select#2 */ select max(`test`.`t2`.`b2`) from `test`.`t2` where `test`.`t2`.`pk2` <= 1) and `test`.`t1`.`pk1` + 1 = `test`.`t2`.`pk2` + 2
+EXPLAIN FORMAT=JSON SELECT * FROM t1 INNER JOIN t2 ON ( pk1+1 = pk2+2 AND a1 = a2 )
WHERE b1 <= ( SELECT MAX(b2) FROM t2 WHERE pk2 <= 1 );
EXPLAIN
{
@@ -2049,27 +2061,27 @@ EXPLAIN
"access_type": "ALL",
"rows": 101,
"filtered": 100,
- "attached_condition": "t2.a2 <> t2.pk2 and t2.a2 is not null"
+ "attached_condition": "t2.a2 is not null"
},
"table": {
"table_name": "t1",
- "access_type": "eq_ref",
- "possible_keys": ["PRIMARY", "b1"],
- "key": "PRIMARY",
- "key_length": "4",
- "used_key_parts": ["pk1"],
+ "access_type": "ref",
+ "possible_keys": ["a1", "b1"],
+ "key": "a1",
+ "key_length": "5",
+ "used_key_parts": ["a1"],
"ref": ["test.t2.a2"],
"rowid_filter": {
"range": {
"key": "b1",
"used_key_parts": ["b1"]
},
- "rows": 87,
- "selectivity_pct": 87
+ "rows": 115,
+ "selectivity_pct": 28.75
},
- "rows": 1,
- "filtered": 87,
- "attached_condition": "t1.b1 <= (subquery#2)"
+ "rows": 36,
+ "filtered": 28.75,
+ "attached_condition": "t1.b1 <= (subquery#2) and t1.pk1 + 1 = t2.pk2 + 2"
},
"subqueries": [
{
@@ -2136,15 +2148,448 @@ set @save_optimizer_switch= @@optimizer_switch;
SET @@optimizer_switch="index_merge_sort_union=OFF";
CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b));
INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4);
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+ANALYZE table t1 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
explain
SELECT * FROM t1 WHERE a > 0 AND b=0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref|filter a,b b|a 5|5 const 2 (14%) Using where; Using rowid filter
+1 SIMPLE t1 range|filter a,b a|b 5|5 NULL 64 (29%) Using index condition; Using where; Using rowid filter
SELECT * FROM t1 WHERE a > 0 AND b=0;
a b
1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
+1 0
drop table t1;
SET @@optimizer_switch=@save_optimizer_switch;
+#
+# MDEV-28846: Poor performance when rowid filter contains no elements
+#
+create table t1 (
+pk int primary key auto_increment,
+nm varchar(32),
+fl1 tinyint default 0,
+fl2 tinyint default 0,
+index idx1(nm, fl1),
+index idx2(fl2)
+) engine=myisam;
+create table name (
+pk int primary key auto_increment,
+nm bigint
+) engine=myisam;
+create table flag2 (
+pk int primary key auto_increment,
+fl2 tinyint
+) engine=myisam;
+insert into name(nm) select seq from seq_1_to_1000 order by rand(17);
+insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+select '500%' as a;
+a
+500%
+set optimizer_switch='rowid_filter=on';
+explain
+select * from t1 where nm like '500%' AND fl2 = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where
+analyze format=json
+select * from t1 where nm like '500%' AND fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx1",
+ "key_length": "35",
+ "used_key_parts": ["nm"],
+ "r_loops": 1,
+ "rows": 1,
+ "r_rows": 1,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 49.20000076,
+ "r_filtered": 100,
+ "index_condition": "t1.nm like '500%'",
+ "attached_condition": "t1.fl2 = 0"
+ }
+ }
+}
+select * from t1 where nm like '500%' AND fl2 = 0;
+pk nm fl1 fl2
+517 500 0 0
+truncate table name;
+truncate table flag2;
+truncate table t1;
+insert into name(nm) select seq from seq_1_to_1000 order by rand(17);
+insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+set optimizer_switch='rowid_filter=off';
+explain
+select * from t1 where nm like '500%' AND fl2 = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where
+analyze format=json
+select * from t1 where nm like '500%' AND fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx1",
+ "key_length": "35",
+ "used_key_parts": ["nm"],
+ "r_loops": 1,
+ "rows": 1,
+ "r_rows": 1,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 49.20000076,
+ "r_filtered": 100,
+ "index_condition": "t1.nm like '500%'",
+ "attached_condition": "t1.fl2 = 0"
+ }
+ }
+}
+select * from t1 where nm like '500%' AND fl2 = 0;
+pk nm fl1 fl2
+517 500 0 0
+truncate table name;
+truncate table flag2;
+truncate table t1;
+insert into name(nm) select seq from seq_1_to_1000 order by rand(17);
+insert into flag2(fl2) select seq mod 10 from seq_1_to_1000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+select '607%' as a;
+a
+607%
+set optimizer_switch='rowid_filter=on';
+explain
+select * from t1 where nm like '607%' AND fl2 = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where
+select * from t1 where nm like '607%' AND fl2 = 0;
+pk nm fl1 fl2
+721 607 0 0
+truncate table name;
+truncate table flag2;
+truncate table t1;
+insert into name(nm) select seq from seq_1_to_10000 order by rand(17);
+insert into flag2(fl2) select seq mod 100 from seq_1_to_10000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+select '75%' as a;
+a
+75%
+set optimizer_switch='rowid_filter=on';
+explain
+select * from t1 where nm like '75%' AND fl2 = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref|filter idx1,idx2 idx2|idx1 2|35 const 55 (1%) Using where; Using rowid filter
+analyze format=json
+select * from t1 where nm like '75%' AND fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ref",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx2",
+ "key_length": "2",
+ "used_key_parts": ["fl2"],
+ "ref": ["const"],
+ "rowid_filter": {
+ "range": {
+ "key": "idx1",
+ "used_key_parts": ["nm"]
+ },
+ "rows": 115,
+ "selectivity_pct": 1.15,
+ "r_rows": 111,
+ "r_lookups": 100,
+ "r_selectivity_pct": 2,
+ "r_buffer_size": "REPLACED",
+ "r_filling_time_ms": "REPLACED"
+ },
+ "r_loops": 1,
+ "rows": 55,
+ "r_rows": 2,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 1.149999976,
+ "r_filtered": 100,
+ "attached_condition": "t1.nm like '75%'"
+ }
+ }
+}
+select * from t1 where nm like '75%' AND fl2 = 0;
+pk nm fl1 fl2
+4543 7503 0 0
+7373 7518 0 0
+drop table name, flag2;
+drop table t1;
+create table t1 (
+pk int primary key auto_increment,
+nm char(255),
+fl1 tinyint default 0,
+fl2 int default 0,
+index idx1(nm, fl1),
+index idx2(fl2)
+) engine=myisam;
+create table name (
+pk int primary key auto_increment,
+nm bigint
+) engine=myisam;
+create table flag2 (
+pk int primary key auto_increment,
+fl2 int
+) engine=myisam;
+insert into name(nm) select seq from seq_1_to_10000 order by rand(17);
+insert into flag2(fl2) select seq mod 10 from seq_1_to_10000 order by rand(19);
+insert into t1(nm,fl2)
+select nm, fl2 from name, flag2 where name.pk = flag2.pk;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+select * from t1
+where
+(
+nm like '3400%' or nm like '3402%' or nm like '3403%' or
+nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or
+nm like '3409%' or
+nm like '3411%' or nm like '3412%' or nm like '3413%' or
+nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or
+nm like '3418%' or nm like '3419%' or
+nm like '3421%' or nm like '3422%' or nm like '3423%' or
+nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or
+nm like '3428%' or nm like '3429%' or
+nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or
+nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or
+nm like '3439%' or
+nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or
+nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or
+nm like '3448%'
+) and fl2 = 0;
+pk nm fl1 fl2
+analyze format=json select * from t1
+where
+(
+nm like '3400%' or nm like '3402%' or nm like '3403%' or
+nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or
+nm like '3409%' or
+nm like '3411%' or nm like '3412%' or nm like '3413%' or
+nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or
+nm like '3418%' or nm like '3419%' or
+nm like '3421%' or nm like '3422%' or nm like '3423%' or
+nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or
+nm like '3428%' or nm like '3429%' or
+nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or
+nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or
+nm like '3439%' or
+nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or
+nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or
+nm like '3448%'
+) and fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ref",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx2",
+ "key_length": "5",
+ "used_key_parts": ["fl2"],
+ "ref": ["const"],
+ "rowid_filter": {
+ "range": {
+ "key": "idx1",
+ "used_key_parts": ["nm"]
+ },
+ "rows": 44,
+ "selectivity_pct": 0.44,
+ "r_rows": 44,
+ "r_lookups": 1000,
+ "r_selectivity_pct": 0,
+ "r_buffer_size": "REPLACED",
+ "r_filling_time_ms": "REPLACED"
+ },
+ "r_loops": 1,
+ "rows": 863,
+ "r_rows": 0,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 0.439999998,
+ "r_filtered": 100,
+ "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'"
+ }
+ }
+}
+create table t0 select * from t1 where nm like '34%';
+delete from t1 using t1,t0 where t1.nm=t0.nm;
+analyze format=json select * from t1
+where
+(
+nm like '3400%' or nm like '3402%' or nm like '3403%' or
+nm like '3404%' or nm like '3405%' or nm like '3406%' or nm like '3407%' or
+nm like '3409%' or
+nm like '3411%' or nm like '3412%' or nm like '3413%' or
+nm like '3414%' or nm like '3415%' or nm like '3416%' or nm like '3417%' or
+nm like '3418%' or nm like '3419%' or
+nm like '3421%' or nm like '3422%' or nm like '3423%' or
+nm like '3424%' or nm like '3425%' or nm like '3426%' or nm like '3427%' or
+nm like '3428%' or nm like '3429%' or
+nm like '3430%' or nm like '3431%' or nm like '3432%' or nm like '3433%' or
+nm like '3434%' or nm like '3435%' or nm like '3436%' or nm like '3437%' or
+nm like '3439%' or
+nm like '3440%' or nm like '3441%' or nm like '3442%' or nm like '3443%' or
+nm like '3444%' or nm like '3445%' or nm like '3446%' or nm like '3447%' or
+nm like '3448%'
+) and fl2 = 0;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ref",
+ "possible_keys": ["idx1", "idx2"],
+ "key": "idx2",
+ "key_length": "5",
+ "used_key_parts": ["fl2"],
+ "ref": ["const"],
+ "rowid_filter": {
+ "range": {
+ "key": "idx1",
+ "used_key_parts": ["nm"]
+ },
+ "rows": 44,
+ "selectivity_pct": 0.44,
+ "r_rows": 0,
+ "r_lookups": 0,
+ "r_selectivity_pct": 0,
+ "r_buffer_size": "REPLACED",
+ "r_filling_time_ms": "REPLACED"
+ },
+ "r_loops": 1,
+ "rows": 853,
+ "r_rows": 0,
+ "filtered": 0.439999998,
+ "r_filtered": 100,
+ "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'"
+ }
+ }
+}
+drop table t0;
+set optimizer_switch='rowid_filter=default';
+drop table name, flag2;
+drop table t1;
set @@use_stat_tables=@save_use_stat_tables;
SET GLOBAL innodb_stats_persistent=@save_stats_persistent;
#
@@ -2170,6 +2615,10 @@ insert into t1 values
(81,'a','a',20),(82,'a','a',0),(83,'a','a',0),(84,'a','a',null),
(85,'a','a',-1),(86,'a','a',5),(87,'a','a',null),(88,'a','a',160),
(89,null,null,null),(90,'a','a',14785),(91,'a','a',0),(92,'a','a',null);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
( select * from t1
where (f1 is null and f2 is null) and (f2 between 'a' and 'z' or f1 in ('a')))
union
@@ -2280,46 +2729,44 @@ drop table t1, t2;
#
create table t1 (a int, b int, key (b), key (a)) engine=innodb;
insert into t1
-select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000;
+select (rand(1)*1000)/10, (rand(1001)*1000)/20 from seq_1_to_1000;
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
set @save_optimizer_switch= @@optimizer_switch;
set optimizer_switch='rowid_filter=off';
-select count(*) from t1 where a in (22,83,11) and b=2;
+select count(*) from t1 where a between 21 and 30 and b=2;
count(*)
-6
-explain extended select count(*) from t1 where a in (22,83,11) and b=2;
+5
+explain extended select count(*) from t1 where a between 21 and 30 and b=2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range b,a a 5 NULL 33 5.90 Using index condition; Using where
+1 SIMPLE t1 ref b,a b 5 const 24 9.60 Using where
Warnings:
-Note 1003 select count(0) AS `count(*)` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (22,83,11)
-select * from t1 where a in (22,83,11) and b=2;
+Note 1003 select count(0) AS `count(*)` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` between 21 and 30
+select * from t1 where a between 21 and 30 and b=2;
a b
-11 2
-11 2
-11 2
+30 2
+21 2
22 2
-83 2
-83 2
+26 2
+25 2
set optimizer_switch='rowid_filter=on';
-select count(*) from t1 where a in (22,83,11) and b=2;
+select count(*) from t1 where a between 21 and 30 and b=2;
count(*)
-6
-explain extended select count(*) from t1 where a in (22,83,11) and b=2;
+5
+explain extended select count(*) from t1 where a between 21 and 30 and b=2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ref|filter b,a b|a 5|5 const 59 (3%) 3.30 Using where; Using rowid filter
+1 SIMPLE t1 ref|filter b,a b|a 5|5 const 24 (10%) 9.60 Using where; Using rowid filter
Warnings:
-Note 1003 select count(0) AS `count(*)` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (22,83,11)
-select * from t1 where a in (22,83,11) and b=2;
+Note 1003 select count(0) AS `count(*)` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` between 21 and 30
+select * from t1 where a between 21 and 30 and b=2;
a b
-11 2
-11 2
-83 2
-11 2
-83 2
+30 2
+21 2
22 2
+26 2
+25 2
drop table t1;
set optimizer_switch=@save_optimizer_switch;
SET SESSION DEFAULT_STORAGE_ENGINE=DEFAULT;
@@ -2474,7 +2921,7 @@ set global innodb_stats_persistent= @stats.save;
#
CREATE TABLE t1 (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
-domain varchar(255) NOT NULL,
+domain varchar(32) NOT NULL,
registrant_name varchar(255) DEFAULT NULL,
registrant_organization varchar(255) DEFAULT NULL,
registrant_street1 varchar(255) DEFAULT NULL,
@@ -2565,21 +3012,216 @@ null, 'SUELZBURGSTRASSE 158A', null, null, null, null, 'KOELN', '50937',
'MAXIMILIAN V. KETELHODT', null, 'SUELZBURGSTRASSE 158A', null, null, null,
null, 'KOELN', '50937', 'GERMANY', 'ICANN@EXPIRES-2009.WEBCARE24.COM',
'492214307580', '', '2017-01-30 10:08:29');
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+VALUES
+('www.mailhost.i-dev.fr', null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, '', '2016-12-22 09:18:28');
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+VALUES
+('www.mailhost.i-dev.fr', null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, '', '2016-12-22 09:18:28');
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+VALUES
+('www.mailhost.i-dev.fr', null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, '', '2016-12-22 09:18:28');
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+VALUES
+('www.mailhost.i-dev.fr', null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, '', '2016-12-22 09:18:28');
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+VALUES
+('www.mailhost.i-dev.fr', null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, '', '2016-12-22 09:18:28');
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+VALUES
+('www.mailhost.i-dev.fr', null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, '', '2016-12-22 09:18:28');
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+VALUES
+('www.mailhost.i-dev.fr', null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, '', '2016-12-22 09:18:28');
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+VALUES
+('www.mailhost.i-dev.fr', null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, '', '2016-12-22 09:18:28');
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+SELECT
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp
+FROM t1;
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+SELECT
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp
+FROM t1;
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze Warning Engine-independent statistics are not collected for column 'json'
+test.t1 analyze status OK
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch='mrr=on,mrr_sort_keys=on';
SELECT * FROM t1
WHERE 1 = 1 AND domain = 'www.mailhost.i-dev.fr' AND
-timestamp >= DATE_ADD(CURRENT_TIMESTAMP, INTERVAL -1 MONTH)
+timestamp >= DATE_ADD('2017-01-30 08:24:51', INTERVAL -1 MONTH)
ORDER BY timestamp DESC;
id domain registrant_name registrant_organization registrant_street1 registrant_street2 registrant_street3 registrant_street4 registrant_street5 registrant_city registrant_postal_code registrant_country registrant_email registrant_telephone administrative_name administrative_organization administrative_street1 administrative_street2 administrative_street3 administrative_street4 administrative_street5 administrative_city administrative_postal_code administrative_country administrative_email administrative_telephone technical_name technical_organization technical_street1 technical_street2 technical_street3 technical_street4 technical_street5 technical_city technical_postal_code technical_country technical_email technical_telephone json timestamp
+80551 www.mailhost.i-dev.fr NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 2017-01-30 10:00:56
+80579 www.mailhost.i-dev.fr NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 2017-01-30 10:00:56
+80594 www.mailhost.i-dev.fr NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 2017-01-30 10:00:56
+80609 www.mailhost.i-dev.fr NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 2017-01-30 10:00:56
EXPLAIN EXTENDED SELECT * FROM t1
WHERE 1 = 1 AND domain = 'www.mailhost.i-dev.fr' AND
-timestamp >= DATE_ADD(CURRENT_TIMESTAMP, INTERVAL -1 MONTH)
+timestamp >= DATE_ADD('2017-01-30 08:24:51', INTERVAL -1 MONTH)
ORDER BY timestamp DESC;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ref|filter ixEventWhoisDomainDomain,ixEventWhoisDomainTimestamp ixEventWhoisDomainDomain|ixEventWhoisDomainTimestamp 767|4 const 2 (14%) 14.29 Using index condition; Using where; Using filesort; Using rowid filter
+1 SIMPLE t1 ALL ixEventWhoisDomainDomain,ixEventWhoisDomainTimestamp NULL NULL NULL 60 22.22 Using where; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`domain` AS `domain`,`test`.`t1`.`registrant_name` AS `registrant_name`,`test`.`t1`.`registrant_organization` AS `registrant_organization`,`test`.`t1`.`registrant_street1` AS `registrant_street1`,`test`.`t1`.`registrant_street2` AS `registrant_street2`,`test`.`t1`.`registrant_street3` AS `registrant_street3`,`test`.`t1`.`registrant_street4` AS `registrant_street4`,`test`.`t1`.`registrant_street5` AS `registrant_street5`,`test`.`t1`.`registrant_city` AS `registrant_city`,`test`.`t1`.`registrant_postal_code` AS `registrant_postal_code`,`test`.`t1`.`registrant_country` AS `registrant_country`,`test`.`t1`.`registrant_email` AS `registrant_email`,`test`.`t1`.`registrant_telephone` AS `registrant_telephone`,`test`.`t1`.`administrative_name` AS `administrative_name`,`test`.`t1`.`administrative_organization` AS `administrative_organization`,`test`.`t1`.`administrative_street1` AS `administrative_street1`,`test`.`t1`.`administrative_street2` AS `administrative_street2`,`test`.`t1`.`administrative_street3` AS `administrative_street3`,`test`.`t1`.`administrative_street4` AS `administrative_street4`,`test`.`t1`.`administrative_street5` AS `administrative_street5`,`test`.`t1`.`administrative_city` AS `administrative_city`,`test`.`t1`.`administrative_postal_code` AS `administrative_postal_code`,`test`.`t1`.`administrative_country` AS `administrative_country`,`test`.`t1`.`administrative_email` AS `administrative_email`,`test`.`t1`.`administrative_telephone` AS `administrative_telephone`,`test`.`t1`.`technical_name` AS `technical_name`,`test`.`t1`.`technical_organization` AS `technical_organization`,`test`.`t1`.`technical_street1` AS `technical_street1`,`test`.`t1`.`technical_street2` AS `technical_street2`,`test`.`t1`.`technical_street3` AS `technical_street3`,`test`.`t1`.`technical_street4` AS `technical_street4`,`test`.`t1`.`technical_street5` AS `technical_street5`,`test`.`t1`.`technical_city` AS `technical_city`,`test`.`t1`.`technical_postal_code` AS `technical_postal_code`,`test`.`t1`.`technical_country` AS `technical_country`,`test`.`t1`.`technical_email` AS `technical_email`,`test`.`t1`.`technical_telephone` AS `technical_telephone`,`test`.`t1`.`json` AS `json`,`test`.`t1`.`timestamp` AS `timestamp` from `test`.`t1` where `test`.`t1`.`domain` = 'www.mailhost.i-dev.fr' and `test`.`t1`.`timestamp` >= <cache>(current_timestamp() + interval -1 month) order by `test`.`t1`.`timestamp` desc
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`domain` AS `domain`,`test`.`t1`.`registrant_name` AS `registrant_name`,`test`.`t1`.`registrant_organization` AS `registrant_organization`,`test`.`t1`.`registrant_street1` AS `registrant_street1`,`test`.`t1`.`registrant_street2` AS `registrant_street2`,`test`.`t1`.`registrant_street3` AS `registrant_street3`,`test`.`t1`.`registrant_street4` AS `registrant_street4`,`test`.`t1`.`registrant_street5` AS `registrant_street5`,`test`.`t1`.`registrant_city` AS `registrant_city`,`test`.`t1`.`registrant_postal_code` AS `registrant_postal_code`,`test`.`t1`.`registrant_country` AS `registrant_country`,`test`.`t1`.`registrant_email` AS `registrant_email`,`test`.`t1`.`registrant_telephone` AS `registrant_telephone`,`test`.`t1`.`administrative_name` AS `administrative_name`,`test`.`t1`.`administrative_organization` AS `administrative_organization`,`test`.`t1`.`administrative_street1` AS `administrative_street1`,`test`.`t1`.`administrative_street2` AS `administrative_street2`,`test`.`t1`.`administrative_street3` AS `administrative_street3`,`test`.`t1`.`administrative_street4` AS `administrative_street4`,`test`.`t1`.`administrative_street5` AS `administrative_street5`,`test`.`t1`.`administrative_city` AS `administrative_city`,`test`.`t1`.`administrative_postal_code` AS `administrative_postal_code`,`test`.`t1`.`administrative_country` AS `administrative_country`,`test`.`t1`.`administrative_email` AS `administrative_email`,`test`.`t1`.`administrative_telephone` AS `administrative_telephone`,`test`.`t1`.`technical_name` AS `technical_name`,`test`.`t1`.`technical_organization` AS `technical_organization`,`test`.`t1`.`technical_street1` AS `technical_street1`,`test`.`t1`.`technical_street2` AS `technical_street2`,`test`.`t1`.`technical_street3` AS `technical_street3`,`test`.`t1`.`technical_street4` AS `technical_street4`,`test`.`t1`.`technical_street5` AS `technical_street5`,`test`.`t1`.`technical_city` AS `technical_city`,`test`.`t1`.`technical_postal_code` AS `technical_postal_code`,`test`.`t1`.`technical_country` AS `technical_country`,`test`.`t1`.`technical_email` AS `technical_email`,`test`.`t1`.`technical_telephone` AS `technical_telephone`,`test`.`t1`.`json` AS `json`,`test`.`t1`.`timestamp` AS `timestamp` from `test`.`t1` where `test`.`t1`.`domain` = 'www.mailhost.i-dev.fr' and `test`.`t1`.`timestamp` >= <cache>('2017-01-30 08:24:51' + interval -1 month) order by `test`.`t1`.`timestamp` desc
SET optimizer_switch=@save_optimizer_switch;
DROP TABLE t1;
#
@@ -2741,6 +3383,10 @@ insert into filt(id,aceid,clid,fh) values
(6341490487802728361,6341490487802728360,1,1291319099896431785),
(6341490487802728362,6341490487802728360,1,8948400944397203540),
(6341490487802728363,6341490487802728361,1,6701841652906431497);
+insert into filt select id+10000,aceid,clid,fh from filt;
+insert into filt select id+20000,aceid,clid,fh from filt;
+insert into filt select id+40000,aceid,clid,fh from filt;
+insert into filt select id+80000,aceid,clid,fh from filt;
analyze table filt, acei, acli;
Table Op Msg_type Msg_text
test.filt analyze status Engine-independent statistics collected
@@ -2765,7 +3411,7 @@ fi.fh in (6311439873746261694,-397087483897438286,
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t index_merge PRIMARY,acli_rid,acli_tp acli_tp,acli_rid 2,767 NULL 2 100.00 Using intersect(acli_tp,acli_rid); Using where; Using index
1 SIMPLE a ref PRIMARY,acei_aclid acei_aclid 8 test.t.id 1 100.00 Using where
-1 SIMPLE fi ref filt_aceid,filt_fh filt_aceid 8 test.a.id 1 17.14 Using where
+1 SIMPLE fi ref filt_aceid,filt_fh filt_aceid 8 test.a.id 24 14.46 Using where
Warnings:
Note 1003 select `test`.`t`.`id` AS `id`,`test`.`fi`.`id` AS `id`,`test`.`fi`.`aceid` AS `aceid`,`test`.`fi`.`clid` AS `clid`,`test`.`fi`.`fh` AS `fh` from `test`.`acli` `t` join `test`.`acei` `a` join `test`.`filt` `fi` where `test`.`t`.`tp` = 121 and `test`.`a`.`atp` = 1 and `test`.`fi`.`aceid` = `test`.`a`.`id` and `test`.`a`.`aclid` = `test`.`t`.`id` and `test`.`t`.`rid` = 'B5FCC8C7111E4E3CBC21AAF5012F59C2' and `test`.`fi`.`fh` in (6311439873746261694,-397087483897438286,8518228073041491534,-5420422472375069774)
set statement optimizer_switch='rowid_filter=off' for select t.id, fi.*
@@ -2780,6 +3426,36 @@ fi.fh in (6311439873746261694,-397087483897438286,
id id aceid clid fh
3080602882609775594 3080602882609775600 3080602882609775598 1 6311439873746261694
3080602882609775594 3080602882609775601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609785600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609785601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609795600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609795601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609805600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609805601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609815600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609815601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609825600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609825601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609835600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609835601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609845600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609845601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609855600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609855601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609865600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609865601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609875600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609875601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609885600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609885601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609895600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609895601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609905600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609905601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609915600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609915601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609925600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609925601 3080602882609775598 1 6311439873746261694
set statement optimizer_switch='rowid_filter=on' for explain extended select t.id, fi.*
from (acli t inner join acei a on a.aclid = t.id)
inner join filt fi on a.id = fi.aceid
@@ -2792,7 +3468,7 @@ fi.fh in (6311439873746261694,-397087483897438286,
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t index_merge PRIMARY,acli_rid,acli_tp acli_tp,acli_rid 2,767 NULL 2 100.00 Using intersect(acli_tp,acli_rid); Using where; Using index
1 SIMPLE a ref PRIMARY,acei_aclid acei_aclid 8 test.t.id 1 100.00 Using where
-1 SIMPLE fi ref|filter filt_aceid,filt_fh filt_aceid|filt_fh 8|8 test.a.id 1 (17%) 17.14 Using where; Using rowid filter
+1 SIMPLE fi ref|filter filt_aceid,filt_fh filt_aceid|filt_fh 8|8 test.a.id 24 (14%) 14.46 Using where; Using rowid filter
Warnings:
Note 1003 select `test`.`t`.`id` AS `id`,`test`.`fi`.`id` AS `id`,`test`.`fi`.`aceid` AS `aceid`,`test`.`fi`.`clid` AS `clid`,`test`.`fi`.`fh` AS `fh` from `test`.`acli` `t` join `test`.`acei` `a` join `test`.`filt` `fi` where `test`.`t`.`tp` = 121 and `test`.`a`.`atp` = 1 and `test`.`fi`.`aceid` = `test`.`a`.`id` and `test`.`a`.`aclid` = `test`.`t`.`id` and `test`.`t`.`rid` = 'B5FCC8C7111E4E3CBC21AAF5012F59C2' and `test`.`fi`.`fh` in (6311439873746261694,-397087483897438286,8518228073041491534,-5420422472375069774)
set statement optimizer_switch='rowid_filter=on' for select t.id, fi.*
@@ -2807,6 +3483,36 @@ fi.fh in (6311439873746261694,-397087483897438286,
id id aceid clid fh
3080602882609775594 3080602882609775600 3080602882609775598 1 6311439873746261694
3080602882609775594 3080602882609775601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609785600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609785601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609795600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609795601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609805600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609805601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609815600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609815601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609825600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609825601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609835600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609835601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609845600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609845601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609855600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609855601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609865600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609865601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609875600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609875601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609885600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609885601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609895600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609895601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609905600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609905601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609915600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609915601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609925600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609925601 3080602882609775598 1 6311439873746261694
set optimizer_switch='mrr=on';
set join_cache_level=6;
set statement optimizer_switch='rowid_filter=off' for explain extended select t.id, fi.*
@@ -2821,7 +3527,7 @@ fi.fh in (6311439873746261694,-397087483897438286,
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t index_merge PRIMARY,acli_rid,acli_tp acli_tp,acli_rid 2,767 NULL 2 100.00 Using intersect(acli_tp,acli_rid); Using where; Using index
1 SIMPLE a ref PRIMARY,acei_aclid acei_aclid 8 test.t.id 1 100.00 Using where; Using join buffer (flat, BKA join); Rowid-ordered scan
-1 SIMPLE fi ref filt_aceid,filt_fh filt_aceid 8 test.a.id 1 17.14 Using where; Using join buffer (incremental, BKA join); Rowid-ordered scan
+1 SIMPLE fi ref filt_aceid,filt_fh filt_aceid 8 test.a.id 24 14.46 Using where; Using join buffer (incremental, BKA join); Rowid-ordered scan
Warnings:
Note 1003 select `test`.`t`.`id` AS `id`,`test`.`fi`.`id` AS `id`,`test`.`fi`.`aceid` AS `aceid`,`test`.`fi`.`clid` AS `clid`,`test`.`fi`.`fh` AS `fh` from `test`.`acli` `t` join `test`.`acei` `a` join `test`.`filt` `fi` where `test`.`t`.`tp` = 121 and `test`.`a`.`atp` = 1 and `test`.`fi`.`aceid` = `test`.`a`.`id` and `test`.`a`.`aclid` = `test`.`t`.`id` and `test`.`t`.`rid` = 'B5FCC8C7111E4E3CBC21AAF5012F59C2' and `test`.`fi`.`fh` in (6311439873746261694,-397087483897438286,8518228073041491534,-5420422472375069774)
set statement optimizer_switch='rowid_filter=off' for select t.id, fi.*
@@ -2836,6 +3542,36 @@ fi.fh in (6311439873746261694,-397087483897438286,
id id aceid clid fh
3080602882609775594 3080602882609775600 3080602882609775598 1 6311439873746261694
3080602882609775594 3080602882609775601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609785600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609785601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609795600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609795601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609805600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609805601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609815600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609815601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609825600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609825601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609835600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609835601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609845600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609845601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609855600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609855601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609865600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609865601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609875600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609875601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609885600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609885601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609895600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609895601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609905600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609905601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609915600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609915601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609925600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609925601 3080602882609775598 1 6311439873746261694
set statement optimizer_switch='rowid_filter=on' for explain extended select t.id, fi.*
from (acli t inner join acei a on a.aclid = t.id)
inner join filt fi on a.id = fi.aceid
@@ -2848,7 +3584,7 @@ fi.fh in (6311439873746261694,-397087483897438286,
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t index_merge PRIMARY,acli_rid,acli_tp acli_tp,acli_rid 2,767 NULL 2 100.00 Using intersect(acli_tp,acli_rid); Using where; Using index
1 SIMPLE a ref PRIMARY,acei_aclid acei_aclid 8 test.t.id 1 100.00 Using where; Using join buffer (flat, BKA join); Rowid-ordered scan
-1 SIMPLE fi ref|filter filt_aceid,filt_fh filt_aceid|filt_fh 8|8 test.a.id 1 (17%) 17.14 Using where; Using join buffer (incremental, BKA join); Rowid-ordered scan; Using rowid filter
+1 SIMPLE fi ref|filter filt_aceid,filt_fh filt_aceid|filt_fh 8|8 test.a.id 24 (14%) 14.46 Using where; Using join buffer (incremental, BKA join); Rowid-ordered scan; Using rowid filter
Warnings:
Note 1003 select `test`.`t`.`id` AS `id`,`test`.`fi`.`id` AS `id`,`test`.`fi`.`aceid` AS `aceid`,`test`.`fi`.`clid` AS `clid`,`test`.`fi`.`fh` AS `fh` from `test`.`acli` `t` join `test`.`acei` `a` join `test`.`filt` `fi` where `test`.`t`.`tp` = 121 and `test`.`a`.`atp` = 1 and `test`.`fi`.`aceid` = `test`.`a`.`id` and `test`.`a`.`aclid` = `test`.`t`.`id` and `test`.`t`.`rid` = 'B5FCC8C7111E4E3CBC21AAF5012F59C2' and `test`.`fi`.`fh` in (6311439873746261694,-397087483897438286,8518228073041491534,-5420422472375069774)
set statement optimizer_switch='rowid_filter=on' for select t.id, fi.*
@@ -2863,6 +3599,36 @@ fi.fh in (6311439873746261694,-397087483897438286,
id id aceid clid fh
3080602882609775594 3080602882609775600 3080602882609775598 1 6311439873746261694
3080602882609775594 3080602882609775601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609785600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609785601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609795600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609795601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609805600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609805601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609815600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609815601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609825600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609825601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609835600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609835601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609845600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609845601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609855600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609855601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609865600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609865601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609875600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609875601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609885600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609885601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609895600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609895601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609905600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609905601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609915600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609915601 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609925600 3080602882609775598 1 6311439873746261694
+3080602882609775594 3080602882609925601 3080602882609775598 1 6311439873746261694
set statement optimizer_switch='rowid_filter=on' for analyze format=json select t.id, fi.*
from (acli t inner join acei a on a.aclid = t.id)
inner join filt fi on a.id = fi.aceid
@@ -2943,23 +3709,24 @@ ANALYZE
"key": "filt_fh",
"used_key_parts": ["fh"]
},
- "rows": 6,
- "selectivity_pct": 17.14285714,
- "r_rows": 5,
+ "rows": 81,
+ "selectivity_pct": 14.46428571,
+ "r_rows": 80,
+ "r_lookups": 80,
"r_selectivity_pct": 40,
"r_buffer_size": "REPLACED",
"r_filling_time_ms": "REPLACED"
},
"r_loops": 1,
- "rows": 1,
- "r_rows": 2,
+ "rows": 24,
+ "r_rows": 32,
"r_table_time_ms": "REPLACED",
"r_other_time_ms": "REPLACED",
- "filtered": 17.1428566,
+ "filtered": 14.46428585,
"r_filtered": 100
},
"buffer_type": "incremental",
- "buffer_size": "603",
+ "buffer_size": "4Kb",
"join_type": "BKA",
"mrr_type": "Rowid-ordered scan",
"attached_condition": "fi.fh in (6311439873746261694,-397087483897438286,8518228073041491534,-5420422472375069774)",
@@ -2980,39 +3747,100 @@ CREATE TABLE t1 (pk int NOT NULL, c1 varchar(1)) engine=innodb;
INSERT INTO t1 VALUES
(1,NULL),(15,'o'),(16,'x'),(19,'t'),(35,'k'),(36,'h'),(42,'t'),(43,'h'),
(53,'l'),(62,'a'),(71,NULL),(79,'u'),(128,'y'),(129,NULL),(133,NULL);
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
CREATE TABLE t2 (
-i1 int, c1 varchar(1) NOT NULL, KEY c1 (c1), KEY i1 (i1)
+i1 int, c1 varchar(1) NOT NULL,
+filler1 char(255) default '0', filler2 char(255) default '0',
+KEY c1 (c1), KEY i1 (i1)
) engine=innodb;
-INSERT INTO t2 VALUES
-(1,'1'),(NULL,'1'),(42,'t'),(NULL,'1'),(79,'u'),(NULL,'1'),
-(NULL,'4'),(NULL,'4'),(NULL,'1'),(NULL,'u'),(2,'1'),(NULL,'w');
+INSERT INTO t2(i1,c1) VALUES
+(NULL,'1'),(1,'1'),(2,'t'),(3,'1'),(4,'u'),(5,'1'),
+(6,'4'),(7,'4'),(8,'1'),(1,'u'),(2,'1'),(NULL,'w');
INSERT INTO t2 SELECT * FROM t2;
+INSERT INTO t2 SELECT * FROM t2;
+INSERT INTO t2 SELECT * FROM t2;
+INSERT INTO t2 SELECT * FROM t2;
+ANALYZE TABLE t1,t2 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
SELECT * FROM t1
WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1
-WHERE t2.i1 = t1.pk AND t2.i1 IS NOT NULL);
+WHERE t2.i1 = t1.pk AND t2.i1 BETWEEN 3 AND 5);
pk c1
+1 NULL
+15 o
+16 x
+19 t
+35 k
+36 h
+42 t
+43 h
+53 l
+62 a
+71 NULL
+79 u
+128 y
+129 NULL
+133 NULL
+1 NULL
+15 o
+16 x
+19 t
+35 k
+36 h
+42 t
+43 h
+53 l
+62 a
+71 NULL
+79 u
+128 y
+129 NULL
+133 NULL
+1 NULL
+15 o
+16 x
+19 t
+35 k
+36 h
+42 t
+43 h
+53 l
+62 a
+71 NULL
+79 u
+128 y
+129 NULL
+133 NULL
+1 NULL
15 o
16 x
19 t
35 k
36 h
+42 t
43 h
53 l
62 a
71 NULL
+79 u
128 y
129 NULL
133 NULL
EXPLAIN EXTENDED SELECT * FROM t1
WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1
-WHERE t2.i1 = t1.pk AND t2.i1 IS NOT NULL);
+WHERE t2.i1 = t1.pk AND t2.i1 BETWEEN 3 AND 5);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 15 100.00 Using where
-2 DEPENDENT SUBQUERY t2 ref|filter c1,i1 c1|i1 3|5 func 6 (33%) 33.33 Using where; Full scan on NULL key; Using rowid filter
-2 DEPENDENT SUBQUERY a1 ALL NULL NULL NULL NULL 15 100.00 Using join buffer (flat, BNL join)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 60 100.00 Using where
+2 DEPENDENT SUBQUERY t2 ref|filter c1,i1 c1|i1 3|5 func 38 (25%) 25.00 Using where; Full scan on NULL key; Using rowid filter
+2 DEPENDENT SUBQUERY a1 ALL NULL NULL NULL NULL 60 100.00 Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1
-Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c1` AS `c1` from `test`.`t1` where !<expr_cache><`test`.`t1`.`c1`,`test`.`t1`.`pk`>(<in_optimizer>(`test`.`t1`.`c1`,<exists>(/* select#2 */ select `test`.`t2`.`c1` from `test`.`t2` join `test`.`t1` `a1` where `test`.`t2`.`i1` = `test`.`t1`.`pk` and `test`.`t2`.`i1` is not null and trigcond(<cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c1`))))
+Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c1` AS `c1` from `test`.`t1` where !<expr_cache><`test`.`t1`.`c1`,`test`.`t1`.`pk`>(<in_optimizer>(`test`.`t1`.`c1`,<exists>(/* select#2 */ select `test`.`t2`.`c1` from `test`.`t2` join `test`.`t1` `a1` where `test`.`t2`.`i1` = `test`.`t1`.`pk` and `test`.`t2`.`i1` between 3 and 5 and trigcond(<cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c1`))))
DROP TABLE t1,t2;
set global innodb_stats_persistent= @stats.save;
# End of 10.4 tests
diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test
index 1112d7b69c6..8705a0c9a12 100644
--- a/mysql-test/main/rowid_filter_innodb.test
+++ b/mysql-test/main/rowid_filter_innodb.test
@@ -38,6 +38,8 @@ insert into t1 values
(85,'a','a',-1),(86,'a','a',5),(87,'a','a',null),(88,'a','a',160),
(89,null,null,null),(90,'a','a',14785),(91,'a','a',0),(92,'a','a',null);
+analyze table t1;
+
let $q=
( select * from t1
where (f1 is null and f2 is null) and (f2 between 'a' and 'z' or f1 in ('a')))
@@ -79,13 +81,13 @@ drop table t1, t2;
create table t1 (a int, b int, key (b), key (a)) engine=innodb;
insert into t1
-select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000;
+select (rand(1)*1000)/10, (rand(1001)*1000)/20 from seq_1_to_1000;
analyze table t1;
let $q=
-select count(*) from t1 where a in (22,83,11) and b=2;
+select count(*) from t1 where a between 21 and 30 and b=2;
let $q1=
-select * from t1 where a in (22,83,11) and b=2;
+select * from t1 where a between 21 and 30 and b=2;
set @save_optimizer_switch= @@optimizer_switch;
@@ -230,7 +232,7 @@ set global innodb_stats_persistent= @stats.save;
CREATE TABLE t1 (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
- domain varchar(255) NOT NULL,
+ domain varchar(32) NOT NULL,
registrant_name varchar(255) DEFAULT NULL,
registrant_organization varchar(255) DEFAULT NULL,
registrant_street1 varchar(255) DEFAULT NULL,
@@ -323,6 +325,66 @@ technical_email, technical_telephone, json, timestamp) VALUES
null, 'KOELN', '50937', 'GERMANY', 'ICANN@EXPIRES-2009.WEBCARE24.COM',
'492214307580', '', '2017-01-30 10:08:29');
+let $sqi=
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+VALUES
+('www.mailhost.i-dev.fr', null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, '', '2016-12-22 09:18:28');
+
+eval $sqi;
+eval $sqi;
+eval $sqi;
+eval $sqi;
+eval $sqi;
+eval $sqi;
+eval $sqi;
+eval $sqi;
+
+let $qi=
+INSERT INTO t1 (
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp)
+SELECT
+domain, registrant_name, registrant_organization, registrant_street1,
+registrant_street2, registrant_street3, registrant_street4, registrant_street5,
+registrant_city, registrant_postal_code, registrant_country, registrant_email,
+registrant_telephone, administrative_name, administrative_organization,
+administrative_street1, administrative_street2, administrative_street3,
+administrative_street4, administrative_street5, administrative_city,
+administrative_postal_code, administrative_country, administrative_email,
+administrative_telephone, technical_name, technical_organization,
+technical_street1, technical_street2, technical_street3, technical_street4,
+technical_street5, technical_city, technical_postal_code, technical_country,
+technical_email, technical_telephone, json, timestamp
+FROM t1;
+
+eval $qi;
+eval $qi;
+
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch='mrr=on,mrr_sort_keys=on';
@@ -330,7 +392,7 @@ SET optimizer_switch='mrr=on,mrr_sort_keys=on';
let $q=
SELECT * FROM t1
WHERE 1 = 1 AND domain = 'www.mailhost.i-dev.fr' AND
- timestamp >= DATE_ADD(CURRENT_TIMESTAMP, INTERVAL -1 MONTH)
+ timestamp >= DATE_ADD('2017-01-30 08:24:51', INTERVAL -1 MONTH)
ORDER BY timestamp DESC;
eval $q;
@@ -503,6 +565,11 @@ insert into filt(id,aceid,clid,fh) values
(6341490487802728362,6341490487802728360,1,8948400944397203540),
(6341490487802728363,6341490487802728361,1,6701841652906431497);
+insert into filt select id+10000,aceid,clid,fh from filt;
+insert into filt select id+20000,aceid,clid,fh from filt;
+insert into filt select id+40000,aceid,clid,fh from filt;
+insert into filt select id+80000,aceid,clid,fh from filt;
+
analyze table filt, acei, acli;
let $q=
@@ -553,19 +620,28 @@ CREATE TABLE t1 (pk int NOT NULL, c1 varchar(1)) engine=innodb;
INSERT INTO t1 VALUES
(1,NULL),(15,'o'),(16,'x'),(19,'t'),(35,'k'),(36,'h'),(42,'t'),(43,'h'),
(53,'l'),(62,'a'),(71,NULL),(79,'u'),(128,'y'),(129,NULL),(133,NULL);
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
CREATE TABLE t2 (
-i1 int, c1 varchar(1) NOT NULL, KEY c1 (c1), KEY i1 (i1)
+i1 int, c1 varchar(1) NOT NULL,
+filler1 char(255) default '0', filler2 char(255) default '0',
+KEY c1 (c1), KEY i1 (i1)
) engine=innodb;
-INSERT INTO t2 VALUES
-(1,'1'),(NULL,'1'),(42,'t'),(NULL,'1'),(79,'u'),(NULL,'1'),
-(NULL,'4'),(NULL,'4'),(NULL,'1'),(NULL,'u'),(2,'1'),(NULL,'w');
+INSERT INTO t2(i1,c1) VALUES
+(NULL,'1'),(1,'1'),(2,'t'),(3,'1'),(4,'u'),(5,'1'),
+(6,'4'),(7,'4'),(8,'1'),(1,'u'),(2,'1'),(NULL,'w');
+INSERT INTO t2 SELECT * FROM t2;
+INSERT INTO t2 SELECT * FROM t2;
INSERT INTO t2 SELECT * FROM t2;
+INSERT INTO t2 SELECT * FROM t2;
+
+ANALYZE TABLE t1,t2 PERSISTENT FOR ALL;
let $q=
SELECT * FROM t1
WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1
- WHERE t2.i1 = t1.pk AND t2.i1 IS NOT NULL);
+ WHERE t2.i1 = t1.pk AND t2.i1 BETWEEN 3 AND 5);
eval $q;
eval EXPLAIN EXTENDED $q;
diff --git a/mysql-test/main/rowid_filter_innodb_debug.result b/mysql-test/main/rowid_filter_innodb_debug.result
index 6fd75294bdb..5a3fa374bd1 100644
--- a/mysql-test/main/rowid_filter_innodb_debug.result
+++ b/mysql-test/main/rowid_filter_innodb_debug.result
@@ -2,12 +2,8 @@ set default_storage_engine=innodb;
#
# MDEV-22761 KILL QUERY during rowid_filter, crashes
#
-create table t0(a int);
-insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-create table t1(a int);
-insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
create table t2(a int);
-insert into t2 select A.a + B.a* 10 from t0 A, t0 B;
+insert into t2 select * from seq_0_to_99;
CREATE TABLE t3 (
key1 int ,
key2 int,
@@ -21,11 +17,10 @@ engine
InnoDB
insert into t3
select
-A.a,
-A.a,
+A.seq,
+B.seq,
'filler-data-filler-data'
-from
-t0 A, t1 B;
+from seq_0_to_99 A, seq_0_to_99 B;
analyze table t2,t3;
Table Op Msg_type Msg_text
test.t2 analyze status Engine-independent statistics collected
@@ -38,13 +33,12 @@ where
t3.key1=t2.a and t3.key2 in (2,3);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 100 Using where
-1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 1000 (20%) Using where; Using rowid filter
+1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 100 (2%) Using where; Using rowid filter
set debug_sync='handler_rowid_filter_check SIGNAL at_rowid_filter_check WAIT_FOR go';
select * from t2, t3
where
t3.key1=t2.a and t3.key2 in (2,3);
connect con1, localhost, root,,;
-connection con1;
set debug_sync='now WAIT_FOR at_rowid_filter_check';
kill query $target_id;
set debug_sync='now SIGNAL go';
@@ -52,7 +46,7 @@ connection default;
disconnect con1;
ERROR 70100: Query execution was interrupted
set debug_sync='RESET';
-drop table t0,t1,t2,t3;
+drop table t2,t3;
set default_storage_engine=default;
set @save_optimizer_switch= @@optimizer_switch;
set @save_use_stat_tables= @@use_stat_tables;
@@ -69,7 +63,6 @@ INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4);
set debug_sync='handler_rowid_filter_check SIGNAL killme WAIT_FOR go';
SELECT * FROM t1 WHERE a > 0 AND b=0;
connect con1, localhost, root,,;
-connection con1;
set debug_sync='now WAIT_FOR killme';
kill query @id;
set debug_sync='now SIGNAL go';
diff --git a/mysql-test/main/rowid_filter_innodb_debug.test b/mysql-test/main/rowid_filter_innodb_debug.test
index 31fbd937304..f89a2a82da8 100644
--- a/mysql-test/main/rowid_filter_innodb_debug.test
+++ b/mysql-test/main/rowid_filter_innodb_debug.test
@@ -31,7 +31,6 @@ set debug_sync='handler_rowid_filter_check SIGNAL killme WAIT_FOR go';
send SELECT * FROM t1 WHERE a > 0 AND b=0;
connect (con1, localhost, root,,);
-connection con1;
let $ignore= `SELECT @id := $ID`;
set debug_sync='now WAIT_FOR killme';
kill query @id;
diff --git a/mysql-test/main/rowid_filter_myisam_debug.result b/mysql-test/main/rowid_filter_myisam_debug.result
index 16fcb2a416e..75a8fad6947 100644
--- a/mysql-test/main/rowid_filter_myisam_debug.result
+++ b/mysql-test/main/rowid_filter_myisam_debug.result
@@ -1,12 +1,8 @@
#
# MDEV-22761 KILL QUERY during rowid_filter, crashes
#
-create table t0(a int);
-insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-create table t1(a int);
-insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
create table t2(a int);
-insert into t2 select A.a + B.a* 10 from t0 A, t0 B;
+insert into t2 select * from seq_0_to_99;
CREATE TABLE t3 (
key1 int ,
key2 int,
@@ -20,11 +16,10 @@ engine
MyISAM
insert into t3
select
-A.a,
-A.a,
+A.seq,
+B.seq,
'filler-data-filler-data'
-from
-t0 A, t1 B;
+from seq_0_to_99 A, seq_0_to_99 B;
analyze table t2,t3;
Table Op Msg_type Msg_text
test.t2 analyze status Engine-independent statistics collected
@@ -37,13 +32,12 @@ where
t3.key1=t2.a and t3.key2 in (2,3);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 100 Using where
-1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 1000 (18%) Using where; Using rowid filter
+1 SIMPLE t3 ref|filter key1,key2 key1|key2 5|5 test.t2.a 100 (2%) Using where; Using rowid filter
set debug_sync='handler_rowid_filter_check SIGNAL at_rowid_filter_check WAIT_FOR go';
select * from t2, t3
where
t3.key1=t2.a and t3.key2 in (2,3);
connect con1, localhost, root,,;
-connection con1;
set debug_sync='now WAIT_FOR at_rowid_filter_check';
kill query $target_id;
set debug_sync='now SIGNAL go';
@@ -51,4 +45,4 @@ connection default;
disconnect con1;
ERROR 70100: Query execution was interrupted
set debug_sync='RESET';
-drop table t0,t1,t2,t3;
+drop table t2,t3;
diff --git a/mysql-test/main/select.result b/mysql-test/main/select.result
index a48b879de5d..acf08e6a8e9 100644
--- a/mysql-test/main/select.result
+++ b/mysql-test/main/select.result
@@ -3474,13 +3474,13 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
-1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using rowid filter
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition
+1 SIMPLE t2 ref c c 5 test.t1.a 2
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
-1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using rowid filter
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 2
DROP TABLE t1, t2;
create table t1 (
a int unsigned not null auto_increment primary key,
@@ -3744,7 +3744,7 @@ EXPLAIN SELECT * FROM t1
WHERE ID_better=1 AND ID1_with_null IS NULL AND
(ID2_with_null=1 OR ID2_with_null=2);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref|filter idx1,idx2 idx1|idx2 5|4 const 2 (1%) Using index condition; Using where; Using rowid filter
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where
DROP TABLE t1;
CREATE TABLE t1 (a INT, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY ts(ts));
INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00");
diff --git a/mysql-test/main/select_jcl6.result b/mysql-test/main/select_jcl6.result
index f217964adc3..9259fa750cf 100644
--- a/mysql-test/main/select_jcl6.result
+++ b/mysql-test/main/select_jcl6.result
@@ -3485,13 +3485,13 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
-1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
-1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
DROP TABLE t1, t2;
create table t1 (
a int unsigned not null auto_increment primary key,
@@ -3755,7 +3755,7 @@ EXPLAIN SELECT * FROM t1
WHERE ID_better=1 AND ID1_with_null IS NULL AND
(ID2_with_null=1 OR ID2_with_null=2);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref|filter idx1,idx2 idx1|idx2 5|4 const 2 (1%) Using index condition; Using where; Using rowid filter
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where
DROP TABLE t1;
CREATE TABLE t1 (a INT, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY ts(ts));
INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00");
diff --git a/mysql-test/main/select_pkeycache.result b/mysql-test/main/select_pkeycache.result
index a48b879de5d..acf08e6a8e9 100644
--- a/mysql-test/main/select_pkeycache.result
+++ b/mysql-test/main/select_pkeycache.result
@@ -3474,13 +3474,13 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
-1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using rowid filter
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition
+1 SIMPLE t2 ref c c 5 test.t1.a 2
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
-1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using rowid filter
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 2
DROP TABLE t1, t2;
create table t1 (
a int unsigned not null auto_increment primary key,
@@ -3744,7 +3744,7 @@ EXPLAIN SELECT * FROM t1
WHERE ID_better=1 AND ID1_with_null IS NULL AND
(ID2_with_null=1 OR ID2_with_null=2);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref|filter idx1,idx2 idx1|idx2 5|4 const 2 (1%) Using index condition; Using where; Using rowid filter
+1 SIMPLE t1 ref idx1,idx2 idx2 4 const 2 Using where
DROP TABLE t1;
CREATE TABLE t1 (a INT, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY ts(ts));
INSERT INTO t1 VALUES (30,"2006-01-03 23:00:00"), (31,"2006-01-03 23:00:00");
diff --git a/mysql-test/main/selectivity.result b/mysql-test/main/selectivity.result
index 2cd3cbdd8eb..749c74f431b 100644
--- a/mysql-test/main/selectivity.result
+++ b/mysql-test/main/selectivity.result
@@ -1641,8 +1641,8 @@ drop function f1;
#
create table t1 (a int, b int, key (b), key (a));
insert into t1
-select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000;
-analyze table t1 ;
+select (rand(1)*1000)/10, (rand(1001)*1000)/20 from seq_1_to_1000;
+analyze table t1 persistent for all;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status Table is already up to date
@@ -1654,14 +1654,14 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`a` in (17,51,5)
explain extended select * from t1 use index () where b=2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 5.47 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 2.34 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`b` = 2
# Now, the equality is used for ref access, while the range condition
# gives selectivity data
explain extended select * from t1 where a in (17,51,5) and b=2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ref|filter b,a b|a 5|5 const 58 (3%) 2.90 Using where; Using rowid filter
+1 SIMPLE t1 ref|filter b,a b|a 5|5 const 24 (3%) 2.90 Using where; Using rowid filter
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (17,51,5)
drop table t1;
@@ -1817,6 +1817,12 @@ create table t1 (id int, a int, PRIMARY KEY(id), key(a));
insert into t1 select seq,seq from seq_1_to_100;
create table t2 (id int, a int, b int, PRIMARY KEY(id), key(a), key(b));
insert into t2 select seq,seq,seq from seq_1_to_100;
+analyze table t1,t2 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status Table is already up to date
set optimizer_switch='exists_to_in=off';
set optimizer_use_condition_selectivity=2;
SELECT * FROM t1
@@ -1850,7 +1856,7 @@ WHERE A.a=t1.a AND t2.b < 20);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 100 Using where
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1
-2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (10%) Using where; Using rowid filter
+2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A const PRIMARY,a PRIMARY 4 const 1
@@ -1862,7 +1868,7 @@ WHERE A.a=t1.a AND t2.b < 20);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 100 Using where
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1
-2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (10%) Using where; Using rowid filter
+2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
set optimizer_switch= @save_optimizer_switch;
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
drop table t1,t2;
diff --git a/mysql-test/main/selectivity.test b/mysql-test/main/selectivity.test
index 9c82a8d37a7..4e4513d09d6 100644
--- a/mysql-test/main/selectivity.test
+++ b/mysql-test/main/selectivity.test
@@ -1111,8 +1111,8 @@ drop function f1;
--echo #
create table t1 (a int, b int, key (b), key (a));
insert into t1
-select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000;
-analyze table t1 ;
+select (rand(1)*1000)/10, (rand(1001)*1000)/20 from seq_1_to_1000;
+analyze table t1 persistent for all;
--echo # Check what info the optimizer has about selectivities
explain extended select * from t1 use index () where a in (17,51,5);
@@ -1249,6 +1249,8 @@ insert into t1 select seq,seq from seq_1_to_100;
create table t2 (id int, a int, b int, PRIMARY KEY(id), key(a), key(b));
insert into t2 select seq,seq,seq from seq_1_to_100;
+analyze table t1,t2 persistent for all;
+
set optimizer_switch='exists_to_in=off';
set optimizer_use_condition_selectivity=2;
diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result
index 07cdf15163c..d0de50722a7 100644
--- a/mysql-test/main/selectivity_innodb.result
+++ b/mysql-test/main/selectivity_innodb.result
@@ -1653,8 +1653,8 @@ drop function f1;
#
create table t1 (a int, b int, key (b), key (a));
insert into t1
-select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000;
-analyze table t1 ;
+select (rand(1)*1000)/10, (rand(1001)*1000)/20 from seq_1_to_1000;
+analyze table t1 persistent for all;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
@@ -1666,14 +1666,14 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`a` in (17,51,5)
explain extended select * from t1 use index () where b=2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 5.47 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 2.34 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`b` = 2
# Now, the equality is used for ref access, while the range condition
# gives selectivity data
explain extended select * from t1 where a in (17,51,5) and b=2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ref|filter b,a b|a 5|5 const 59 (3%) 2.90 Using where; Using rowid filter
+1 SIMPLE t1 ref|filter b,a b|a 5|5 const 24 (3%) 2.90 Using where; Using rowid filter
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (17,51,5)
drop table t1;
@@ -1829,6 +1829,12 @@ create table t1 (id int, a int, PRIMARY KEY(id), key(a));
insert into t1 select seq,seq from seq_1_to_100;
create table t2 (id int, a int, b int, PRIMARY KEY(id), key(a), key(b));
insert into t2 select seq,seq,seq from seq_1_to_100;
+analyze table t1,t2 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
set optimizer_switch='exists_to_in=off';
set optimizer_use_condition_selectivity=2;
SELECT * FROM t1
@@ -1862,7 +1868,7 @@ WHERE A.a=t1.a AND t2.b < 20);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
-2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (19%) Using where; Using rowid filter
+2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A const PRIMARY,a PRIMARY 4 const 1
@@ -1874,7 +1880,7 @@ WHERE A.a=t1.a AND t2.b < 20);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
-2 DEPENDENT SUBQUERY t2 ref|filter a,b a|b 5|5 test.A.id 1 (19%) Using where; Using rowid filter
+2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
set optimizer_switch= @save_optimizer_switch;
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
drop table t1,t2;
diff --git a/mysql-test/main/subselect.result b/mysql-test/main/subselect.result
index 17470fa128a..4209e2bc529 100644
--- a/mysql-test/main/subselect.result
+++ b/mysql-test/main/subselect.result
@@ -7382,6 +7382,17 @@ a
drop table t1,t2,t3;
# End of 10.2 tests
#
+# MDEV-29926: ASAN heap-use-after-free in Explain_query::~Explain_query
+#
+CREATE TABLE t (a VARCHAR(1)) CHARACTER SET utf8mb3;
+EXECUTE IMMEDIATE "SELECT COUNT(*) FROM t WHERE a < (SELECT 'x')";
+COUNT(*)
+0
+DROP TABLE t;
+#
+# End of 10.3 tests
+#
+#
# Start of 10.4 tests
#
#
diff --git a/mysql-test/main/subselect.test b/mysql-test/main/subselect.test
index 8c11517f5d3..be22169a1d6 100644
--- a/mysql-test/main/subselect.test
+++ b/mysql-test/main/subselect.test
@@ -6298,6 +6298,20 @@ drop table t1,t2,t3;
--echo # End of 10.2 tests
+--echo #
+--echo # MDEV-29926: ASAN heap-use-after-free in Explain_query::~Explain_query
+--echo #
+
+CREATE TABLE t (a VARCHAR(1)) CHARACTER SET utf8mb3;
+EXECUTE IMMEDIATE "SELECT COUNT(*) FROM t WHERE a < (SELECT 'x')";
+
+# Cleanup
+DROP TABLE t;
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
+
--echo #
--echo # Start of 10.4 tests
diff --git a/mysql-test/main/subselect_no_exists_to_in.result b/mysql-test/main/subselect_no_exists_to_in.result
index 394a13a4207..e32e6007328 100644
--- a/mysql-test/main/subselect_no_exists_to_in.result
+++ b/mysql-test/main/subselect_no_exists_to_in.result
@@ -7382,6 +7382,17 @@ a
drop table t1,t2,t3;
# End of 10.2 tests
#
+# MDEV-29926: ASAN heap-use-after-free in Explain_query::~Explain_query
+#
+CREATE TABLE t (a VARCHAR(1)) CHARACTER SET utf8mb3;
+EXECUTE IMMEDIATE "SELECT COUNT(*) FROM t WHERE a < (SELECT 'x')";
+COUNT(*)
+0
+DROP TABLE t;
+#
+# End of 10.3 tests
+#
+#
# Start of 10.4 tests
#
#
diff --git a/mysql-test/main/subselect_no_mat.result b/mysql-test/main/subselect_no_mat.result
index 3d19a80871e..07755a5144a 100644
--- a/mysql-test/main/subselect_no_mat.result
+++ b/mysql-test/main/subselect_no_mat.result
@@ -7375,6 +7375,17 @@ a
drop table t1,t2,t3;
# End of 10.2 tests
#
+# MDEV-29926: ASAN heap-use-after-free in Explain_query::~Explain_query
+#
+CREATE TABLE t (a VARCHAR(1)) CHARACTER SET utf8mb3;
+EXECUTE IMMEDIATE "SELECT COUNT(*) FROM t WHERE a < (SELECT 'x')";
+COUNT(*)
+0
+DROP TABLE t;
+#
+# End of 10.3 tests
+#
+#
# Start of 10.4 tests
#
#
diff --git a/mysql-test/main/subselect_no_opts.result b/mysql-test/main/subselect_no_opts.result
index 2934726811a..15688fc1717 100644
--- a/mysql-test/main/subselect_no_opts.result
+++ b/mysql-test/main/subselect_no_opts.result
@@ -7373,6 +7373,17 @@ a
drop table t1,t2,t3;
# End of 10.2 tests
#
+# MDEV-29926: ASAN heap-use-after-free in Explain_query::~Explain_query
+#
+CREATE TABLE t (a VARCHAR(1)) CHARACTER SET utf8mb3;
+EXECUTE IMMEDIATE "SELECT COUNT(*) FROM t WHERE a < (SELECT 'x')";
+COUNT(*)
+0
+DROP TABLE t;
+#
+# End of 10.3 tests
+#
+#
# Start of 10.4 tests
#
#
diff --git a/mysql-test/main/subselect_no_scache.result b/mysql-test/main/subselect_no_scache.result
index 3c6dfbaa9c3..e3bdddbf84b 100644
--- a/mysql-test/main/subselect_no_scache.result
+++ b/mysql-test/main/subselect_no_scache.result
@@ -7388,6 +7388,17 @@ a
drop table t1,t2,t3;
# End of 10.2 tests
#
+# MDEV-29926: ASAN heap-use-after-free in Explain_query::~Explain_query
+#
+CREATE TABLE t (a VARCHAR(1)) CHARACTER SET utf8mb3;
+EXECUTE IMMEDIATE "SELECT COUNT(*) FROM t WHERE a < (SELECT 'x')";
+COUNT(*)
+0
+DROP TABLE t;
+#
+# End of 10.3 tests
+#
+#
# Start of 10.4 tests
#
#
diff --git a/mysql-test/main/subselect_no_semijoin.result b/mysql-test/main/subselect_no_semijoin.result
index 9b31fbf5f3e..a06a4aef99b 100644
--- a/mysql-test/main/subselect_no_semijoin.result
+++ b/mysql-test/main/subselect_no_semijoin.result
@@ -7373,6 +7373,17 @@ a
drop table t1,t2,t3;
# End of 10.2 tests
#
+# MDEV-29926: ASAN heap-use-after-free in Explain_query::~Explain_query
+#
+CREATE TABLE t (a VARCHAR(1)) CHARACTER SET utf8mb3;
+EXECUTE IMMEDIATE "SELECT COUNT(*) FROM t WHERE a < (SELECT 'x')";
+COUNT(*)
+0
+DROP TABLE t;
+#
+# End of 10.3 tests
+#
+#
# Start of 10.4 tests
#
#
diff --git a/mysql-test/main/type_time_hires.result b/mysql-test/main/type_time_hires.result
index 5fa9d11591a..cf7dce59f1f 100644
--- a/mysql-test/main/type_time_hires.result
+++ b/mysql-test/main/type_time_hires.result
@@ -360,7 +360,7 @@ select cast(1e-6 as time(6));
cast(1e-6 as time(6))
00:00:00.000001
#
-# Start of 10.4 tests
+# End of 5.5 tests
#
#
# MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE()
@@ -907,3 +907,14 @@ a CEILING(a) CEILING_SP(a) CEILING(a)=CEILING_SP(a)
DROP FUNCTION FLOOR_SP;
DROP FUNCTION CEILING_SP;
DROP TABLE t1;
+#
+# MDEV-29924 Assertion `(((nr) % (1LL << 24)) % (int) log_10_int[6 - dec]) == 0' failed in my_time_packed_to_binary on SELECT when using TIME field
+#
+create table t1 (c decimal(3,1),d time(6));
+insert into t1 values (null,0.1),(null,0.1), (0.1,0.2);
+select c from t1 where c<all (select d from t1);
+c
+drop table t1;
+#
+# End of 10.4 tests
+#
diff --git a/mysql-test/main/type_time_hires.test b/mysql-test/main/type_time_hires.test
index f9b4a5a9f27..51824c689ad 100644
--- a/mysql-test/main/type_time_hires.test
+++ b/mysql-test/main/type_time_hires.test
@@ -11,9 +11,8 @@ drop table t1;
select cast(1e-6 as time(6));
-
--echo #
---echo # Start of 10.4 tests
+--echo # End of 5.5 tests
--echo #
--echo #
@@ -196,3 +195,15 @@ DROP FUNCTION FLOOR_SP;
DROP FUNCTION CEILING_SP;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-29924 Assertion `(((nr) % (1LL << 24)) % (int) log_10_int[6 - dec]) == 0' failed in my_time_packed_to_binary on SELECT when using TIME field
+--echo #
+create table t1 (c decimal(3,1),d time(6));
+insert into t1 values (null,0.1),(null,0.1), (0.1,0.2);
+select c from t1 where c<all (select d from t1);
+drop table t1;
+
+--echo #
+--echo # End of 10.4 tests
+--echo #
diff --git a/mysql-test/std_data/mysql_upgrade/mdev28822_100427_innodb.frm b/mysql-test/std_data/mysql_upgrade/mdev28822_100427_innodb.frm
new file mode 100644
index 00000000000..d9cc5e6cc69
--- /dev/null
+++ b/mysql-test/std_data/mysql_upgrade/mdev28822_100427_innodb.frm
Binary files differ
diff --git a/mysql-test/suite/binlog/r/binlog_empty_xa_prepared.result b/mysql-test/suite/binlog/r/binlog_empty_xa_prepared.result
index 9f998e049c0..b11484367b8 100644
--- a/mysql-test/suite/binlog/r/binlog_empty_xa_prepared.result
+++ b/mysql-test/suite/binlog/r/binlog_empty_xa_prepared.result
@@ -1,3 +1,4 @@
+RESET MASTER;
CREATE TEMPORARY SEQUENCE seq_1;
XA START '3';
CREATE TEMPORARY TABLE tmp_1(c INT);
@@ -108,3 +109,111 @@ master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP SEQUENCE `s` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+connect con1,localhost,root,,;
+XA START '1';
+INSERT INTO t1 VALUES (2),(1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+SELECT * FROM t1 WHERE a = 2;
+a
+XA END '1';
+XA PREPARE '1';
+disconnect con1;
+connection default;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 1
+XA COMMIT '1';
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+Must be no XA PREPARE group nor XA completion one:
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (1)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE SEQUENCE s ENGINE=InnoDB
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Annotate_rows # # SELECT NEXT VALUE FOR s
+master-bin.000001 # Table_map # # table_id: # (test.s)
+master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Gtid # # XA START X'32',X'',1 GTID #-#-#
+master-bin.000001 # Query # # XA END X'32',X'',1
+master-bin.000001 # XA_prepare # # XA PREPARE X'32',X'',1
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # XA ROLLBACK X'32',X'',1
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP SEQUENCE `s` /* generated by server */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (1)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+DROP TABLE t1;
+connect con2,localhost,root,,;
+CREATE TABLE tm (a INT PRIMARY KEY) ENGINE=MyISAM;
+XA START '1';
+INSERT INTO tm VALUES (1),(1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+SELECT * FROM tm WHERE a = 2;
+a
+XA END '1';
+XA PREPARE '1';
+disconnect con2;
+connection default;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 1
+XA ROLLBACK '1';
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+Must be no XA PREPARE group nor XA completion one:
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (1)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE SEQUENCE s ENGINE=InnoDB
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Annotate_rows # # SELECT NEXT VALUE FOR s
+master-bin.000001 # Table_map # # table_id: # (test.s)
+master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Gtid # # XA START X'32',X'',1 GTID #-#-#
+master-bin.000001 # Query # # XA END X'32',X'',1
+master-bin.000001 # XA_prepare # # XA PREPARE X'32',X'',1
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # XA ROLLBACK X'32',X'',1
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP SEQUENCE `s` /* generated by server */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (1)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # use `test`; CREATE TABLE tm (a INT PRIMARY KEY) ENGINE=MyISAM
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `test`; INSERT INTO tm VALUES (1),(1)
+master-bin.000001 # Query # # COMMIT
+DROP TABLE tm;
diff --git a/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_binary.result b/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_binary.result
index 789bc6cd178..7514380b715 100644
--- a/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_binary.result
+++ b/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_binary.result
@@ -1,3 +1,4 @@
+RESET MASTER;
#
# Verify that SET string values and character sets can be printed correctly
#
diff --git a/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_ucs2.result b/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_ucs2.result
index 1b1d2a79725..a889a2fa82e 100644
--- a/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_ucs2.result
+++ b/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_ucs2.result
@@ -1,3 +1,4 @@
+RESET MASTER;
#
# Verify that SET string values and character sets can be printed correctly
#
diff --git a/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_utf32.result b/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_utf32.result
index 6fdda842bac..e44d0a275d7 100644
--- a/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_utf32.result
+++ b/mysql-test/suite/binlog/r/binlog_table_map_optional_metadata_utf32.result
@@ -1,3 +1,4 @@
+RESET MASTER;
#
# Verify that SET string values and character sets can be printed correctly
#
diff --git a/mysql-test/suite/binlog/t/binlog_empty_xa_prepared.test b/mysql-test/suite/binlog/t/binlog_empty_xa_prepared.test
index 443feb60627..b127178ebf7 100644
--- a/mysql-test/suite/binlog/t/binlog_empty_xa_prepared.test
+++ b/mysql-test/suite/binlog/t/binlog_empty_xa_prepared.test
@@ -4,7 +4,7 @@
--source include/have_binlog_format_mixed.inc
--source include/have_innodb.inc
-
+RESET MASTER; # clear binlogs
# MDEV-22420 DDL on temporary object is prohibited when XA is in prepare state
# Temporary sequnce may not be created within a transaction
@@ -80,3 +80,55 @@ DROP TABLE t1;
--echo # Proof of correct logging incl empty XA-PREPARE
--source include/show_binlog_events.inc
+
+
+# MDEV-25616 Binlog event for XA COMMIT is generated without matching XA START
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+
+--source include/count_sessions.inc
+--connect(con1,localhost,root,,)
+
+XA START '1';
+ --error ER_DUP_ENTRY
+ INSERT INTO t1 VALUES (2),(1);
+ SELECT * FROM t1 WHERE a = 2;
+XA END '1';
+XA PREPARE '1';
+
+--disconnect con1
+
+--connection default
+--source include/wait_until_count_sessions.inc
+XA RECOVER;
+
+--error ER_XA_RBROLLBACK
+XA COMMIT '1';
+--echo Must be no XA PREPARE group nor XA completion one:
+--source include/show_binlog_events.inc
+DROP TABLE t1;
+
+--source include/count_sessions.inc
+
+--connect(con2,localhost,root,,)
+CREATE TABLE tm (a INT PRIMARY KEY) ENGINE=MyISAM;
+XA START '1';
+ --error ER_DUP_ENTRY
+ INSERT INTO tm VALUES (1),(1);
+ SELECT * FROM tm WHERE a = 2;
+XA END '1';
+XA PREPARE '1';
+
+--disconnect con2
+
+--connection default
+--source include/wait_until_count_sessions.inc
+XA RECOVER;
+
+--error ER_XA_RBROLLBACK
+XA ROLLBACK '1';
+--echo Must be no XA PREPARE group nor XA completion one:
+--source include/show_binlog_events.inc
+DROP TABLE tm;
+
diff --git a/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_binary.test b/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_binary.test
index 5997cfd5d27..29e10ede98a 100644
--- a/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_binary.test
+++ b/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_binary.test
@@ -20,6 +20,7 @@
--let $MYSQLD_DATADIR= `select @@datadir`
--let $binlog_file= $MYSQLD_DATADIR/master-bin.000001
+RESET MASTER;
--echo #
--echo # Verify that SET string values and character sets can be printed correctly
--echo #
diff --git a/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_ucs2.test b/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_ucs2.test
index 1e218acdfea..8c9e22421b6 100644
--- a/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_ucs2.test
+++ b/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_ucs2.test
@@ -21,6 +21,7 @@
--let $MYSQLD_DATADIR= `select @@datadir`
--let $binlog_file= $MYSQLD_DATADIR/master-bin.000001
+RESET MASTER;
--echo #
--echo # Verify that SET string values and character sets can be printed correctly
--echo #
diff --git a/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_utf32.test b/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_utf32.test
index c1d449abf2f..094de058028 100644
--- a/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_utf32.test
+++ b/mysql-test/suite/binlog/t/binlog_table_map_optional_metadata_utf32.test
@@ -21,6 +21,7 @@
--let $MYSQLD_DATADIR= `select @@datadir`
--let $binlog_file= $MYSQLD_DATADIR/master-bin.000001
+RESET MASTER;
--echo #
--echo # Verify that SET string values and character sets can be printed correctly
--echo #
diff --git a/mysql-test/suite/encryption/r/innochecksum,debug.rdiff b/mysql-test/suite/encryption/r/innochecksum,debug.rdiff
new file mode 100644
index 00000000000..c3e3eed26bd
--- /dev/null
+++ b/mysql-test/suite/encryption/r/innochecksum,debug.rdiff
@@ -0,0 +1,10 @@
+@@ -30,6 +30,9 @@
+ # Space ID mismatch
+ # Restore the original tables
+ # Corrupt FIL_DATA+10 (data)
++# FOUND 1 is expected for both.
++FOUND 1 /InnoDB: Crash recovery is broken due to insufficient innodb_log_file_size; last checkpoint LSN=\d+, current LSN=\d+\. Shutdown is in progress\..*InnoDB: Crash recovery was broken.*/ in mysqld.1.err
++FOUND 1 /InnoDB: Crash recovery was broken/ in mysqld.1.err
+ # Run innochecksum on t2
+ # Run innochecksum on t3
+ # Run innochecksum on t6
diff --git a/mysql-test/suite/encryption/t/innochecksum.test b/mysql-test/suite/encryption/t/innochecksum.test
index 59d90fbb3d7..ecabce30ab7 100644
--- a/mysql-test/suite/encryption/t/innochecksum.test
+++ b/mysql-test/suite/encryption/t/innochecksum.test
@@ -9,6 +9,7 @@
-- source include/have_file_key_management_plugin.inc
-- source include/innodb_page_size_small.inc
-- source include/innodb_checksum_algorithm.inc
+-- source include/maybe_debug.inc
if (!$INNOCHECKSUM) {
--echo Need innochecksum binary
@@ -18,6 +19,10 @@ if (!$INNOCHECKSUM) {
--disable_query_log
# This may be triggered on a slow system or one that lacks native AIO.
call mtr.add_suppression("InnoDB: Trying to delete tablespace.*pending operations");
+if ($have_debug) {
+SET GLOBAL DEBUG_DBUG='+d,ib_log_checkpoint_avoid_hard';
+call mtr.add_suppression("InnoDB: Crash recovery is broken due to insufficient innodb_log_file_size");
+}
--enable_query_log
let $checksum_algorithm = `SELECT @@innodb_checksum_algorithm`;
@@ -259,6 +264,15 @@ print FILE pack("H*", "c00lcafedeadb017");
close FILE or die "close";
EOF
+if ($have_debug) {
+--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err
+--let SEARCH_PATTERN= InnoDB: Crash recovery is broken due to insufficient innodb_log_file_size; last checkpoint LSN=\\d+, current LSN=\\d+\\. Shutdown is in progress\\..*InnoDB: Crash recovery was broken.*
+--echo # FOUND 1 is expected for both.
+--source include/search_pattern_in_file.inc
+--let SEARCH_PATTERN= InnoDB: Crash recovery was broken
+--source include/search_pattern_in_file.inc
+}
+
-- disable_result_log
--error 1
--exec $INNOCHECKSUM $t1_IBD
diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result
index 28736515327..c0b91a68da7 100644
--- a/mysql-test/suite/federated/federatedx_create_handlers.result
+++ b/mysql-test/suite/federated/federatedx_create_handlers.result
@@ -422,6 +422,100 @@ SELECT * FROM (SELECT * FROM federated.t1 LIMIT 70000) dt;
SELECT COUNT(DISTINCT a) FROM federated.t2;
COUNT(DISTINCT a)
70000
+#
+# MDEV-29640 FederatedX does not properly handle pushdown
+# in case of difference in local and remote table names
+#
+connection master;
+# Use tables from the previous test. Make sure pushdown works:
+EXPLAIN SELECT COUNT(DISTINCT a) FROM federated.t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL
+SELECT COUNT(DISTINCT a) FROM federated.t2;
+COUNT(DISTINCT a)
+70000
+# Link remote table `federated.t1` with the local table named `t1_local`
+CREATE TABLE federated.t1_local ENGINE="FEDERATED"
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
+# No pushdown here due to table names mismatch, retrieve data as usual:
+EXPLAIN SELECT COUNT(DISTINCT a) FROM federated.t1_local;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1_local ALL NULL NULL NULL NULL 70000
+SELECT COUNT(DISTINCT a) FROM federated.t1_local;
+COUNT(DISTINCT a)
+70000
+#
+# MDEV-29863 Server crashes in federatedx_txn::acquire after select from
+# the Federated table with partitions and federated_pushdown=1
+# in case of difference in local and remote table names
+#
+connection slave;
+CREATE TABLE federated.t3 (a INT);
+INSERT INTO federated.t3 VALUES (1),(2),(3);
+CREATE TABLE federated.t4 (a INT);
+connection master;
+CREATE SERVER fedlink FOREIGN DATA WRAPPER mysql
+OPTIONS (USER 'root', HOST '127.0.0.1', DATABASE 'federated',
+PORT SLAVE_PORT);
+CREATE TABLE federated.t3 (a INT)
+ENGINE=FEDERATED
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t3'
+ PARTITION BY list (a)
+(PARTITION p1 VALUES IN (1) CONNECTION='fedlink/t3',
+PARTITION p2 VALUES IN (2) CONNECTION='fedlink/t4');
+EXPLAIN SELECT * FROM federated.t3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 ALL NULL NULL NULL NULL 3
+SELECT * FROM federated.t3;
+a
+1
+2
+3
+#
+# MDEV-29655: ASAN heap-use-after-free in
+# Pushdown_derived::Pushdown_derived
+#
+connection slave;
+DROP TABLE IF EXISTS federated.t1;
+CREATE TABLE federated.t1 (
+id int(20) NOT NULL,
+name varchar(16) NOT NULL default ''
+)
+DEFAULT CHARSET=latin1;
+INSERT INTO federated.t1 VALUES
+(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');
+connection master;
+DROP TABLE IF EXISTS federated.t1;
+CREATE TABLE federated.t1 (
+id int(20) NOT NULL,
+name varchar(16) NOT NULL default ''
+)
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
+use federated;
+SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
+WHERE id=2) dt2) dt;
+id name
+connection slave;
+CREATE TABLE federated.t10 (a INT,b INT);
+CREATE TABLE federated.t11 (a INT, b INT);
+INSERT INTO federated.t10 VALUES (1,1),(2,2);
+INSERT INTO federated.t11 VALUES (1,1),(2,2);
+connection master;
+CREATE TABLE federated.t10
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t10';
+CREATE TABLE federated.t11
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t11';
+use federated;
+SELECT * FROM t10 LEFT JOIN
+(t11, (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
+WHERE id=2) dt2) dt
+) ON t10.a=t11.a;
+a b a b id name
+1 1 NULL NULL NULL NULL
+2 2 NULL NULL NULL NULL
set global federated_pushdown=0;
connection master;
DROP TABLE IF EXISTS federated.t1;
diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test
index 8863a057b47..f827c141f3d 100644
--- a/mysql-test/suite/federated/federatedx_create_handlers.test
+++ b/mysql-test/suite/federated/federatedx_create_handlers.test
@@ -1,6 +1,7 @@
--source have_federatedx.inc
--source include/federated.inc
--source include/no_valgrind_without_big.inc
+--source include/have_partition.inc
connection default;
@@ -266,6 +267,110 @@ INSERT INTO federated.t2
SELECT * FROM (SELECT * FROM federated.t1 LIMIT 70000) dt;
SELECT COUNT(DISTINCT a) FROM federated.t2;
+--echo #
+--echo # MDEV-29640 FederatedX does not properly handle pushdown
+--echo # in case of difference in local and remote table names
+--echo #
+connection master;
+--echo # Use tables from the previous test. Make sure pushdown works:
+EXPLAIN SELECT COUNT(DISTINCT a) FROM federated.t2;
+SELECT COUNT(DISTINCT a) FROM federated.t2;
+
+--echo # Link remote table `federated.t1` with the local table named `t1_local`
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval
+CREATE TABLE federated.t1_local ENGINE="FEDERATED"
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
+
+--echo # No pushdown here due to table names mismatch, retrieve data as usual:
+EXPLAIN SELECT COUNT(DISTINCT a) FROM federated.t1_local;
+SELECT COUNT(DISTINCT a) FROM federated.t1_local;
+
+
+--echo #
+--echo # MDEV-29863 Server crashes in federatedx_txn::acquire after select from
+--echo # the Federated table with partitions and federated_pushdown=1
+--echo # in case of difference in local and remote table names
+--echo #
+connection slave;
+CREATE TABLE federated.t3 (a INT);
+INSERT INTO federated.t3 VALUES (1),(2),(3);
+CREATE TABLE federated.t4 (a INT);
+
+connection master;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE SERVER fedlink FOREIGN DATA WRAPPER mysql
+ OPTIONS (USER 'root', HOST '127.0.0.1', DATABASE 'federated',
+ PORT $SLAVE_MYPORT);
+
+CREATE TABLE federated.t3 (a INT)
+ ENGINE=FEDERATED
+ CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t3'
+ PARTITION BY list (a)
+ (PARTITION p1 VALUES IN (1) CONNECTION='fedlink/t3',
+ PARTITION p2 VALUES IN (2) CONNECTION='fedlink/t4');
+
+EXPLAIN SELECT * FROM federated.t3;
+SELECT * FROM federated.t3;
+
+--echo #
+--echo # MDEV-29655: ASAN heap-use-after-free in
+--echo # Pushdown_derived::Pushdown_derived
+--echo #
+
+connection slave;
+DROP TABLE IF EXISTS federated.t1;
+
+CREATE TABLE federated.t1 (
+ id int(20) NOT NULL,
+ name varchar(16) NOT NULL default ''
+)
+DEFAULT CHARSET=latin1;
+
+INSERT INTO federated.t1 VALUES
+ (3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');
+
+connection master;
+DROP TABLE IF EXISTS federated.t1;
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval
+CREATE TABLE federated.t1 (
+ id int(20) NOT NULL,
+ name varchar(16) NOT NULL default ''
+)
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
+
+use federated;
+SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
+ WHERE id=2) dt2) dt;
+
+connection slave;
+CREATE TABLE federated.t10 (a INT,b INT);
+CREATE TABLE federated.t11 (a INT, b INT);
+INSERT INTO federated.t10 VALUES (1,1),(2,2);
+INSERT INTO federated.t11 VALUES (1,1),(2,2);
+
+connection master;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval
+CREATE TABLE federated.t10
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t10';
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval
+CREATE TABLE federated.t11
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t11';
+
+use federated;
+SELECT * FROM t10 LEFT JOIN
+ (t11, (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
+ WHERE id=2) dt2) dt
+ ) ON t10.a=t11.a;
+
set global federated_pushdown=0;
source include/federated_cleanup.inc;
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index e518dca5a84..feac559ff55 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -37,4 +37,6 @@ query_cache: MDEV-15805 Test failure on galera.query_cache
versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch
galera_bf_abort_at_after_statement : Unstable
galera_bf_abort_shutdown : MDEV-29773 Assertion failure on sql/wsrep_mysqld.cc:2893 in wsrep_bf_abort_shutdown
-
+galera.MW-284 : MDEV-29861: Galera test case hangs
+galera.galera_binlog_checksum : MDEV-29861: Galera test case hangs
+galera_var_notify_ssl_ipv6 : MDEV-29861: Galera test case hangs
diff --git a/mysql-test/suite/galera/r/galera_many_rows.result b/mysql-test/suite/galera/r/galera_many_rows.result
index 566bc59f8ab..b34c2484aea 100644
--- a/mysql-test/suite/galera/r/galera_many_rows.result
+++ b/mysql-test/suite/galera/r/galera_many_rows.result
@@ -5,32 +5,32 @@ connection node_2;
connection node_1;
SET SESSION innodb_lock_wait_timeout=600;
SET SESSION lock_wait_timeout=600;
-CREATE TABLE ten (f1 INTEGER) engine=InnoDB;
+CREATE TABLE ten (f1 INTEGER NOT NULL PRIMARY KEY) engine=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 INTEGER) Engine=InnoDB;
-INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;
+INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
connection node_2;
SET SESSION wsrep_sync_wait = 0;
SET SESSION wsrep_sync_wait = 15;
SET GLOBAL wsrep_provider_options = 'repl.causal_read_timeout=PT1H';
SELECT COUNT(*) FROM t1;
COUNT(*)
-100000
-INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;
+10000
+INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
connection node_1;
SELECT COUNT(*) FROM t1;
COUNT(*)
-200000
+20000
UPDATE t1 SET f2 = 1;
connection node_2;
SELECT COUNT(*) FROM t1 WHERE f2 = 1;
COUNT(*)
-200000
+20000
connection node_1;
START TRANSACTION;
SELECT COUNT(*) FROM t1;
COUNT(*)
-200000
+20000
UPDATE t1 SET f2 = 3;
connection node_2;
START TRANSACTION;
diff --git a/mysql-test/suite/galera/t/galera_many_rows.test b/mysql-test/suite/galera/t/galera_many_rows.test
index bc9e99db8da..3623b3f33b0 100644
--- a/mysql-test/suite/galera/t/galera_many_rows.test
+++ b/mysql-test/suite/galera/t/galera_many_rows.test
@@ -10,11 +10,11 @@
SET SESSION innodb_lock_wait_timeout=600;
SET SESSION lock_wait_timeout=600;
-CREATE TABLE ten (f1 INTEGER) engine=InnoDB;
+CREATE TABLE ten (f1 INTEGER NOT NULL PRIMARY KEY) engine=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 INTEGER) Engine=InnoDB;
-INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;
+INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
--connection node_2
SET SESSION wsrep_sync_wait = 0;
@@ -24,7 +24,7 @@ SET SESSION wsrep_sync_wait = 15;
SET GLOBAL wsrep_provider_options = 'repl.causal_read_timeout=PT1H';
SELECT COUNT(*) FROM t1;
-INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;
+INSERT INTO t1 (f2) SELECT a1.f1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
--connection node_1
SELECT COUNT(*) FROM t1;
diff --git a/mysql-test/suite/innodb/r/innodb-fkcheck.result b/mysql-test/suite/innodb/r/innodb-fkcheck.result
index 2c2be83a3ff..f86ba50597f 100644
--- a/mysql-test/suite/innodb/r/innodb-fkcheck.result
+++ b/mysql-test/suite/innodb/r/innodb-fkcheck.result
@@ -33,11 +33,19 @@ b bigint unsigned NOT NULL,
d1 date NOT NULL,
PRIMARY KEY (b,d1)
) ENGINE=InnoDB;
+DROP TABLE b;
+set foreign_key_checks = 1;
+CREATE TABLE b (
+b bigint unsigned NOT NULL,
+d1 date NOT NULL,
+PRIMARY KEY (b,d1)
+) ENGINE=InnoDB;
ERROR HY000: Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Error 1005 Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint for `b`
+set foreign_key_checks = 0;
DROP TABLE IF EXISTS d;
Warnings:
Note 1051 Unknown table 'bug_fk.d'
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index edbdcd2b28e..47e5f0f5c94 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -2531,9 +2531,19 @@ disconnect b;
set foreign_key_checks=0;
create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
-ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed")
set foreign_key_checks=1;
+insert into t2 values (1,1);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`a`))
+set foreign_key_checks=0;
+drop table t1;
+set foreign_key_checks=1;
+insert into t2 values (1,1);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`a`))
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed")
drop table t2;
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+drop table t1;
set foreign_key_checks=0;
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
diff --git a/mysql-test/suite/innodb/r/insert_into_empty.result b/mysql-test/suite/innodb/r/insert_into_empty.result
index 38378fd687f..be5082489f8 100644
--- a/mysql-test/suite/innodb/r/insert_into_empty.result
+++ b/mysql-test/suite/innodb/r/insert_into_empty.result
@@ -186,10 +186,30 @@ DROP TABLE t;
# MDEV-28327 InnoDB persistent statistics fail to update
# after bulk insert
#
-CREATE TABLE t1 (a INT PRIMARY KEY)ENGINE=InnoDB;
+CREATE TABLE t1 (a INT PRIMARY KEY)ENGINE=InnoDB
+STATS_PERSISTENT=1 STATS_AUTO_RECALC=1;
INSERT INTO t1 SELECT * FROM seq_1_to_4096;
# Wait till statistics update after bulk insert operation
-SELECT n_rows FROM mysql.innodb_table_stats WHERE TABLE_NAME="t1";
-n_rows
-4096
+SELECT n_rows>=4096 FROM mysql.innodb_table_stats WHERE TABLE_NAME="t1";
+n_rows>=4096
+1
+DROP TABLE t1;
+#
+# MDEV-27214 Import with disabled keys corrupts meta-data like rows, indexes, ...
+#
+SET UNIQUE_CHECKS=0;
+SET FOREIGN_KEY_CHECKS=0;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL,
+`a` int(11) DEFAULT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+STATS_PERSISTENT=1 STATS_AUTO_RECALC=1;
+INSERT INTO `t1` VALUES (1,2),(2,3),(3,4);
+# Wait till statistics update after bulk insert operation
+SELECT TABLE_ROWS, AVG_ROW_LENGTH>0 FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
+TABLE_ROWS AVG_ROW_LENGTH>0
+3 1
DROP TABLE t1;
+# End of 10.6 tests
diff --git a/mysql-test/suite/innodb/r/insert_into_empty_notembedded.result b/mysql-test/suite/innodb/r/insert_into_empty_notembedded.result
new file mode 100644
index 00000000000..5305b2e7a85
--- /dev/null
+++ b/mysql-test/suite/innodb/r/insert_into_empty_notembedded.result
@@ -0,0 +1,30 @@
+#
+# Start of 10.6 tests
+#
+#
+# MDEV-27214 Import with disabled keys corrupts meta-data like rows, indexes, ...
+#
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (id int, a int,PRIMARY KEY (id)) ENGINE=InnoDB
+STATS_PERSISTENT=1 STATS_AUTO_RECALC=1;
+INSERT INTO db1.t1 VALUES (1,2),(2,3),(3,4);
+DROP DATABASE IF EXISTS db1;
+CREATE DATABASE db1;
+# Wait till statistics update after bulk insert operation
+SELECT TABLE_ROWS, AVG_ROW_LENGTH>0 FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='db1';
+TABLE_ROWS AVG_ROW_LENGTH>0
+3 1
+OPTIMIZE TABLE db1.t1;
+Table Op Msg_type Msg_text
+db1.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+db1.t1 optimize status OK
+# Wait till statistics update after bulk insert operation
+SELECT TABLE_ROWS, AVG_ROW_LENGTH>0 FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='db1';
+TABLE_ROWS AVG_ROW_LENGTH>0
+3 1
+DROP DATABASE db1;
+#
+# End of 10.6 tests
+#
diff --git a/mysql-test/suite/innodb/r/instant_alter.result b/mysql-test/suite/innodb/r/instant_alter.result
index 6744f0fe061..4a67e04205b 100644
--- a/mysql-test/suite/innodb/r/instant_alter.result
+++ b/mysql-test/suite/innodb/r/instant_alter.result
@@ -2929,3 +2929,14 @@ t1 CREATE TABLE `t1` (
KEY `f2` (`f2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1, t2;
+#
+# MDEV-28822 Table from older version requires table rebuild when adding column to table with multi-column index
+#
+CREATE TABLE mdev28822_100427_innodb (
+id int not null primary key,
+msg varchar(10),
+index(id, msg)
+) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+FLUSH TABLES;
+ALTER TABLE mdev28822_100427_innodb ADD i1 INTEGER, ALGORITHM=INSTANT;
+DROP TABLE mdev28822_100427_innodb;
diff --git a/mysql-test/suite/innodb/r/instant_alter_crash.result b/mysql-test/suite/innodb/r/instant_alter_crash.result
index 843f33fddd1..f0fedcc7673 100644
--- a/mysql-test/suite/innodb/r/instant_alter_crash.result
+++ b/mysql-test/suite/innodb/r/instant_alter_crash.result
@@ -34,13 +34,15 @@ ROLLBACK;
InnoDB 0 transactions not purged
INSERT INTO t2 VALUES
(16,1551,'Omnium enim rerum'),(128,1571,' principia parva sunt');
+BEGIN;
+UPDATE t1 SET c2=c2+1;
connect ddl, localhost, root;
SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever';
ALTER TABLE t2 DROP COLUMN c3, ADD COLUMN c5 TEXT DEFAULT 'naturam abhorrere';
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
-UPDATE t1 SET c2=c2+1;
+COMMIT;
# Kill the server
disconnect ddl;
# restart
@@ -61,6 +63,8 @@ DELETE FROM t2;
ROLLBACK;
InnoDB 0 transactions not purged
INSERT INTO t2 VALUES (64,42,'De finibus bonorum'), (347,33101,' et malorum');
+BEGIN;
+DELETE FROM t1;
connect ddl, localhost, root;
ALTER TABLE t2 DROP COLUMN c3;
SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever';
@@ -68,7 +72,7 @@ ALTER TABLE t2 ADD COLUMN (c4 TEXT NOT NULL DEFAULT ' et malorum');
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
-DELETE FROM t1;
+COMMIT;
# Kill the server
disconnect ddl;
# restart
@@ -138,6 +142,8 @@ InnoDB 0 transactions not purged
#
# MDEV-24323 Crash on recovery after kill during instant ADD COLUMN
#
+BEGIN;
+INSERT INTO t1 VALUES(0,0);
connect ddl, localhost, root;
CREATE TABLE t3(id INT PRIMARY KEY, c2 INT, v2 INT AS(c2) VIRTUAL, UNIQUE(v2))
ENGINE=InnoDB;
@@ -147,7 +153,7 @@ ALTER TABLE t3 ADD COLUMN c3 TEXT NOT NULL DEFAULT 'sic transit gloria mundi';
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
-INSERT INTO t1 VALUES(0,0);
+COMMIT;
# Kill the server
disconnect ddl;
# restart
@@ -183,13 +189,15 @@ DROP TABLE t2,t3;
#
CREATE TABLE t2(a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6);
+BEGIN;
+DELETE FROM t1;
connect ddl, localhost, root;
SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever';
ALTER TABLE t2 ADD COLUMN b TINYINT UNSIGNED NOT NULL DEFAULT 42 FIRST;
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
-DELETE FROM t1;
+COMMIT;
# Kill the server
disconnect ddl;
# restart
diff --git a/mysql-test/suite/innodb/r/temporary_table.result b/mysql-test/suite/innodb/r/temporary_table.result
index a8a073cb257..ffcee726f0d 100644
--- a/mysql-test/suite/innodb/r/temporary_table.result
+++ b/mysql-test/suite/innodb/r/temporary_table.result
@@ -789,4 +789,16 @@ CHECK TABLE t EXTENDED;
Table Op Msg_type Msg_text
test.t check status OK
DROP TEMPORARY TABLE t;
+#
+# MDEV-29978 Corruption errors upon CHECK on temporary InnoDB table
+#
+CREATE TEMPORARY TABLE t (f INT UNIQUE) ENGINE=InnoDB;
+INSERT INTO t (f) VALUES (1),(2);
+CHECK TABLE t;
+Table Op Msg_type Msg_text
+test.t check status OK
+CHECK TABLE t EXTENDED;
+Table Op Msg_type Msg_text
+test.t check status OK
+DROP TEMPORARY TABLE t;
# End of 10.6 tests
diff --git a/mysql-test/suite/innodb/r/truncate_foreign.result b/mysql-test/suite/innodb/r/truncate_foreign.result
index 3154674aabf..e587baa5288 100644
--- a/mysql-test/suite/innodb/r/truncate_foreign.result
+++ b/mysql-test/suite/innodb/r/truncate_foreign.result
@@ -80,9 +80,19 @@ SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (a), ALGORITHM=COPY;
INSERT INTO t1 VALUES (1,1);
LOCK TABLES t1 WRITE;
+SET FOREIGN_KEY_CHECKS=1;
TRUNCATE t1;
ERROR HY000: Cannot add foreign key constraint for `t1`
INSERT INTO t1 VALUES (2,2);
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+SELECT * FROM t1;
+pk a
+1 1
+UNLOCK TABLES;
+INSERT INTO t1 VALUES (2,2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+SET FOREIGN_KEY_CHECKS=0;
+INSERT INTO t1 VALUES (2,2);
SELECT * FROM t1;
pk a
1 1
diff --git a/mysql-test/suite/innodb/t/alter_dml_apply.test b/mysql-test/suite/innodb/t/alter_dml_apply.test
index 01bfe458f1a..ac0455902fd 100644
--- a/mysql-test/suite/innodb/t/alter_dml_apply.test
+++ b/mysql-test/suite/innodb/t/alter_dml_apply.test
@@ -2,6 +2,7 @@
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/have_sequence.inc
+--source include/no_valgrind_without_big.inc
CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL,
f3 CHAR(200), f4 CHAR(200),
diff --git a/mysql-test/suite/innodb/t/import_corrupted.test b/mysql-test/suite/innodb/t/import_corrupted.test
index 57c8c6dd9be..bc2ee341fe2 100644
--- a/mysql-test/suite/innodb/t/import_corrupted.test
+++ b/mysql-test/suite/innodb/t/import_corrupted.test
@@ -1,4 +1,5 @@
--source include/have_innodb.inc
+--source include/no_valgrind_without_big.inc
call mtr.add_suppression("Table `test`.`t2` should have 2 indexes but the tablespace has 1 indexes");
call mtr.add_suppression("Index for table 't2' is corrupt; try to repair it");
diff --git a/mysql-test/suite/innodb/t/innodb-fkcheck.test b/mysql-test/suite/innodb/t/innodb-fkcheck.test
index 4657edc4d65..5ff3533fce1 100644
--- a/mysql-test/suite/innodb/t/innodb-fkcheck.test
+++ b/mysql-test/suite/innodb/t/innodb-fkcheck.test
@@ -46,7 +46,15 @@ show create table c;
#
# Note that column b has different type in parent table
#
---error 1005
+CREATE TABLE b (
+ b bigint unsigned NOT NULL,
+ d1 date NOT NULL,
+ PRIMARY KEY (b,d1)
+) ENGINE=InnoDB;
+DROP TABLE b;
+
+set foreign_key_checks = 1;
+--error ER_CANT_CREATE_TABLE
CREATE TABLE b (
b bigint unsigned NOT NULL,
d1 date NOT NULL,
@@ -54,6 +62,7 @@ CREATE TABLE b (
) ENGINE=InnoDB;
show warnings;
+set foreign_key_checks = 0;
DROP TABLE IF EXISTS d;
@@ -64,7 +73,7 @@ CREATE TABLE d (
CONSTRAINT bd_fk FOREIGN KEY (b) REFERENCES b (b)
) ENGINE=InnoDB;
-show warnings;
+show warnings;
set foreign_key_checks = 1;
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index 3a8c12dfbbd..3b3b2770df7 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -1598,12 +1598,22 @@ disconnect b;
set foreign_key_checks=0;
create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+set foreign_key_checks=1;
+--error ER_NO_REFERENCED_ROW_2
+insert into t2 values (1,1);
+set foreign_key_checks=0;
+drop table t1;
+set foreign_key_checks=1;
+--error ER_NO_REFERENCED_ROW_2
+insert into t2 values (1,1);
# Embedded server doesn't chdir to data directory
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
--error ER_CANT_CREATE_TABLE
create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
-set foreign_key_checks=1;
drop table t2;
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+drop table t1;
# test that FKs between different charsets are not accepted in CREATE even
# when f_k_c is 0
diff --git a/mysql-test/suite/innodb/t/innodb_scrub.test b/mysql-test/suite/innodb/t/innodb_scrub.test
index 88b4e9cfd76..c7d06187e9f 100644
--- a/mysql-test/suite/innodb/t/innodb_scrub.test
+++ b/mysql-test/suite/innodb/t/innodb_scrub.test
@@ -1,4 +1,5 @@
-- source include/have_innodb.inc
+-- source include/no_valgrind_without_big.inc
let $MYSQLD_DATADIR=`select @@datadir`;
CREATE TABLE t1(f1 int auto_increment primary key,
diff --git a/mysql-test/suite/innodb/t/insert_into_empty.test b/mysql-test/suite/innodb/t/insert_into_empty.test
index 4181087472f..b545927d690 100644
--- a/mysql-test/suite/innodb/t/insert_into_empty.test
+++ b/mysql-test/suite/innodb/t/insert_into_empty.test
@@ -1,4 +1,5 @@
--source include/have_innodb.inc
+--source include/innodb_page_size.inc
--source include/have_sequence.inc
--source include/maybe_debug.inc
--source include/have_partition.inc
@@ -198,11 +199,37 @@ DROP TABLE t;
--echo # MDEV-28327 InnoDB persistent statistics fail to update
--echo # after bulk insert
--echo #
-CREATE TABLE t1 (a INT PRIMARY KEY)ENGINE=InnoDB;
+CREATE TABLE t1 (a INT PRIMARY KEY)ENGINE=InnoDB
+STATS_PERSISTENT=1 STATS_AUTO_RECALC=1;
INSERT INTO t1 SELECT * FROM seq_1_to_4096;
--echo # Wait till statistics update after bulk insert operation
let $wait_condition= select n_rows > 100 from mysql.innodb_table_stats
where table_name="t1";
source include/wait_condition.inc;
-SELECT n_rows FROM mysql.innodb_table_stats WHERE TABLE_NAME="t1";
+SELECT n_rows>=4096 FROM mysql.innodb_table_stats WHERE TABLE_NAME="t1";
DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-27214 Import with disabled keys corrupts meta-data like rows, indexes, ...
+--echo #
+
+SET UNIQUE_CHECKS=0;
+SET FOREIGN_KEY_CHECKS=0;
+CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `a` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+STATS_PERSISTENT=1 STATS_AUTO_RECALC=1;
+INSERT INTO `t1` VALUES (1,2),(2,3),(3,4);
+--echo # Wait till statistics update after bulk insert operation
+let $wait_condition= select n_rows > 0 from mysql.innodb_table_stats
+where database_name='test' and table_name='t1';
+source include/wait_condition.inc;
+SELECT TABLE_ROWS, AVG_ROW_LENGTH>0 FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
+DROP TABLE t1;
+
+
+--echo # End of 10.6 tests
diff --git a/mysql-test/suite/innodb/t/insert_into_empty_notembedded.test b/mysql-test/suite/innodb/t/insert_into_empty_notembedded.test
new file mode 100644
index 00000000000..267501133ea
--- /dev/null
+++ b/mysql-test/suite/innodb/t/insert_into_empty_notembedded.test
@@ -0,0 +1,43 @@
+--source include/not_embedded.inc
+--source include/have_innodb.inc
+--source include/innodb_page_size.inc
+--source include/maybe_debug.inc
+
+--echo #
+--echo # Start of 10.6 tests
+--echo #
+
+--echo #
+--echo # MDEV-27214 Import with disabled keys corrupts meta-data like rows, indexes, ...
+--echo #
+
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (id int, a int,PRIMARY KEY (id)) ENGINE=InnoDB
+STATS_PERSISTENT=1 STATS_AUTO_RECALC=1;
+INSERT INTO db1.t1 VALUES (1,2),(2,3),(3,4);
+--let $file = $MYSQLTEST_VARDIR/tmp/dump.sql
+--exec $MYSQL_DUMP db1 t1 >$file
+DROP DATABASE IF EXISTS db1;
+
+CREATE DATABASE db1;
+--exec $MYSQL db1 < $file
+--remove_file $file
+--echo # Wait till statistics update after bulk insert operation
+let $wait_condition= select n_rows > 0 from mysql.innodb_table_stats
+where database_name='db1' and table_name='t1';
+source include/wait_condition.inc;
+SELECT TABLE_ROWS, AVG_ROW_LENGTH>0 FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='db1';
+
+OPTIMIZE TABLE db1.t1;
+--echo # Wait till statistics update after bulk insert operation
+let $wait_condition= select n_rows > 0 from mysql.innodb_table_stats
+where database_name='db1' and table_name='t1';
+source include/wait_condition.inc;
+SELECT TABLE_ROWS, AVG_ROW_LENGTH>0 FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='db1';
+DROP DATABASE db1;
+
+--echo #
+--echo # End of 10.6 tests
+--echo #
diff --git a/mysql-test/suite/innodb/t/instant_alter.test b/mysql-test/suite/innodb/t/instant_alter.test
index 22815798f69..8e333e3bb72 100644
--- a/mysql-test/suite/innodb/t/instant_alter.test
+++ b/mysql-test/suite/innodb/t/instant_alter.test
@@ -1,6 +1,8 @@
--source include/innodb_page_size.inc
--source include/have_sequence.inc
+let $datadir=`select @@datadir`;
+
--echo #
--echo # MDEV-11369: Instant ADD COLUMN for InnoDB
--echo #
@@ -949,3 +951,19 @@ ALTER TABLE t1 DROP COLUMN f3, ADD FOREIGN KEY fk (f1)
ALTER TABLE t1 DROP COLUMN f5;
SHOW CREATE TABLE t1;
DROP TABLE t1, t2;
+
+
+--echo #
+--echo # MDEV-28822 Table from older version requires table rebuild when adding column to table with multi-column index
+--echo #
+
+CREATE TABLE mdev28822_100427_innodb (
+ id int not null primary key,
+ msg varchar(10),
+ index(id, msg)
+) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+FLUSH TABLES;
+remove_file $datadir/test/mdev28822_100427_innodb.frm;
+copy_file std_data/mysql_upgrade/mdev28822_100427_innodb.frm $datadir/test/mdev28822_100427_innodb.frm;
+ALTER TABLE mdev28822_100427_innodb ADD i1 INTEGER, ALGORITHM=INSTANT;
+DROP TABLE mdev28822_100427_innodb;
diff --git a/mysql-test/suite/innodb/t/instant_alter_crash.test b/mysql-test/suite/innodb/t/instant_alter_crash.test
index 4d211ece106..0bd983a2b4c 100644
--- a/mysql-test/suite/innodb/t/instant_alter_crash.test
+++ b/mysql-test/suite/innodb/t/instant_alter_crash.test
@@ -47,6 +47,9 @@ ROLLBACK;
INSERT INTO t2 VALUES
(16,1551,'Omnium enim rerum'),(128,1571,' principia parva sunt');
+BEGIN;
+UPDATE t1 SET c2=c2+1;
+
connect ddl, localhost, root;
SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever';
--send
@@ -55,7 +58,7 @@ ALTER TABLE t2 DROP COLUMN c3, ADD COLUMN c5 TEXT DEFAULT 'naturam abhorrere';
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
-UPDATE t1 SET c2=c2+1;
+COMMIT;
--source include/kill_mysqld.inc
disconnect ddl;
@@ -73,6 +76,8 @@ ROLLBACK;
--source include/wait_all_purged.inc
INSERT INTO t2 VALUES (64,42,'De finibus bonorum'), (347,33101,' et malorum');
+BEGIN;
+DELETE FROM t1;
connect ddl, localhost, root;
ALTER TABLE t2 DROP COLUMN c3;
@@ -83,7 +88,7 @@ ALTER TABLE t2 ADD COLUMN (c4 TEXT NOT NULL DEFAULT ' et malorum');
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
-DELETE FROM t1;
+COMMIT;
--source include/kill_mysqld.inc
disconnect ddl;
@@ -177,6 +182,9 @@ DELETE FROM t2;
--echo #
--echo # MDEV-24323 Crash on recovery after kill during instant ADD COLUMN
--echo #
+BEGIN;
+INSERT INTO t1 VALUES(0,0);
+
connect ddl, localhost, root;
CREATE TABLE t3(id INT PRIMARY KEY, c2 INT, v2 INT AS(c2) VIRTUAL, UNIQUE(v2))
ENGINE=InnoDB;
@@ -189,7 +197,7 @@ ALTER TABLE t3 ADD COLUMN c3 TEXT NOT NULL DEFAULT 'sic transit gloria mundi';
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
-INSERT INTO t1 VALUES(0,0);
+COMMIT;
--source include/kill_mysqld.inc
disconnect ddl;
@@ -207,6 +215,9 @@ DROP TABLE t2,t3;
CREATE TABLE t2(a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6);
+BEGIN;
+DELETE FROM t1;
+
connect ddl, localhost, root;
SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever';
--send
@@ -215,7 +226,7 @@ ALTER TABLE t2 ADD COLUMN b TINYINT UNSIGNED NOT NULL DEFAULT 42 FIRST;
connection default;
SET DEBUG_SYNC='now WAIT_FOR ddl';
SET GLOBAL innodb_flush_log_at_trx_commit=1;
-DELETE FROM t1;
+COMMIT;
--source include/kill_mysqld.inc
disconnect ddl;
diff --git a/mysql-test/suite/innodb/t/temporary_table.test b/mysql-test/suite/innodb/t/temporary_table.test
index 0cc3b29feb1..5d7e5d51696 100644
--- a/mysql-test/suite/innodb/t/temporary_table.test
+++ b/mysql-test/suite/innodb/t/temporary_table.test
@@ -624,4 +624,15 @@ UPDATE t SET a=2;
CHECK TABLE t;
CHECK TABLE t EXTENDED;
DROP TEMPORARY TABLE t;
+
+--echo #
+--echo # MDEV-29978 Corruption errors upon CHECK on temporary InnoDB table
+--echo #
+
+CREATE TEMPORARY TABLE t (f INT UNIQUE) ENGINE=InnoDB;
+INSERT INTO t (f) VALUES (1),(2);
+CHECK TABLE t;
+CHECK TABLE t EXTENDED;
+DROP TEMPORARY TABLE t;
+
--echo # End of 10.6 tests
diff --git a/mysql-test/suite/innodb/t/truncate_foreign.test b/mysql-test/suite/innodb/t/truncate_foreign.test
index e40029e18be..abbe1b3df87 100644
--- a/mysql-test/suite/innodb/t/truncate_foreign.test
+++ b/mysql-test/suite/innodb/t/truncate_foreign.test
@@ -92,8 +92,19 @@ SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (a), ALGORITHM=COPY;
INSERT INTO t1 VALUES (1,1);
LOCK TABLES t1 WRITE;
+SET FOREIGN_KEY_CHECKS=1;
--error ER_CANNOT_ADD_FOREIGN
TRUNCATE t1;
+# Whether TRUNCATE succeeds or fails, it will reload FOREIGN KEY constraints.
+# As a result, ha_innobase::referenced_by_foreign_key() will retun TRUE
+# (for the self-referential key), and the statement will fail.
+--error ER_TABLE_NOT_LOCKED
+INSERT INTO t1 VALUES (2,2);
+SELECT * FROM t1;
+UNLOCK TABLES;
+--error ER_NO_REFERENCED_ROW_2
+INSERT INTO t1 VALUES (2,2);
+SET FOREIGN_KEY_CHECKS=0;
INSERT INTO t1 VALUES (2,2);
SELECT * FROM t1;
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_fts/r/misc_debug.result b/mysql-test/suite/innodb_fts/r/misc_debug.result
index 18f715b9d95..11df7d89f0b 100644
--- a/mysql-test/suite/innodb_fts/r/misc_debug.result
+++ b/mysql-test/suite/innodb_fts/r/misc_debug.result
@@ -62,7 +62,6 @@ SET @saved_debug_dbug= @@debug_dbug;
CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
TRUNCATE t1;
-ERROR HY000: Got error -1 "Internal error < 0 (Not system error)" from storage engine InnoDB
SET debug_dbug=@saved_debug_dbug;
DROP TABLE t1;
# End of 10.3 tests
diff --git a/mysql-test/suite/innodb_fts/t/misc_debug.test b/mysql-test/suite/innodb_fts/t/misc_debug.test
index c086348b631..9246d27a704 100644
--- a/mysql-test/suite/innodb_fts/t/misc_debug.test
+++ b/mysql-test/suite/innodb_fts/t/misc_debug.test
@@ -91,7 +91,6 @@ SET @saved_debug_dbug= @@debug_dbug;
CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
---error ER_GET_ERRNO
TRUNCATE t1;
SET debug_dbug=@saved_debug_dbug;
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_gis/r/alter_spatial_index.result b/mysql-test/suite/innodb_gis/r/alter_spatial_index.result
index d58cf0dfd18..08632b67514 100644
--- a/mysql-test/suite/innodb_gis/r/alter_spatial_index.result
+++ b/mysql-test/suite/innodb_gis/r/alter_spatial_index.result
@@ -795,4 +795,14 @@ ENGINE=InnoDB;
INSERT INTO t VALUES (REPEAT('MariaDB Corporation Ab ',351),POINT(0,0));
ALTER TABLE t FORCE;
DROP TABLE t;
+#
+# MDEV-29856 heap-use-after-poison in row_merge_spatial_rows()
+# with PRIMARY KEY on column prefix
+#
+CREATE TABLE t (id INT, f TEXT, s POINT NOT NULL,
+PRIMARY KEY(id,f(1)), SPATIAL(s)) ENGINE=InnoDB;
+INSERT INTO t VALUES
+(1,REPEAT('x',8192),@p:=ST_GeomFromText('POINT(0 0)')),(2,'',@p);
+ALTER TABLE t FORCE;
+DROP TABLE t;
# End of 10.3 tests
diff --git a/mysql-test/suite/innodb_gis/t/alter_spatial_index.test b/mysql-test/suite/innodb_gis/t/alter_spatial_index.test
index 88e10d07b99..6f30b38b6d4 100644
--- a/mysql-test/suite/innodb_gis/t/alter_spatial_index.test
+++ b/mysql-test/suite/innodb_gis/t/alter_spatial_index.test
@@ -791,4 +791,16 @@ ALTER TABLE t FORCE;
# Cleanup
DROP TABLE t;
+--echo #
+--echo # MDEV-29856 heap-use-after-poison in row_merge_spatial_rows()
+--echo # with PRIMARY KEY on column prefix
+--echo #
+
+CREATE TABLE t (id INT, f TEXT, s POINT NOT NULL,
+ PRIMARY KEY(id,f(1)), SPATIAL(s)) ENGINE=InnoDB;
+INSERT INTO t VALUES
+(1,REPEAT('x',8192),@p:=ST_GeomFromText('POINT(0 0)')),(2,'',@p);
+ALTER TABLE t FORCE;
+DROP TABLE t;
+
--echo # End of 10.3 tests
diff --git a/mysql-test/suite/innodb_zip/disabled.def b/mysql-test/suite/innodb_zip/disabled.def
deleted file mode 100644
index 8b137891791..00000000000
--- a/mysql-test/suite/innodb_zip/disabled.def
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/mysql-test/suite/maria/rollback.result b/mysql-test/suite/maria/rollback.result
index 959f596edf2..2e58387ce57 100644
--- a/mysql-test/suite/maria/rollback.result
+++ b/mysql-test/suite/maria/rollback.result
@@ -1,3 +1,4 @@
+reset master;
call mtr.add_suppression("Table was marked as crashed");
call mtr.add_suppression("Checking table: .*");
create table t1 (a int primary key auto_increment, b int) engine=aria transactional= 1;
diff --git a/mysql-test/suite/maria/rollback.test b/mysql-test/suite/maria/rollback.test
index 1469c26eaa2..d42be9274e6 100644
--- a/mysql-test/suite/maria/rollback.test
+++ b/mysql-test/suite/maria/rollback.test
@@ -3,6 +3,8 @@
# no-protocol doesn't print warnings about repaired tables
--source include/no_protocol.inc
+reset master; # clear binlogs
+
call mtr.add_suppression("Table was marked as crashed");
call mtr.add_suppression("Checking table: .*");
diff --git a/mysql-test/suite/mariabackup/big_innodb_log.test b/mysql-test/suite/mariabackup/big_innodb_log.test
index 23ac59c13eb..85d22a8227b 100644
--- a/mysql-test/suite/mariabackup/big_innodb_log.test
+++ b/mysql-test/suite/mariabackup/big_innodb_log.test
@@ -5,6 +5,7 @@
# recovery process with such numbers.
--source include/have_innodb.inc
--source include/have_debug.inc
+--source include/no_valgrind_without_big.inc
--let MYSQLD_DATADIR= `select @@datadir`
let $MYSQLD_BOOTSTRAP_CMD= $MYSQLD_BOOTSTRAP_CMD --datadir=$MYSQLD_DATADIR --tmpdir=$MYSQL_TMP_DIR --debug-dbug=+d,innodb_small_log_block_no_limit;
diff --git a/mysql-test/suite/mariabackup/defer_space.result b/mysql-test/suite/mariabackup/defer_space.result
index 41239c476e7..6453aff5502 100644
--- a/mysql-test/suite/mariabackup/defer_space.result
+++ b/mysql-test/suite/mariabackup/defer_space.result
@@ -1,6 +1,7 @@
call mtr.add_suppression("InnoDB: Expected tablespace id .*");
# Mariabackup --backup with page0 INIT_PAGE redo record
# and there is no FILE_CREATE for the tablespace t1
+SET @save_dbug = @@SESSION.debug_dbug;
SET DEBUG_DBUG="+d,checkpoint_after_file_create";
CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB;
INSERT INTO t1 VALUES(1);
@@ -14,7 +15,7 @@ SELECT * FROM t1;
f1
1
DROP TABLE t1;
-SET DEBUG_DBUG="-d,checkpoint_after_file_create";
+SET @@SESSION.DEBUG_DBUG= @save_debug;
# Mariabackup fails after corrupting the page0 in disk
# and there is no INIT_PAGE for page0
CREATE TABLE t1(c INT) ENGINE=INNODB;
diff --git a/mysql-test/suite/mariabackup/defer_space.test b/mysql-test/suite/mariabackup/defer_space.test
index 65f2262fd1d..397a1ff5dc2 100644
--- a/mysql-test/suite/mariabackup/defer_space.test
+++ b/mysql-test/suite/mariabackup/defer_space.test
@@ -1,10 +1,12 @@
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/not_embedded.inc
+--source include/no_valgrind_without_big.inc
call mtr.add_suppression("InnoDB: Expected tablespace id .*");
--echo # Mariabackup --backup with page0 INIT_PAGE redo record
--echo # and there is no FILE_CREATE for the tablespace t1
+SET @save_dbug = @@SESSION.debug_dbug;
SET DEBUG_DBUG="+d,checkpoint_after_file_create";
CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB;
INSERT INTO t1 VALUES(1);
@@ -25,7 +27,7 @@ exec $XTRABACKUP --prepare --target-dir=$targetdir;
SELECT * FROM t1;
DROP TABLE t1;
rmdir $targetdir;
-SET DEBUG_DBUG="-d,checkpoint_after_file_create";
+SET @@SESSION.DEBUG_DBUG= @save_debug;
--echo # Mariabackup fails after corrupting the page0 in disk
--echo # and there is no INIT_PAGE for page0
@@ -38,16 +40,13 @@ let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
--echo # Corrupt the table
perl;
-use strict;
-use warnings;
-use Fcntl qw(:DEFAULT :seek);
-my $page_size = $ENV{INNODB_PAGE_SIZE};
+my $ps = $ENV{INNODB_PAGE_SIZE};
-sysopen FILE, "$ENV{MYSQLD_DATADIR}/test/t1.ibd", O_RDWR
-|| die "Cannot open t1.ibd\n";
-sysseek(FILE, 0, SEEK_SET) || die "Cannot seek t1.ibd\n";
-my $page=chr(0) x $page_size;
-syswrite(FILE, $page, $page_size)==$page_size;
+my $file = "$ENV{MYSQLD_DATADIR}/test/t1.ibd";
+open(FILE, "+<$file") || die "Unable to open $file";
+binmode FILE;
+seek (FILE, 0, SEEK_SET) or die "seek";
+print FILE chr(0x00) x $ps;
close FILE or die "close";
EOF
diff --git a/mysql-test/suite/mariabackup/full_backup.opt b/mysql-test/suite/mariabackup/full_backup.opt
new file mode 100644
index 00000000000..7928cd812d0
--- /dev/null
+++ b/mysql-test/suite/mariabackup/full_backup.opt
@@ -0,0 +1 @@
+--innodb_undo_tablespaces=2
diff --git a/mysql-test/suite/mariabackup/full_backup.result b/mysql-test/suite/mariabackup/full_backup.result
index e2d5cf185d5..e69d00f86f6 100644
--- a/mysql-test/suite/mariabackup/full_backup.result
+++ b/mysql-test/suite/mariabackup/full_backup.result
@@ -12,3 +12,18 @@ SELECT * FROM t;
i
1
DROP TABLE t;
+#
+# MDEV-27121 mariabackup incompatible with disabled dedicated
+# undo log tablespaces
+#
+call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces");
+# restart: --innodb_undo_tablespaces=0
+# xtrabackup backup
+# xtrabackup prepare
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart: --innodb_undo_tablespaces=0
+# Display undo log files from target directory
+undo001
+undo002
diff --git a/mysql-test/suite/mariabackup/full_backup.test b/mysql-test/suite/mariabackup/full_backup.test
index 66bed34cf3d..a0243527438 100644
--- a/mysql-test/suite/mariabackup/full_backup.test
+++ b/mysql-test/suite/mariabackup/full_backup.test
@@ -29,3 +29,27 @@ SELECT * FROM t;
DROP TABLE t;
rmdir $targetdir;
+--echo #
+--echo # MDEV-27121 mariabackup incompatible with disabled dedicated
+--echo # undo log tablespaces
+--echo #
+call mtr.add_suppression("InnoDB: innodb_undo_tablespaces=0 disables dedicated undo log tablespaces");
+
+let $restart_parameters=--innodb_undo_tablespaces=0;
+--source include/restart_mysqld.inc
+
+echo # xtrabackup backup;
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
+--enable_result_log
+
+echo # xtrabackup prepare;
+--disable_result_log
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+-- source include/restart_and_restore.inc
+--enable_result_log
+
+--echo # Display undo log files from target directory
+list_files $targetdir undo*;
+
+rmdir $targetdir;
diff --git a/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.test b/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.test
index 22165ff29be..8bbd4e761a6 100644
--- a/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.test
+++ b/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.test
@@ -1,6 +1,7 @@
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_sequence.inc
+--source include/no_valgrind_without_big.inc
CREATE TABLE t(i INT) ENGINE=INNODB;
diff --git a/mysql-test/suite/mariabackup/innodb_redo_overwrite.test b/mysql-test/suite/mariabackup/innodb_redo_overwrite.test
index e27229c5f33..1ed75607be8 100644
--- a/mysql-test/suite/mariabackup/innodb_redo_overwrite.test
+++ b/mysql-test/suite/mariabackup/innodb_redo_overwrite.test
@@ -1,5 +1,6 @@
--source include/have_innodb.inc
--source include/have_debug_sync.inc
+--source include/no_valgrind_without_big.inc
CREATE TABLE t(i INT) ENGINE=INNODB;
diff --git a/mysql-test/suite/mariabackup/mdev-14447.combinations b/mysql-test/suite/mariabackup/mdev-14447.combinations
new file mode 100644
index 00000000000..79e5f7836ed
--- /dev/null
+++ b/mysql-test/suite/mariabackup/mdev-14447.combinations
@@ -0,0 +1,5 @@
+[crc32]
+--innodb-checksum-algorithm=crc32
+
+[full_crc32]
+--innodb-checksum-algorithm=full_crc32
diff --git a/mysql-test/suite/plugins/t/false_dupes-6543.test b/mysql-test/suite/plugins/t/false_dupes-6543.test
index ebdbe00e47c..ca278685967 100644
--- a/mysql-test/suite/plugins/t/false_dupes-6543.test
+++ b/mysql-test/suite/plugins/t/false_dupes-6543.test
@@ -1,3 +1,4 @@
+source include/not_embedded.inc;
#
# MDEV-6543 Crash if enable 'federatedx' when 'federated' plugin already enabled, and vice-versa
#
diff --git a/mysql-test/suite/rpl/include/rpl_xa_empty_transaction.inc b/mysql-test/suite/rpl/include/rpl_xa_empty_transaction.inc
new file mode 100644
index 00000000000..4cb4fe8962f
--- /dev/null
+++ b/mysql-test/suite/rpl/include/rpl_xa_empty_transaction.inc
@@ -0,0 +1,10 @@
+#
+# Helper file to run each empty-due-to-err XA transaction test case both with
+# and without detaching from the connection when the transaction is prepared.
+#
+
+--let $use_disconnect=0
+--source rpl_xa_empty_transaction_test_case.inc
+
+--let $use_disconnect=1
+--source rpl_xa_empty_transaction_test_case.inc
diff --git a/mysql-test/suite/rpl/include/rpl_xa_empty_transaction_test_case.inc b/mysql-test/suite/rpl/include/rpl_xa_empty_transaction_test_case.inc
new file mode 100644
index 00000000000..6368336b8e3
--- /dev/null
+++ b/mysql-test/suite/rpl/include/rpl_xa_empty_transaction_test_case.inc
@@ -0,0 +1,131 @@
+#
+# Helper script to create an XA transaction and validate it was not
+# binlogged
+#
+# Parameters
+# $xa_completion_action : The action to end the XA transaction, either
+# COMMIT or ROLLBACK
+# $trx_statements : A comma separated list specifying how to build
+# the statements of the transaction. Each item in
+# the list is either T (for transactional) or N
+# (for non-transactional). An empty list will not
+# add any statements to the transaction.
+# $use_disconnect : When TRUE, disconnect after preparing the XA
+# transaction to test the detach/rollback case
+#
+
+#
+# Setup
+--let $generic_assert_text= should not binlog XA transaction
+
+--connection server_1
+--let server_1_datadir=`select @@datadir`
+
+--connection server_2
+--let server_2_datadir=`select @@datadir`
+
+--connection server_3
+--let server_3_datadir=`select @@datadir`
+
+--let assert_file=$MYSQLTEST_VARDIR/tmp/binlog_decoded.out
+
+--connection server_1
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+--source include/save_master_gtid.inc
+
+--connection server_3
+--source include/sync_with_master_gtid.inc
+
+--connection server_1
+
+if ($use_disconnect)
+{
+ --source include/count_sessions.inc
+ --connect(con1,localhost,root,,)
+}
+
+XA START 'x';
+--let $_stmt_items= $trx_statements
+--let $_ctr= 1
+while($_stmt_items)
+{
+ --let $_cur_stmt= `SELECT SUBSTRING_INDEX('$_stmt_items', ',', 1)`
+ --let $_stmt_items= `SELECT LTRIM(SUBSTRING('$_stmt_items', LENGTH('$_cur_stmt') + 2))`
+
+ if (`SELECT strcmp("$_cur_stmt","T") = 0`)
+ {
+ --let $target_table= ti
+ }
+
+ if (`SELECT strcmp("$_cur_stmt","N") = 0`)
+ {
+ --let $target_table= tm
+ }
+
+ --error ER_DUP_ENTRY
+ --eval INSERT INTO $target_table VALUES ($_ctr),($_ctr);
+ inc $_ctr;
+
+}
+XA END 'x';
+XA PREPARE 'x';
+
+if ($use_disconnect)
+{
+ --disconnect con1
+ --connection server_1
+ --source include/wait_until_count_sessions.inc
+ XA RECOVER;
+
+ --error ER_XA_RBROLLBACK
+ --eval XA $xa_completion_action 'x';
+}
+if (!$use_disconnect)
+{
+ --eval XA $xa_completion_action 'x';
+}
+
+--source include/save_master_gtid.inc
+
+--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1)
+FLUSH LOGS;
+
+--echo # MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+--exec $MYSQL_BINLOG $server_1_datadir/$binlog_filename --result-file=$assert_file
+
+--let assert_text= server_1 $generic_assert_text
+--let assert_count= 0
+--let assert_select= XA START|XA END|XA PREPARE|XA COMMIT|XA ROLLBACK
+--source include/assert_grep.inc
+
+--connection server_2
+--source include/sync_with_master_gtid.inc
+--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1)
+FLUSH LOGS;
+
+--echo # MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+--exec $MYSQL_BINLOG $server_2_datadir/$binlog_filename --result-file=$assert_file
+
+--let assert_text= server_2 $generic_assert_text
+--source include/assert_grep.inc
+
+--connection server_3
+--source include/sync_with_master_gtid.inc
+--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1)
+FLUSH LOGS;
+
+--echo # MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+--exec $MYSQL_BINLOG $server_3_datadir/$binlog_filename --result-file=$assert_file
+
+--let assert_text= server_3 $generic_assert_text
+--source include/assert_grep.inc
+
+#
+# Cleanup
+--connection server_1
+DROP TABLE ti,tm;
+--source include/save_master_gtid.inc
+
+--connection server_3
+--source include/sync_with_master_gtid.inc
diff --git a/mysql-test/suite/rpl/r/rpl_xa_empty_transaction.result b/mysql-test/suite/rpl/r/rpl_xa_empty_transaction.result
new file mode 100644
index 00000000000..f3ea53c219a
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_xa_empty_transaction.result
@@ -0,0 +1,1169 @@
+include/rpl_init.inc [topology=1->2->3]
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+#
+# Test Case 1: An XA transaction without any statements should not be
+# binlogged
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+XA END 'x';
+XA PREPARE 'x';
+XA COMMIT 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA COMMIT 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+XA END 'x';
+XA PREPARE 'x';
+XA ROLLBACK 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA ROLLBACK 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+#
+# Test Case 2: An XA transaction consisting of a successfully rolled back
+# statement should not be binlogged
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA COMMIT 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA COMMIT 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA ROLLBACK 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA ROLLBACK 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+#
+# Test Case 3: An XA transaction with a statement that cannot be rolled
+# back should be binlogged
+connection server_1;
+set @sav_binlog_format = @@binlog_format;
+set @@binlog_format = row;
+set @@global.binlog_format = row;
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA COMMIT 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA COMMIT 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA ROLLBACK 'x';;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA ROLLBACK 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+set @@binlog_format = @sav_binlog_format;
+set @@global.binlog_format = @sav_binlog_format;
+#
+# Test Case 4: An XA transaction with multiple statements that can all
+# be rolled back should not be binlogged
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO ti VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA COMMIT 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO ti VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA COMMIT 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO ti VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA ROLLBACK 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO ti VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA ROLLBACK 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+#
+# Test Case 5: A mixed XA transaction consisting of one statement that
+# can successfully be rolled back (first statement), and another that
+# can not (second statement) should be binlogged
+connection server_1;
+set @sav_binlog_format = @@binlog_format;
+set @@binlog_format = row;
+set @@global.binlog_format = row;
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tm VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA COMMIT 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tm VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA COMMIT 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tm VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA ROLLBACK 'x';;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO ti VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tm VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA ROLLBACK 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+set @@binlog_format = @sav_binlog_format;
+set @@global.binlog_format = @sav_binlog_format;
+#
+# Test Case 6: A mixed XA transaction consisting of one statement that
+# cannot successfully be rolled back (first statement), and another that
+# can (second statement) should be binlogged
+connection server_1;
+set @sav_binlog_format = @@binlog_format;
+set @@binlog_format = row;
+set @@global.binlog_format = row;
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO ti VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA COMMIT 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO ti VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA COMMIT 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO ti VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA ROLLBACK 'x';;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO ti VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA ROLLBACK 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+set @@binlog_format = @sav_binlog_format;
+set @@global.binlog_format = @sav_binlog_format;
+#
+# Test Case 7: An XA transaction consisting of two failed
+# non-transactional statements should be binlogged
+connection server_1;
+set @sav_binlog_format = @@binlog_format;
+set @@binlog_format = row;
+set @@global.binlog_format = row;
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tm VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA COMMIT 'x';;
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tm VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA COMMIT 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tm VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+XA ROLLBACK 'x';;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connection server_2;
+connection server_3;
+connection server_1;
+CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam;
+CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+connect con1,localhost,root,,;
+XA START 'x';
+INSERT INTO tm VALUES (1),(1);;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tm VALUES (2),(2);;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+XA END 'x';
+XA PREPARE 'x';
+disconnect con1;
+connection server_1;
+XA RECOVER;
+formatID gtrid_length bqual_length data
+1 1 0 x
+XA ROLLBACK 'x';;
+ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
+include/save_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_1 should not binlog XA transaction]
+connection server_2;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_2 should not binlog XA transaction]
+connection server_3;
+include/sync_with_master_gtid.inc
+FLUSH LOGS;
+# MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file
+include/assert_grep.inc [server_3 should not binlog XA transaction]
+connection server_1;
+DROP TABLE ti,tm;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_1;
+set @@binlog_format = @sav_binlog_format;
+set @@global.binlog_format = @sav_binlog_format;
+connection server_1;
+include/rpl_end.inc
+# End of rpl_xa_empty_transaction.test
diff --git a/mysql-test/suite/rpl/t/rpl_xa_empty_transaction.cnf b/mysql-test/suite/rpl/t/rpl_xa_empty_transaction.cnf
new file mode 100644
index 00000000000..92acd0c73a6
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_xa_empty_transaction.cnf
@@ -0,0 +1,18 @@
+!include include/default_mysqld.cnf
+
+[mysqld.1]
+log-slave-updates
+innodb
+
+[mysqld.2]
+log-slave-updates
+innodb
+
+[mysqld.3]
+log-slave-updates
+innodb
+
+[ENV]
+SERVER_MYPORT_1= @mysqld.1.port
+SERVER_MYPORT_2= @mysqld.2.port
+SERVER_MYPORT_3= @mysqld.3.port
diff --git a/mysql-test/suite/rpl/t/rpl_xa_empty_transaction.test b/mysql-test/suite/rpl/t/rpl_xa_empty_transaction.test
new file mode 100644
index 00000000000..61cc0621d5a
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_xa_empty_transaction.test
@@ -0,0 +1,175 @@
+#
+# Purpose:
+# This test ensures consistency in binlogging behavior for XA transactions
+# that have all statements error and rollback, effectively leaving an "empty"
+# transaction. In such cases, an empty XA transaction should be binlogged. The
+# bug reported by MDEV-25616 revealed that an "empty" XA transaction would
+# binlog an XA ROLLBACK or XA COMMIT event without a preceding setup, i.e.
+# XA START through XA PREPARE. The bug presented differently for XA
+# transactions consisting of transactional and non-transactional statements.
+# Therefore, this test validates that an entire XA transaction is binlogged
+# for different combinations of transactional or non-transactional statements.
+# Note that the behavior changes when binlogging empty XA transactions
+# depending on the binlog_row_format variables. That is, when the content of
+# the transaction consists of errored transactional statements, in row format,
+# an empty XA transaction will be binlogged; however, in mixed and statement
+# formats, nothing will be written into the binary log.
+#
+# Methodology:
+# Create XA transactions with various combinations of erroring transactional
+# or non-transactional statements. The binary log is examined to ensure all
+# XA components are written. Chain replication is used, i.e.
+# (primary->replica->replica), to ensure replica binlogging is consistent with
+# manual execution. The transactional and non-transactional tables use InnoDB
+# and MyISAM, respectively.
+#
+# Parameters
+# $expect_transactional_xa_binlog : Boolean indicating whether or not an
+# errored transactional statement should result in XA statements written
+# into the binary log.
+#
+# References:
+# MDEV-25616: Binlog event for XA COMMIT is generated without matching
+# XA START, replication aborts
+#
+--source include/have_log_bin.inc
+
+--let $rpl_server_count= 3
+--let $rpl_topology= 1->2->3
+--source include/rpl_init.inc
+
+--connection server_1
+-- source include/have_innodb.inc
+--connection server_2
+-- source include/have_innodb.inc
+--connection server_3
+-- source include/have_innodb.inc
+--connection server_1
+
+--echo #
+--echo # Test Case 1: An XA transaction without any statements should not be
+--echo # binlogged
+--let $trx_statements=
+
+--let $xa_completion_action= COMMIT
+--source include/rpl_xa_empty_transaction.inc
+
+--let $xa_completion_action= ROLLBACK
+--source include/rpl_xa_empty_transaction.inc
+
+
+--echo #
+--echo # Test Case 2: An XA transaction consisting of a successfully rolled back
+--echo # statement should not be binlogged
+--let $trx_statements= T
+
+--let $xa_completion_action= COMMIT
+--source include/rpl_xa_empty_transaction.inc
+
+--let $xa_completion_action= ROLLBACK
+--source include/rpl_xa_empty_transaction.inc
+
+
+--echo #
+--echo # Test Case 3: An XA transaction with a statement that cannot be rolled
+--echo # back should be binlogged
+
+# TODO: remove work-around MDEV-24654 when fixed.
+--connection server_1
+set @sav_binlog_format = @@binlog_format;
+set @@binlog_format = row;
+set @@global.binlog_format = row;
+--let $trx_statements= N
+
+--let $xa_completion_action= COMMIT
+--source include/rpl_xa_empty_transaction.inc
+
+--let $xa_completion_action= ROLLBACK
+--source include/rpl_xa_empty_transaction.inc
+
+--connection server_1
+set @@binlog_format = @sav_binlog_format;
+set @@global.binlog_format = @sav_binlog_format;
+
+
+--echo #
+--echo # Test Case 4: An XA transaction with multiple statements that can all
+--echo # be rolled back should not be binlogged
+--let $trx_statements= T,T
+
+--let $xa_completion_action= COMMIT
+--source include/rpl_xa_empty_transaction.inc
+
+--let $xa_completion_action= ROLLBACK
+--source include/rpl_xa_empty_transaction.inc
+
+
+--echo #
+--echo # Test Case 5: A mixed XA transaction consisting of one statement that
+--echo # can successfully be rolled back (first statement), and another that
+--echo # can not (second statement) should be binlogged
+
+--connection server_1
+set @sav_binlog_format = @@binlog_format;
+set @@binlog_format = row;
+set @@global.binlog_format = row;
+--let $trx_statements= T,N
+
+--let $xa_completion_action= COMMIT
+--source include/rpl_xa_empty_transaction.inc
+
+--let $xa_completion_action= ROLLBACK
+--source include/rpl_xa_empty_transaction.inc
+
+--connection server_1
+set @@binlog_format = @sav_binlog_format;
+set @@global.binlog_format = @sav_binlog_format;
+
+
+--echo #
+--echo # Test Case 6: A mixed XA transaction consisting of one statement that
+--echo # cannot successfully be rolled back (first statement), and another that
+--echo # can (second statement) should be binlogged
+
+--connection server_1
+set @sav_binlog_format = @@binlog_format;
+set @@binlog_format = row;
+set @@global.binlog_format = row;
+--let $trx_statements= N,T
+
+--let $xa_completion_action= COMMIT
+--source include/rpl_xa_empty_transaction.inc
+
+--let $xa_completion_action= ROLLBACK
+--source include/rpl_xa_empty_transaction.inc
+
+--connection server_1
+set @@binlog_format = @sav_binlog_format;
+set @@global.binlog_format = @sav_binlog_format;
+
+--echo #
+--echo # Test Case 7: An XA transaction consisting of two failed
+--echo # non-transactional statements should be binlogged
+
+--connection server_1
+set @sav_binlog_format = @@binlog_format;
+set @@binlog_format = row;
+set @@global.binlog_format = row;
+--let $trx_statements= N,N
+
+--let $xa_completion_action= COMMIT
+--source include/rpl_xa_empty_transaction.inc
+
+--let $xa_completion_action= ROLLBACK
+--source include/rpl_xa_empty_transaction.inc
+
+--connection server_1
+set @@binlog_format = @sav_binlog_format;
+set @@global.binlog_format = @sav_binlog_format;
+
+#
+# Cleanup
+--connection server_1
+--source include/rpl_end.inc
+
+--echo # End of rpl_xa_empty_transaction.test
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index 444a47bb7c5..2d4385f4684 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -202,7 +202,7 @@ int start_addr2line_fork(const char *binary_path)
close(out[0]);
close(out[1]);
execlp("addr2line", "addr2line", "-C", "-f", "-e", binary_path, NULL);
- exit(1);
+ _exit(1);
}
close(in[0]);
@@ -319,12 +319,20 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
/* Save result for future comparisons. */
strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
+#ifdef _AIX
+ /*
+ info.dli_fbase is a char on AIX and casting it doesn't fool gcc.
+ leave backtracing broken on AIX until a real solution can be found.
+ */
+ addr_offset= NULL;
+#else
/*
Check if we should use info.dli_fbase as an offset or not
for the base program. This is depending on if the compilation is
done with PIE or not.
*/
- addr_offset= (void*) info.dli_fbase;
+ addr_offset= info.dli_fbase;
+#endif
#ifndef __PIE__
if (strcmp(info.dli_fname, my_progname) == 0 &&
addr_resolve((void*) my_addr_resolve, loc) == 0 &&
diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c
index 6bba553a549..1f344af88fd 100644
--- a/mysys/my_gethwaddr.c
+++ b/mysys/my_gethwaddr.c
@@ -23,7 +23,7 @@
#ifndef MAIN
-#if defined(_AIX) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__sun) || defined(_WIN32)
+#if defined(_AIX) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__linux__) || defined(__sun) || defined(_WIN32)
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
{
uint i, res= 1;
@@ -35,8 +35,14 @@ static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
}
#endif
-#if defined(__APPLE__) || defined(__FreeBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+#ifdef __OpenBSD__
+#include <netinet/in.h>
+#include <net/if_arp.h>
+#include <netinet/if_ether.h>
+#else
#include <net/ethernet.h>
+#endif
#include <sys/sysctl.h>
#include <net/route.h>
#include <net/if.h>
@@ -110,7 +116,7 @@ my_bool my_gethwaddr(uchar *to)
uint i;
for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++)
{
-#if !defined(_AIX) || !defined(__linux__)
+#if defined(_AIX) || defined(__linux__)
#if defined(__linux__)
#define HWADDR_DATA ifr[i].ifr_hwaddr.sa_data
#else
diff --git a/sql/derived_handler.cc b/sql/derived_handler.cc
index f48b95cbf76..70cc04bf9c7 100644
--- a/sql/derived_handler.cc
+++ b/sql/derived_handler.cc
@@ -44,11 +44,6 @@ Pushdown_derived::Pushdown_derived(TABLE_LIST *tbl, derived_handler *h)
}
-Pushdown_derived::~Pushdown_derived()
-{
- delete handler;
-}
-
int Pushdown_derived::execute()
{
diff --git a/sql/field.cc b/sql/field.cc
index bdd52c4626b..fbb0047e653 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -10841,8 +10841,6 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
type_handler()->Column_definition_reuse_fix_attributes(thd, this, old_field);
- type_handler()->Column_definition_implicit_upgrade(this);
-
/*
Copy the default (constant/function) from the column object orig_field, if
supplied. We do this if all these conditions are met:
diff --git a/sql/field.h b/sql/field.h
index 3451568a046..8d34e259fea 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1760,12 +1760,6 @@ public:
Used by the ALTER TABLE
*/
virtual bool is_equal(const Column_definition &new_field) const= 0;
- // Used as double dispatch pattern: calls virtual method of handler
- virtual bool
- can_be_converted_by_engine(const Column_definition &new_type) const
- {
- return false;
- }
/* convert decimal to longlong with overflow check */
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
int *err);
@@ -4052,11 +4046,6 @@ public:
void sql_type(String &str) const override;
void sql_rpl_type(String*) const override;
bool is_equal(const Column_definition &new_field) const override;
- bool can_be_converted_by_engine(const Column_definition &new_type) const
- override
- {
- return table->file->can_convert_string(this, new_type);
- }
uchar *pack(uchar *to, const uchar *from, uint max_length) override;
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
uint param_data) override;
@@ -4211,11 +4200,6 @@ public:
uchar *new_ptr, uint32 length,
uchar *new_null_ptr, uint new_null_bit) override;
bool is_equal(const Column_definition &new_field) const override;
- bool can_be_converted_by_engine(const Column_definition &new_type) const
- override
- {
- return table->file->can_convert_varstring(this, new_type);
- }
void hash(ulong *nr, ulong *nr2) override;
uint length_size() const override { return length_bytes; }
void print_key_value(String *out, uint32 length) override;
@@ -4654,11 +4638,6 @@ public:
uint32 char_length() const override;
uint32 character_octet_length() const override;
bool is_equal(const Column_definition &new_field) const override;
- bool can_be_converted_by_engine(const Column_definition &new_type) const
- override
- {
- return table->file->can_convert_blob(this, new_type);
- }
void print_key_value(String *out, uint32 length) override;
Binlog_type_info binlog_type_info() const override;
@@ -5691,6 +5670,12 @@ public:
}
/* Used to make a clone of this object for ALTER/CREATE TABLE */
Create_field *clone(MEM_ROOT *mem_root) const;
+ static void upgrade_data_types(List<Create_field> &list)
+ {
+ List_iterator<Create_field> it(list);
+ while (Create_field *f= it++)
+ f->type_handler()->Column_definition_implicit_upgrade(f);
+ }
};
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index e39ee8246a6..688db6403b4 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -12120,35 +12120,12 @@ int ha_partition::info_push(uint info_type, void *info)
bool
-ha_partition::can_convert_string(const Field_string* field,
- const Column_definition& new_type) const
+ha_partition::can_convert_nocopy(const Field &field,
+ const Column_definition &new_type) const
{
for (uint index= 0; index < m_tot_parts; index++)
{
- if (!m_file[index]->can_convert_string(field, new_type))
- return false;
- }
- return true;
-}
-
-bool
-ha_partition::can_convert_varstring(const Field_varstring* field,
- const Column_definition& new_type) const{
- for (uint index= 0; index < m_tot_parts; index++)
- {
- if (!m_file[index]->can_convert_varstring(field, new_type))
- return false;
- }
- return true;
-}
-
-bool
-ha_partition::can_convert_blob(const Field_blob* field,
- const Column_definition& new_type) const
-{
- for (uint index= 0; index < m_tot_parts; index++)
- {
- if (!m_file[index]->can_convert_blob(field, new_type))
+ if (!m_file[index]->can_convert_nocopy(field, new_type))
return false;
}
return true;
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 4a4b899708e..437280d6d5d 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -1629,16 +1629,8 @@ public:
friend int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
friend int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
- bool can_convert_string(
- const Field_string* field,
- const Column_definition& new_field) const override;
- bool can_convert_varstring(
- const Field_varstring* field,
- const Column_definition& new_field) const override;
-
- bool can_convert_blob(
- const Field_blob* field,
- const Column_definition& new_field) const override;
+ bool can_convert_nocopy(const Field &field,
+ const Column_definition &new_field) const override;
};
#endif /* HA_PARTITION_INCLUDED */
diff --git a/sql/handler.cc b/sql/handler.cc
index bc8502bb1be..14c228cc353 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -7320,8 +7320,13 @@ int handler::check_duplicate_long_entries_update(const uchar *new_rec)
{
int error;
field= keypart->field;
- /* Compare fields if they are different then check for duplicates */
- if (field->cmp_binary_offset(reclength))
+ /*
+ Compare fields if they are different then check for duplicates
+ cmp_binary_offset cannot differentiate between null and empty string
+ So also check for that too
+ */
+ if((field->is_null(0) != field->is_null(reclength)) ||
+ field->cmp_binary_offset(reclength))
{
if((error= check_duplicate_long_entry_key(new_rec, i)))
return error;
diff --git a/sql/handler.h b/sql/handler.h
index c50e1ced377..f60f7956257 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -5172,18 +5172,8 @@ public:
These functions check for such possibility.
Implementation could be based on Field_xxx::is_equal()
*/
- virtual bool can_convert_string(const Field_string *field,
- const Column_definition &new_type) const
- {
- return false;
- }
- virtual bool can_convert_varstring(const Field_varstring *field,
- const Column_definition &new_type) const
- {
- return false;
- }
- virtual bool can_convert_blob(const Field_blob *field,
- const Column_definition &new_type) const
+ virtual bool can_convert_nocopy(const Field &,
+ const Column_definition &) const
{
return false;
}
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index 7a1115425d9..0010e86557d 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -2585,56 +2585,58 @@ double Item_func_sphere_distance::spherical_distance_points(Geometry *g1,
double res= 0.0;
// Length for the single point (25 Bytes)
uint32 len= SRID_SIZE + POINT_DATA_SIZE + WKB_HEADER_SIZE;
- int error= 0;
+ int err_hv= 0, err_sph= 0;
switch (g2->get_class_info()->m_type_id)
{
case Geometry::wkb_point:
- // Optimization for point-point case
+ {
+ Gis_point *g2p= static_cast<Gis_point *>(g2);
+ // Optimization for point-point case
if (g1->get_class_info()->m_type_id == Geometry::wkb_point)
{
- res= static_cast<Gis_point *>(g2)->calculate_haversine(g1, r, &error);
+ res= g2p->calculate_haversine(g1, r, &err_hv);
}
else
{
// Optimization for single point in Multipoint
if (g1->get_data_size() == len)
{
- res= static_cast<Gis_point *>(g2)->calculate_haversine(g1, r, &error);
+ res= g2p->calculate_haversine(g1, r, &err_hv);
}
else
{
// There are multipoints in g1
// g1 is MultiPoint and calculate MP.sphericaldistance from g2 Point
if (g1->get_data_size() != GET_SIZE_ERROR)
- static_cast<Gis_point *>(g2)->spherical_distance_multipoints(
- (Gis_multi_point *)g1, r, &res, &error);
+ err_sph= g2p->spherical_distance_multipoints(g1, r, &res, &err_hv);
}
}
break;
+ }
case Geometry::wkb_multipoint:
// Optimization for point-point case
if (g1->get_class_info()->m_type_id == Geometry::wkb_point)
{
+ Gis_point *g1p= static_cast<Gis_point *>(g1);
// Optimization for single point in Multipoint g2
if (g2->get_data_size() == len)
{
- res= static_cast<Gis_point *>(g1)->calculate_haversine(g2, r, &error);
+ res= g1p->calculate_haversine(g2, r, &err_hv);
}
else
{
if (g2->get_data_size() != GET_SIZE_ERROR)
// g1 is a point (casted to multi_point) and g2 multipoint
- static_cast<Gis_point *>(g1)->spherical_distance_multipoints(
- (Gis_multi_point *)g2, r, &res, &error);
+ err_sph= g1p->spherical_distance_multipoints(g2, r, &res, &err_hv);
}
}
else
{
+ Gis_multi_point *g1mp= static_cast<Gis_multi_point *>(g1);
// Multipoints in g1 and g2 - no optimization
- static_cast<Gis_multi_point *>(g1)->spherical_distance_multipoints(
- (Gis_multi_point *)g2, r, &res, &error);
+ err_sph= g1mp->spherical_distance_multipoints(g2, r, &res, &err_hv);
}
break;
@@ -2643,16 +2645,14 @@ double Item_func_sphere_distance::spherical_distance_points(Geometry *g1,
break;
}
- if (res < 0)
- goto handle_error;
-
- handle_error:
- if (error > 0)
- my_error(ER_STD_OUT_OF_RANGE_ERROR, MYF(0),
- "Longitude should be [-180,180]", "ST_Distance_Sphere");
- else if(error < 0)
- my_error(ER_STD_OUT_OF_RANGE_ERROR, MYF(0),
- "Latitude should be [-90,90]", "ST_Distance_Sphere");
+ if (err_hv == 1)
+ my_error(ER_STD_OUT_OF_RANGE_ERROR, MYF(0),
+ "Longitude should be [-180,180]", "ST_Distance_Sphere");
+ else if(err_hv < 0)
+ my_error(ER_STD_OUT_OF_RANGE_ERROR, MYF(0),
+ "Latitude should be [-90,90]", "ST_Distance_Sphere");
+ else if (err_sph || err_hv == 2)
+ my_error(ER_CANT_CREATE_GEOMETRY_OBJECT, MYF(0));
return res;
}
diff --git a/sql/log.cc b/sql/log.cc
index a23abad2bc5..b8f8d3daae7 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1995,29 +1995,62 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all)
int binlog_commit_by_xid(handlerton *hton, XID *xid)
{
+ int rc= 0;
THD *thd= current_thd;
if (thd->is_current_stmt_binlog_disabled())
return 0;
+
+ /* the asserted state can't be reachable with xa commit */
+ DBUG_ASSERT(!thd->get_stmt_da()->is_error() ||
+ thd->get_stmt_da()->sql_errno() != ER_XA_RBROLLBACK);
+ /*
+ This is a recovered user xa transaction commit.
+ Create a "temporary" binlog transaction to write the commit record
+ into binlog.
+ */
+ THD_TRANS trans;
+ trans.ha_list= NULL;
+
+ thd->ha_data[hton->slot].ha_info[1].register_ha(&trans, hton);
+ thd->ha_data[binlog_hton->slot].ha_info[1].set_trx_read_write();
(void) thd->binlog_setup_trx_data();
DBUG_ASSERT(thd->lex->sql_command == SQLCOM_XA_COMMIT);
- return binlog_commit(thd, TRUE, FALSE);
+ rc= binlog_commit(thd, TRUE, FALSE);
+ thd->ha_data[binlog_hton->slot].ha_info[1].reset();
+
+ return rc;
}
int binlog_rollback_by_xid(handlerton *hton, XID *xid)
{
+ int rc= 0;
THD *thd= current_thd;
if (thd->is_current_stmt_binlog_disabled())
return 0;
+
+ if (thd->get_stmt_da()->is_error() &&
+ thd->get_stmt_da()->sql_errno() == ER_XA_RBROLLBACK)
+ return rc;
+
+ THD_TRANS trans;
+ trans.ha_list= NULL;
+
+ thd->ha_data[hton->slot].ha_info[1].register_ha(&trans, hton);
+ thd->ha_data[hton->slot].ha_info[1].set_trx_read_write();
(void) thd->binlog_setup_trx_data();
DBUG_ASSERT(thd->lex->sql_command == SQLCOM_XA_ROLLBACK ||
(thd->transaction->xid_state.get_state_code() == XA_ROLLBACK_ONLY));
- return binlog_rollback(hton, thd, TRUE);
+
+ rc= binlog_rollback(hton, thd, TRUE);
+ thd->ha_data[hton->slot].ha_info[1].reset();
+
+ return rc;
}
@@ -2151,10 +2184,16 @@ int binlog_commit(THD *thd, bool all, bool ro_1pc)
}
if (cache_mngr->trx_cache.empty() &&
- thd->transaction->xid_state.get_state_code() != XA_PREPARED)
+ (thd->transaction->xid_state.get_state_code() != XA_PREPARED ||
+ !(thd->ha_data[binlog_hton->slot].ha_info[1].is_started() &&
+ thd->ha_data[binlog_hton->slot].ha_info[1].is_trx_read_write())))
{
/*
- we're here because cache_log was flushed in MYSQL_BIN_LOG::log_xid()
+ This is an empty transaction commit (both the regular and xa),
+ or such transaction xa-prepare or
+ either one's statement having no effect on the transactional cache
+ as any prior to it.
+ The empty xa-prepare sinks in only when binlog is read-only.
*/
cache_mngr->reset(false, true);
THD_STAGE_INFO(thd, org_stage);
@@ -2239,10 +2278,12 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
}
if (!cache_mngr->trx_cache.has_incident() && cache_mngr->trx_cache.empty() &&
- thd->transaction->xid_state.get_state_code() != XA_PREPARED)
+ (thd->transaction->xid_state.get_state_code() != XA_PREPARED ||
+ !(thd->ha_data[binlog_hton->slot].ha_info[1].is_started() &&
+ thd->ha_data[binlog_hton->slot].ha_info[1].is_trx_read_write())))
{
/*
- we're here because cache_log was flushed in MYSQL_BIN_LOG::log_xid()
+ The same comments apply as in the binlog commit method's branch.
*/
cache_mngr->reset(false, true);
thd->reset_binlog_for_next_statement();
@@ -10444,6 +10485,7 @@ int TC_LOG_BINLOG::unlog_xa_prepare(THD *thd, bool all)
/* an empty XA-prepare event group is logged */
rc= write_empty_xa_prepare(thd, cache_mngr); // normally gains need_unlog
trans_register_ha(thd, true, binlog_hton, 0); // do it for future commmit
+ thd->ha_data[binlog_hton->slot].ha_info[1].set_trx_read_write();
}
if (rw_count == 0 || !cache_mngr->need_unlog)
return rc;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b008df491fd..988ffd678f4 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4089,8 +4089,8 @@ static int init_common_variables()
files= my_set_max_open_files(max_open_files);
SYSVAR_AUTOSIZE_IF_CHANGED(open_files_limit, files, ulong);
- if (files < wanted_files && global_system_variables.log_warnings)
- sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
+ if (files < max_open_files && global_system_variables.log_warnings)
+ sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, max_open_files);
/* If we required too much tc_instances than we reduce */
SYSVAR_AUTOSIZE_IF_CHANGED(tc_instances,
@@ -4613,10 +4613,9 @@ static void init_ssl()
DBUG_PRINT("info",("ssl_acceptor_fd: %p", ssl_acceptor_fd));
if (!ssl_acceptor_fd)
{
- sql_print_warning("Failed to setup SSL");
- sql_print_warning("SSL error: %s", sslGetErrString(error));
- opt_use_ssl = 0;
- have_ssl= SHOW_OPTION_DISABLED;
+ sql_print_error("Failed to setup SSL");
+ sql_print_error("SSL error: %s", sslGetErrString(error));
+ unireg_abort(1);
}
else
ssl_acceptor_stats.init();
diff --git a/sql/rowid_filter.h b/sql/rowid_filter.h
index 12710aecb18..cb1615c5925 100644
--- a/sql/rowid_filter.h
+++ b/sql/rowid_filter.h
@@ -192,6 +192,9 @@ public:
*/
virtual bool check(void *ctxt, char *elem) = 0;
+ /* True if the container does not contain any element */
+ virtual bool is_empty() = 0;
+
virtual ~Rowid_filter_container() {}
};
@@ -231,6 +234,8 @@ public:
virtual ~Rowid_filter() {}
+ bool is_empty() { return container->is_empty(); }
+
Rowid_filter_container *get_container() { return container; }
void set_tracker(Rowid_filter_tracker *track_arg) { tracker= track_arg; }
@@ -268,6 +273,8 @@ public:
bool check(char *elem)
{
+ if (container->is_empty())
+ return false;
bool was_checked= container->check(table, elem);
tracker->increment_checked_elements_count(was_checked);
return was_checked;
@@ -340,6 +347,8 @@ public:
my_qsort2(array->front(), array->elements()/elem_size,
elem_size, (qsort2_cmp) cmp, cmp_arg);
}
+
+ bool is_empty() { return elements() == 0; }
};
@@ -369,6 +378,8 @@ public:
bool add(void *ctxt, char *elem) { return refpos_container.add(elem); }
bool check(void *ctxt, char *elem);
+
+ bool is_empty() { return refpos_container.is_empty(); }
};
/**
diff --git a/sql/spatial.cc b/sql/spatial.cc
index 527a1df9d1f..ec8279daa7a 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -1094,10 +1094,9 @@ double Gis_point::calculate_haversine(const Geometry *g,
point_temp[point_size-1]= '\0';
Geometry_buffer gbuff;
Geometry *gg= Geometry::construct(&gbuff, point_temp, point_size-1);
- DBUG_ASSERT(gg);
- if (static_cast<Gis_point *>(gg)->get_xy_radian(&x2r, &y2r))
+ if (!gg || static_cast<Gis_point *>(gg)->get_xy_radian(&x2r, &y2r))
{
- DBUG_ASSERT(0);
+ *error= 2;
return -1;
}
}
@@ -1105,15 +1104,16 @@ double Gis_point::calculate_haversine(const Geometry *g,
{
if (static_cast<const Gis_point *>(g)->get_xy_radian(&x2r, &y2r))
{
- DBUG_ASSERT(0);
+ *error= 2;
return -1;
}
}
if (this->get_xy_radian(&x1r, &y1r))
{
- DBUG_ASSERT(0);
+ *error= 2;
return -1;
}
+ //
// Check boundary conditions: longitude[-180,180]
if (!((x2r >= -M_PI && x2r <= M_PI) && (x1r >= -M_PI && x1r <= M_PI)))
{
@@ -1166,15 +1166,20 @@ int Gis_point::spherical_distance_multipoints(Geometry *g, const double r,
{
Geometry_buffer buff_temp;
Geometry *temp;
+ const char *pt_ptr= g->get_data_ptr()+
+ 4+WKB_HEADER_SIZE*i + POINT_DATA_SIZE*(i-1);
// First 4 bytes are handled already, make sure to create a Point
memset(s + 4, Geometry::wkb_point, 1);
+ if (g->no_data(pt_ptr, POINT_DATA_SIZE))
+ return 1;
+
memcpy(s + 5, g->get_data_ptr() + 5, 4);
- memcpy(s + 4 + WKB_HEADER_SIZE, g->get_data_ptr() + 4 + WKB_HEADER_SIZE*i +\
- POINT_DATA_SIZE*(i-1), POINT_DATA_SIZE);
+ memcpy(s + 4 + WKB_HEADER_SIZE, pt_ptr, POINT_DATA_SIZE);
s[len-1]= '\0';
temp= Geometry::construct(&buff_temp, s, len);
- DBUG_ASSERT(temp);
+ if (!temp)
+ return 1;
temp_res= this->calculate_haversine(temp, r, err);
if (res > temp_res)
res= temp_res;
@@ -2351,14 +2356,18 @@ int Gis_multi_point::spherical_distance_multipoints(Geometry *g, const double r,
Geometry *temp;
double temp_res= 0.0;
char s[len];
+ const char *pt_ptr= get_data_ptr()+
+ 4+WKB_HEADER_SIZE*i + POINT_DATA_SIZE*(i-1);
// First 4 bytes are handled already, make sure to create a Point
memset(s + 4, Geometry::wkb_point, 1);
+ if (no_data(pt_ptr, POINT_DATA_SIZE))
+ return 1;
memcpy(s + 5, this->get_data_ptr() + 5, 4);
- memcpy(s + 4 + WKB_HEADER_SIZE, this->get_data_ptr() + 4 + WKB_HEADER_SIZE*i +\
- POINT_DATA_SIZE*(i-1), POINT_DATA_SIZE);
+ memcpy(s + 4 + WKB_HEADER_SIZE, pt_ptr, POINT_DATA_SIZE);
s[len-1]= '\0';
temp= Geometry::construct(&buff_temp, s, len);
- DBUG_ASSERT(temp);
+ if (!temp)
+ return 1;
// Optimization for single Multipoint
if (num_of_points2 == 1)
{
@@ -2370,14 +2379,18 @@ int Gis_multi_point::spherical_distance_multipoints(Geometry *g, const double r,
Geometry_buffer buff_temp2;
Geometry *temp2;
char s2[len];
+ const char *pt_ptr= g->get_data_ptr()+
+ 4+WKB_HEADER_SIZE*j + POINT_DATA_SIZE*(j-1);
// First 4 bytes are handled already, make sure to create a Point
memset(s2 + 4, Geometry::wkb_point, 1);
+ if (g->no_data(pt_ptr, POINT_DATA_SIZE))
+ return 1;
memcpy(s2 + 5, g->get_data_ptr() + 5, 4);
- memcpy(s2 + 4 + WKB_HEADER_SIZE, g->get_data_ptr() + 4 + WKB_HEADER_SIZE*j +\
- POINT_DATA_SIZE*(j-1), POINT_DATA_SIZE);
+ memcpy(s2 + 4 + WKB_HEADER_SIZE, pt_ptr, POINT_DATA_SIZE);
s2[len-1]= '\0';
temp2= Geometry::construct(&buff_temp2, s2, len);
- DBUG_ASSERT(temp2);
+ if (!temp2)
+ return 1;
temp_res= static_cast<Gis_point *>(temp)->calculate_haversine(temp2, r, err);
if (res > temp_res)
res= temp_res;
diff --git a/sql/spatial.h b/sql/spatial.h
index 7b33529ee94..8974511adf9 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -353,6 +353,7 @@ protected:
const char *get_mbr_for_points(MBR *mbr, const char *data, uint offset)
const;
+public:
/**
Check if there're enough data remaining as requested
@@ -383,6 +384,7 @@ protected:
(expected_points > ((m_data_end - data) /
(POINT_DATA_SIZE + extra_point_space))));
}
+protected:
const char *m_data;
const char *m_data_end;
};
diff --git a/sql/sql_analyze_stmt.h b/sql/sql_analyze_stmt.h
index 990c79fb9ad..968b8d38295 100644
--- a/sql/sql_analyze_stmt.h
+++ b/sql/sql_analyze_stmt.h
@@ -416,12 +416,13 @@ public:
uint get_container_elements() const { return container_elements; }
+ uint get_container_lookups() { return n_checks; }
+
double get_r_selectivity_pct() const
{
- return static_cast<double>(n_positive_checks) /
- static_cast<double>(n_checks);
+ return n_checks ? static_cast<double>(n_positive_checks) /
+ static_cast<double>(n_checks) : 0;
}
size_t get_container_buff_size() const { return container_buff_size; }
};
-
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 405ac8e8f31..6276b00b939 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3737,8 +3737,10 @@ int select_max_min_finder_subselect::send_data(List<Item> &items)
{
cache= val_item->get_cache(thd);
set_op(val_item->type_handler());
+ cache->setup(thd, val_item);
}
- cache->store(val_item);
+ else
+ cache->store(val_item);
it->store(0, cache);
}
it->assigned(1);
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 579ea34b8e4..6f0857239dd 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1016,11 +1016,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
/* Create an object for execution of the query specifying the table */
if (!(derived->pushdown_derived=
new (thd->mem_root) Pushdown_derived(derived, derived->dt_handler)))
- {
- delete derived->dt_handler;
- derived->dt_handler= NULL;
DBUG_RETURN(TRUE);
- }
}
lex->current_select= first_select;
@@ -1245,7 +1241,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
/* Execute the query that specifies the derived table by a foreign engine */
res= derived->pushdown_derived->execute();
unit->executed= true;
- delete derived->pushdown_derived;
DBUG_RETURN(res);
}
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc
index 79e06640768..480a1259ba8 100644
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@ -1683,6 +1683,7 @@ void Explain_rowid_filter::print_explain_json(Explain_query *query,
if (is_analyze)
{
writer->add_member("r_rows").add_double(tracker->get_container_elements());
+ writer->add_member("r_lookups").add_ll(tracker->get_container_lookups());
writer->add_member("r_selectivity_pct").
add_double(tracker->get_r_selectivity_pct() * 100.0);
writer->add_member("r_buffer_size").
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 196bfcaf6e8..5ad968f19a0 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -4487,6 +4487,16 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
alter_info->create_list.push_back(cr_field, thd->mem_root);
}
+ /*
+ Item*::type_handler() always returns pointers to
+ type_handler_{time2|datetime2|timestamp2} no matter what
+ the current mysql56_temporal_format says.
+ Let's convert them according to mysql56_temporal_format.
+ QQ: This perhaps should eventually be fixed to have Item*::type_handler()
+ respect mysql56_temporal_format, and remove the upgrade from here.
+ */
+ Create_field::upgrade_data_types(alter_info->create_list);
+
if (create_info->check_fields(thd, alter_info,
create_table->table_name,
create_table->db,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 71b9dad3dd1..60b2641e670 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -67,6 +67,7 @@
#include "select_handler.h"
#include "my_json_writer.h"
#include "opt_trace.h"
+#include "derived_handler.h"
#include "create_tmp_table.h"
/*
@@ -1324,6 +1325,15 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
/* Fix items that requires the join structure to exist */
fix_items_after_optimize(thd, select_lex);
+ /*
+ It is hack which force creating EXPLAIN object always on runt-time arena
+ (because very top JOIN::prepare executes always with runtime arena, but
+ constant subquery like (SELECT 'x') can be called with statement arena
+ during prepare phase of top SELECT).
+ */
+ if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE))
+ create_explain_query_if_not_exists(thd->lex, thd->mem_root);
+
if (select_lex->handle_derived(thd->lex, DT_PREPARE))
DBUG_RETURN(-1);
@@ -1811,7 +1821,6 @@ bool JOIN::build_explain()
int JOIN::optimize()
{
int res= 0;
- create_explain_query_if_not_exists(thd->lex, thd->mem_root);
join_optimization_state init_state= optimization_state;
if (select_lex->pushdown_select)
{
@@ -7727,6 +7736,7 @@ best_access_path(JOIN *join,
double best= DBL_MAX;
double best_time= DBL_MAX;
double records= DBL_MAX;
+ ha_rows records_for_key= 0;
table_map best_ref_depends_map= 0;
/*
key_dependent is 0 if all key parts could be used or if there was an
@@ -7737,6 +7747,7 @@ best_access_path(JOIN *join,
table_map key_dependent= 0;
Range_rowid_filter_cost_info *best_filter= 0;
double tmp;
+ double keyread_tmp= 0;
ha_rows rec;
bool best_uses_jbuf= FALSE;
MY_BITMAP *eq_join_set= &s->table->eq_join_set;
@@ -8021,8 +8032,12 @@ best_access_path(JOIN *join,
/* Limit the number of matched rows */
tmp= cost_for_index_read(thd, table, key, (ha_rows) records,
(ha_rows) s->worst_seeks);
+ records_for_key= (ha_rows) records;
+ set_if_smaller(records_for_key, thd->variables.max_seeks_for_key);
+ keyread_tmp= table->file->keyread_time(key, 1, records_for_key);
got_cost:
tmp= COST_MULT(tmp, record_count);
+ keyread_tmp= COST_MULT(keyread_tmp, record_count);
}
}
else
@@ -8196,12 +8211,14 @@ best_access_path(JOIN *join,
}
/* Limit the number of matched rows */
- tmp= records;
- set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
- tmp= cost_for_index_read(thd, table, key, (ha_rows) tmp,
+ tmp= cost_for_index_read(thd, table, key, (ha_rows) records,
(ha_rows) s->worst_seeks);
+ records_for_key= (ha_rows) records;
+ set_if_smaller(records_for_key, thd->variables.max_seeks_for_key);
+ keyread_tmp= table->file->keyread_time(key, 1, records_for_key);
got_cost2:
tmp= COST_MULT(tmp, record_count);
+ keyread_tmp= COST_MULT(keyread_tmp, record_count);
}
else
{
@@ -8220,7 +8237,35 @@ best_access_path(JOIN *join,
(found_part & 1)) // start_key->key can be used for index access
{
double rows= record_count * records;
- double access_cost_factor= MY_MIN(tmp / rows, 1.0);
+
+ /*
+ If we use filter F with selectivity s the the cost of fetching data
+ by key using this filter will be
+ cost_of_fetching_1_row * rows * s +
+ cost_of_fetching_1_key_tuple * rows * (1 - s) +
+ cost_of_1_lookup_into_filter * rows
+ Without using any filter the cost would be just
+ cost_of_fetching_1_row * rows
+
+ So the gain in access cost per row will be
+ cost_of_fetching_1_row * (1 - s) -
+ cost_of_fetching_1_key_tuple * (1 - s) -
+ cost_of_1_lookup_into_filter
+ =
+ (cost_of_fetching_1_row - cost_of_fetching_1_key_tuple) * (1 - s)
+ - cost_of_1_lookup_into_filter
+
+ Here we have:
+ cost_of_fetching_1_row = tmp/rows
+ cost_of_fetching_1_key_tuple = keyread_tmp/rows
+
+ Note that access_cost_factor may be greater than 1.0. In this case
+ we still can expect a gain of using rowid filter due to smaller number
+ of checks for conditions pushed to the joined table.
+ */
+ double rows_access_cost= MY_MIN(rows, s->worst_seeks);
+ double access_cost_factor= MY_MIN((rows_access_cost - keyread_tmp) /
+ rows, 1.0);
filter=
table->best_range_rowid_filter_for_partial_join(start_key->key, rows,
access_cost_factor);
@@ -8405,6 +8450,10 @@ best_access_path(JOIN *join,
double rows= record_count * s->found_records;
double access_cost_factor= MY_MIN(tmp / rows, 1.0);
uint key_no= s->quick->index;
+
+ /* See the comment concerning using rowid filter for with ref access */
+ keyread_tmp= s->table->opt_range[key_no].index_only_cost;
+ access_cost_factor= MY_MIN((rows - keyread_tmp) / rows, 1.0);
filter=
s->table->best_range_rowid_filter_for_partial_join(key_no, rows,
access_cost_factor);
@@ -14531,6 +14580,7 @@ void JOIN::cleanup(bool full)
}
}
}
+ free_pushdown_handlers(*join_list);
}
/* Restore ref array to original state */
if (current_ref_ptrs != items0)
@@ -14541,6 +14591,32 @@ void JOIN::cleanup(bool full)
DBUG_VOID_RETURN;
}
+/**
+ Clean up all derived pushdown handlers in this join.
+
+ @detail
+ Note that dt_handler is picked at the prepare stage (as opposed
+ to optimization stage where one could expect this).
+ Because of that, we have to do cleanups in this function that is called
+ from JOIN::cleanup() and not in JOIN_TAB::cleanup.
+ */
+void JOIN::free_pushdown_handlers(List<TABLE_LIST>& join_list)
+{
+ List_iterator<TABLE_LIST> li(join_list);
+ TABLE_LIST *table_ref;
+ while ((table_ref= li++))
+ {
+ if (table_ref->nested_join)
+ free_pushdown_handlers(table_ref->nested_join->join_list);
+ if (table_ref->pushdown_derived)
+ {
+ delete table_ref->pushdown_derived;
+ table_ref->pushdown_derived= NULL;
+ }
+ delete table_ref->dt_handler;
+ table_ref->dt_handler= NULL;
+ }
+}
/**
Remove the following expressions from ORDER BY and GROUP BY:
@@ -21257,6 +21333,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
DBUG_RETURN(NESTED_LOOP_ERROR);
join_tab->build_range_rowid_filter_if_needed();
+ if (join_tab->rowid_filter && join_tab->rowid_filter->is_empty())
+ rc= NESTED_LOOP_NO_MORE_ROWS;
join->return_tab= join_tab;
@@ -28021,12 +28099,6 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
result, unit, first);
}
- if (unit->derived && unit->derived->pushdown_derived)
- {
- delete unit->derived->pushdown_derived;
- unit->derived->pushdown_derived= NULL;
- }
-
DBUG_RETURN(res || thd->is_error());
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 5aa775f4a2d..c9e0fa25421 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1791,6 +1791,7 @@ private:
bool add_having_as_table_cond(JOIN_TAB *tab);
bool make_aggr_tables_info();
bool add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *fields);
+ void free_pushdown_handlers(List<TABLE_LIST>& join_list);
void init_join_cache_and_keyread();
bool transform_in_predicates_into_equalities(THD *thd);
bool transform_all_conds_and_on_exprs(THD *thd,
@@ -2471,8 +2472,6 @@ public:
Pushdown_derived(TABLE_LIST *tbl, derived_handler *h);
- ~Pushdown_derived();
-
int execute();
};
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 8e7d8c366a1..ee4406da975 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -6436,7 +6436,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar,
bool is_equal= field->is_equal(*new_field);
if (!is_equal)
{
- if (field->can_be_converted_by_engine(*new_field))
+ if (field->table->file->can_convert_nocopy(*field, *new_field))
{
/*
New column type differs from the old one, but storage engine can
@@ -9983,6 +9983,18 @@ do_continue:;
set_table_default_charset(thd, create_info, alter_ctx.db);
+ /*
+ The ALTER related code cannot alter partitions and change column data types
+ at the same time. So in case of partition change statements like:
+ ALTER TABLE t1 DROP PARTITION p1;
+ we skip implicit data type upgrade (such as "MariaDB 5.3 TIME" to
+ "MySQL 5.6 TIME" or vice versa according to mysql56_temporal_format).
+ Note, one can run a separate "ALTER TABLE t1 FORCE;" statement
+ before or after the partition change ALTER statement to upgrade data types.
+ */
+ if (IF_PARTITIONING(!fast_alter_partition, 1))
+ Create_field::upgrade_data_types(alter_info->create_list);
+
if (create_info->check_fields(thd, alter_info,
table_list->table_name, table_list->db) ||
create_info->fix_period_fields(thd, alter_info))
diff --git a/sql/sql_type_geom.h b/sql/sql_type_geom.h
index a2bcd45e0e8..3bc25808bc3 100644
--- a/sql/sql_type_geom.h
+++ b/sql/sql_type_geom.h
@@ -2,7 +2,7 @@
#define SQL_TYPE_GEOM_H_INCLUDED
/*
Copyright (c) 2015 MariaDB Foundation
- Copyright (c) 2019 MariaDB
+ Copyright (c) 2019, 2022, MariaDB Corporation.
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
@@ -397,12 +397,6 @@ public:
!table->copy_blobs;
}
bool is_equal(const Column_definition &new_field) const override;
- bool can_be_converted_by_engine(const Column_definition &new_type)
- const override
- {
- return false; // Override the Field_blob behavior
- }
-
int store(const char *to, size_t length, CHARSET_INFO *charset) override;
int store(double nr) override;
int store(longlong nr, bool unsigned_val) override;
diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore
-Subproject 1071ce954807104d25c0951f422e83d5e17406f
+Subproject 5923beeab9397aa22563ff7b1f0f31ad8054bae
diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp
index 8dc892998cb..618c0168470 100644
--- a/storage/connect/bsonudf.cpp
+++ b/storage/connect/bsonudf.cpp
@@ -3573,14 +3573,14 @@ char *bson_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!CheckMemory(g, initid, args, 2, false, false, true)) {
JTYP type;
BJNX bnx(g);
- PBVAL jvp, top = NULL;
+ PBVAL jvp = NULL, top = NULL;
PBVAL jsp[2] = {NULL, NULL};
for (int i = 0; i < 2; i++) {
jvp = bnx.MakeValue(args, i, true);
if (i) {
- if (jvp->Type != type) {
+ if (jvp && (jvp->Type != type)) {
PUSH_WARNING("Argument types mismatch");
goto fin;
} // endif type
@@ -5724,14 +5724,14 @@ char *bbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!CheckMemory(g, initid, args, 2, false, false, true)) {
JTYP type;
BJNX bnx(g);
- PBVAL jvp, top = NULL;
+ PBVAL jvp = NULL, top = NULL;
PBVAL jsp[2] = {NULL, NULL};
for (int i = 0; i < 2; i++) {
if (i) {
jvp = bnx.MakeValue(args, i, true);
- if (jvp->Type != type) {
+ if (jvp && (jvp->Type != type)) {
PUSH_WARNING("Argument types mismatch");
goto fin;
} // endif type
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index b9ce16c5a7e..c7206b4def3 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -245,7 +245,7 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, PTOS topt, bool info)
int rc, type, len, field, fields;
bool bad, mul;
PCSZ target, pwd;
- DBFHEADER mainhead, *hp;
+ DBFHEADER mainhead, *hp = NULL;
DESCRIPTOR thisfield, *tfp;
FILE *infile = NULL;
UNZIPUTL *zutp = NULL;
diff --git a/storage/connect/mysql-test/connect/r/odbc_postgresql.result b/storage/connect/mysql-test/connect/r/odbc_postgresql.result
index 6bd8d75a601..9ecb66307e6 100644
--- a/storage/connect/mysql-test/connect/r/odbc_postgresql.result
+++ b/storage/connect/mysql-test/connect/r/odbc_postgresql.result
@@ -319,3 +319,12 @@ SELECT * from pg_in_maria;
my space column
My value
DROP TABLE pg_in_maria;
+#
+# MDEV-29397 UPDATE with WHERE on part of two-part primary key causes
+# info to turn into error.
+#
+CREATE TABLE t1 (a VARCHAR(6), b VARCHAR(6), PRIMARY KEY(a, b)) ENGINE=CONNECT TABNAME='schema1.t3' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr';
+UPDATE t1 SET a='10' WHERE a='20';
+Warnings:
+Note 1105 schema1.t3: 0 affected rows
+DROP TABLE t1;
diff --git a/storage/connect/mysql-test/connect/t/odbc_postgresql.test b/storage/connect/mysql-test/connect/t/odbc_postgresql.test
index ec98453d630..187bec55b38 100644
--- a/storage/connect/mysql-test/connect/t/odbc_postgresql.test
+++ b/storage/connect/mysql-test/connect/t/odbc_postgresql.test
@@ -223,3 +223,12 @@ DROP TABLE t1;
CREATE TABLE pg_in_maria ENGINE=CONNECT TABNAME='schema1.space_in_column_name' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' quoted=1;
SELECT * from pg_in_maria;
DROP TABLE pg_in_maria;
+
+--echo #
+--echo # MDEV-29397 UPDATE with WHERE on part of two-part primary key causes
+--echo # info to turn into error.
+--echo #
+CREATE TABLE t1 (a VARCHAR(6), b VARCHAR(6), PRIMARY KEY(a, b)) ENGINE=CONNECT TABNAME='schema1.t3' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr';
+UPDATE t1 SET a='10' WHERE a='20';
+DROP TABLE t1;
+
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index 09140712de8..0c5903baa77 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -2583,7 +2583,7 @@ int ODBConn::Rewind(char *sql, ODBCCOL *tocols)
int rc, rbuf = -1;
if (!m_hstmt)
- rbuf = -1;
+ rbuf = 0;
else if (m_Full)
rbuf = m_Rows; // No need to "rewind"
else if (m_Scrollable) {
diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp
index dcd93539f19..96a9f70e4a3 100644
--- a/storage/connect/tabext.cpp
+++ b/storage/connect/tabext.cpp
@@ -472,7 +472,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
my_len= res - buf + 1;
my_schema_table= (char *) malloc(my_len);
memcpy(my_schema_table, buf, my_len - 1);
- my_schema_table[my_len] = 0;
+ my_schema_table[my_len - 1] = 0;
Query->Append(Quote);
Query->Append(my_schema_table);
Query->Append(Quote);
@@ -480,7 +480,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
Query->Append(".");
// Parse table
my_len= strlen(buf) - my_len + 1;
- my_schema_table= (char *) malloc(my_len);
+ my_schema_table= (char *) malloc(my_len + 1);
memcpy(my_schema_table, ++res, my_len);
my_schema_table[my_len] = 0;
Query->Append(Quote);
diff --git a/storage/federatedx/CMakeLists.txt b/storage/federatedx/CMakeLists.txt
index 5f983b5d637..6a9b12ee362 100644
--- a/storage/federatedx/CMakeLists.txt
+++ b/storage/federatedx/CMakeLists.txt
@@ -1,2 +1,3 @@
SET(FEDERATEDX_SOURCES ha_federatedx.cc federatedx_txn.cc federatedx_io.cc federatedx_io_null.cc federatedx_io_mysql.cc)
-MYSQL_ADD_PLUGIN(federatedx ${FEDERATEDX_SOURCES} STORAGE_ENGINE)
+MYSQL_ADD_PLUGIN(federatedx ${FEDERATEDX_SOURCES} STORAGE_ENGINE
+ RECOMPILE_FOR_EMBEDDED)
diff --git a/storage/federatedx/federatedx_io_mysql.cc b/storage/federatedx/federatedx_io_mysql.cc
index d420de738b9..5cb8b7efa5b 100644
--- a/storage/federatedx/federatedx_io_mysql.cc
+++ b/storage/federatedx/federatedx_io_mysql.cc
@@ -31,6 +31,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <my_global.h>
#include "sql_priv.h"
#include <mysqld_error.h>
+#include <mysql.h>
#include "ha_federatedx.h"
diff --git a/storage/federatedx/federatedx_pushdown.cc b/storage/federatedx/federatedx_pushdown.cc
index 664f0570238..0d58e0d8270 100644
--- a/storage/federatedx/federatedx_pushdown.cc
+++ b/storage/federatedx/federatedx_pushdown.cc
@@ -35,6 +35,64 @@
*/
+/*
+ Check if table and database names are equal on local and remote servers
+
+ SYNOPSIS
+ local_and_remote_names_match()
+ tbl_share Pointer to current table TABLE_SHARE structure
+ fshare Pointer to current table FEDERATEDX_SHARE structure
+
+ DESCRIPTION
+ FederatedX table on the local server may refer to a table having another
+ name on the remote server. The remote table may even reside in a different
+ database. For example:
+
+ -- Remote server
+ CREATE TABLE t1 (id int(32));
+
+ -- Local server
+ CREATE TABLE t2 ENGINE="FEDERATEDX"
+ CONNECTION="mysql://joe:joespass@192.168.1.111:9308/federatedx/t1";
+
+ It's not a problem while the federated_pushdown is disabled 'cause
+ the CONNECTION strings are being parsed for every table during
+ the execution, so the table names are translated from local to remote.
+ But in case of the federated_pushdown the whole query is pushed down
+ to the engine without any translation, so the remote server may try
+ to select data from a nonexistent table (for example, query
+ "SELECT * FROM t2" will try to retrieve data from nonexistent "t2").
+
+ This function checks whether there is a mismatch between local and remote
+ table/database names
+
+ RETURN VALUE
+ false names are equal
+ true names are not equal
+
+*/
+bool local_and_remote_names_mismatch(const TABLE_SHARE *tbl_share,
+ const FEDERATEDX_SHARE *fshare)
+{
+
+ if (lower_case_table_names)
+ {
+ if (strcasecmp(fshare->database, tbl_share->db.str) != 0)
+ return true;
+ }
+ else
+ {
+ if (strncmp(fshare->database, tbl_share->db.str, tbl_share->db.length) != 0)
+ return true;
+ }
+
+ return my_strnncoll(system_charset_info, (uchar *) fshare->table_name,
+ strlen(fshare->table_name),
+ (uchar *) tbl_share->table_name.str,
+ tbl_share->table_name.length) != 0;
+}
+
+
static derived_handler*
create_federatedx_derived_handler(THD* thd, TABLE_LIST *derived)
{
@@ -42,7 +100,6 @@ create_federatedx_derived_handler(THD* thd, TABLE_LIST *derived)
return 0;
ha_federatedx_derived_handler* handler = NULL;
- handlerton *ht= 0;
SELECT_LEX_UNIT *unit= derived->derived;
@@ -54,9 +111,16 @@ create_federatedx_derived_handler(THD* thd, TABLE_LIST *derived)
{
if (!tbl->table)
return 0;
- if (!ht)
- ht= tbl->table->file->partition_ht();
- else if (ht != tbl->table->file->partition_ht())
+ /*
+ We intentionally don't support partitioned federatedx tables here, so
+ use file->ht and not file->partition_ht().
+ */
+ if (tbl->table->file->ht != federatedx_hton)
+ return 0;
+
+ const FEDERATEDX_SHARE *fshare=
+ ((ha_federatedx*)tbl->table->file)->get_federatedx_share();
+ if (local_and_remote_names_mismatch(tbl->table->s, fshare))
return 0;
}
}
@@ -170,15 +234,22 @@ create_federatedx_select_handler(THD* thd, SELECT_LEX *sel)
return 0;
ha_federatedx_select_handler* handler = NULL;
- handlerton *ht= 0;
for (TABLE_LIST *tbl= thd->lex->query_tables; tbl; tbl= tbl->next_global)
{
if (!tbl->table)
return 0;
- if (!ht)
- ht= tbl->table->file->partition_ht();
- else if (ht != tbl->table->file->partition_ht())
+ /*
+ We intentionally don't support partitioned federatedx tables here, so
+ use file->ht and not file->partition_ht().
+ */
+ if (tbl->table->file->ht != federatedx_hton)
+ return 0;
+
+ const FEDERATEDX_SHARE *fshare=
+ ((ha_federatedx*)tbl->table->file)->get_federatedx_share();
+
+ if (local_and_remote_names_mismatch(tbl->table->s, fshare))
return 0;
}
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index dbf83aec127..50d63e53b26 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -315,6 +315,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define MYSQL_SERVER 1
#include <my_global.h>
#include <mysql/plugin.h>
+#include <mysql.h>
#include "ha_federatedx.h"
#include "sql_servers.h"
#include "sql_analyse.h" // append_escaped()
@@ -610,7 +611,7 @@ error:
parse_url()
mem_root MEM_ROOT pointer for memory allocation
share pointer to FEDERATEDX share
- table pointer to current TABLE class
+ table_s pointer to current TABLE_SHARE class
table_create_flag determines what error to throw
DESCRIPTION
diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h
index 377af888d79..2bbb116d646 100644
--- a/storage/federatedx/ha_federatedx.h
+++ b/storage/federatedx/ha_federatedx.h
@@ -464,6 +464,7 @@ public:
int reset(void);
int free_result(void);
+ const FEDERATEDX_SHARE *get_federatedx_share() const { return share; }
friend class ha_federatedx_derived_handler;
friend class ha_federatedx_select_handler;
};
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 422d7cd6f4c..c1d73b1b9d4 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -280,8 +280,7 @@ SET(INNOBASE_SOURCES
include/handler0alter.h
include/hash0hash.h
include/ibuf0ibuf.h
- include/ibuf0ibuf.inl/
- include/ibuf0types.h
+ include/ibuf0ibuf.inl
include/lock0iter.h
include/lock0lock.h
include/lock0lock.inl
diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc
index 3d5a0c2fb00..223d903c803 100644
--- a/storage/innobase/btr/btr0bulk.cc
+++ b/storage/innobase/btr/btr0bulk.cc
@@ -563,8 +563,9 @@ inline void PageBulk::finish()
void PageBulk::commit(bool success)
{
finish();
- if (success && !dict_index_is_clust(m_index) && page_is_leaf(m_page))
- ibuf_set_bitmap_for_bulk_load(m_block, innobase_fill_factor == 100);
+ if (success && !m_index->is_clust() && page_is_leaf(m_page))
+ ibuf_set_bitmap_for_bulk_load(m_block, &m_mtr,
+ innobase_fill_factor == 100);
m_mtr.commit();
}
@@ -634,7 +635,7 @@ PageBulk::getSplitRec()
< total_used_size / 2);
/* Keep at least one record on left page */
- if (page_rec_is_second(rec, m_page)) {
+ if (page_rec_is_first(rec, m_page)) {
rec = page_rec_get_next(rec);
ut_ad(page_rec_is_user_rec(rec));
}
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index d52f061827f..af28557364b 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -2393,9 +2393,8 @@ need_opposite_intention:
page hash index, while holding search latch. */
if (!btr_search_enabled) {
} else if (tuple->info_bits & REC_INFO_MIN_REC_FLAG) {
- ut_ad(index->is_instant());
/* This may be a search tuple for
- btr_pcur_restore_position(). */
+ btr_pcur_t::restore_position(). */
ut_ad(tuple->is_metadata()
|| (tuple->is_metadata(tuple->info_bits
^ REC_STATUS_INSTANT)));
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 8eb2dc50cb9..6f7ae9b85c5 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -591,7 +591,7 @@ buf_page_is_corrupted(
DBUG_EXECUTE_IF(
"page_intermittent_checksum_mismatch", {
static int page_counter;
- if (page_counter++ == 2) {
+ if (page_counter++ == 3) {
crc32++;
}
});
@@ -726,7 +726,7 @@ buf_page_is_corrupted(
DBUG_EXECUTE_IF(
"page_intermittent_checksum_mismatch", {
static int page_counter;
- if (page_counter++ == 2) return true;
+ if (page_counter++ == 3) return true;
});
if ((checksum_field1 != crc32
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index fb1c1821aee..4ebffce7d0f 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1913,6 +1913,7 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn)
write out before we can advance the checkpoint. */
if (sync_lsn > log_sys.get_flushed_lsn())
log_write_up_to(sync_lsn, true);
+ DBUG_EXECUTE_IF("ib_log_checkpoint_avoid_hard", return;);
log_checkpoint();
}
}
@@ -1928,6 +1929,8 @@ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious)
if (recv_recovery_is_on())
recv_sys.apply(true);
+ DBUG_EXECUTE_IF("ib_log_checkpoint_avoid_hard", return;);
+
Atomic_relaxed<lsn_t> &limit= furious
? buf_flush_sync_lsn : buf_flush_async_lsn;
@@ -2280,6 +2283,7 @@ unemployed:
buf_pool.page_cleaner_set_idle(true);
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", continue;);
+ DBUG_EXECUTE_IF("ib_log_checkpoint_avoid_hard", continue;);
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
@@ -2363,6 +2367,7 @@ do_checkpoint:
here should not affect correctness, because log_free_check()
should still be invoking checkpoints when needed. */
DBUG_EXECUTE_IF("ib_log_checkpoint_avoid", goto next;);
+ DBUG_EXECUTE_IF("ib_log_checkpoint_avoid_hard", goto next;);
if (!recv_recovery_is_on() && srv_operation == SRV_OPERATION_NORMAL)
log_checkpoint();
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index b74cd043439..362b949e10f 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -685,8 +685,7 @@ dict_acquire_mdl_shared(dict_table_t *table,
}
else
{
- ut_ad(dict_sys.frozen());
- ut_ad(!dict_sys.locked());
+ ut_ad(dict_sys.frozen_not_locked());
db_len= dict_get_db_name_len(table->name.m_name);
}
@@ -1003,7 +1002,7 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line))
latch_ex_wait_start.store(0, std::memory_order_relaxed);
ut_ad(!latch_readers);
ut_ad(!latch_ex);
- ut_d(latch_ex= true);
+ ut_d(latch_ex= pthread_self());
return;
}
@@ -1021,15 +1020,15 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line))
latch.wr_lock(SRW_LOCK_ARGS(file, line));
ut_ad(!latch_readers);
ut_ad(!latch_ex);
- ut_d(latch_ex= true);
+ ut_d(latch_ex= pthread_self());
}
#ifdef UNIV_PFS_RWLOCK
ATTRIBUTE_NOINLINE void dict_sys_t::unlock()
{
- ut_ad(latch_ex);
+ ut_ad(latch_ex == pthread_self());
ut_ad(!latch_readers);
- ut_d(latch_ex= false);
+ ut_d(latch_ex= 0);
latch.wr_unlock();
}
@@ -1488,6 +1487,7 @@ dict_table_t::rename_tablespace(span<const char> new_name, bool replace) const
err= DB_TABLESPACE_EXISTS;
else
{
+ space->x_lock();
err= space->rename(path, true, replace);
if (data_dir)
{
@@ -1495,6 +1495,7 @@ dict_table_t::rename_tablespace(span<const char> new_name, bool replace) const
new_name= {name.m_name, strlen(name.m_name)};
RemoteDatafile::delete_link_file(new_name);
}
+ space->x_unlock();
}
ut_free(path);
@@ -2747,17 +2748,6 @@ dict_index_build_internal_fts(
}
/*====================== FOREIGN KEY PROCESSING ========================*/
-/*********************************************************************//**
-Checks if a table is referenced by foreign keys.
-@return TRUE if table is referenced by a foreign key */
-ibool
-dict_table_is_referenced_by_foreign_key(
-/*====================================*/
- const dict_table_t* table) /*!< in: InnoDB table */
-{
- return(!table->referenced_set.empty());
-}
-
/**********************************************************************//**
Removes a foreign constraint struct from the dictionary cache. */
void
diff --git a/storage/innobase/dict/drop.cc b/storage/innobase/dict/drop.cc
index edb6add0787..9013841ba5e 100644
--- a/storage/innobase/dict/drop.cc
+++ b/storage/innobase/dict/drop.cc
@@ -267,8 +267,7 @@ void trx_t::commit(std::vector<pfs_os_file_t> &deleted)
if (btr_defragment_active)
btr_defragment_remove_table(table);
const fil_space_t *space= table->space;
- ut_ad(!strstr(table->name.m_name, "/FTS_") ||
- purge_sys.must_wait_FTS());
+ ut_ad(!p.second.is_aux_table() || purge_sys.must_wait_FTS());
dict_sys.remove(table);
if (const auto id= space ? space->id : 0)
{
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 31c6523c700..efa15251bbe 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1373,6 +1373,13 @@ static dberr_t fts_drop_table(trx_t *trx, const char *table_name, bool rename)
return err;
}
+#ifdef UNIV_DEBUG
+ for (auto &p : trx->mod_tables)
+ {
+ if (p.first == table)
+ p.second.set_aux_table();
+ }
+#endif /* UNIV_DEBUG */
return DB_SUCCESS;
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index d2b6bd62520..dba0352b5ce 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -54,7 +54,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <my_bitmap.h>
#include <mysql/service_thd_alloc.h>
#include <mysql/service_thd_wait.h>
-#include "field.h"
+#include "sql_type_geom.h"
#include "scope.h"
#include "srv0srv.h"
@@ -11473,6 +11473,8 @@ innobase_fts_load_stopword(
trx_t* trx, /*!< in: transaction */
THD* thd) /*!< in: current thread */
{
+ ut_ad(dict_sys.locked());
+
const char *stopword_table= THDVAR(thd, ft_user_stopword_table);
if (!stopword_table)
{
@@ -11482,9 +11484,11 @@ innobase_fts_load_stopword(
mysql_mutex_unlock(&LOCK_global_system_variables);
}
- return !high_level_read_only &&
- fts_load_stopword(table, trx, stopword_table,
- THDVAR(thd, ft_enable_stopword), false);
+ table->fts->dict_locked= true;
+ bool success= fts_load_stopword(table, trx, stopword_table,
+ THDVAR(thd, ft_enable_stopword), false);
+ table->fts->dict_locked= false;
+ return success;
}
/** Parse the table name into normal name and remote path if needed.
@@ -12820,15 +12824,18 @@ int create_table_info_t::create_table(bool create_fk)
dberr_t err = create_fk ? create_foreign_keys() : DB_SUCCESS;
if (err == DB_SUCCESS) {
+ const dict_err_ignore_t ignore_err = m_trx->check_foreigns
+ ? DICT_ERR_IGNORE_NONE : DICT_ERR_IGNORE_FK_NOKEY;
+
/* Check that also referencing constraints are ok */
dict_names_t fk_tables;
err = dict_load_foreigns(m_table_name, nullptr,
m_trx->id, true,
- DICT_ERR_IGNORE_NONE, fk_tables);
+ ignore_err, fk_tables);
while (err == DB_SUCCESS && !fk_tables.empty()) {
dict_sys.load_table(
{fk_tables.front(), strlen(fk_tables.front())},
- DICT_ERR_IGNORE_NONE);
+ ignore_err);
fk_tables.pop_front();
}
}
@@ -13109,96 +13116,59 @@ bool create_table_info_t::row_size_is_acceptable(
return true;
}
-/** Update a new table in an InnoDB database.
-@return error number */
-int
-create_table_info_t::create_table_update_dict()
+void create_table_info_t::create_table_update_dict(dict_table_t *table,
+ THD *thd,
+ const HA_CREATE_INFO &info,
+ const TABLE &t)
{
- dict_table_t* innobase_table;
-
- DBUG_ENTER("create_table_update_dict");
-
- innobase_table = dict_table_open_on_name(
- m_table_name, false, DICT_ERR_IGNORE_NONE);
-
- DBUG_ASSERT(innobase_table != 0);
- if (innobase_table->fts != NULL) {
- if (innobase_table->fts_doc_id_index == NULL) {
- innobase_table->fts_doc_id_index
- = dict_table_get_index_on_name(
- innobase_table, FTS_DOC_ID_INDEX_NAME);
- DBUG_ASSERT(innobase_table->fts_doc_id_index != NULL);
- } else {
- DBUG_ASSERT(innobase_table->fts_doc_id_index
- == dict_table_get_index_on_name(
- innobase_table,
- FTS_DOC_ID_INDEX_NAME));
- }
- }
-
- DBUG_ASSERT((innobase_table->fts == NULL)
- == (innobase_table->fts_doc_id_index == NULL));
-
- innobase_copy_frm_flags_from_create_info(innobase_table, m_create_info);
+ ut_ad(dict_sys.locked());
- dict_stats_update(innobase_table, DICT_STATS_EMPTY_TABLE);
-
- /* Load server stopword into FTS cache */
- if (m_flags2 & DICT_TF2_FTS) {
- if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) {
- innobase_table->release();
- DBUG_RETURN(-1);
- }
-
- dict_sys.lock(SRW_LOCK_CALL);
- fts_optimize_add_table(innobase_table);
- dict_sys.unlock();
- }
+ DBUG_ASSERT(table->get_ref_count());
+ if (table->fts)
+ {
+ if (!table->fts_doc_id_index)
+ table->fts_doc_id_index=
+ dict_table_get_index_on_name(table, FTS_DOC_ID_INDEX_NAME);
+ else
+ DBUG_ASSERT(table->fts_doc_id_index ==
+ dict_table_get_index_on_name(table, FTS_DOC_ID_INDEX_NAME));
+ }
- if (const Field* ai = m_form->found_next_number_field) {
- ut_ad(ai->stored_in_db());
+ DBUG_ASSERT(!table->fts == !table->fts_doc_id_index);
- ib_uint64_t autoinc = m_create_info->auto_increment_value;
+ innobase_copy_frm_flags_from_create_info(table, &info);
- if (autoinc == 0) {
- autoinc = 1;
- }
+ /* Load server stopword into FTS cache */
+ if (table->flags2 & DICT_TF2_FTS &&
+ innobase_fts_load_stopword(table, nullptr, thd))
+ fts_optimize_add_table(table);
- innobase_table->autoinc_mutex.wr_lock();
- dict_table_autoinc_initialize(innobase_table, autoinc);
+ if (const Field *ai = t.found_next_number_field)
+ {
+ ut_ad(ai->stored_in_db());
+ ib_uint64_t autoinc= info.auto_increment_value;
+ if (autoinc == 0)
+ autoinc= 1;
- if (innobase_table->is_temporary()) {
- /* AUTO_INCREMENT is not persistent for
- TEMPORARY TABLE. Temporary tables are never
- evicted. Keep the counter in memory only. */
- } else {
- const unsigned col_no = innodb_col_no(ai);
-
- innobase_table->persistent_autoinc
- = static_cast<uint16_t>(
- dict_table_get_nth_col_pos(
- innobase_table, col_no, NULL)
- + 1)
- & dict_index_t::MAX_N_FIELDS;
-
- /* Persist the "last used" value, which
- typically is AUTO_INCREMENT - 1.
- In btr_create(), the value 0 was already written. */
- if (--autoinc) {
- btr_write_autoinc(
- dict_table_get_first_index(
- innobase_table),
- autoinc);
- }
- }
+ table->autoinc_mutex.wr_lock();
+ dict_table_autoinc_initialize(table, autoinc);
- innobase_table->autoinc_mutex.wr_unlock();
- }
+ if (!table->is_temporary())
+ {
+ const unsigned col_no= innodb_col_no(ai);
+ table->persistent_autoinc= static_cast<uint16_t>
+ (dict_table_get_nth_col_pos(table, col_no, nullptr) + 1) &
+ dict_index_t::MAX_N_FIELDS;
+ /* Persist the "last used" value, which typically is AUTO_INCREMENT - 1.
+ In btr_create(), the value 0 was already written. */
+ if (--autoinc)
+ btr_write_autoinc(dict_table_get_first_index(table), autoinc);
+ }
- innobase_parse_hint_from_comment(m_thd, innobase_table, m_form->s);
+ table->autoinc_mutex.wr_unlock();
+ }
- dict_table_close(innobase_table);
- DBUG_RETURN(0);
+ innobase_parse_hint_from_comment(thd, table, t.s);
}
/** Allocate a new trx. */
@@ -13215,89 +13185,80 @@ create_table_info_t::allocate_trx()
@param[in] create_info Create info (including create statement string).
@param[in] file_per_table whether to create .ibd file
@param[in,out] trx dictionary transaction, or NULL to create new
-@return 0 if success else error number. */
-inline int
-ha_innobase::create(
- const char* name,
- TABLE* form,
- HA_CREATE_INFO* create_info,
- bool file_per_table,
- trx_t* trx)
+@return error code
+@retval 0 on success */
+int
+ha_innobase::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info,
+ bool file_per_table, trx_t *trx= nullptr)
{
- char norm_name[FN_REFLEN]; /* {database}/{tablename} */
- char remote_path[FN_REFLEN]; /* Absolute path of table */
+ char norm_name[FN_REFLEN]; /* {database}/{tablename} */
+ char remote_path[FN_REFLEN]; /* Absolute path of table */
- DBUG_ENTER("ha_innobase::create");
+ DBUG_ENTER("ha_innobase::create");
+ DBUG_ASSERT(form->s == table_share);
+ DBUG_ASSERT(table_share->table_type == TABLE_TYPE_SEQUENCE ||
+ table_share->table_type == TABLE_TYPE_NORMAL);
- DBUG_ASSERT(form->s == table_share);
- DBUG_ASSERT(table_share->table_type == TABLE_TYPE_SEQUENCE
- || table_share->table_type == TABLE_TYPE_NORMAL);
+ create_table_info_t info(ha_thd(), form, create_info, norm_name,
+ remote_path, file_per_table, trx);
- create_table_info_t info(ha_thd(),
- form,
- create_info,
- norm_name,
- remote_path,
- file_per_table, trx);
+ int error= info.initialize();
+ if (!error)
+ error= info.prepare_create_table(name, !trx);
+ if (error)
+ DBUG_RETURN(error);
- {
- int error = info.initialize();
- if (!error) {
- error = info.prepare_create_table(name, !trx);
- }
- if (error) {
- if (trx) {
- trx_rollback_for_mysql(trx);
- row_mysql_unlock_data_dictionary(trx);
- }
- DBUG_RETURN(error);
- }
- }
+ const bool own_trx= !trx;
+ if (own_trx)
+ {
+ info.allocate_trx();
+ trx= info.trx();
+ DBUG_ASSERT(trx_state_eq(trx, TRX_STATE_NOT_STARTED));
- const bool own_trx = !trx;
- int error = 0;
+ if (!(info.flags2() & DICT_TF2_TEMPORARY))
+ {
+ trx_start_for_ddl(trx);
+ if (dberr_t err= lock_sys_tables(trx))
+ error= convert_error_code_to_mysql(err, 0, nullptr);
+ }
+ row_mysql_lock_data_dictionary(trx);
+ }
- if (own_trx) {
- info.allocate_trx();
- trx = info.trx();
- DBUG_ASSERT(trx_state_eq(trx, TRX_STATE_NOT_STARTED));
- }
- if (own_trx && !(info.flags2() & DICT_TF2_TEMPORARY)) {
- trx_start_for_ddl(trx);
- if (dberr_t err = lock_sys_tables(trx)) {
- error = convert_error_code_to_mysql(err, 0, nullptr);
- }
- }
- if (own_trx) {
- row_mysql_lock_data_dictionary(trx);
- }
+ if (!error)
+ error= info.create_table(own_trx);
- if (!error) {
- error = info.create_table(own_trx);
- }
+ if (own_trx || (info.flags2() & DICT_TF2_TEMPORARY))
+ {
+ if (error)
+ trx_rollback_for_mysql(trx);
+ else
+ {
+ std::vector<pfs_os_file_t> deleted;
+ trx->commit(deleted);
+ ut_ad(deleted.empty());
+ info.table()->acquire();
+ info.create_table_update_dict(info.table(), info.thd(),
+ *create_info, *form);
+ }
- if (error) {
- /* Rollback will drop the being-created table. */
- trx_rollback_for_mysql(trx);
- row_mysql_unlock_data_dictionary(trx);
- } else {
- /* When this is invoked as part of ha_innobase::truncate(),
- the old copy of the table will be deleted here. */
- std::vector<pfs_os_file_t> deleted;
- trx->commit(deleted);
- row_mysql_unlock_data_dictionary(trx);
- for (pfs_os_file_t d : deleted) os_file_close(d);
- error = info.create_table_update_dict();
- if (!(info.flags2() & DICT_TF2_TEMPORARY)) {
- log_write_up_to(trx->commit_lsn, true);
- }
- }
+ if (own_trx)
+ {
+ row_mysql_unlock_data_dictionary(trx);
- if (own_trx) {
- trx->free();
- }
+ if (!error)
+ {
+ dict_stats_update(info.table(), DICT_STATS_EMPTY_TABLE);
+ if (!info.table()->is_temporary())
+ log_write_up_to(trx->commit_lsn, true);
+ info.table()->release();
+ }
+ trx->free();
+ }
+ }
+ else if (!error && m_prebuilt)
+ m_prebuilt->table= info.table();
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
/** Create a new table to an InnoDB database.
@@ -13305,13 +13266,10 @@ ha_innobase::create(
@param[in] form Table format; columns and index information.
@param[in] create_info Create info (including create statement string).
@return 0 if success else error number. */
-int
-ha_innobase::create(
- const char* name,
- TABLE* form,
- HA_CREATE_INFO* create_info)
+int ha_innobase::create(const char *name, TABLE *form,
+ HA_CREATE_INFO *create_info)
{
- return create(name, form, create_info, srv_file_per_table);
+ return create(name, form, create_info, srv_file_per_table);
}
/*****************************************************************//**
@@ -13840,229 +13798,247 @@ static dberr_t innobase_rename_table(trx_t *trx, const char *from,
@retval 0 on success */
int ha_innobase::truncate()
{
- DBUG_ENTER("ha_innobase::truncate");
+ DBUG_ENTER("ha_innobase::truncate");
- update_thd();
+ update_thd();
- if (is_read_only()) {
- DBUG_RETURN(HA_ERR_TABLE_READONLY);
- }
+ if (is_read_only())
+ DBUG_RETURN(HA_ERR_TABLE_READONLY);
- HA_CREATE_INFO info;
- dict_table_t* ib_table = m_prebuilt->table;
- info.init();
- update_create_info_from_table(&info, table);
- switch (dict_tf_get_rec_format(ib_table->flags)) {
- case REC_FORMAT_REDUNDANT:
- info.row_type = ROW_TYPE_REDUNDANT;
- break;
- case REC_FORMAT_COMPACT:
- info.row_type = ROW_TYPE_COMPACT;
- break;
- case REC_FORMAT_COMPRESSED:
- info.row_type = ROW_TYPE_COMPRESSED;
- break;
- case REC_FORMAT_DYNAMIC:
- info.row_type = ROW_TYPE_DYNAMIC;
- break;
- }
+ HA_CREATE_INFO info;
+ dict_table_t *ib_table= m_prebuilt->table;
+ info.init();
+ update_create_info_from_table(&info, table);
+ switch (dict_tf_get_rec_format(ib_table->flags)) {
+ case REC_FORMAT_REDUNDANT:
+ info.row_type= ROW_TYPE_REDUNDANT;
+ break;
+ case REC_FORMAT_COMPACT:
+ info.row_type= ROW_TYPE_COMPACT;
+ break;
+ case REC_FORMAT_COMPRESSED:
+ info.row_type= ROW_TYPE_COMPRESSED;
+ break;
+ case REC_FORMAT_DYNAMIC:
+ info.row_type= ROW_TYPE_DYNAMIC;
+ break;
+ }
- const auto stored_lock = m_prebuilt->stored_select_lock_type;
- trx_t* trx = innobase_trx_allocate(m_user_thd);
- trx_start_for_ddl(trx);
+ const auto stored_lock= m_prebuilt->stored_select_lock_type;
+ trx_t *trx= innobase_trx_allocate(m_user_thd);
+ trx_start_for_ddl(trx);
- if (ib_table->is_temporary()) {
- info.options|= HA_LEX_CREATE_TMP_TABLE;
- btr_drop_temporary_table(*ib_table);
- m_prebuilt->table = nullptr;
- row_prebuilt_free(m_prebuilt);
- m_prebuilt = nullptr;
- my_free(m_upd_buf);
- m_upd_buf = nullptr;
- m_upd_buf_size = 0;
+ if (ib_table->is_temporary())
+ {
+ info.options|= HA_LEX_CREATE_TMP_TABLE;
+ btr_drop_temporary_table(*ib_table);
+ m_prebuilt->table= nullptr;
+ row_prebuilt_free(m_prebuilt);
+ m_prebuilt= nullptr;
+ my_free(m_upd_buf);
+ m_upd_buf= nullptr;
+ m_upd_buf_size= 0;
- row_mysql_lock_data_dictionary(trx);
- ib_table->release();
- dict_sys.remove(ib_table, false, true);
+ row_mysql_lock_data_dictionary(trx);
+ ib_table->release();
+ dict_sys.remove(ib_table, false, true);
+ int err= create(ib_table->name.m_name, table, &info, true, trx);
+ row_mysql_unlock_data_dictionary(trx);
- int err = create(ib_table->name.m_name, table, &info, true,
- trx);
- ut_ad(!err);
- if (!err) {
- err = open(ib_table->name.m_name, 0, 0);
- m_prebuilt->stored_select_lock_type = stored_lock;
- }
+ ut_ad(!err);
+ if (!err)
+ {
+ err= open(ib_table->name.m_name, 0, 0);
+ m_prebuilt->table->release();
+ m_prebuilt->stored_select_lock_type= stored_lock;
+ }
- trx->free();
+ trx->free();
#ifdef BTR_CUR_HASH_ADAPT
- if (UT_LIST_GET_LEN(ib_table->freed_indexes)) {
- ib_table->vc_templ = nullptr;
- ib_table->id = 0;
- DBUG_RETURN(err);
- }
+ if (UT_LIST_GET_LEN(ib_table->freed_indexes))
+ {
+ ib_table->vc_templ= nullptr;
+ ib_table->id= 0;
+ }
+ else
#endif /* BTR_CUR_HASH_ADAPT */
+ dict_mem_table_free(ib_table);
- dict_mem_table_free(ib_table);
- DBUG_RETURN(err);
- }
+ DBUG_RETURN(err);
+ }
- mem_heap_t* heap = mem_heap_create(1000);
+ mem_heap_t *heap= mem_heap_create(1000);
- dict_get_and_save_data_dir_path(ib_table);
- info.data_file_name = ib_table->data_dir_path;
- const char* temp_name = dict_mem_create_temporary_tablename(
- heap, ib_table->name.m_name, ib_table->id);
- const char* name = mem_heap_strdup(heap, ib_table->name.m_name);
+ dict_get_and_save_data_dir_path(ib_table);
+ info.data_file_name= ib_table->data_dir_path;
+ const char *temp_name=
+ dict_mem_create_temporary_tablename(heap,
+ ib_table->name.m_name, ib_table->id);
+ const char *name= mem_heap_strdup(heap, ib_table->name.m_name);
- dict_table_t *table_stats = nullptr, *index_stats = nullptr;
- MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr;
+ dict_table_t *table_stats = nullptr, *index_stats = nullptr;
+ MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr;
- dberr_t error = DB_SUCCESS;
+ dberr_t error= DB_SUCCESS;
- dict_sys.freeze(SRW_LOCK_CALL);
- for (const dict_foreign_t* f : ib_table->referenced_set) {
- if (dict_table_t* child = f->foreign_table) {
- error = lock_table_for_trx(child, trx, LOCK_X);
- if (error != DB_SUCCESS) {
- break;
- }
- }
- }
- dict_sys.unfreeze();
+ dict_sys.freeze(SRW_LOCK_CALL);
+ for (const dict_foreign_t *f : ib_table->referenced_set)
+ if (dict_table_t *child= f->foreign_table)
+ if ((error= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS)
+ break;
+ dict_sys.unfreeze();
- if (error == DB_SUCCESS) {
- error = lock_table_for_trx(ib_table, trx, LOCK_X);
- }
+ if (error == DB_SUCCESS)
+ error= lock_table_for_trx(ib_table, trx, LOCK_X);
- const bool fts = error == DB_SUCCESS
- && ib_table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS);
+ const bool fts= error == DB_SUCCESS &&
+ ib_table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS);
- if (fts) {
- fts_optimize_remove_table(ib_table);
- purge_sys.stop_FTS(*ib_table);
- error = fts_lock_tables(trx, *ib_table);
- }
+ if (fts)
+ {
+ fts_optimize_remove_table(ib_table);
+ purge_sys.stop_FTS(*ib_table);
+ error= fts_lock_tables(trx, *ib_table);
+ }
- /* Wait for purge threads to stop using the table. */
- for (uint n = 15; ib_table->get_ref_count() > 1; ) {
- if (!--n) {
- error = DB_LOCK_WAIT_TIMEOUT;
- break;
- }
+ /* Wait for purge threads to stop using the table. */
+ for (uint n = 15; ib_table->get_ref_count() > 1; )
+ {
+ if (!--n)
+ {
+ error= DB_LOCK_WAIT_TIMEOUT;
+ break;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
+ }
- std::this_thread::sleep_for(std::chrono::milliseconds(50));
- }
+ if (error == DB_SUCCESS && dict_stats_is_persistent_enabled(ib_table) &&
+ !ib_table->is_stats_table())
+ {
+ table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false,
+ DICT_ERR_IGNORE_NONE);
+ if (table_stats)
+ {
+ dict_sys.freeze(SRW_LOCK_CALL);
+ table_stats= dict_acquire_mdl_shared<false>(table_stats, m_user_thd,
+ &mdl_table);
+ dict_sys.unfreeze();
+ }
+ index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false,
+ DICT_ERR_IGNORE_NONE);
+ if (index_stats)
+ {
+ dict_sys.freeze(SRW_LOCK_CALL);
+ index_stats= dict_acquire_mdl_shared<false>(index_stats, m_user_thd,
+ &mdl_index);
+ dict_sys.unfreeze();
+ }
- if (error == DB_SUCCESS && dict_stats_is_persistent_enabled(ib_table)
- && !ib_table->is_stats_table()) {
- table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false,
- DICT_ERR_IGNORE_NONE);
- if (table_stats) {
- dict_sys.freeze(SRW_LOCK_CALL);
- table_stats = dict_acquire_mdl_shared<false>(
- table_stats, m_user_thd, &mdl_table);
- dict_sys.unfreeze();
- }
- index_stats = dict_table_open_on_name(INDEX_STATS_NAME, false,
- DICT_ERR_IGNORE_NONE);
- if (index_stats) {
- dict_sys.freeze(SRW_LOCK_CALL);
- index_stats = dict_acquire_mdl_shared<false>(
- index_stats, m_user_thd, &mdl_index);
- dict_sys.unfreeze();
- }
+ if (table_stats && index_stats &&
+ !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) &&
+ !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) &&
+ !(error= lock_table_for_trx(table_stats, trx, LOCK_X)))
+ error= lock_table_for_trx(index_stats, trx, LOCK_X);
+ }
- if (table_stats && index_stats
- && !strcmp(table_stats->name.m_name, TABLE_STATS_NAME)
- && !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) &&
- !(error = lock_table_for_trx(table_stats, trx, LOCK_X))) {
- error = lock_table_for_trx(index_stats, trx, LOCK_X);
- }
- }
+ if (error == DB_SUCCESS)
+ error= lock_sys_tables(trx);
- if (error == DB_SUCCESS) {
- error = lock_sys_tables(trx);
- }
+ std::vector<pfs_os_file_t> deleted;
- row_mysql_lock_data_dictionary(trx);
+ row_mysql_lock_data_dictionary(trx);
- if (error == DB_SUCCESS) {
- error = innobase_rename_table(trx, ib_table->name.m_name,
- temp_name, false);
+ if (error == DB_SUCCESS)
+ {
+ error= innobase_rename_table(trx, ib_table->name.m_name, temp_name, false);
+ if (error == DB_SUCCESS)
+ error= trx->drop_table(*ib_table);
+ }
- if (error == DB_SUCCESS) {
- error = trx->drop_table(*ib_table);
- }
- }
+ int err = convert_error_code_to_mysql(error, ib_table->flags, m_user_thd);
+ const auto update_time = ib_table->update_time;
- int err = convert_error_code_to_mysql(error, ib_table->flags,
- m_user_thd);
- if (err) {
- trx_rollback_for_mysql(trx);
- if (fts) {
- fts_optimize_add_table(ib_table);
- purge_sys.resume_FTS();
- }
- row_mysql_unlock_data_dictionary(trx);
- } else {
- const auto update_time = ib_table->update_time;
- const auto stored_lock = m_prebuilt->stored_select_lock_type;
- const auto def_trx_id = ib_table->def_trx_id;
- ib_table->release();
- m_prebuilt->table = nullptr;
+ if (err)
+ {
+ trx_rollback_for_mysql(trx);
+ if (fts)
+ fts_optimize_add_table(ib_table);
+ }
+ else
+ {
+ const auto def_trx_id= ib_table->def_trx_id;
+ ib_table->release();
+ m_prebuilt->table= nullptr;
- err = create(name, table, &info,
- dict_table_is_file_per_table(ib_table), trx);
- /* On success, create() durably committed trx. */
- if (fts) {
- purge_sys.resume_FTS();
- }
+ err= create(name, table, &info, dict_table_is_file_per_table(ib_table),
+ trx);
+ if (!err)
+ {
+ m_prebuilt->table->acquire();
+ create_table_info_t::create_table_update_dict(m_prebuilt->table,
+ m_user_thd, info, *table);
+ trx->commit(deleted);
+ }
+ else
+ {
+ trx_rollback_for_mysql(trx);
+ m_prebuilt->table= dict_table_open_on_name(name, true,
+ DICT_ERR_IGNORE_FK_NOKEY);
+ m_prebuilt->table->def_trx_id= def_trx_id;
+ }
+ dict_names_t fk_tables;
+ dict_load_foreigns(m_prebuilt->table->name.m_name, nullptr, 1, true,
+ DICT_ERR_IGNORE_FK_NOKEY, fk_tables);
+ for (const char *f : fk_tables)
+ dict_sys.load_table({f, strlen(f)});
+ }
- if (err) {
-reload:
- m_prebuilt->table = dict_table_open_on_name(
- name, false, DICT_ERR_IGNORE_NONE);
- m_prebuilt->table->def_trx_id = def_trx_id;
- } else {
- row_prebuilt_t* prebuilt = m_prebuilt;
- uchar* upd_buf = m_upd_buf;
- ulint upd_buf_size = m_upd_buf_size;
- /* Mimic ha_innobase::close(). */
- m_prebuilt = nullptr;
- m_upd_buf = nullptr;
- m_upd_buf_size = 0;
+ if (fts)
+ purge_sys.resume_FTS();
- err = open(name, 0, 0);
+ row_mysql_unlock_data_dictionary(trx);
+ for (pfs_os_file_t d : deleted) os_file_close(d);
- if (!err) {
- m_prebuilt->stored_select_lock_type
- = stored_lock;
- m_prebuilt->table->update_time = update_time;
- row_prebuilt_free(prebuilt);
- my_free(upd_buf);
- } else {
- /* Revert to the old table. */
- m_prebuilt = prebuilt;
- m_upd_buf = upd_buf;
- m_upd_buf_size = upd_buf_size;
- goto reload;
- }
- }
- }
+ if (!err)
+ {
+ dict_stats_update(m_prebuilt->table, DICT_STATS_EMPTY_TABLE);
+ log_write_up_to(trx->commit_lsn, true);
+ row_prebuilt_t *prebuilt= m_prebuilt;
+ uchar *upd_buf= m_upd_buf;
+ ulint upd_buf_size= m_upd_buf_size;
+ /* Mimic ha_innobase::close(). */
+ m_prebuilt= nullptr;
+ m_upd_buf= nullptr;
+ m_upd_buf_size= 0;
+
+ err= open(name, 0, 0);
+ if (!err)
+ {
+ m_prebuilt->stored_select_lock_type= stored_lock;
+ m_prebuilt->table->update_time= update_time;
+ row_prebuilt_free(prebuilt);
+ my_free(upd_buf);
+ }
+ else
+ {
+ /* Revert to the old table. */
+ m_prebuilt= prebuilt;
+ m_upd_buf= upd_buf;
+ m_upd_buf_size= upd_buf_size;
+ }
+ }
- trx->free();
+ trx->free();
- mem_heap_free(heap);
+ mem_heap_free(heap);
- if (table_stats) {
- dict_table_close(table_stats, false, m_user_thd, mdl_table);
- }
- if (index_stats) {
- dict_table_close(index_stats, false, m_user_thd, mdl_index);
- }
+ if (table_stats)
+ dict_table_close(table_stats, false, m_user_thd, mdl_table);
+ if (index_stats)
+ dict_table_close(index_stats, false, m_user_thd, mdl_index);
- DBUG_RETURN(err);
+ DBUG_RETURN(err);
}
/*********************************************************************//**
@@ -15656,30 +15632,12 @@ delete is then allowed internally to resolve a duplicate key conflict in
REPLACE, not an update.
@return > 0 if referenced by a FOREIGN KEY */
-uint
-ha_innobase::referenced_by_foreign_key(void)
-/*========================================*/
-{
- if (dict_table_is_referenced_by_foreign_key(m_prebuilt->table)) {
-
- return(1);
- }
-
- return(0);
-}
-
-/*******************************************************************//**
-Frees the foreign key create info for a table stored in InnoDB, if it is
-non-NULL. */
-
-void
-ha_innobase::free_foreign_key_create_info(
-/*======================================*/
- char* str) /*!< in, own: create info string to free */
+uint ha_innobase::referenced_by_foreign_key()
{
- if (str != NULL) {
- my_free(str);
- }
+ dict_sys.freeze(SRW_LOCK_CALL);
+ const bool empty= m_prebuilt->table->referenced_set.empty();
+ dict_sys.unfreeze();
+ return !empty;
}
/*******************************************************************//**
@@ -20631,6 +20589,26 @@ bool ha_innobase::can_convert_blob(const Field_blob *field,
return true;
}
+
+bool ha_innobase::can_convert_nocopy(const Field &field,
+ const Column_definition &new_type) const
+{
+ if (const Field_string *tf= dynamic_cast<const Field_string *>(&field))
+ return can_convert_string(tf, new_type);
+
+ if (const Field_varstring *tf= dynamic_cast<const Field_varstring *>(&field))
+ return can_convert_varstring(tf, new_type);
+
+ if (dynamic_cast<const Field_geom *>(&field))
+ return false;
+
+ if (const Field_blob *tf= dynamic_cast<const Field_blob *>(&field))
+ return can_convert_blob(tf, new_type);
+
+ return false;
+}
+
+
Compare_keys ha_innobase::compare_key_parts(
const Field &old_field, const Column_definition &new_field,
const KEY_PART_INFO &old_part, const KEY_PART_INFO &new_part) const
@@ -20641,7 +20619,7 @@ Compare_keys ha_innobase::compare_key_parts(
if (!is_equal)
{
- if (!old_field.can_be_converted_by_engine(new_field))
+ if (!old_field.table->file->can_convert_nocopy(old_field, new_field))
return Compare_keys::NotEqual;
if (!Charset(old_cs).eq_collation_specific_names(new_cs))
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index 01acde3d8e6..1f42bf180a8 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -190,12 +190,12 @@ public:
void update_create_info(HA_CREATE_INFO* create_info) override;
- inline int create(
+ int create(
const char* name,
TABLE* form,
HA_CREATE_INFO* create_info,
bool file_per_table,
- trx_t* trx = NULL);
+ trx_t* trx);
int create(
const char* name,
@@ -225,7 +225,7 @@ public:
uint referenced_by_foreign_key() override;
- void free_foreign_key_create_info(char* str) override;
+ void free_foreign_key_create_info(char* str) override { my_free(str); }
uint lock_count(void) const override;
@@ -422,15 +422,9 @@ public:
@retval false if pushed (always) */
bool rowid_filter_push(Rowid_filter *rowid_filter) override;
- bool
- can_convert_string(const Field_string* field,
- const Column_definition& new_field) const override;
- bool can_convert_varstring(
- const Field_varstring* field,
- const Column_definition& new_field) const override;
- bool
- can_convert_blob(const Field_blob* field,
- const Column_definition& new_field) const override;
+ bool can_convert_nocopy(const Field &field,
+ const Column_definition& new_field) const
+ override;
/** @return whether innodb_strict_mode is active */
static bool is_innodb_strict_mode(THD* thd);
@@ -445,6 +439,16 @@ public:
const KEY_PART_INFO& new_part) const override;
protected:
+ bool
+ can_convert_string(const Field_string* field,
+ const Column_definition& new_field) const;
+ bool can_convert_varstring(
+ const Field_varstring* field,
+ const Column_definition& new_field) const;
+ bool
+ can_convert_blob(const Field_blob* field,
+ const Column_definition& new_field) const;
+
dberr_t innobase_get_autoinc(ulonglong* value);
dberr_t innobase_lock_autoinc();
ulonglong innobase_peek_autoinc();
@@ -639,8 +643,9 @@ public:
@param create_fk whether to add FOREIGN KEY constraints */
int create_table(bool create_fk = true);
- /** Update the internal data dictionary. */
- int create_table_update_dict();
+ static void create_table_update_dict(dict_table_t* table, THD* thd,
+ const HA_CREATE_INFO& info,
+ const TABLE& t);
/** Validates the create options. Checks that the options
KEY_BLOCK_SIZE, ROW_FORMAT, DATA DIRECTORY, TEMPORARY & TABLESPACE
@@ -700,12 +705,13 @@ public:
trx_t* trx() const
{ return(m_trx); }
- /** Return table name. */
- const char* table_name() const
- { return(m_table_name); }
+ /** @return table name */
+ const char* table_name() const { return(m_table_name); }
+
+ /** @return the created table */
+ dict_table_t *table() const { return m_table; }
- THD* thd() const
- { return(m_thd); }
+ THD* thd() const { return(m_thd); }
private:
/** Parses the table name into normal name and either temp path or
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index fa86a920dd8..8ef58d64167 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -7286,13 +7286,10 @@ error_handling_drop_uncached:
goto error_handling;
}
- ctx->new_table->fts->dict_locked = true;
-
error = innobase_fts_load_stopword(
ctx->new_table, ctx->trx,
ctx->prebuilt->trx->mysql_thd)
? DB_SUCCESS : DB_ERROR;
- ctx->new_table->fts->dict_locked = false;
if (error != DB_SUCCESS) {
goto error_handling;
@@ -9882,7 +9879,7 @@ innobase_update_foreign_cache(
err = dict_load_foreigns(user_table->name.m_name,
ctx->col_names, 1, true,
- DICT_ERR_IGNORE_NONE,
+ DICT_ERR_IGNORE_FK_NOKEY,
fk_tables);
if (err == DB_CANNOT_ADD_CONSTRAINT) {
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 82b8968876f..bb2f1b6beda 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -6491,7 +6491,9 @@ static int i_s_sys_tablespaces_fill_table(THD *thd, TABLE_LIST *tables, Item*)
{
space.reacquire();
mysql_mutex_unlock(&fil_system.mutex);
+ space.s_lock();
err= i_s_sys_tablespaces_fill(thd, space, tables->table);
+ space.s_unlock();
mysql_mutex_lock(&fil_system.mutex);
space.release();
if (err)
@@ -6719,8 +6721,10 @@ i_s_tablespaces_encryption_fill_table(
&& !space.is_stopping()) {
space.reacquire();
mysql_mutex_unlock(&fil_system.mutex);
+ space.s_lock();
err = i_s_dict_fill_tablespaces_encryption(
thd, &space, tables->table);
+ space.s_unlock();
mysql_mutex_lock(&fil_system.mutex);
space.release();
if (err) {
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index 1ef4df62d6e..39a0d19bfa9 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -2385,16 +2385,11 @@ done:
#endif
}
-/*********************************************************************//**
-Contracts insert buffer trees by reading pages to the buffer pool.
+/** Contract the change buffer by reading pages to the buffer pool.
@return a lower limit for the combined size in bytes of entries which
-will be merged from ibuf trees to the pages read, 0 if ibuf is
-empty */
-static
-ulint
-ibuf_merge_pages(
-/*=============*/
- ulint* n_pages) /*!< out: number of pages to which merged */
+will be merged from ibuf trees to the pages read
+@retval 0 if ibuf.empty */
+ulint ibuf_contract()
{
mtr_t mtr;
btr_pcur_t pcur;
@@ -2402,8 +2397,6 @@ ibuf_merge_pages(
uint32_t page_nos[IBUF_MAX_N_PAGES_MERGED];
uint32_t space_ids[IBUF_MAX_N_PAGES_MERGED];
- *n_pages = 0;
-
ibuf_mtr_start(&mtr);
/* Open a cursor to a randomly chosen leaf of the tree, at a random
@@ -2436,13 +2429,14 @@ ibuf_merge_pages(
return(0);
}
+ ulint n_pages = 0;
sum_sizes = ibuf_get_merge_page_nos(TRUE,
btr_pcur_get_rec(&pcur), &mtr,
space_ids,
- page_nos, n_pages);
+ page_nos, &n_pages);
ibuf_mtr_commit(&mtr);
- ibuf_read_merge_pages(space_ids, page_nos, *n_pages);
+ ibuf_read_merge_pages(space_ids, page_nos, n_pages);
return(sum_sizes + 1);
}
@@ -2464,6 +2458,7 @@ ibuf_merge_space(
ut_ad(space < SRV_SPACE_ID_UPPER_BOUND);
+ log_free_check();
ibuf_mtr_start(&mtr);
/* Position the cursor on the first matching record. */
@@ -2513,72 +2508,6 @@ ibuf_merge_space(
return(n_pages);
}
-/** Contract the change buffer by reading pages to the buffer pool.
-@param[out] n_pages number of pages merged
-@param[in] sync whether the caller waits for
-the issued reads to complete
-@return a lower limit for the combined size in bytes of entries which
-will be merged from ibuf trees to the pages read, 0 if ibuf is
-empty */
-MY_ATTRIBUTE((warn_unused_result))
-static ulint ibuf_merge(ulint* n_pages)
-{
- *n_pages = 0;
-
- /* We perform a dirty read of ibuf.empty, without latching
- the insert buffer root page. We trust this dirty read except
- when a slow shutdown is being executed. During a slow
- shutdown, the insert buffer merge must be completed. */
-
- if (ibuf.empty && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
- return(0);
-#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
- } else if (ibuf_debug) {
- return(0);
-#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
- } else {
- return ibuf_merge_pages(n_pages);
- }
-}
-
-/** Contract the change buffer by reading pages to the buffer pool.
-@return a lower limit for the combined size in bytes of entries which
-will be merged from ibuf trees to the pages read, 0 if ibuf is empty */
-static ulint ibuf_contract()
-{
- ulint n_pages;
- return ibuf_merge_pages(&n_pages);
-}
-
-/** Contract the change buffer by reading pages to the buffer pool.
-@return a lower limit for the combined size in bytes of entries which
-will be merged from ibuf trees to the pages read, 0 if ibuf is
-empty */
-ulint ibuf_merge_all()
-{
-#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
- if (ibuf_debug) {
- return(0);
- }
-#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
-
- ulint sum_bytes = 0;
- ulint n_pages = srv_io_capacity;
-
- for (ulint sum_pages = 0; sum_pages < n_pages; ) {
- ulint n_pag2;
- ulint n_bytes = ibuf_merge(&n_pag2);
-
- if (n_bytes == 0) {
- break;
- }
-
- sum_bytes += n_bytes;
- }
-
- return sum_bytes;
-}
-
/*********************************************************************//**
Contract insert buffer trees after insert if they are too big. */
UNIV_INLINE
@@ -2588,13 +2517,7 @@ ibuf_contract_after_insert(
ulint entry_size) /*!< in: size of a record which was inserted
into an ibuf tree */
{
- /* Perform dirty reads of ibuf.size and ibuf.max_size, to
- reduce ibuf_mutex contention. ibuf.max_size remains constant
- after ibuf_init_at_db_start(), but ibuf.size should be
- protected by ibuf_mutex. Given that ibuf.size fits in a
- machine word, this should be OK; at worst we are doing some
- excessive ibuf_contract() or occasionally skipping a
- ibuf_contract(). */
+ /* dirty comparison, to avoid contention on ibuf_mutex */
if (ibuf.size < ibuf.max_size) {
return;
}
@@ -3222,16 +3145,17 @@ ibuf_insert_low(
do_merge = FALSE;
- /* Perform dirty reads of ibuf.size and ibuf.max_size, to
- reduce ibuf_mutex contention. Given that ibuf.max_size and
- ibuf.size fit in a machine word, this should be OK; at worst
- we are doing some excessive ibuf_contract() or occasionally
+ /* Perform dirty comparison of ibuf.max_size and ibuf.size to
+ reduce ibuf_mutex contention. This should be OK; at worst we
+ are doing some excessive ibuf_contract() or occasionally
skipping an ibuf_contract(). */
- if (ibuf.max_size == 0) {
+ const ulint max_size = ibuf.max_size;
+
+ if (max_size == 0) {
return(DB_STRONG_FAIL);
}
- if (ibuf.size >= ibuf.max_size + IBUF_CONTRACT_DO_NOT_INSERT) {
+ if (ibuf.size >= max_size + IBUF_CONTRACT_DO_NOT_INSERT) {
/* Insert buffer is now too big, contract it but do not try
to insert */
@@ -4461,7 +4385,7 @@ reset_bit:
}
/** Delete all change buffer entries for a tablespace,
-in DISCARD TABLESPACE, IMPORT TABLESPACE, or crash recovery.
+in DISCARD TABLESPACE, IMPORT TABLESPACE, or read-ahead.
@param[in] space missing or to-be-discarded tablespace */
void ibuf_delete_for_discarded_space(ulint space)
{
@@ -4483,6 +4407,7 @@ void ibuf_delete_for_discarded_space(ulint space)
memset(dops, 0, sizeof(dops));
loop:
+ log_free_check();
ibuf_mtr_start(&mtr);
/* Position pcur in the insert buffer at the first entry for the
@@ -4573,7 +4498,7 @@ ibuf_print(
fprintf(file,
"Ibuf: size " ULINTPF ", free list len " ULINTPF ","
" seg size " ULINTPF ", " ULINTPF " merges\n",
- ibuf.size,
+ ulint{ibuf.size},
ibuf.free_list_len,
ibuf.seg_size,
ulint{ibuf.n_merges});
@@ -4622,9 +4547,6 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
}
mtr_start(&mtr);
-
- mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
-
ibuf_enter(&mtr);
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(
@@ -4712,29 +4634,18 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
return(DB_SUCCESS);
}
-/** Updates free bits and buffered bits for bulk loaded page.
-@param[in] block index page
-@param[in] reset flag if reset free val */
-void
-ibuf_set_bitmap_for_bulk_load(
- buf_block_t* block,
- bool reset)
+void ibuf_set_bitmap_for_bulk_load(buf_block_t *block, mtr_t *mtr, bool reset)
{
- mtr_t mtr;
-
ut_a(page_is_leaf(block->page.frame));
- mtr.start();
- fil_space_t *space= mtr.set_named_space_id(block->page.id().space());
if (buf_block_t *bitmap_page=
- ibuf_bitmap_get_map_page(block->page.id(), space->zip_size(), &mtr))
+ ibuf_bitmap_get_map_page(block->page.id(), block->zip_size(), mtr))
{
ulint free_val= reset ? 0 : ibuf_index_page_calc_free(block);
/* FIXME: update the bitmap byte only once! */
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>
- (bitmap_page, block->page.id(), block->physical_size(), free_val, &mtr);
+ (bitmap_page, block->page.id(), block->physical_size(), free_val, mtr);
ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>
- (bitmap_page, block->page.id(), block->physical_size(), false, &mtr);
+ (bitmap_page, block->page.id(), block->physical_size(), false, mtr);
}
- mtr.commit();
}
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index cfaf4fab83e..e54a138cc02 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -421,14 +421,6 @@ dict_foreign_add_to_cache(
dict_err_ignore_t ignore_err)
/*!< in: error to be ignored */
MY_ATTRIBUTE((nonnull(1), warn_unused_result));
-/*********************************************************************//**
-Checks if a table is referenced by foreign keys.
-@return TRUE if table is referenced by a foreign key */
-ibool
-dict_table_is_referenced_by_foreign_key(
-/*====================================*/
- const dict_table_t* table) /*!< in: InnoDB table */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************************//**
Replace the index passed in with another equivalent index in the
foreign key lists of the table.
@@ -1329,7 +1321,7 @@ class dict_sys_t
alignas(CPU_LEVEL1_DCACHE_LINESIZE) srw_lock latch;
#ifdef UNIV_DEBUG
/** whether latch is being held in exclusive mode (by any thread) */
- bool latch_ex;
+ Atomic_relaxed<pthread_t> latch_ex;
/** number of S-latch holders */
Atomic_counter<uint32_t> latch_readers;
#endif
@@ -1503,11 +1495,12 @@ public:
/** @return whether any thread (not necessarily the current thread)
is holding the latch; that is, this check may return false
positives */
- bool frozen() const { return latch_readers || locked(); }
+ bool frozen() const { return latch_readers || latch_ex; }
/** @return whether any thread (not necessarily the current thread)
- is holding the exclusive latch; that is, this check may return false
- positives */
- bool locked() const { return latch_ex; }
+ is holding a shared latch */
+ bool frozen_not_locked() const { return latch_readers; }
+ /** @return whether the current thread holds the exclusive latch */
+ bool locked() const { return latch_ex == pthread_self(); }
#endif
private:
/** Acquire the exclusive latch */
@@ -1526,7 +1519,7 @@ public:
{
ut_ad(!latch_readers);
ut_ad(!latch_ex);
- ut_d(latch_ex= true);
+ ut_d(latch_ex= pthread_self());
}
else
lock_wait(SRW_LOCK_ARGS(file, line));
@@ -1543,9 +1536,9 @@ public:
/** Unlock the data dictionary cache. */
void unlock()
{
- ut_ad(latch_ex);
+ ut_ad(latch_ex == pthread_self());
ut_ad(!latch_readers);
- ut_d(latch_ex= false);
+ ut_d(latch_ex= 0);
latch.wr_unlock();
}
/** Acquire a shared lock on the dictionary cache. */
diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h
index a94823b4a86..f7d33d5b43b 100644
--- a/storage/innobase/include/dict0load.h
+++ b/storage/innobase/include/dict0load.h
@@ -100,7 +100,7 @@ dict_load_foreigns(
which must be loaded
subsequently to load all the
foreign key constraints. */
- MY_ATTRIBUTE((nonnull(1), warn_unused_result));
+ MY_ATTRIBUTE((nonnull(1)));
/********************************************************************//**
This function opens a system table, and return the first record.
diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h
index 93e46e7b0be..e38515f0402 100644
--- a/storage/innobase/include/ibuf0ibuf.h
+++ b/storage/innobase/include/ibuf0ibuf.h
@@ -30,7 +30,6 @@ Created 7/19/1997 Heikki Tuuri
#include "mtr0mtr.h"
#include "dict0mem.h"
#include "fsp0fsp.h"
-#include "ibuf0types.h"
/** Default value for maximum on-disk size of change buffer in terms
of percentage of the buffer pool. */
@@ -61,6 +60,37 @@ enum ibuf_use_t {
/** Operations that can currently be buffered. */
extern ulong innodb_change_buffering;
+/** Insert buffer struct */
+struct ibuf_t{
+ Atomic_relaxed<ulint> size; /*!< current size of the ibuf index
+ tree, in pages */
+ Atomic_relaxed<ulint> max_size; /*!< recommended maximum size of the
+ ibuf index tree, in pages */
+ ulint seg_size; /*!< allocated pages of the file
+ segment containing ibuf header and
+ tree */
+ bool empty; /*!< Protected by the page
+ latch of the root page of the
+ insert buffer tree
+ (FSP_IBUF_TREE_ROOT_PAGE_NO). true
+ if and only if the insert
+ buffer tree is empty. */
+ ulint free_list_len; /*!< length of the free list */
+ ulint height; /*!< tree height */
+ dict_index_t* index; /*!< insert buffer index */
+
+ /** number of pages merged */
+ Atomic_counter<ulint> n_merges;
+ Atomic_counter<ulint> n_merged_ops[IBUF_OP_COUNT];
+ /*!< number of operations of each type
+ merged to index pages */
+ Atomic_counter<ulint> n_discarded_ops[IBUF_OP_COUNT];
+ /*!< number of operations of each type
+ discarded without merging due to the
+ tablespace being deleted or the
+ index being dropped */
+};
+
/** The insert buffer control structure */
extern ibuf_t ibuf;
@@ -264,7 +294,6 @@ ibuf_page_low(
MY_ATTRIBUTE((warn_unused_result));
#ifdef UNIV_DEBUG
-
/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
Must not be called when recv_no_ibuf_operations==true.
@param[in] page_id tablespace/page identifier
@@ -274,7 +303,7 @@ Must not be called when recv_no_ibuf_operations==true.
# define ibuf_page(page_id, zip_size, mtr) \
ibuf_page_low(page_id, zip_size, true, mtr)
-#else /* UVIV_DEBUG */
+#else /* UNIV_DEBUG */
/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
Must not be called when recv_no_ibuf_operations==true.
@@ -285,7 +314,7 @@ Must not be called when recv_no_ibuf_operations==true.
# define ibuf_page(page_id, zip_size, mtr) \
ibuf_page_low(page_id, zip_size, mtr)
-#endif /* UVIV_DEBUG */
+#endif /* UNIV_DEBUG */
/***********************************************************************//**
Frees excess pages from the ibuf free list. This function is called when an OS
thread calls fsp services to allocate a new file segment, or a new page to a
@@ -334,15 +363,15 @@ dberr_t ibuf_merge_or_delete_for_page(buf_block_t *block,
ulint zip_size);
/** Delete all change buffer entries for a tablespace,
-in DISCARD TABLESPACE, IMPORT TABLESPACE, or crash recovery.
+in DISCARD TABLESPACE, IMPORT TABLESPACE, or read-ahead.
@param[in] space missing or to-be-discarded tablespace */
void ibuf_delete_for_discarded_space(ulint space);
/** Contract the change buffer by reading pages to the buffer pool.
@return a lower limit for the combined size in bytes of entries which
-will be merged from ibuf trees to the pages read, 0 if ibuf is
-empty */
-ulint ibuf_merge_all();
+will be merged from ibuf trees to the pages read
+@retval 0 if ibuf.empty */
+ulint ibuf_contract();
/** Contracts insert buffer trees by reading pages referring to space_id
to the buffer pool.
@@ -385,13 +414,11 @@ ibuf_close(void);
dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/** Updates free bits and buffered bits for bulk loaded page.
-@param[in] block index page
-@param]in] reset flag if reset free val */
-void
-ibuf_set_bitmap_for_bulk_load(
- buf_block_t* block,
- bool reset);
+/** Update free bits and buffered bits for bulk loaded page.
+@param block secondary index leaf page
+@param mtr mini-transaction
+@param reset whether the page is full */
+void ibuf_set_bitmap_for_bulk_load(buf_block_t *block, mtr_t *mtr, bool reset);
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
diff --git a/storage/innobase/include/ibuf0ibuf.inl b/storage/innobase/include/ibuf0ibuf.inl
index 2c2620511c7..9f4e937f31d 100644
--- a/storage/innobase/include/ibuf0ibuf.inl
+++ b/storage/innobase/include/ibuf0ibuf.inl
@@ -64,37 +64,6 @@ ibuf_mtr_commit(
mtr_commit(mtr);
}
-/** Insert buffer struct */
-struct ibuf_t{
- ulint size; /*!< current size of the ibuf index
- tree, in pages */
- ulint max_size; /*!< recommended maximum size of the
- ibuf index tree, in pages */
- ulint seg_size; /*!< allocated pages of the file
- segment containing ibuf header and
- tree */
- bool empty; /*!< Protected by the page
- latch of the root page of the
- insert buffer tree
- (FSP_IBUF_TREE_ROOT_PAGE_NO). true
- if and only if the insert
- buffer tree is empty. */
- ulint free_list_len; /*!< length of the free list */
- ulint height; /*!< tree height */
- dict_index_t* index; /*!< insert buffer index */
-
- /** number of pages merged */
- Atomic_counter<ulint> n_merges;
- Atomic_counter<ulint> n_merged_ops[IBUF_OP_COUNT];
- /*!< number of operations of each type
- merged to index pages */
- Atomic_counter<ulint> n_discarded_ops[IBUF_OP_COUNT];
- /*!< number of operations of each type
- discarded without merging due to the
- tablespace being deleted or the
- index being dropped */
-};
-
/************************************************************************//**
Sets the free bit of the page in the ibuf bitmap. This is done in a separate
mini-transaction, hence this operation does not restrict further work to only
diff --git a/storage/innobase/include/ibuf0types.h b/storage/innobase/include/ibuf0types.h
deleted file mode 100644
index 6b7c47208a0..00000000000
--- a/storage/innobase/include/ibuf0types.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1997, 2009, 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 Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/ibuf0types.h
-Insert buffer global types
-
-Created 7/29/1997 Heikki Tuuri
-*******************************************************/
-
-#ifndef ibuf0types_h
-#define ibuf0types_h
-
-struct ibuf_t;
-
-#endif
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 629ddacdf1b..0f9a4da049b 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, Google Inc.
-Copyright (c) 2017, 2021, MariaDB Corporation.
+Copyright (c) 2017, 2022, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -466,6 +466,11 @@ public:
size_t buf_free;
/** recommended maximum size of buf, after which the buffer is flushed */
size_t max_buf_free;
+
+ /** Log sequence number when a log file overwrite (broken crash recovery)
+ was noticed. Protected by mutex. */
+ lsn_t overwrite_warned;
+
/** mutex to serialize access to the flush list when we are putting
dirty blocks in the list. The idea behind this mutex is to be able
to release log_sys.mutex during mtr_commit and still ensure that
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index ea8973c2d3b..36bc8321833 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -295,10 +295,6 @@ struct mtr_t {
@param type object type
@return bool if lock released */
bool memo_release(const void *object, ulint type);
- /** Release a page latch.
- @param[in] ptr pointer to within a page frame
- @param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */
- void release_page(const void *ptr, mtr_memo_type_t type);
/** Note that the mini-transaction will modify data. */
void flag_modified() { m_modifications = true; }
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index b0e2eb98d01..0ad42474f84 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -795,17 +795,6 @@ page_rec_is_first(
MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
-true if the record is the second user record on a page.
-@return true if the second user record */
-UNIV_INLINE
-bool
-page_rec_is_second(
-/*===============*/
- const rec_t* rec, /*!< in: record */
- const page_t* page) /*!< in: page */
- MY_ATTRIBUTE((warn_unused_result));
-
-/************************************************************//**
true if the record is the last user record on a page.
@return true if the last user record */
UNIV_INLINE
@@ -817,17 +806,6 @@ page_rec_is_last(
MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
-true if the record is the second last user record on a page.
-@return true if the second last user record */
-UNIV_INLINE
-bool
-page_rec_is_second_last(
-/*====================*/
- const rec_t* rec, /*!< in: record */
- const page_t* page) /*!< in: page */
- MY_ATTRIBUTE((warn_unused_result));
-
-/************************************************************//**
Returns the maximum combined size of records which can be inserted on top
of record heap.
@return maximum combined size for inserted records */
diff --git a/storage/innobase/include/page0page.inl b/storage/innobase/include/page0page.inl
index 61c1b96ff79..6c0167edcf9 100644
--- a/storage/innobase/include/page0page.inl
+++ b/storage/innobase/include/page0page.inl
@@ -193,22 +193,6 @@ page_rec_is_first(
}
/************************************************************//**
-true if the record is the second user record on a page.
-@return true if the second user record */
-UNIV_INLINE
-bool
-page_rec_is_second(
-/*===============*/
- const rec_t* rec, /*!< in: record */
- const page_t* page) /*!< in: page */
-{
- ut_ad(page_get_n_recs(page) > 1);
- if (const rec_t *first= page_rec_get_next_const(page_get_infimum_rec(page)))
- return page_rec_get_next_const(first) == rec;
- return false;
-}
-
-/************************************************************//**
true if the record is the last user record on a page.
@return true if the last user record */
UNIV_INLINE
@@ -224,24 +208,6 @@ page_rec_is_last(
}
/************************************************************//**
-true if the record is the second last user record on a page.
-@return true if the second last user record */
-UNIV_INLINE
-bool
-page_rec_is_second_last(
-/*====================*/
- const rec_t* rec, /*!< in: record */
- const page_t* page) /*!< in: page */
-{
- ut_ad(page_get_n_recs(page) > 1);
- ut_ad(!page_rec_is_last(rec, page));
-
- if (const rec_t *next= page_rec_get_next_const(rec))
- return page_rec_is_supremum(page_rec_get_next_const(next));
- return false;
-}
-
-/************************************************************//**
Returns the middle record of the records on the page. If there is an
even number of records in the list, returns the first record of the
upper half-list.
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 2f8bee1bc4d..ad941b89691 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -429,6 +429,10 @@ class trx_mod_table_time_t
/** First modification of a system versioned column
(NONE= no versioning, BULK= the table was dropped) */
undo_no_t first_versioned= NONE;
+#ifdef UNIV_DEBUG
+ /** Whether the modified table is a FTS auxiliary table */
+ bool fts_aux_table= false;
+#endif /* UNIV_DEBUG */
public:
/** Constructor
@param rows number of modified rows so far */
@@ -483,6 +487,12 @@ public:
first_versioned= NONE;
return false;
}
+
+#ifdef UNIV_DEBUG
+ void set_aux_table() { fts_aux_table= true; }
+
+ bool is_aux_table() const { return fts_aux_table; }
+#endif /* UNIV_DEBUG */
};
/** Collection of persistent tables and their first modification
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 448021d840a..db4035157b0 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -3934,8 +3934,7 @@ void lock_release(trx_t *trx)
#ifdef UNIV_DEBUG
std::set<table_id_t> to_evict;
if (innodb_evict_tables_on_commit_debug &&
- !trx->is_recovered && !trx->dict_operation &&
- !trx->dict_operation_lock_mode)
+ !trx->is_recovered && !dict_sys.locked())
for (const auto& p : trx->mod_tables)
if (!p.first->is_temporary())
to_evict.emplace(p.first->id);
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index e127507e544..9cb6b04e25b 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -52,6 +52,7 @@ Created 12/9/1995 Heikki Tuuri
#include "srv0mon.h"
#include "buf0dump.h"
#include "log0sync.h"
+#include "log.h"
/*
General philosophy of InnoDB redo-logs:
@@ -988,11 +989,20 @@ ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn)
DBUG_PRINT("ib_log", ("checkpoint ended at " LSN_PF
", flushed to " LSN_PF,
- lsn_t{log_sys.last_checkpoint_lsn},
+ log_sys.next_checkpoint_lsn,
log_sys.get_flushed_lsn()));
MONITOR_INC(MONITOR_NUM_CHECKPOINT);
+ if (log_sys.overwrite_warned) {
+ sql_print_information("InnoDB: Crash recovery was broken "
+ "between LSN=" LSN_PF
+ " and checkpoint LSN=" LSN_PF ".",
+ log_sys.overwrite_warned,
+ log_sys.next_checkpoint_lsn);
+ log_sys.overwrite_warned = 0;
+ }
+
mysql_mutex_unlock(&log_sys.mutex);
}
@@ -1020,10 +1030,15 @@ func_exit:
const lsn_t sync_lsn= checkpoint + log_sys.max_checkpoint_age;
if (lsn <= sync_lsn)
{
+#ifndef DBUG_OFF
+ skip_checkpoint:
+#endif
log_sys.set_check_flush_or_checkpoint(false);
goto func_exit;
}
+ DBUG_EXECUTE_IF("ib_log_checkpoint_avoid_hard", goto skip_checkpoint;);
+
mysql_mutex_unlock(&log_sys.mutex);
/* We must wait to prevent the tail of the log overwriting the head. */
@@ -1120,13 +1135,9 @@ loop:
}
/* We need these threads to stop early in shutdown. */
- const char* thread_name;
-
- if (srv_fast_shutdown != 2 && trx_rollback_is_active) {
- thread_name = "rollback of recovered transactions";
- } else {
- thread_name = NULL;
- }
+ const char* thread_name = srv_fast_shutdown != 2
+ && trx_rollback_is_active
+ ? "rollback of recovered transactions" : nullptr;
if (thread_name) {
ut_ad(!srv_read_only_mode);
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 4a1057414e2..85eafceea8a 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -1148,6 +1148,7 @@ public:
}
mtr.commit();
+ clear();
}
/** Clear the data structure */
@@ -1781,7 +1782,7 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2()
if (!log_crypt_101_read_checkpoint(buf))
{
- ib::error() << "Decrypting checkpoint failed";
+ sql_print_error("InnoDB: Decrypting checkpoint failed");
continue;
}
@@ -1803,11 +1804,11 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2()
if (!lsn)
{
- ib::error() << "Upgrade after a crash is not supported."
- " This redo log was created before MariaDB 10.2.2,"
- " and we did not find a valid checkpoint."
- " Please follow the instructions at"
- " https://mariadb.com/kb/en/library/upgrading/";
+ sql_print_error("InnoDB: Upgrade after a crash is not supported."
+ " This redo log was created before MariaDB 10.2.2,"
+ " and we did not find a valid checkpoint."
+ " Please follow the instructions at"
+ " https://mariadb.com/kb/en/library/upgrading/");
return DB_ERROR;
}
@@ -1816,7 +1817,7 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2()
const lsn_t source_offset= log_sys.log.calc_lsn_offset_old(lsn);
static constexpr char NO_UPGRADE_RECOVERY_MSG[]=
- "Upgrade after a crash is not supported."
+ "InnoDB: Upgrade after a crash is not supported."
" This redo log was created before MariaDB 10.2.2";
recv_sys.read(source_offset & ~511, {buf, 512});
@@ -1824,7 +1825,7 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2()
if (log_block_calc_checksum_format_0(buf) != log_block_get_checksum(buf) &&
!log_crypt_101_read_block(buf, lsn))
{
- ib::error() << NO_UPGRADE_RECOVERY_MSG << ", and it appears corrupted.";
+ sql_print_error("%s, and it appears corrupted.", NO_UPGRADE_RECOVERY_MSG);
return DB_CORRUPTION;
}
@@ -1841,10 +1842,13 @@ ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2()
}
if (buf[20 + 32 * 9] == 2)
- ib::error() << "Cannot decrypt log for upgrading."
- " The encrypted log was created before MariaDB 10.2.2.";
+ sql_print_error("InnoDB: Cannot decrypt log for upgrading."
+ " The encrypted log was created before MariaDB 10.2.2.");
else
- ib::error() << NO_UPGRADE_RECOVERY_MSG << ".";
+ sql_print_error("%s. You must start up and shut down"
+ " MariaDB 10.1 or MySQL 5.6 or earlier"
+ " on the data directory.",
+ NO_UPGRADE_RECOVERY_MSG);
return DB_ERROR;
}
@@ -1951,8 +1955,8 @@ recv_find_max_checkpoint(ulint* max_field)
: 0;
if (log_sys.log.format != log_t::FORMAT_3_23
&& !recv_check_log_header_checksum(buf)) {
- ib::error() << "Invalid redo log header checksum.";
- return(DB_CORRUPTION);
+ sql_print_error("InnoDB: Invalid redo log header checksum.");
+ return DB_CORRUPTION;
}
char creator[LOG_HEADER_CREATOR_END - LOG_HEADER_CREATOR + 1];
@@ -1974,9 +1978,9 @@ recv_find_max_checkpoint(ulint* max_field)
case log_t::FORMAT_10_5 | log_t::FORMAT_ENCRYPTED:
break;
default:
- ib::error() << "Unsupported redo log format."
- " The redo log was created with " << creator << ".";
- return(DB_ERROR);
+ sql_print_error("InnoDB: Unsupported redo log format."
+ " The redo log was created with %s.", creator);
+ return DB_ERROR;
}
for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
@@ -1998,8 +2002,8 @@ recv_find_max_checkpoint(ulint* max_field)
if (log_sys.is_encrypted()
&& !log_crypt_read_checkpoint_buf(buf)) {
- ib::error() << "Reading checkpoint"
- " encryption info failed.";
+ sql_print_error("InnoDB: Reading checkpoint"
+ " encryption info failed.");
continue;
}
@@ -2028,11 +2032,11 @@ recv_find_max_checkpoint(ulint* max_field)
was filled with zeroes, and were killed. After
10.2.2, we would reject such a file already earlier,
when checking the file header. */
- ib::error() << "No valid checkpoint found"
- " (corrupted redo log)."
- " You can try --innodb-force-recovery=6"
- " as a last resort.";
- return(DB_ERROR);
+ sql_print_error("InnoDB: No valid checkpoint found"
+ " (corrupted redo log)."
+ " You can try --innodb-force-recovery=6"
+ " as a last resort.");
+ return DB_ERROR;
}
switch (log_sys.log.format) {
@@ -2041,11 +2045,15 @@ recv_find_max_checkpoint(ulint* max_field)
break;
default:
if (dberr_t err = recv_log_recover_10_4()) {
- ib::error()
- << "Upgrade after a crash is not supported."
- " The redo log was created with " << creator
- << (err == DB_ERROR
- ? "." : ", and it appears corrupted.");
+ sql_print_error("InnoDB: Upgrade after a crash "
+ "is not supported."
+ " The redo log was created with %s%s.",
+ creator,
+ err == DB_ERROR
+ ? ". You must start up and shut down"
+ " MariaDB 10.4 or earlier"
+ " on the data directory"
+ : ", and it appears corrupted");
return err;
}
}
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 02965821ced..c376e15ff0f 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -24,18 +24,19 @@ Mini-transaction buffer
Created 11/26/1995 Heikki Tuuri
*******************************************************/
-#include "mtr0mtr.h"
+#include "mtr0log.h"
#include "buf0buf.h"
#include "buf0flu.h"
#include "fsp0sysspace.h"
#include "page0types.h"
-#include "mtr0log.h"
#include "log0recv.h"
#include "my_cpu.h"
#ifdef BTR_CUR_HASH_ADAPT
# include "btr0sea.h"
#endif
+#include "srv0start.h"
+#include "log.h"
/** Iterate over a memo block in reverse. */
template <typename Functor>
@@ -838,32 +839,8 @@ mtr_t::memo_release(const void* object, ulint type)
return(false);
}
-/** Release a page latch.
-@param[in] ptr pointer to within a page frame
-@param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */
-void
-mtr_t::release_page(const void* ptr, mtr_memo_type_t type)
-{
- ut_ad(is_active());
-
- /* We cannot release a page that has been written to in the
- middle of a mini-transaction. */
- ut_ad(!m_modifications || type != MTR_MEMO_PAGE_X_FIX);
-
- Iterate<FindPage> iteration(FindPage(ptr, type));
-
- if (!m_memo.for_each_block_in_reverse(iteration)) {
- memo_slot_release(iteration.functor.get_slot());
- return;
- }
-
- /* The page was not found! */
- ut_ad(0);
-}
-
static bool log_margin_warned;
static time_t log_margin_warn_time;
-static bool log_close_warned;
static time_t log_close_warn_time;
/** Check margin not to overwrite transaction log from the last checkpoint.
@@ -901,8 +878,8 @@ static void log_margin_checkpoint_age(ulint len)
log_margin_warned= true;
log_margin_warn_time= t;
- ib::error() << "innodb_log_file_size is too small "
- "for mini-transaction size " << len;
+ sql_print_error("InnoDB: innodb_log_file_size is too small "
+ "for mini-transaction size " ULINTPF, len);
}
}
else if (UNIV_LIKELY(lsn + margin <= log_sys.last_checkpoint_lsn +
@@ -1028,14 +1005,19 @@ static mtr_t::page_flush_ahead log_close(lsn_t lsn)
checkpoint_age != lsn)
{
time_t t= time(nullptr);
- if (!log_close_warned || difftime(t, log_close_warn_time) > 15)
+ if (!log_sys.overwrite_warned || difftime(t, log_close_warn_time) > 15)
{
- log_close_warned= true;
+ if (!log_sys.overwrite_warned)
+ log_sys.overwrite_warned= lsn;
log_close_warn_time= t;
- ib::error() << "The age of the last checkpoint is " << checkpoint_age
- << ", which exceeds the log capacity "
- << log_sys.log_capacity << ".";
+ sql_print_error("InnoDB: Crash recovery is broken due to"
+ " insufficient innodb_log_file_size;"
+ " last checkpoint LSN=" LSN_PF ", current LSN=" LSN_PF
+ "%s.",
+ lsn_t{log_sys.last_checkpoint_lsn}, lsn,
+ srv_shutdown_state != SRV_SHUTDOWN_INITIATED
+ ? ". Shutdown is in progress" : "");
}
}
else if (UNIV_LIKELY(checkpoint_age <= log_sys.max_modified_age_async))
diff --git a/storage/innobase/plugin_exports b/storage/innobase/plugin_exports
deleted file mode 100644
index 235ae3d5e72..00000000000
--- a/storage/innobase/plugin_exports
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- global:
- _maria_plugin_interface_version_;
- _maria_sizeof_struct_st_plugin_;
- _maria_plugin_declarations_;
- my_snprintf_service;
- thd_alloc_service;
- thd_autoinc_service;
- thd_error_context_service;
- thd_kill_statement_service;
- thd_wait_service;
- local:
- *;
-};
diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc
index 80c34af2790..c5fe7c04a17 100644
--- a/storage/innobase/que/que0que.cc
+++ b/storage/innobase/que/que0que.cc
@@ -260,17 +260,10 @@ que_graph_free_recursive(
ind_node_t* cre_ind;
purge_node_t* purge;
- DBUG_ENTER("que_graph_free_recursive");
-
if (node == NULL) {
-
- DBUG_VOID_RETURN;
+ return;
}
- DBUG_PRINT("que_graph_free_recursive",
- ("node: %p, type: " ULINTPF, node,
- que_node_get_type(node)));
-
switch (que_node_get_type(node)) {
case QUE_NODE_FORK:
@@ -410,8 +403,6 @@ que_graph_free_recursive(
default:
ut_error;
}
-
- DBUG_VOID_RETURN;
}
/**********************************************************************//**
@@ -507,66 +498,6 @@ que_node_get_containing_loop_node(
return(node);
}
-#ifdef DBUG_TRACE
-/** Gets information of an SQL query graph node.
-@return type description */
-static MY_ATTRIBUTE((warn_unused_result, nonnull))
-const char*
-que_node_type_string(
-/*=================*/
- const que_node_t* node) /*!< in: query graph node */
-{
- switch (que_node_get_type(node)) {
- case QUE_NODE_SELECT:
- return("SELECT");
- case QUE_NODE_INSERT:
- return("INSERT");
- case QUE_NODE_UPDATE:
- return("UPDATE");
- case QUE_NODE_WHILE:
- return("WHILE");
- case QUE_NODE_ASSIGNMENT:
- return("ASSIGNMENT");
- case QUE_NODE_IF:
- return("IF");
- case QUE_NODE_FETCH:
- return("FETCH");
- case QUE_NODE_OPEN:
- return("OPEN");
- case QUE_NODE_PROC:
- return("STORED PROCEDURE");
- case QUE_NODE_FUNC:
- return("FUNCTION");
- case QUE_NODE_LOCK:
- return("LOCK");
- case QUE_NODE_THR:
- return("QUERY THREAD");
- case QUE_NODE_COMMIT:
- return("COMMIT");
- case QUE_NODE_UNDO:
- return("UNDO ROW");
- case QUE_NODE_PURGE:
- return("PURGE ROW");
- case QUE_NODE_ROLLBACK:
- return("ROLLBACK");
- case QUE_NODE_CREATE_TABLE:
- return("CREATE TABLE");
- case QUE_NODE_CREATE_INDEX:
- return("CREATE INDEX");
- case QUE_NODE_FOR:
- return("FOR LOOP");
- case QUE_NODE_RETURN:
- return("RETURN");
- case QUE_NODE_EXIT:
- return("EXIT");
- default:
- ut_ad(0);
- return("UNKNOWN NODE TYPE");
- }
-}
-#endif /* DBUG_TRACE */
-
-
/**********************************************************************//**
Performs an execution step of an open or close cursor statement node.
@param thr query thread */
@@ -614,10 +545,6 @@ que_thr_step(
old_thr = thr;
- DBUG_PRINT("ib_que", ("Execute %u (%s) at %p",
- unsigned(type), que_node_type_string(node),
- (const void*) node));
-
if (type & QUE_NODE_CONTROL_STAT) {
if ((thr->prev_node != que_node_get_parent(node))
&& que_node_get_next(thr->prev_node)) {
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index f2b29ae0f16..571e8cf3a83 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -61,57 +61,49 @@ Completed by Sunny Bains and Marko Makela
/* Whether to disable file system cache */
char srv_disable_sort_file_cache;
-/** Class that caches index row tuples made from a single cluster
+/** Class that caches spatial index row tuples made from a single cluster
index page scan, and then insert into corresponding index tree */
-class index_tuple_info_t {
+class spatial_index_info {
public:
- /** constructor
- @param[in] heap memory heap
- @param[in] index index to be created */
- index_tuple_info_t(mem_heap_t* heap, dict_index_t* index) :
- m_dtuple_vec(UT_NEW_NOKEY(idx_tuple_vec())),
- m_index(index), m_heap(heap)
- { ut_ad(index->is_spatial()); }
-
- /** destructor */
- ~index_tuple_info_t()
- {
- UT_DELETE(m_dtuple_vec);
- }
-
- /** Get the index object
- @return the index object */
- dict_index_t* get_index() UNIV_NOTHROW
- {
- return(m_index);
- }
-
- /** Caches an index row into index tuple vector
- @param[in] row table row
- @param[in] ext externally stored column
- prefixes, or NULL */
- void add(
- const dtuple_t* row,
- const row_ext_t* ext) UNIV_NOTHROW
- {
- dtuple_t* dtuple;
-
- dtuple = row_build_index_entry(row, ext, m_index, m_heap);
-
- ut_ad(dtuple);
-
- m_dtuple_vec->push_back(dtuple);
- }
+ /** constructor
+ @param index spatial index to be created */
+ spatial_index_info(dict_index_t *index) : index(index)
+ {
+ ut_ad(index->is_spatial());
+ }
+
+ /** Caches an index row into index tuple vector
+ @param[in] row table row
+ @param[in] ext externally stored column prefixes, or NULL */
+ void add(const dtuple_t *row, const row_ext_t *ext, mem_heap_t *heap)
+ {
+ dtuple_t *dtuple= row_build_index_entry(row, ext, index, heap);
+ ut_ad(dtuple);
+ ut_ad(dtuple->n_fields == index->n_fields);
+ if (ext)
+ {
+ /* Replace any references to ext, because ext will be allocated
+ from row_heap. */
+ for (ulint i= 1; i < dtuple->n_fields; i++)
+ {
+ dfield_t &dfield= dtuple->fields[i];
+ if (dfield.data >= ext->buf &&
+ dfield.data <= &ext->buf[ext->n_ext * ext->max_len])
+ dfield_dup(&dfield, heap);
+ }
+ }
+ m_dtuple_vec.push_back(dtuple);
+ }
/** Insert spatial index rows cached in vector into spatial index
@param[in] trx_id transaction id
- @param[in,out] row_heap memory heap
@param[in] pcur cluster index scanning cursor
@param[in,out] mtr_started whether scan_mtr is active
+ @param[in,out] heap temporary memory heap
@param[in,out] scan_mtr mini-transaction for pcur
@return DB_SUCCESS if successful, else error number */
- dberr_t insert(trx_id_t trx_id, mem_heap_t* row_heap, btr_pcur_t* pcur,
- bool& mtr_started, mtr_t* scan_mtr) const
+ dberr_t insert(trx_id_t trx_id, btr_pcur_t* pcur,
+ bool& mtr_started, mem_heap_t* heap, mtr_t* scan_mtr)
{
big_rec_t* big_rec;
rec_t* rec;
@@ -130,8 +122,8 @@ public:
DBUG_EXECUTE_IF("row_merge_instrument_log_check_flush",
log_sys.set_check_flush_or_checkpoint(););
- for (idx_tuple_vec::iterator it = m_dtuple_vec->begin();
- it != m_dtuple_vec->end();
+ for (idx_tuple_vec::iterator it = m_dtuple_vec.begin();
+ it != m_dtuple_vec.end();
++it) {
dtuple = *it;
ut_ad(dtuple);
@@ -151,29 +143,29 @@ public:
}
mtr.start();
- m_index->set_modified(mtr);
+ index->set_modified(mtr);
- ins_cur.index = m_index;
- rtr_init_rtr_info(&rtr_info, false, &ins_cur, m_index,
+ ins_cur.index = index;
+ rtr_init_rtr_info(&rtr_info, false, &ins_cur, index,
false);
rtr_info_update_btr(&ins_cur, &rtr_info);
error = btr_cur_search_to_nth_level(
- m_index, 0, dtuple, PAGE_CUR_RTREE_INSERT,
+ index, 0, dtuple, PAGE_CUR_RTREE_INSERT,
BTR_MODIFY_LEAF, &ins_cur, &mtr);
/* It need to update MBR in parent entry,
so change search mode to BTR_MODIFY_TREE */
if (error == DB_SUCCESS && rtr_info.mbr_adj) {
- mtr_commit(&mtr);
+ mtr.commit();
rtr_clean_rtr_info(&rtr_info, true);
rtr_init_rtr_info(&rtr_info, false, &ins_cur,
- m_index, false);
+ index, false);
rtr_info_update_btr(&ins_cur, &rtr_info);
- mtr_start(&mtr);
- m_index->set_modified(mtr);
+ mtr.start();
+ index->set_modified(mtr);
error = btr_cur_search_to_nth_level(
- m_index, 0, dtuple,
+ index, 0, dtuple,
PAGE_CUR_RTREE_INSERT,
BTR_MODIFY_TREE, &ins_cur, &mtr);
}
@@ -181,7 +173,7 @@ public:
if (error == DB_SUCCESS) {
error = btr_cur_optimistic_insert(
flag, &ins_cur, &ins_offsets,
- &row_heap, dtuple, &rec, &big_rec,
+ &heap, dtuple, &rec, &big_rec,
0, NULL, &mtr);
}
@@ -190,15 +182,15 @@ public:
if (error == DB_FAIL) {
mtr.commit();
mtr.start();
- m_index->set_modified(mtr);
+ index->set_modified(mtr);
rtr_clean_rtr_info(&rtr_info, true);
rtr_init_rtr_info(&rtr_info, false,
- &ins_cur, m_index, false);
+ &ins_cur, index, false);
rtr_info_update_btr(&ins_cur, &rtr_info);
error = btr_cur_search_to_nth_level(
- m_index, 0, dtuple,
+ index, 0, dtuple,
PAGE_CUR_RTREE_INSERT,
BTR_MODIFY_TREE,
&ins_cur, &mtr);
@@ -206,7 +198,7 @@ public:
if (error == DB_SUCCESS) {
error = btr_cur_pessimistic_insert(
flag, &ins_cur, &ins_offsets,
- &row_heap, dtuple, &rec,
+ &heap, dtuple, &rec,
&big_rec, 0, NULL, &mtr);
}
}
@@ -232,30 +224,26 @@ public:
}
}
- mtr_commit(&mtr);
+ mtr.commit();
rtr_clean_rtr_info(&rtr_info, true);
}
- m_dtuple_vec->clear();
+ m_dtuple_vec.clear();
return(error);
}
private:
- /** Cache index rows made from a cluster index scan. Usually
- for rows on single cluster index page */
- typedef std::vector<dtuple_t*, ut_allocator<dtuple_t*> >
- idx_tuple_vec;
-
- /** vector used to cache index rows made from cluster index scan */
- idx_tuple_vec* const m_dtuple_vec;
+ /** Cache index rows made from a cluster index scan. Usually
+ for rows on single cluster index page */
+ typedef std::vector<dtuple_t*, ut_allocator<dtuple_t*> > idx_tuple_vec;
- /** the index being built */
- dict_index_t* const m_index;
-
- /** memory heap for creating index tuples */
- mem_heap_t* const m_heap;
+ /** vector used to cache index rows made from cluster index scan */
+ idx_tuple_vec m_dtuple_vec;
+public:
+ /** the index being built */
+ dict_index_t*const index;
};
/* Maximum pending doc memory limit in bytes for a fts tokenization thread */
@@ -1578,8 +1566,7 @@ row_mtuple_cmp(
@param[in] trx_id transaction id
@param[in] sp_tuples cached spatial rows
@param[in] num_spatial number of spatial indexes
-@param[in,out] heap heap for insert
-@param[in,out] sp_heap heap for tuples
+@param[in,out] heap temporary memory heap
@param[in,out] pcur cluster index cursor
@param[in,out] started whether mtr is active
@param[in,out] mtr mini-transaction
@@ -1588,10 +1575,9 @@ static
dberr_t
row_merge_spatial_rows(
trx_id_t trx_id,
- index_tuple_info_t** sp_tuples,
+ spatial_index_info** sp_tuples,
ulint num_spatial,
mem_heap_t* heap,
- mem_heap_t* sp_heap,
btr_pcur_t* pcur,
bool& started,
mtr_t* mtr)
@@ -1600,10 +1586,10 @@ row_merge_spatial_rows(
return DB_SUCCESS;
for (ulint j= 0; j < num_spatial; j++)
- if (dberr_t err= sp_tuples[j]->insert(trx_id, heap, pcur, started, mtr))
+ if (dberr_t err= sp_tuples[j]->insert(trx_id, pcur, started, heap, mtr))
return err;
- mem_heap_empty(sp_heap);
+ mem_heap_empty(heap);
return DB_SUCCESS;
}
@@ -1719,8 +1705,7 @@ row_merge_read_clustered_index(
doc_id_t max_doc_id = 0;
ibool add_doc_id = FALSE;
pthread_cond_t* fts_parallel_sort_cond = nullptr;
- index_tuple_info_t** sp_tuples = NULL;
- mem_heap_t* sp_heap = NULL;
+ spatial_index_info** sp_tuples = nullptr;
ulint num_spatial = 0;
BtrBulk* clust_btr_bulk = NULL;
bool clust_temp_file = false;
@@ -1809,9 +1794,7 @@ row_merge_read_clustered_index(
if (num_spatial > 0) {
ulint count = 0;
- sp_heap = mem_heap_create(512);
-
- sp_tuples = static_cast<index_tuple_info_t**>(
+ sp_tuples = static_cast<spatial_index_info**>(
ut_malloc_nokey(num_spatial
* sizeof(*sp_tuples)));
@@ -1819,9 +1802,7 @@ row_merge_read_clustered_index(
if (dict_index_is_spatial(index[i])) {
sp_tuples[count]
= UT_NEW_NOKEY(
- index_tuple_info_t(
- sp_heap,
- index[i]));
+ spatial_index_info(index[i]));
count++;
}
}
@@ -1996,7 +1977,7 @@ corrupted_rec:
/* Insert the cached spatial index rows. */
err = row_merge_spatial_rows(
trx->id, sp_tuples, num_spatial,
- row_heap, sp_heap, &pcur, mtr_started, &mtr);
+ row_heap, &pcur, mtr_started, &mtr);
if (err != DB_SUCCESS) {
goto func_exit;
@@ -2390,7 +2371,7 @@ write_buffers:
continue;
}
- ut_ad(sp_tuples[s_idx_cnt]->get_index()
+ ut_ad(sp_tuples[s_idx_cnt]->index
== buf->index);
/* If the geometry field is invalid, report
@@ -2400,7 +2381,7 @@ write_buffers:
break;
}
- sp_tuples[s_idx_cnt]->add(row, ext);
+ sp_tuples[s_idx_cnt]->add(row, ext, buf->heap);
s_idx_cnt++;
continue;
@@ -2522,7 +2503,7 @@ write_buffers:
err = row_merge_spatial_rows(
trx->id, sp_tuples,
num_spatial,
- row_heap, sp_heap,
+ row_heap,
&pcur, mtr_started,
&mtr);
@@ -2884,10 +2865,6 @@ wait_again:
UT_DELETE(sp_tuples[i]);
}
ut_free(sp_tuples);
-
- if (sp_heap) {
- mem_heap_free(sp_heap);
- }
}
/* Update the next Doc ID we used. Table should be locked, so
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 82079cbd06b..f65b47c0af8 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -6300,14 +6300,16 @@ rec_loop:
goto next_rec;
}
- if (index->is_clust())
+ if (prebuilt->table->is_temporary())
{
- if (prebuilt->trx->isolation_level == TRX_ISO_READ_UNCOMMITTED)
- {
- if (!rec_deleted)
- goto count_row;
+ count_or_not:
+ if (rec_deleted)
goto next_rec;
- }
+ }
+ else if (index->is_clust())
+ {
+ if (prebuilt->trx->isolation_level == TRX_ISO_READ_UNCOMMITTED)
+ goto count_or_not;
trx_id_t rec_trx_id= row_get_rec_trx_id(rec, index, offsets);
@@ -6371,10 +6373,7 @@ rec_loop:
ER_NOT_KEYFILE, "InnoDB: %s", w.m_oss.str().c_str());
}
- if (!rec_deleted)
- goto count_row;
-
- goto next_rec;
+ goto count_or_not;
}
else if (const trx_id_t page_trx_id= page_get_max_trx_id(page_align(rec)))
{
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index dfccf8dc394..587b5718a24 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -398,9 +398,6 @@ mysql_mutex_t srv_misc_tmpfile_mutex;
/** Temporary file for miscellanous diagnostic output */
FILE* srv_misc_tmpfile;
-static ulint srv_main_thread_process_no;
-static ulint srv_main_thread_id;
-
/* The following counts are used by the srv_master_callback. */
/** Iterations of the loop bounded by 'srv_active' label. */
@@ -895,12 +892,7 @@ srv_printf_innodb_monitor(
n_reserved);
}
- fprintf(file,
- "Process ID=" ULINTPF
- ", Main thread ID=" ULINTPF
- ", state: %s\n",
- srv_main_thread_process_no,
- srv_main_thread_id,
+ fprintf(file, "Process ID=0, Main thread ID=0, state: %s\n",
srv_main_thread_op_info);
fprintf(file,
"Number of rows inserted " ULINTPF
@@ -1487,31 +1479,29 @@ static void srv_sync_log_buffer_in_background()
}
}
-/*********************************************************************//**
-This function prints progress message every 60 seconds during server
-shutdown, for any activities that master thread is pending on. */
-static
-void
-srv_shutdown_print_master_pending(
-/*==============================*/
- time_t* last_print_time, /*!< last time the function
- print the message */
- ulint n_bytes_merged) /*!< number of change buffer
- just merged */
+/** Report progress during shutdown.
+@param last time of last output
+@param n_read number of page reads initiated for change buffer merge */
+static void srv_shutdown_print(time_t &last, ulint n_read)
{
- time_t current_time = time(NULL);
-
- if (difftime(current_time, *last_print_time) > 60) {
- *last_print_time = current_time;
+ time_t now= time(nullptr);
+ if (now - last >= 15)
+ {
+ last= now;
- /* Check change buffer merge, we only wait for change buffer
- merge if it is a slow shutdown */
- if (!srv_fast_shutdown && n_bytes_merged) {
- ib::info() << "Waiting for change buffer merge to"
- " complete number of bytes of change buffer"
- " just merged: " << n_bytes_merged;
- }
- }
+ const ulint ibuf_size= ibuf.size;
+ sql_print_information("Completing change buffer merge;"
+ " %zu page reads initiated;"
+ " %zu change buffer pages remain",
+ n_read, ibuf_size);
+#if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY
+ service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "Completing change buffer merge;"
+ " %zu page reads initiated;"
+ " %zu change buffer pages remain",
+ n_read, ibuf_size);
+#endif
+ }
}
/** Perform periodic tasks whenever the server is active.
@@ -1556,7 +1546,7 @@ Complete the shutdown tasks such as background DROP TABLE,
and optionally change buffer merge (on innodb_fast_shutdown=0). */
void srv_shutdown(bool ibuf_merge)
{
- ulint n_bytes_merged = 0;
+ ulint n_read = 0;
time_t now = time(NULL);
do {
@@ -1565,21 +1555,12 @@ void srv_shutdown(bool ibuf_merge)
++srv_main_shutdown_loops;
if (ibuf_merge) {
- srv_main_thread_op_info = "checking free log space";
- log_free_check();
srv_main_thread_op_info = "doing insert buffer merge";
- n_bytes_merged = ibuf_merge_all();
-
- /* Flush logs if needed */
- srv_sync_log_buffer_in_background();
- }
-
- /* Print progress message every 60 seconds during shutdown */
- if (srv_print_verbose_log) {
- srv_shutdown_print_master_pending(&now,
- n_bytes_merged);
+ log_free_check();
+ n_read = ibuf_contract();
+ srv_shutdown_print(now, n_read);
}
- } while (n_bytes_merged);
+ } while (n_read);
}
/** The periodic master task controlling the server. */
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index 2d012928601..9d1c13e11cd 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -191,7 +191,7 @@ ADD_DEPENDENCIES(rocksdb_aux_lib GenError)
# MARIAROCKS-TODO: how to properly depend on -lrt ?
TARGET_LINK_LIBRARIES(rocksdb_aux_lib rocksdblib ${ZLIB_LIBRARY})
-if (UNIX AND NOT APPLE)
+if (UNIX AND NOT APPLE AND NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
TARGET_LINK_LIBRARIES(rocksdb_aux_lib -lrt)
endif()
TARGET_LINK_LIBRARIES(rocksdb_aux_lib ${ATOMIC_EXTRA_LIBS})
@@ -242,7 +242,7 @@ ENDIF()
# ADD_SUBDIRECTORY(unittest)
#ENDIF()
-if (UNIX AND NOT APPLE)
+if (UNIX AND NOT APPLE AND NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
SET(rocksdb_static_libs ${rocksdb_static_libs} "-lrt")
endif()
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index 32300d7e0c6..d11e9a5f681 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -266,7 +266,7 @@ Rdb_cf_manager cf_manager;
Rdb_ddl_manager ddl_manager;
Rdb_binlog_manager binlog_manager;
-#if !defined(_WIN32) && !defined(__APPLE__)
+#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__)
Rdb_io_watchdog *io_watchdog = nullptr;
#endif
/**
@@ -850,7 +850,7 @@ static void rocksdb_set_io_write_timeout(
void *const var_ptr MY_ATTRIBUTE((__unused__)), const void *const save) {
DBUG_ASSERT(save != nullptr);
DBUG_ASSERT(rdb != nullptr);
-#if !defined(_WIN32) && !defined(__APPLE__)
+#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__)
DBUG_ASSERT(io_watchdog != nullptr);
#endif
@@ -859,7 +859,7 @@ static void rocksdb_set_io_write_timeout(
const uint32_t new_val = *static_cast<const uint32_t *>(save);
rocksdb_io_write_timeout_secs = new_val;
-#if !defined(_WIN32) && !defined(__APPLE__)
+#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__)
io_watchdog->reset_timeout(rocksdb_io_write_timeout_secs);
#endif
RDB_MUTEX_UNLOCK_CHECK(rdb_sysvars_mutex);
@@ -5798,7 +5798,7 @@ static int rocksdb_init_func(void *const p) {
directories.push_back(myrocks::rocksdb_wal_dir);
}
-#if !defined(_WIN32) && !defined(__APPLE__)
+#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__)
io_watchdog = new Rdb_io_watchdog(std::move(directories));
io_watchdog->reset_timeout(rocksdb_io_write_timeout_secs);
#endif
@@ -5905,7 +5905,7 @@ static int rocksdb_done_func(void *const p) {
delete commit_latency_stats;
commit_latency_stats = nullptr;
-#if !defined(_WIN32) && !defined(__APPLE__)
+#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__)
delete io_watchdog;
io_watchdog = nullptr;
#endif
diff --git a/storage/sphinx/CMakeLists.txt b/storage/sphinx/CMakeLists.txt
index 7cae7982e05..185ffdaaf91 100644
--- a/storage/sphinx/CMakeLists.txt
+++ b/storage/sphinx/CMakeLists.txt
@@ -19,4 +19,4 @@ IF(MSVC)
ENDIF(MSVC)
SET(SPHINX_SOURCES ha_sphinx.cc snippets_udf.cc)
-MYSQL_ADD_PLUGIN(sphinx ${SPHINX_SOURCES} STORAGE_ENGINE)
+MYSQL_ADD_PLUGIN(sphinx ${SPHINX_SOURCES} STORAGE_ENGINE RECOMPILE_FOR_EMBEDDED)
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index 8ff71212878..289c28d4cf4 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -97,7 +97,7 @@ sslGetErrString(enum enum_ssl_init_error e)
static int
vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
- enum enum_ssl_init_error* error)
+ my_bool is_client, enum enum_ssl_init_error* error)
{
DBUG_ENTER("vio_set_cert_stuff");
DBUG_PRINT("enter", ("ctx: %p cert_file: %s key_file: %s",
@@ -134,10 +134,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
}
/*
- If we are using DSA, we can copy the parameters from the private key
- Now we know that a key and cert have been set against the SSL context
+ If certificate is used check if private key matches.
+ Note, that server side has to use certificate.
*/
- if (cert_file && !SSL_CTX_check_private_key(ctx))
+ if ((cert_file != NULL || !is_client) && !SSL_CTX_check_private_key(ctx))
{
*error= SSL_INITERR_NOMATCH;
DBUG_PRINT("error", ("%s",sslGetErrString(*error)));
@@ -353,7 +353,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
#endif
}
- if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file, error))
+ if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file,
+ is_client_method, error))
{
DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
goto err2;