summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-03-30 09:41:14 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-03-30 09:41:14 +0300
commit8680eedb2650ba017305cf8db26c96d056196375 (patch)
tree67706bfa48f3808fb1180bd53b503caddc4f9b02
parent0c4c064f98120e179ddfa49a1010d465a07bdc0a (diff)
parent5c69e936308b9b636d3e58aff624d2716f289fbd (diff)
downloadmariadb-git-8680eedb2650ba017305cf8db26c96d056196375.tar.gz
Merge 10.8 into 10.9
-rw-r--r--CREDITS2
-rw-r--r--client/mysqlbinlog.cc1
-rw-r--r--client/mysqltest.cc455
-rw-r--r--cmake/submodules.cmake35
-rwxr-xr-xdebian/autobake-deb.sh179
-rw-r--r--debian/control43
-rw-r--r--debian/mariadb-plugin-provider-bzip2.lintian-overrides3
-rw-r--r--debian/mariadb-plugin-provider-lz4.lintian-overrides3
-rw-r--r--debian/mariadb-plugin-provider-lzma.lintian-overrides3
-rw-r--r--debian/mariadb-plugin-provider-lzo.lintian-overrides3
-rw-r--r--debian/mariadb-plugin-provider-snappy.lintian-overrides3
-rwxr-xr-xdebian/rules2
-rw-r--r--debian/source/lintian-overrides4
-rw-r--r--extra/innochecksum.cc2
-rw-r--r--include/my_atomic.h18
-rw-r--r--mysql-test/include/have_innodb.inc12
-rw-r--r--mysql-test/main/contributors.result2
-rw-r--r--mysql-test/main/create_or_replace.result45
-rw-r--r--mysql-test/main/create_or_replace.test47
-rw-r--r--mysql-test/main/ctype_utf32.result48
-rw-r--r--mysql-test/main/ctype_utf32.test38
-rw-r--r--mysql-test/main/ctype_utf32_uca.result15
-rw-r--r--mysql-test/main/ctype_utf32_uca.test13
-rw-r--r--mysql-test/main/drop_bad_db_type.result54
-rw-r--r--mysql-test/main/drop_bad_db_type.test19
-rw-r--r--mysql-test/main/error_simulation.result10
-rw-r--r--mysql-test/main/error_simulation.test13
-rw-r--r--mysql-test/main/flush_block_commit_notembedded.test4
-rw-r--r--mysql-test/main/func_json_notembedded.result6
-rw-r--r--mysql-test/main/func_json_notembedded.test4
-rw-r--r--mysql-test/main/multi_update_innodb.result15
-rw-r--r--mysql-test/main/multi_update_innodb.test19
-rw-r--r--mysql-test/main/opt_tvc.result27
-rw-r--r--mysql-test/main/opt_tvc.test26
-rw-r--r--mysql-test/main/partition_not_blackhole.result2
-rw-r--r--mysql-test/main/partition_not_blackhole.test2
-rw-r--r--mysql-test/main/processlist.result20
-rw-r--r--mysql-test/main/processlist.test35
-rw-r--r--mysql-test/main/sp-cursor.result63
-rw-r--r--mysql-test/main/sp-cursor.test56
-rw-r--r--mysql-test/main/truncate_notembedded.result2
-rw-r--r--mysql-test/main/view.result28
-rw-r--r--mysql-test/main/view.test26
-rw-r--r--mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result6
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result7
-rw-r--r--mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang-master.opt1
-rw-r--r--mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test45
-rw-r--r--mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test45
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-package.result308
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-package.test327
-rw-r--r--mysql-test/suite/encryption/t/innochecksum.test5
-rw-r--r--mysql-test/suite/funcs_2/charset/charset_master.test20
-rw-r--r--mysql-test/suite/funcs_2/r/innodb_charset.result80
-rw-r--r--mysql-test/suite/funcs_2/r/memory_charset.result80
-rw-r--r--mysql-test/suite/funcs_2/r/myisam_charset.result80
-rw-r--r--mysql-test/suite/galera/disabled.def1
-rw-r--r--mysql-test/suite/galera/include/kill_galera.inc2
-rw-r--r--mysql-test/suite/galera/r/MDEV-24143.result23
-rw-r--r--mysql-test/suite/galera/r/MDEV-27713.result46
-rw-r--r--mysql-test/suite/galera/r/galera_bf_abort_ps_bind.result37
-rw-r--r--mysql-test/suite/galera/r/galera_ist_restart_joiner.result1
-rw-r--r--mysql-test/suite/galera/r/galera_kill_applier.result4
-rw-r--r--mysql-test/suite/galera/t/MDEV-24143.test20
-rw-r--r--mysql-test/suite/galera/t/MDEV-27713.test67
-rw-r--r--mysql-test/suite/galera/t/MW-44.test6
-rw-r--r--mysql-test/suite/galera/t/galera_bf_abort_ps_bind.cnf7
-rw-r--r--mysql-test/suite/galera/t/galera_bf_abort_ps_bind.test58
-rw-r--r--mysql-test/suite/galera/t/galera_ist_restart_joiner.test14
-rw-r--r--mysql-test/suite/galera/t/galera_kill_applier.test6
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_garbd_backup.result41
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_garbd_backup.cnf13
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_garbd_backup.test134
-rw-r--r--mysql-test/suite/galera_sr/disabled.def1
-rw-r--r--mysql-test/suite/galera_sr/r/MDEV-27553.result25
-rw-r--r--mysql-test/suite/galera_sr/t/MDEV-27553.test65
-rw-r--r--mysql-test/suite/gcol/inc/gcol_supported_sql_funcs_main.inc3
-rw-r--r--mysql-test/suite/innodb/include/innodb-page-compression.inc4
-rw-r--r--mysql-test/suite/innodb/r/insert_into_empty.result10
-rw-r--r--mysql-test/suite/innodb/r/row_format_redundant.result23
-rw-r--r--mysql-test/suite/innodb/t/alter_crash_rebuild.test26
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_compression_bzip2.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_compression_lz4.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_compression_lzma.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_compression_lzo.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_compression_tables.test4
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_compression_zip.test5
-rw-r--r--mysql-test/suite/innodb/t/insert_into_empty.test11
-rw-r--r--mysql-test/suite/innodb/t/row_format_redundant.test27
-rw-r--r--mysql-test/suite/innodb/t/undo_truncate.test3
-rw-r--r--mysql-test/suite/innodb_zip/r/innochecksum.result3
-rw-r--r--mysql-test/suite/innodb_zip/r/innochecksum_2.result3
-rw-r--r--mysql-test/suite/innodb_zip/r/innochecksum_3.result1
-rw-r--r--mysql-test/suite/innodb_zip/t/innochecksum.test8
-rw-r--r--mysql-test/suite/parts/r/partition_alter_innodb.result8
-rw-r--r--mysql-test/suite/parts/t/partition_alter_innodb.test8
-rw-r--r--mysql-test/suite/perfschema/include/program_nested_setup.inc3
-rw-r--r--mysql-test/suite/perfschema/r/max_program_zero.result2
-rw-r--r--mysql-test/suite/perfschema/r/statement_program_lost_inst.result2
-rw-r--r--mysql-test/suite/perfschema/r/statement_program_nested.result5
-rw-r--r--mysql-test/suite/perfschema/r/statement_program_nesting_event_check.result5
-rw-r--r--mysql-test/suite/perfschema/t/statement_program_nested.test2
-rw-r--r--mysql-test/suite/perfschema/t/statement_program_nesting_event_check.test3
-rw-r--r--mysql-test/suite/rpl/r/mdev_24667.result30
-rw-r--r--mysql-test/suite/rpl/r/rpl_circular_semi_sync.result76
-rw-r--r--mysql-test/suite/rpl/t/mdev_24667.cnf8
-rw-r--r--mysql-test/suite/rpl/t/mdev_24667.test56
-rw-r--r--mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf11
-rw-r--r--mysql-test/suite/rpl/t/rpl_circular_semi_sync.test115
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result5
-rw-r--r--mysql-test/suite/versioning/common.inc2
-rw-r--r--mysys/my_rename.c9
-rw-r--r--plugin/server_audit/server_audit.c6
-rw-r--r--scripts/CMakeLists.txt1
-rw-r--r--scripts/mysql_install_db.sh2
-rw-r--r--scripts/mysql_system_tables_fix.sql9
-rw-r--r--scripts/wsrep_sst_backup.sh112
-rw-r--r--sql/contributors.h2
-rw-r--r--sql/ha_partition.cc85
-rw-r--r--sql/ha_partition.h3
-rw-r--r--sql/handler.h4
-rw-r--r--sql/item.cc22
-rw-r--r--sql/item_cmpfunc.cc7
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/log.cc2
-rw-r--r--sql/mysqld.cc7
-rw-r--r--sql/rpl_rli.cc2
-rw-r--r--sql/semisync_master.cc1
-rw-r--r--sql/share/errmsg-utf8.txt48
-rw-r--r--sql/slave.cc24
-rw-r--r--sql/sp_head.cc1
-rw-r--r--sql/sql_class.cc53
-rw-r--r--sql/sql_class.h30
-rw-r--r--sql/sql_lex.cc87
-rw-r--r--sql/sql_lex.h9
-rw-r--r--sql/sql_parse.cc40
-rw-r--r--sql/sql_prepare.cc12
-rw-r--r--sql/sql_show.cc12
-rw-r--r--sql/sql_table.cc69
-rw-r--r--sql/sql_tvc.cc31
-rw-r--r--sql/sql_update.cc5
-rw-r--r--sql/sql_view.cc3
-rw-r--r--sql/sql_yacc.yy50
-rw-r--r--sql/sys_vars.cc4
-rw-r--r--sql/table.cc39
-rw-r--r--sql/temporary_tables.cc8
-rw-r--r--sql/unireg.cc11
-rw-r--r--sql/unireg.h16
-rw-r--r--sql/wsrep_client_service.cc1
-rw-r--r--sql/wsrep_high_priority_service.cc1
-rw-r--r--sql/wsrep_mysqld.cc87
-rw-r--r--sql/wsrep_mysqld.h1
-rw-r--r--sql/wsrep_sst.cc81
-rw-r--r--storage/innobase/btr/btr0btr.cc24
-rw-r--r--storage/innobase/buf/buf0buf.cc99
-rw-r--r--storage/innobase/buf/buf0flu.cc10
-rw-r--r--storage/innobase/buf/buf0rea.cc57
-rw-r--r--storage/innobase/dict/dict0crea.cc62
-rw-r--r--storage/innobase/dict/dict0load.cc736
-rw-r--r--storage/innobase/fil/fil0fil.cc40
-rw-r--r--storage/innobase/fts/fts0fts.cc13
-rw-r--r--storage/innobase/handler/ha_innodb.cc39
-rw-r--r--storage/innobase/handler/handler0alter.cc8
-rw-r--r--storage/innobase/handler/i_s.cc17
-rw-r--r--storage/innobase/include/buf0buf.h7
-rw-r--r--storage/innobase/include/dict0load.h14
-rw-r--r--storage/innobase/include/fil0fil.h7
-rw-r--r--storage/innobase/include/lock0lock.h18
-rw-r--r--storage/innobase/include/log0log.h8
-rw-r--r--storage/innobase/include/mtr0mtr.h9
-rw-r--r--storage/innobase/include/rem0rec.h8
-rw-r--r--storage/innobase/include/trx0purge.h6
-rw-r--r--storage/innobase/lock/lock0lock.cc82
-rw-r--r--storage/innobase/log/log0log.cc22
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc59
-rw-r--r--storage/innobase/rem/rem0rec.cc11
-rw-r--r--storage/innobase/row/row0import.cc8
-rw-r--r--storage/innobase/row/row0merge.cc18
-rw-r--r--storage/innobase/row/row0mysql.cc2
-rw-r--r--storage/innobase/row/row0row.cc16
-rw-r--r--storage/innobase/row/row0sel.cc43
-rw-r--r--storage/innobase/srv/srv0start.cc6
-rw-r--r--storage/innobase/trx/trx0rec.cc3
-rw-r--r--storage/maria/CMakeLists.txt5
-rw-r--r--storage/maria/ma_open.c9
-rw-r--r--storage/maria/s3_func.c2
-rw-r--r--storage/perfschema/unittest/stub_pfs_global.h14
-rw-r--r--strings/decimal.c32
-rw-r--r--tpool/aio_liburing.cc3
-rw-r--r--tpool/aio_linux.cc3
-rw-r--r--tpool/tpool.h12
-rw-r--r--tpool/tpool_generic.cc15
191 files changed, 4771 insertions, 1249 deletions
diff --git a/CREDITS b/CREDITS
index f5e87e18752..35092602ccf 100644
--- a/CREDITS
+++ b/CREDITS
@@ -4,9 +4,11 @@ organization registered in the USA.
The current main sponsors of the MariaDB Foundation are:
Alibaba Cloud https://www.alibabacloud.com/ (2017)
+Intel https://www.intel.com (2022)
MariaDB Corporation https://www.mariadb.com (2013)
Microsoft https://microsoft.com/ (2017)
ServiceNow https://servicenow.com (2019)
+SIT https://sit.org (2022)
Tencent Cloud https://cloud.tencent.com (2017)
Development Bank of Singapore https://dbs.com (2016)
IBM https://www.ibm.com (2017)
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 600810d7dab..21980ca03d6 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -2893,6 +2893,7 @@ static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info,
error("Could not write into log file '%s'", out_file_name);
DBUG_RETURN(ERROR_STOP);
}
+ fflush(result_file);
DBUG_RETURN(OK_CONTINUE);
}
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 92a24154cbc..e411ff49df4 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2021, MariaDB
+ Copyright (c) 2009, 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
@@ -319,6 +319,7 @@ struct st_connection
char *name;
size_t name_len;
MYSQL_STMT* stmt;
+ MYSQL_BIND *ps_params;
/* Set after send to disallow other queries before reap */
my_bool pending;
@@ -393,6 +394,10 @@ enum enum_commands {
Q_ENABLE_PREPARE_WARNINGS, Q_DISABLE_PREPARE_WARNINGS,
Q_RESET_CONNECTION,
Q_OPTIMIZER_TRACE,
+ Q_PS_PREPARE,
+ Q_PS_BIND,
+ Q_PS_EXECUTE,
+ Q_PS_CLOSE,
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
Q_COMMENT_WITH_COMMAND,
@@ -506,6 +511,10 @@ const char *command_names[]=
"disable_prepare_warnings",
"reset_connection",
"optimizer_trace",
+ "PS_prepare",
+ "PS_bind",
+ "PS_execute",
+ "PS_close",
0
};
@@ -7958,6 +7967,15 @@ static void handle_no_active_connection(struct st_command *command,
var_set_errno(2006);
}
+/* handler functions to execute prepared statement calls in client C API */
+void run_prepare_stmt(struct st_connection *cn, struct st_command *command, const char *query,
+ size_t query_len, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings);
+void run_bind_stmt(struct st_connection *cn, struct st_command *command, const char *query,
+ size_t query_len, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings);
+void run_execute_stmt(struct st_connection *cn, struct st_command *command, const char *query,
+ size_t query_len, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings);
+void run_close_stmt(struct st_connection *cn, struct st_command *command, const char *query,
+ size_t query_len, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings);
/*
Run query using MySQL C API
@@ -7989,6 +8007,32 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
DBUG_VOID_RETURN;
}
+ /* handle prepared statement commands */
+ switch (command->type) {
+ case Q_PS_PREPARE:
+ run_prepare_stmt(cn, command, query, query_len, ds, ds_warnings);
+ flags &= ~QUERY_SEND_FLAG;
+ goto end;
+ break;
+ case Q_PS_BIND:
+ run_bind_stmt(cn, command, query, query_len, ds, ds_warnings);
+ flags &= ~QUERY_SEND_FLAG;
+ goto end;
+ break;
+ case Q_PS_EXECUTE:
+ run_execute_stmt(cn, command, query, query_len, ds, ds_warnings);
+ flags &= ~QUERY_SEND_FLAG;
+ goto end;
+ break;
+ case Q_PS_CLOSE:
+ run_close_stmt(cn, command, query, query_len, ds, ds_warnings);
+ flags &= ~QUERY_SEND_FLAG;
+ goto end;
+ break;
+ default: /* not a prepared statement command */
+ break;
+ }
+
if (flags & QUERY_SEND_FLAG)
{
/*
@@ -8562,6 +8606,411 @@ end:
DBUG_VOID_RETURN;
}
+/*
+ prepare query using prepared statement C API
+
+ SYNPOSIS
+ run_prepare_stmt
+ mysql - mysql handle
+ command - current command pointer
+ query - query string to execute
+ query_len - length query string to execute
+ ds - output buffer where to store result form query
+
+ RETURN VALUE
+ error - function will not return
+*/
+
+void run_prepare_stmt(struct st_connection *cn, struct st_command *command, const char *query, size_t query_len, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
+{
+
+ MYSQL *mysql= cn->mysql;
+ MYSQL_STMT *stmt;
+ DYNAMIC_STRING ds_prepare_warnings;
+ DBUG_ENTER("run_prepare_stmt");
+ DBUG_PRINT("query", ("'%-.60s'", query));
+
+ /*
+ Init a new stmt if it's not already one created for this connection
+ */
+ if(!(stmt= cn->stmt))
+ {
+ if (!(stmt= mysql_stmt_init(mysql)))
+ die("unable to init stmt structure");
+ cn->stmt= stmt;
+ }
+
+ /* Init dynamic strings for warnings */
+ if (!disable_warnings)
+ {
+ init_dynamic_string(&ds_prepare_warnings, NULL, 0, 256);
+ }
+
+ /*
+ Prepare the query
+ */
+ char* PS_query= command->first_argument;
+ size_t PS_query_len= command->end - command->first_argument;
+ if (do_stmt_prepare(cn, PS_query, PS_query_len))
+ {
+ handle_error(command, mysql_stmt_errno(stmt),
+ mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
+ goto end;
+ }
+
+ /*
+ Get the warnings from mysql_stmt_prepare and keep them in a
+ separate string
+ */
+ if (!disable_warnings)
+ append_warnings(&ds_prepare_warnings, mysql);
+ end:
+ DBUG_VOID_RETURN;
+}
+
+/*
+ bind parameters for a prepared statement C API
+
+ SYNPOSIS
+ run_bind_stmt
+ mysql - mysql handle
+ command - current command pointer
+ query - query string to execute
+ query_len - length query string to execute
+ ds - output buffer where to store result form query
+
+ RETURN VALUE
+ error - function will not return
+*/
+
+void run_bind_stmt(struct st_connection *cn, struct st_command *command,
+ const char *query, size_t query_len, DYNAMIC_STRING *ds,
+ DYNAMIC_STRING *ds_warnings
+ )
+{
+ MYSQL_STMT *stmt= cn->stmt;
+ DBUG_ENTER("run_bind_stmt");
+ DBUG_PRINT("query", ("'%-.60s'", query));
+ MYSQL_BIND *ps_params= cn->ps_params;
+ if (ps_params)
+ {
+ for (size_t i=0; i<stmt->param_count; i++)
+ {
+ my_free(ps_params[i].buffer);
+ ps_params[i].buffer= NULL;
+ }
+ my_free(ps_params);
+ ps_params= NULL;
+ }
+
+ /* Init PS-parameters. */
+ cn->ps_params= ps_params = (MYSQL_BIND*)my_malloc(PSI_NOT_INSTRUMENTED,
+ sizeof(MYSQL_BIND) *
+ stmt->param_count,
+ MYF(MY_WME));
+ bzero((char *) ps_params, sizeof(MYSQL_BIND) * stmt->param_count);
+
+ int i=0;
+ char *c;
+ long *l;
+ double *d;
+
+ char *p= strtok((char*)command->first_argument, " ");
+ while (p != nullptr)
+ {
+ (void)strtol(p, &c, 10);
+ if (!*c)
+ {
+ ps_params[i].buffer_type= MYSQL_TYPE_LONG;
+ l= (long*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(long), MYF(MY_WME));
+ *l= strtol(p, &c, 10);
+ ps_params[i].buffer= (void*)l;
+ ps_params[i].buffer_length= 8;
+ }
+ else
+ {
+ (void)strtod(p, &c);
+ if (!*c)
+ {
+ ps_params[i].buffer_type= MYSQL_TYPE_DECIMAL;
+ d= (double*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(double),
+ MYF(MY_WME));
+ *d= strtod(p, &c);
+ ps_params[i].buffer= (void*)d;
+ ps_params[i].buffer_length= 8;
+ }
+ else
+ {
+ ps_params[i].buffer_type= MYSQL_TYPE_STRING;
+ ps_params[i].buffer= strdup(p);
+ ps_params[i].buffer_length= (unsigned long)strlen(p);
+ }
+ }
+
+ p= strtok(nullptr, " ");
+ i++;
+ }
+
+ int rc= mysql_stmt_bind_param(stmt, ps_params);
+ if (rc)
+ {
+ die("mysql_stmt_bind_param() failed': %d %s",
+ mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+/*
+ execute query using prepared statement C API
+
+ SYNPOSIS
+ run_axecute_stmt
+ mysql - mysql handle
+ command - current command pointer
+ query - query string to execute
+ query_len - length query string to execute
+ ds - output buffer where to store result form query
+
+ RETURN VALUE
+ error - function will not return
+*/
+
+void run_execute_stmt(struct st_connection *cn, struct st_command *command,
+ const char *query, size_t query_len, DYNAMIC_STRING *ds,
+ DYNAMIC_STRING *ds_warnings
+ )
+{
+ MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */
+ MYSQL *mysql= cn->mysql;
+ MYSQL_STMT *stmt= cn->stmt;
+ DYNAMIC_STRING ds_execute_warnings;
+ DBUG_ENTER("run_execute_stmt");
+ DBUG_PRINT("query", ("'%-.60s'", query));
+
+ /* Init dynamic strings for warnings */
+ if (!disable_warnings)
+ {
+ init_dynamic_string(&ds_execute_warnings, NULL, 0, 256);
+ }
+
+#if MYSQL_VERSION_ID >= 50000
+ if (cursor_protocol_enabled)
+ {
+ /*
+ Use cursor when retrieving result
+ */
+ ulong type= CURSOR_TYPE_READ_ONLY;
+ if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type))
+ die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s",
+ mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
+ }
+#endif
+
+ /*
+ Execute the query
+ */
+ if (do_stmt_execute(cn))
+ {
+ handle_error(command, mysql_stmt_errno(stmt),
+ mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
+ goto end;
+ }
+
+ /*
+ When running in cursor_protocol get the warnings from execute here
+ and keep them in a separate string for later.
+ */
+ if (cursor_protocol_enabled && !disable_warnings)
+ append_warnings(&ds_execute_warnings, mysql);
+
+ /*
+ We instruct that we want to update the "max_length" field in
+ mysql_stmt_store_result(), this is our only way to know how much
+ buffer to allocate for result data
+ */
+ {
+ my_bool one= 1;
+ if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one))
+ die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s",
+ mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
+ }
+
+ /*
+ If we got here the statement succeeded and was expected to do so,
+ get data. Note that this can still give errors found during execution!
+ Store the result of the query if if will return any fields
+ */
+ if (mysql_stmt_field_count(stmt) && mysql_stmt_store_result(stmt))
+ {
+ handle_error(command, mysql_stmt_errno(stmt),
+ mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
+ goto end;
+ }
+
+ /* If we got here the statement was both executed and read successfully */
+ handle_no_error(command);
+ if (!disable_result_log)
+ {
+ /*
+ Not all statements creates a result set. If there is one we can
+ now create another normal result set that contains the meta
+ data. This set can be handled almost like any other non prepared
+ statement result set.
+ */
+ if ((res= mysql_stmt_result_metadata(stmt)) != NULL)
+ {
+ /* Take the column count from meta info */
+ MYSQL_FIELD *fields= mysql_fetch_fields(res);
+ uint num_fields= mysql_num_fields(res);
+
+ if (display_metadata)
+ append_metadata(ds, fields, num_fields);
+
+ if (!display_result_vertically)
+ append_table_headings(ds, fields, num_fields);
+
+ append_stmt_result(ds, stmt, fields, num_fields);
+
+ mysql_free_result(res); /* Free normal result set with meta data */
+
+ /*
+ Normally, if there is a result set, we do not show warnings from the
+ prepare phase. This is because some warnings are generated both during
+ prepare and execute; this would generate different warning output
+ between normal and ps-protocol test runs.
+
+ The --enable_prepare_warnings command can be used to change this so
+ that warnings from both the prepare and execute phase are shown.
+ */
+ }
+ else
+ {
+ /*
+ This is a query without resultset
+ */
+ }
+
+ /*
+ Fetch info before fetching warnings, since it will be reset
+ otherwise.
+ */
+ if (!disable_info)
+ append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql));
+
+ if (display_session_track_info)
+ append_session_track_info(ds, mysql);
+
+
+ if (!disable_warnings)
+ {
+ /* Get the warnings from execute */
+
+ /* Append warnings to ds - if there are any */
+ if (append_warnings(&ds_execute_warnings, mysql) ||
+ ds_execute_warnings.length ||
+ ds_warnings->length)
+ {
+ dynstr_append_mem(ds, "Warnings:\n", 10);
+ if (ds_warnings->length)
+ dynstr_append_mem(ds, ds_warnings->str,
+ ds_warnings->length);
+ if (ds_execute_warnings.length)
+ dynstr_append_mem(ds, ds_execute_warnings.str,
+ ds_execute_warnings.length);
+ }
+ }
+ }
+
+end:
+ if (!disable_warnings)
+ {
+ dynstr_free(&ds_execute_warnings);
+ }
+
+ /*
+ We save the return code (mysql_stmt_errno(stmt)) from the last call sent
+ to the server into the mysqltest builtin variable $mysql_errno. This
+ variable then can be used from the test case itself.
+ */
+
+ var_set_errno(mysql_stmt_errno(stmt));
+
+ revert_properties();
+
+ /* Close the statement if reconnect, need new prepare */
+ {
+#ifndef EMBEDDED_LIBRARY
+ my_bool reconnect;
+ mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect);
+ if (reconnect)
+#else
+ if (mysql->reconnect)
+#endif
+ {
+ if (cn->ps_params)
+ {
+ for (size_t i=0; i<stmt->param_count; i++)
+ {
+ my_free(cn->ps_params[i].buffer);
+ cn->ps_params[i].buffer= NULL;
+ }
+ my_free(cn->ps_params);
+ }
+ mysql_stmt_close(stmt);
+ cn->stmt= NULL;
+ cn->ps_params= NULL;
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
+ close a prepared statement C API
+
+ SYNPOSIS
+ run_close_stmt
+ mysql - mysql handle
+ command - current command pointer
+ query - query string to execute
+ query_len - length query string to execute
+ ds - output buffer where to store result form query
+
+ RETURN VALUE
+ error - function will not return
+*/
+
+void run_close_stmt(struct st_connection *cn, struct st_command *command,
+ const char *query, size_t query_len, DYNAMIC_STRING *ds,
+ DYNAMIC_STRING *ds_warnings
+ )
+{
+ MYSQL_STMT *stmt= cn->stmt;
+ DBUG_ENTER("run_close_stmt");
+ DBUG_PRINT("query", ("'%-.60s'", query));
+
+ if (cn->ps_params)
+ {
+
+ for (size_t i=0; i<stmt->param_count; i++)
+ {
+ my_free(cn->ps_params[i].buffer);
+ cn->ps_params[i].buffer= NULL;
+ }
+ my_free(cn->ps_params);
+ }
+
+ /* Close the statement */
+ if (stmt)
+ {
+ mysql_stmt_close(stmt);
+ cn->stmt= NULL;
+ }
+ cn->ps_params= NULL;
+
+ DBUG_VOID_RETURN;
+}
+
/*
@@ -9622,6 +10071,10 @@ int main(int argc, char **argv)
/* fall through */
case Q_QUERY:
case Q_REAP:
+ case Q_PS_PREPARE:
+ case Q_PS_BIND:
+ case Q_PS_EXECUTE:
+ case Q_PS_CLOSE:
{
my_bool old_display_result_vertically= display_result_vertically;
/* Default is full query, both reap and send */
diff --git a/cmake/submodules.cmake b/cmake/submodules.cmake
index 91f9f9e487a..34dcfbea77a 100644
--- a/cmake/submodules.cmake
+++ b/cmake/submodules.cmake
@@ -17,20 +17,29 @@ IF(GIT_EXECUTABLE AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
${GIT_EXECUTABLE} config cmake.update-submodules yes")
ELSEIF(git_config_get_result EQUAL 128)
SET(update_result 0)
- ELSEIF (cmake_update_submodules MATCHES force)
- MESSAGE(STATUS "Updating submodules (forced)")
- EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" submodule update --init --force --recursive --depth=1
- WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
- RESULT_VARIABLE update_result)
- ELSEIF (cmake_update_submodules MATCHES yes)
- EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" submodule update --init --recursive --depth=1
- WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
- RESULT_VARIABLE update_result)
ELSE()
- MESSAGE(STATUS "Updating submodules")
- EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" submodule update --init --recursive --depth=1
- WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
- RESULT_VARIABLE update_result)
+ SET(UPDATE_SUBMODULES_COMMAND
+ "${GIT_EXECUTABLE}" submodule update --init --recursive)
+ # Old Git may not work with "--depth 1".
+ # See also: https://github.com/git/git/commit/fb43e31f2b43076e7a30c9cd00d0241cb8cf97eb
+ IF(NOT GIT_VERSION_STRING VERSION_LESS "2.8.0")
+ SET(UPDATE_SUBMODULES_COMMAND ${UPDATE_SUBMODULES_COMMAND} --depth 1)
+ ENDIF()
+ IF(cmake_update_submodules MATCHES force)
+ MESSAGE(STATUS "Updating submodules (forced)")
+ EXECUTE_PROCESS(COMMAND ${UPDATE_SUBMODULES_COMMAND} --force
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+ RESULT_VARIABLE update_result)
+ ELSEIF(cmake_update_submodules MATCHES yes)
+ EXECUTE_PROCESS(COMMAND ${UPDATE_SUBMODULES_COMMAND}
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+ RESULT_VARIABLE update_result)
+ ELSE()
+ MESSAGE(STATUS "Updating submodules")
+ EXECUTE_PROCESS(COMMAND ${UPDATE_SUBMODULES_COMMAND}
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+ RESULT_VARIABLE update_result)
+ ENDIF()
ENDIF()
ENDIF()
diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh
index 58eed048077..60532dd8e0b 100755
--- a/debian/autobake-deb.sh
+++ b/debian/autobake-deb.sh
@@ -11,26 +11,17 @@
# Exit immediately on any error
set -e
-source ./VERSION
-
-CODENAME="$(lsb_release -sc)"
-case "${CODENAME}" in
- stretch)
- # MDEV-28022 libzstd-dev-1.1.3 minimum version
- sed -i -e '/libzstd-dev/d' debian/control
- ;;
-esac
-
-# This file is invoked from Buildbot and Travis-CI to build deb packages.
-# As both of those CI systems have many parallel jobs that include different
-# parts of the test suite, we don't need to run the mysql-test-run at all when
-# building the deb packages here.
+# On Buildbot, don't run the mysql-test-run test suite as part of build.
+# It takes a lot of time, and we will do a better test anyway in
+# Buildbot, running the test suite from installed .debs on a clean VM.
export DEB_BUILD_OPTIONS="nocheck $DEB_BUILD_OPTIONS"
+source ./VERSION
+
# General CI optimizations to keep build output smaller
-if [[ $TRAVIS ]] || [[ $GITLAB_CI ]]
+if [[ $GITLAB_CI ]]
then
- # On both Travis and Gitlab the output log must stay under 4MB so make the
+ # On Gitlab the output log must stay under 4MB so make the
# build less verbose
sed '/Add support for verbose builds/,/^$/d' -i debian/rules
elif [ -d storage/columnstore/columnstore/debian ]
@@ -45,67 +36,106 @@ then
sed "s/10.6/${MYSQL_VERSION_MAJOR}.${MYSQL_VERSION_MINOR}/" <storage/columnstore/columnstore/debian/control >> debian/control
fi
-# Don't build or try to put files in a package for selected plugins and components on Travis-CI
-# in order to keep build small (in both duration and disk space)
-if [[ $TRAVIS ]]
-then
- # Test suite package not relevant on Travis-CI
- sed 's|DINSTALL_MYSQLTESTDIR=share/mysql/mysql-test|DINSTALL_MYSQLTESTDIR=false|' -i debian/rules
- sed '/Package: mariadb-test-data/,/^$/d' -i debian/control
- sed '/Package: mariadb-test$/,/^$/d' -i debian/control
-
- # Extra plugins such as Mroonga, Spider, OQgraph, Sphinx and the embedded build can safely be skipped
- sed 's|-DDEB|-DPLUGIN_MROONGA=NO -DPLUGIN_ROCKSDB=NO -DPLUGIN_SPIDER=NO -DPLUGIN_OQGRAPH=NO -DPLUGIN_PERFSCHEMA=NO -DPLUGIN_SPHINX=NO -DWITH_EMBEDDED_SERVER=OFF -DDEB|' -i debian/rules
- sed "/Package: mariadb-plugin-mroonga/,/^$/d" -i debian/control
- sed "/Package: mariadb-plugin-rocksdb/,/^$/d" -i debian/control
- sed "/Package: mariadb-plugin-spider/,/^$/d" -i debian/control
- sed "/Package: mariadb-plugin-oqgraph/,/^$/d" -i debian/control
- sed "/ha_sphinx.so/d" -i debian/mariadb-server-${MYSQL_VERSION_MAJOR}.${MYSQL_VERSION_MINOR}.install
- sed "/Package: libmariadbd19/,/^$/d" -i debian/control
- sed "/Package: libmariadbd-dev/,/^$/d" -i debian/control
-fi
+# Look up distro-version specific stuff
+#
+# Always keep the actual packaging as up-to-date as possible following the latest
+# Debian policy and targeting Debian Sid. Then case-by-case run in autobake-deb.sh
+# tests for backwards compatibility and strip away parts on older builders.
-# If rocksdb-tools is not available (before Debian Buster and Ubuntu Disco)
-# remove the dependency from the RocksDB plugin so it can install properly
-# and instead ship the one built from MariaDB sources
-if ! apt-cache madison rocksdb-tools | grep 'rocksdb-tools' >/dev/null 2>&1
-then
+remove_rocksdb_tools()
+{
sed '/rocksdb-tools/d' -i debian/control
sed '/sst_dump/d' -i debian/not-installed
- echo "usr/bin/sst_dump" >> debian/mariadb-plugin-rocksdb.install
-fi
-
-# If libcurl4 is not available (before Debian Buster and Ubuntu Bionic)
-# use older libcurl3 instead
-if ! apt-cache madison libcurl4 | grep 'libcurl4' >/dev/null 2>&1
-then
- sed 's/libcurl4/libcurl3/g' -i debian/control
-fi
-
-# From Debian Bullseye/Ubuntu Groovy, liburing replaces libaio
-if ! apt-cache madison liburing-dev | grep 'liburing-dev' >/dev/null 2>&1
-then
+ if ! grep -q sst_dump debian/mariadb-plugin-rocksdb.install
+ then
+ echo "usr/bin/sst_dump" >> debian/mariadb-plugin-rocksdb.install
+ fi
+}
+
+replace_uring_with_aio()
+{
sed 's/liburing-dev/libaio-dev/g' -i debian/control
- sed '/-DIGNORE_AIO_CHECK=YES/d' -i debian/rules
- sed '/-DWITH_URING=yes/d' -i debian/rules
-fi
+ sed -e '/-DIGNORE_AIO_CHECK=YES/d' \
+ -e '/-DWITH_URING=yes/d' -i debian/rules
+}
-# From Debian Buster/Ubuntu Focal onwards libpmem-dev is available
-# Don't reference it when built in distro releases that lack it
-if ! apt-cache madison libpmem-dev | grep 'libpmem-dev' >/dev/null 2>&1
-then
+disable_pmem()
+{
sed '/libpmem-dev/d' -i debian/control
sed '/-DWITH_PMEM=yes/d' -i debian/rules
-fi
+}
-# Debian stretch doesn't support the zstd version 1.1.3 required
-# for RocksDB. zstd isn't enabled in Mroonga even though code exists
-# for it. If someone happens to have a non-default zstd installed
-# (not 1.1.2), assume its a backport and build with it.
-if [ "$(lsb_release -sc)" = stretch ] && [ "$(apt-cache madison 'libzstd-dev' | grep -v 1.1.2)" = '' ]
-then
- sed '/libzstd-dev/d' -i debian/control
-fi
+disable_libfmt()
+{
+ # 0.7+ required
+ sed '/libfmt-dev/d' -i debian/control
+}
+
+architecture=$(dpkg-architecture -q DEB_BUILD_ARCH)
+
+CODENAME="$(lsb_release -sc)"
+case "${CODENAME}" in
+ stretch)
+ # MDEV-16525 libzstd-dev-1.1.3 minimum version
+ sed -e '/libzstd-dev/d' \
+ -e 's/libcurl4/libcurl3/g' -i debian/control
+ remove_rocksdb_tools
+ disable_pmem
+ ;&
+ buster)
+ disable_libfmt
+ replace_uring_with_aio
+ if [ ! "$architecture" = amd64 ]
+ then
+ disable_pmem
+ fi
+ ;&
+ bullseye|bookworm)
+ # mariadb-plugin-rocksdb in control is 4 arches covered by the distro rocksdb-tools
+ # so no removal is necessary.
+ if [[ ! "$architecture" =~ amd64|arm64|ppc64el ]]
+ then
+ disable_pmem
+ fi
+ if [[ ! "$architecture" =~ amd64|arm64|armel|armhf|i386|mips64el|mipsel|ppc64el|s390x ]]
+ then
+ replace_uring_with_aio
+ fi
+ ;&
+ sid)
+ # should always be empty here.
+ # need to match here to avoid the default Error however
+ ;;
+ # UBUNTU
+ bionic)
+ remove_rocksdb_tools
+ [ "$architecture" != amd64 ] && disable_pmem
+ ;&
+ focal)
+ replace_uring_with_aio
+ disable_libfmt
+ ;&
+ impish|jammy)
+ # mariadb-plugin-rocksdb s390x not supported by us (yet)
+ # ubuntu doesn't support mips64el yet, so keep this just
+ # in case something changes.
+ if [[ ! "$architecture" =~ amd64|arm64|ppc64el|s390x ]]
+ then
+ remove_rocksdb_tools
+ fi
+ if [[ ! "$architecture" =~ amd64|arm64|ppc64el ]]
+ then
+ disable_pmem
+ fi
+ if [[ ! "$architecture" =~ amd64|arm64|armhf|ppc64el|s390x ]]
+ then
+ replace_uring_with_aio
+ fi
+ ;;
+ *)
+ echo "Error - unknown release codename $CODENAME" >&2
+ exit 1
+esac
# Adjust changelog, add new version
echo "Incrementing changelog and starting build scripts"
@@ -121,13 +151,6 @@ dch -b -D "${CODENAME}" -v "${VERSION}" "Automatic build with ${LOGSTRING}." --c
echo "Creating package version ${VERSION} ... "
-# On Travis CI and Gitlab-CI, use -b to build binary only packages as there is
-# no need to waste time on generating the source package.
-if [[ $TRAVIS ]]
-then
- BUILDPACKAGE_FLAGS="-b"
-fi
-
# Use eatmydata is available to build faster with less I/O, skipping fsync()
# during the entire build process (safe because a build can always be restarted)
if which eatmydata > /dev/null
@@ -143,8 +166,8 @@ fakeroot $BUILDPACKAGE_PREPEND dpkg-buildpackage -us -uc -I $BUILDPACKAGE_FLAGS
# If the step above fails due to missing dependencies, you can manually run
# sudo mk-build-deps debian/control -r -i
-# Don't log package contents on Travis-CI or Gitlab-CI to save time and log size
-if [[ ! $TRAVIS ]] && [[ ! $GITLAB_CI ]]
+# Don't log package contents on Gitlab-CI to save time and log size
+if [[ ! $GITLAB_CI ]]
then
echo "List package contents ..."
cd ..
diff --git a/debian/control b/debian/control
index c5c5edc2b32..f297e6c5b27 100644
--- a/debian/control
+++ b/debian/control
@@ -5,7 +5,7 @@ Maintainer: MariaDB Developers <maria-developers@lists.launchpad.net>
Build-Depends: bison,
cmake,
cracklib-runtime <!nocheck>,
- debhelper (>= 9.20160709~),
+ debhelper (>= 10),
dh-exec,
flex [amd64],
gdb <!nocheck>,
@@ -23,6 +23,7 @@ Build-Depends: bison,
libcurl4-openssl-dev | libcurl4-dev,
libedit-dev,
libedit-dev:native,
+ libfmt-dev (>= 7.0.0),
libjemalloc-dev [linux-any],
libjudy-dev,
libkrb5-dev,
@@ -34,7 +35,7 @@ Build-Depends: bison,
libnuma-dev [linux-any],
libpam0g-dev,
libpcre2-dev,
- libpmem-dev [amd64 arm64 ppc64el],
+ libpmem-dev [amd64 arm64 ppc64el riscv64],
libsnappy-dev,
libssl-dev,
libssl-dev:native,
@@ -559,6 +560,7 @@ Conflicts: mariadb-server-core-10.0,
mariadb-server-core-10.3,
mariadb-server-core-10.4,
mariadb-server-core-10.5,
+ mariadb-server-core-10.6,
mariadb-server-core-5.1,
mariadb-server-core-5.2,
mariadb-server-core-5.3,
@@ -687,6 +689,7 @@ Conflicts: mariadb-server (<< ${source:Version}),
mariadb-server-10.3,
mariadb-server-10.4,
mariadb-server-10.5,
+ mariadb-server-10.6,
mariadb-server-5.1,
mariadb-server-5.2,
mariadb-server-5.3,
@@ -728,6 +731,7 @@ Replaces: handlersocket-mysql-5.5,
mariadb-server-10.3,
mariadb-server-10.4,
mariadb-server-10.5,
+ mariadb-server-10.6,
mariadb-server-5.1,
mariadb-server-5.2,
mariadb-server-5.3,
@@ -977,6 +981,13 @@ Depends: mariadb-server-10.9,
${misc:Depends},
${shlibs:Depends}
Description: BZip2 compression support in the server and storage engines
+ The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga,
+ can use different compression libraries.
+ .
+ Plugin provides BZip2 (https://sourceware.org/bzip2/) compression
+ .
+ Note that these affect InnoDB and Mroonga only;
+ RocksDB still uses the compression algorithms from its own library
Package: mariadb-plugin-provider-lz4
Architecture: any
@@ -984,6 +995,13 @@ Depends: mariadb-server-10.9,
${misc:Depends},
${shlibs:Depends}
Description: LZ4 compression support in the server and storage engines
+ The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga,
+ can use different compression libraries.
+ .
+ Plugin provides LZ4 (http://lz4.github.io/lz4/) compression
+ .
+ Note that these affect InnoDB and Mroonga only;
+ RocksDB still uses the compression algorithms from its own library
Package: mariadb-plugin-provider-lzma
Architecture: any
@@ -991,6 +1009,13 @@ Depends: mariadb-server-10.9,
${misc:Depends},
${shlibs:Depends}
Description: LZMA compression support in the server and storage engines
+ The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga,
+ can use different compression libraries.
+ .
+ Plugin provides LZMA (https://tukaani.org/lzma/) compression
+ .
+ Note that these affect InnoDB and Mroonga only;
+ RocksDB still uses the compression algorithms from its own library
Package: mariadb-plugin-provider-lzo
Architecture: any
@@ -998,6 +1023,13 @@ Depends: mariadb-server-10.9,
${misc:Depends},
${shlibs:Depends}
Description: LZO compression support in the server and storage engines
+ The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga,
+ can use different compression libraries.
+ .
+ Plugin provides LZO (http://www.oberhumer.com/opensource/lzo/) compression
+ .
+ Note that these affect InnoDB and Mroonga only;
+ RocksDB still uses the compression algorithms from its own library
Package: mariadb-plugin-provider-snappy
Architecture: any
@@ -1005,6 +1037,13 @@ Depends: mariadb-server-10.9,
${misc:Depends},
${shlibs:Depends}
Description: Snappy compression support in the server and storage engines
+ The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga,
+ can use different compression libraries.
+ .
+ Plugin provides Snappy (https://github.com/google/snappy) compression
+ .
+ Note that these affect InnoDB and Mroonga only;
+ RocksDB still uses the compression algorithms from its own library
Package: mariadb-test
Architecture: any
diff --git a/debian/mariadb-plugin-provider-bzip2.lintian-overrides b/debian/mariadb-plugin-provider-bzip2.lintian-overrides
new file mode 100644
index 00000000000..563c05a3a6b
--- /dev/null
+++ b/debian/mariadb-plugin-provider-bzip2.lintian-overrides
@@ -0,0 +1,3 @@
+# It's intentional that bzip2 compression plugin doesn't have symbols from libc
+# More info https://jira.mariadb.org/browse/MDEV-28120
+library-not-linked-against-libc usr/lib/mysql/plugin/provider_bzip2.so \ No newline at end of file
diff --git a/debian/mariadb-plugin-provider-lz4.lintian-overrides b/debian/mariadb-plugin-provider-lz4.lintian-overrides
new file mode 100644
index 00000000000..3f7d7e9ecfb
--- /dev/null
+++ b/debian/mariadb-plugin-provider-lz4.lintian-overrides
@@ -0,0 +1,3 @@
+# It's intentional that LZ4 compression plugin doesn't have symbols from libc
+# More info https://jira.mariadb.org/browse/MDEV-28120
+library-not-linked-against-libc usr/lib/mysql/plugin/provider_lz4.so \ No newline at end of file
diff --git a/debian/mariadb-plugin-provider-lzma.lintian-overrides b/debian/mariadb-plugin-provider-lzma.lintian-overrides
new file mode 100644
index 00000000000..94eafa766a4
--- /dev/null
+++ b/debian/mariadb-plugin-provider-lzma.lintian-overrides
@@ -0,0 +1,3 @@
+# It's intentional that LZMA compression plugin doesn't have symbols from libc
+# More info https://jira.mariadb.org/browse/MDEV-28120
+library-not-linked-against-libc usr/lib/mysql/plugin/provider_lzma.so \ No newline at end of file
diff --git a/debian/mariadb-plugin-provider-lzo.lintian-overrides b/debian/mariadb-plugin-provider-lzo.lintian-overrides
new file mode 100644
index 00000000000..8184923cf9a
--- /dev/null
+++ b/debian/mariadb-plugin-provider-lzo.lintian-overrides
@@ -0,0 +1,3 @@
+# It's intentional that LZO compression plugin doesn't have symbols from libc
+# More info https://jira.mariadb.org/browse/MDEV-28120
+library-not-linked-against-libc usr/lib/mysql/plugin/provider_lzo.so \ No newline at end of file
diff --git a/debian/mariadb-plugin-provider-snappy.lintian-overrides b/debian/mariadb-plugin-provider-snappy.lintian-overrides
new file mode 100644
index 00000000000..6c76162573d
--- /dev/null
+++ b/debian/mariadb-plugin-provider-snappy.lintian-overrides
@@ -0,0 +1,3 @@
+# It's intentional that Snappy compression plugin doesn't have symbols from libc
+# More info https://jira.mariadb.org/browse/MDEV-28120
+library-not-linked-against-libc usr/lib/mysql/plugin/provider_snappy.so \ No newline at end of file
diff --git a/debian/rules b/debian/rules
index 463c5b75b12..06c75264f8c 100755
--- a/debian/rules
+++ b/debian/rules
@@ -60,7 +60,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))
+ifneq (,$(filter $(DEB_HOST_ARCH_CPU),amd64 arm64 ppc64el riscv64))
CMAKEFLAGS += -DWITH_PMEM=yes
endif
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
index c357e14f4af..05f9dbe1af4 100644
--- a/debian/source/lintian-overrides
+++ b/debian/source/lintian-overrides
@@ -23,8 +23,10 @@ version-substvar-for-external-package libmariadbd-dev -> libmariadbclient-dev
# ColumnStore not used in Debian, safe to ignore. Reported upstream in https://jira.mariadb.org/browse/MDEV-24124
source-is-missing storage/columnstore/columnstore/utils/jemalloc/libjemalloc.so.2
# Must be fixed upstream
-source-is-missing storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-ui-1.8.18.custom.js line 58 is 273 characters long (>256)
+source-is-missing storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-ui-1.8.18.custom.js *
# Intentional control relationships
version-substvar-for-external-package Replaces (line 216) ${source:Version} libmariadbd-dev -> libmariadbclient-dev
version-substvar-for-external-package Replaces (line 66) ${source:Version} libmariadb-dev -> libmysqlclient-dev
version-substvar-for-external-package Replaces (line 66) ${source:Version} libmariadb-dev -> libmysqld-dev
+# We can't change build dependencies on a stable branch (10.5..10.8) so just override this
+missing-build-dependency-for-dh-addon systemd *
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc
index a60f38cb7b1..ce40051f1a8 100644
--- a/extra/innochecksum.cc
+++ b/extra/innochecksum.cc
@@ -1188,6 +1188,8 @@ static struct my_option innochecksum_options[] = {
{"allow-mismatches", 'a', "Maximum checksum mismatch allowed.",
&allow_mismatches, &allow_mismatches, 0,
GET_ULL, REQUIRED_ARG, 0, 0, ULLONG_MAX, 0, 1, 0},
+ {"write", 'w', "Rewrite the checksum.",
+ &do_write, &do_write, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"page-type-summary", 'S', "Display a count of each page type "
"in a tablespace.", &page_type_summary, &page_type_summary, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
diff --git a/include/my_atomic.h b/include/my_atomic.h
index 81da9e35cf9..270134a6caf 100644
--- a/include/my_atomic.h
+++ b/include/my_atomic.h
@@ -2,7 +2,7 @@
#define MY_ATOMIC_INCLUDED
/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
- Copyright (c) 2018, 2020, MariaDB
+ Copyright (c) 2018, 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
@@ -115,22 +115,6 @@
#include "atomic/gcc_builtins.h"
#endif
-#if SIZEOF_LONG == 4
-#define my_atomic_addlong(A,B) my_atomic_add32((int32*) (A), (B))
-#define my_atomic_loadlong(A) my_atomic_load32((int32*) (A))
-#define my_atomic_loadlong_explicit(A,O) my_atomic_load32_explicit((int32*) (A), (O))
-#define my_atomic_storelong(A,B) my_atomic_store32((int32*) (A), (B))
-#define my_atomic_faslong(A,B) my_atomic_fas32((int32*) (A), (B))
-#define my_atomic_caslong(A,B,C) my_atomic_cas32((int32*) (A), (int32*) (B), (C))
-#else
-#define my_atomic_addlong(A,B) my_atomic_add64((int64*) (A), (B))
-#define my_atomic_loadlong(A) my_atomic_load64((int64*) (A))
-#define my_atomic_loadlong_explicit(A,O) my_atomic_load64_explicit((int64*) (A), (O))
-#define my_atomic_storelong(A,B) my_atomic_store64((int64*) (A), (B))
-#define my_atomic_faslong(A,B) my_atomic_fas64((int64*) (A), (B))
-#define my_atomic_caslong(A,B,C) my_atomic_cas64((int64*) (A), (int64*) (B), (C))
-#endif
-
#ifndef MY_MEMORY_ORDER_SEQ_CST
#define MY_MEMORY_ORDER_RELAXED
#define MY_MEMORY_ORDER_CONSUME
diff --git a/mysql-test/include/have_innodb.inc b/mysql-test/include/have_innodb.inc
index 69ffdb5b284..0de070e1994 100644
--- a/mysql-test/include/have_innodb.inc
+++ b/mysql-test/include/have_innodb.inc
@@ -2,3 +2,15 @@
# suite.pm will make sure that all tests including this file
# will be skipped unless innodb is enabled
#
+--disable_query_log
+if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "MSAN%"`)
+{
+SET STATEMENT sql_log_bin=0 FOR
+call mtr.add_suppression("InnoDB: Trying to delete tablespace.*pending operations");
+}
+if ($VALGRIND_TEST)
+{
+SET STATEMENT sql_log_bin=0 FOR
+call mtr.add_suppression("InnoDB: Trying to delete tablespace.*pending operations");
+}
+--enable_query_log
diff --git a/mysql-test/main/contributors.result b/mysql-test/main/contributors.result
index 0c7ca03a2c5..8d72373696c 100644
--- a/mysql-test/main/contributors.result
+++ b/mysql-test/main/contributors.result
@@ -5,6 +5,8 @@ Tencent Cloud https://cloud.tencent.com Platinum Sponsor of the MariaDB Foundati
Microsoft https://microsoft.com/ Platinum Sponsor of the MariaDB Foundation
MariaDB Corporation https://mariadb.com Founding member, Platinum Sponsor of the MariaDB Foundation
ServiceNow https://servicenow.com Platinum Sponsor of the MariaDB Foundation
+Intel https://www.intel.com Platinum Sponsor of the MariaDB Foundation
+SIT https://sit.org Platinum Sponsor of the MariaDB Foundation
Visma https://visma.com Gold Sponsor of the MariaDB Foundation
DBS https://dbs.com Gold Sponsor of the MariaDB Foundation
IBM https://www.ibm.com Gold Sponsor of the MariaDB Foundation
diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result
index 294b0623fc1..178b7182666 100644
--- a/mysql-test/main/create_or_replace.result
+++ b/mysql-test/main/create_or_replace.result
@@ -1,3 +1,5 @@
+SET @save_persistent=@@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent=OFF;
CREATE TABLE t2 (a int);
INSERT INTO t2 VALUES(1),(2),(3);
#
@@ -258,8 +260,7 @@ Note 1051 Unknown table 'test.t1,mysqltest2.t2'
create table test.t1 (i int) engine=myisam;
create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write;
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_BACKUP_DML NULL Backup lock
@@ -272,8 +273,7 @@ ERROR 42000: A table must have at least 1 column
show tables;
Tables_in_test
t2
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_BACKUP_DML NULL Backup lock
@@ -282,16 +282,14 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2
create or replace table mysqltest2.t2;
ERROR 42000: A table must have at least 1 column
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
create table t1 (i int);
drop table t1;
create table test.t1 (i int);
create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write;
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_BACKUP_DML NULL Backup lock
@@ -304,8 +302,7 @@ ERROR 42S21: Duplicate column name 'a'
show tables;
Tables_in_test
t2
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_BACKUP_DML NULL Backup lock
@@ -314,16 +311,14 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2
create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a';
ERROR 42S21: Duplicate column name 'a'
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
create table t1 (i int);
drop table t1;
create table test.t1 (i int) engine=innodb;
create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write;
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2
@@ -335,8 +330,7 @@ drop table test.t1,mysqltest2.t2;
create table test.t1 (i int) engine=aria transactional=1 checksum=1;
create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write;
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2
@@ -353,8 +347,7 @@ drop table test.t1;
#
create table t1 (i int);
lock table t1 write;
-select * from information_schema.metadata_lock_info
-where table_schema!='mysql' or table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_BACKUP_DML NULL Backup lock
@@ -365,8 +358,7 @@ ERROR 22001: Data too long for column 'a' at row 1
show tables;
Tables_in_test
t2
-select * from information_schema.metadata_lock_info
-where table_schema!='mysql' or table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
create table t1 (i int);
drop table t1;
@@ -454,8 +446,7 @@ drop view t1;
#
create table t1 (a int);
lock table t1 write, t2 read;
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_BACKUP_DML NULL Backup lock
@@ -463,8 +454,7 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
# MDL_SHARED_READ NULL Table metadata lock test t2
create or replace table t1 (i int);
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_BACKUP_DML NULL Backup lock
@@ -472,8 +462,7 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
# MDL_SHARED_READ NULL Table metadata lock test t2
create or replace table t1 like t2;
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_BACKUP_DML NULL Backup lock
@@ -481,8 +470,7 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
# MDL_SHARED_READ NULL Table metadata lock test t2
create or replace table t1 select 1 as f1;
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_BACKUP_DDL NULL Backup lock
# MDL_BACKUP_DML NULL Backup lock
@@ -580,3 +568,4 @@ ERROR HY000: Table 't3' was not locked with LOCK TABLES
UNLOCK TABLES;
DROP TABLE t3;
# End of 10.4 tests
+SET GLOBAL innodb_stats_persistent=@save_persistent;
diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test
index 7fa08d13847..573e0e177c2 100644
--- a/mysql-test/main/create_or_replace.test
+++ b/mysql-test/main/create_or_replace.test
@@ -5,6 +5,9 @@
--source include/have_innodb.inc
--source include/have_metadata_lock_info.inc
+SET @save_persistent=@@GLOBAL.innodb_stats_persistent;
+SET GLOBAL innodb_stats_persistent=OFF;
+
#
# Create help table
#
@@ -212,21 +215,18 @@ create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
--error ER_TABLE_MUST_HAVE_COLUMNS
create or replace table test.t1;
show tables;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
--error ER_TABLE_MUST_HAVE_COLUMNS
create or replace table mysqltest2.t2;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
create table t1 (i int);
drop table t1;
@@ -235,21 +235,18 @@ create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
--error ER_DUP_FIELDNAME
create or replace table test.t1 (a int) select 1 as 'a', 2 as 'a';
show tables;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
--error ER_DUP_FIELDNAME
create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a';
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
create table t1 (i int);
drop table t1;
@@ -258,8 +255,7 @@ create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
unlock tables;
drop table test.t1,mysqltest2.t2;
@@ -268,8 +264,7 @@ create table mysqltest2.t2 like test.t1;
lock table test.t1 write, mysqltest2.t2 write;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
unlock tables;
drop table t1;
@@ -285,15 +280,13 @@ create table t1 (i int);
lock table t1 write;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_schema!='mysql' or table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
--error ER_DATA_TOO_LONG
create or replace table t1 (a char(1)) engine=Innodb select 'foo' as a;
show tables;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_schema!='mysql' or table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
create table t1 (i int);
drop table t1;
@@ -371,24 +364,20 @@ create table t1 (a int);
lock table t1 write, t2 read;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
create or replace table t1 (i int);
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
create or replace table t1 like t2;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
create or replace table t1 select 1 as f1;
--replace_column 1 #
--sorted_result
-select * from information_schema.metadata_lock_info
-where table_name not like 'innodb_%_stats';
+select * from information_schema.metadata_lock_info;
drop table t1;
unlock tables;
@@ -520,3 +509,5 @@ UNLOCK TABLES;
DROP TABLE t3;
--echo # End of 10.4 tests
+
+SET GLOBAL innodb_stats_persistent=@save_persistent;
diff --git a/mysql-test/main/ctype_utf32.result b/mysql-test/main/ctype_utf32.result
index d7717ece210..069e4174c9d 100644
--- a/mysql-test/main/ctype_utf32.result
+++ b/mysql-test/main/ctype_utf32.result
@@ -2890,5 +2890,53 @@ HEX(c1)
0000006100000063
DROP TABLE t1;
#
+# MDEV-23210 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on ALTER TABLE, SELECT and INSERT
+#
+CREATE TABLE t1 (a CHAR(1));
+SET COLLATION_CONNECTION=utf32_general_ci, CHARACTER_SET_CLIENT=binary;
+ALTER TABLE t1 CHANGE a a ENUM('a','a') CHARACTER SET utf32;
+ERROR HY000: Column 'a' has duplicated value 'a' in ENUM
+ALTER TABLE t1 CHANGE a a ENUM('aaa') CHARACTER SET utf32;
+ERROR HY000: Invalid utf32 character string: '\x00aaa'
+ALTER TABLE t1 CHANGE a a ENUM('aa') CHARACTER SET utf32;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('慡') CHARACTER SET utf32 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 CHANGE a a ENUM('a','b') CHARACTER SET utf32;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('a','b') CHARACTER SET utf32 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SET NAMES utf8;
+#
+# MDEV-28078 Garbage on multiple equal ENUMs with tricky character sets
+#
+CREATE TABLE t1 (
+c1 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a',
+c2 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a'
+);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` enum('a','b') CHARACTER SET utf32 DEFAULT 'a',
+ `c2` enum('a','b') CHARACTER SET utf32 DEFAULT 'a'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 (
+c1 ENUM ('00000061','00000062') DEFAULT '00000061' COLLATE latin1_bin,
+c2 ENUM ('a','b') DEFAULT 'a' COLLATE utf32_general_ci
+);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` enum('00000061','00000062') CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '00000061',
+ `c2` enum('a','b') CHARACTER SET utf32 DEFAULT 'a'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/main/ctype_utf32.test b/mysql-test/main/ctype_utf32.test
index 59cc13015af..0e50405f871 100644
--- a/mysql-test/main/ctype_utf32.test
+++ b/mysql-test/main/ctype_utf32.test
@@ -1048,6 +1048,44 @@ INSERT INTO t1 (c1) VALUES (1),(2),(3);
SELECT HEX(c1) FROM t1 ORDER BY c1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-23210 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on ALTER TABLE, SELECT and INSERT
+--echo #
+
+CREATE TABLE t1 (a CHAR(1));
+SET COLLATION_CONNECTION=utf32_general_ci, CHARACTER_SET_CLIENT=binary;
+--error ER_DUPLICATED_VALUE_IN_TYPE
+ALTER TABLE t1 CHANGE a a ENUM('a','a') CHARACTER SET utf32;
+--error ER_INVALID_CHARACTER_STRING
+ALTER TABLE t1 CHANGE a a ENUM('aaa') CHARACTER SET utf32;
+ALTER TABLE t1 CHANGE a a ENUM('aa') CHARACTER SET utf32;
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 CHANGE a a ENUM('a','b') CHARACTER SET utf32;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+SET NAMES utf8;
+
+
+--echo #
+--echo # MDEV-28078 Garbage on multiple equal ENUMs with tricky character sets
+--echo #
+
+CREATE TABLE t1 (
+ c1 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a',
+ c2 ENUM ('a','b') CHARACTER SET utf32 DEFAULT 'a'
+);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ c1 ENUM ('00000061','00000062') DEFAULT '00000061' COLLATE latin1_bin,
+ c2 ENUM ('a','b') DEFAULT 'a' COLLATE utf32_general_ci
+);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/main/ctype_utf32_uca.result b/mysql-test/main/ctype_utf32_uca.result
index 32ecf49dc70..27aa934cf00 100644
--- a/mysql-test/main/ctype_utf32_uca.result
+++ b/mysql-test/main/ctype_utf32_uca.result
@@ -7941,6 +7941,21 @@ EXECUTE s;
DEALLOCATE PREPARE s;
SET NAMES utf8;
#
+# MDEV-23210 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on ALTER TABLE, SELECT and INSERT
+#
+CREATE TABLE t1 (a CHAR(1));
+SET COLLATION_CONNECTION=utf32_myanmar_ci, CHARACTER_SET_CLIENT=binary;
+ALTER TABLE t1 CHANGE a a ENUM('a','a') CHARACTER SET utf32;
+ERROR HY000: Column 'a' has duplicated value 'a' in ENUM
+ALTER TABLE t1 CHANGE a a ENUM('a','b') CHARACTER SET utf32;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('a','b') CHARACTER SET utf32 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SET NAMES utf8;
+#
# End of 10.2 tests
#
#
diff --git a/mysql-test/main/ctype_utf32_uca.test b/mysql-test/main/ctype_utf32_uca.test
index 0abc6a73fc8..9a6fc3260b0 100644
--- a/mysql-test/main/ctype_utf32_uca.test
+++ b/mysql-test/main/ctype_utf32_uca.test
@@ -290,6 +290,19 @@ EXECUTE s;
DEALLOCATE PREPARE s;
SET NAMES utf8;
+--echo #
+--echo # MDEV-23210 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on ALTER TABLE, SELECT and INSERT
+--echo #
+
+CREATE TABLE t1 (a CHAR(1));
+SET COLLATION_CONNECTION=utf32_myanmar_ci, CHARACTER_SET_CLIENT=binary;
+--error ER_DUPLICATED_VALUE_IN_TYPE
+ALTER TABLE t1 CHANGE a a ENUM('a','a') CHARACTER SET utf32;
+ALTER TABLE t1 CHANGE a a ENUM('a','b') CHARACTER SET utf32;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+SET NAMES utf8;
+
--echo #
--echo # End of 10.2 tests
diff --git a/mysql-test/main/drop_bad_db_type.result b/mysql-test/main/drop_bad_db_type.result
index ae6fe708e60..97869a39aa3 100644
--- a/mysql-test/main/drop_bad_db_type.result
+++ b/mysql-test/main/drop_bad_db_type.result
@@ -3,34 +3,50 @@ SET debug_dbug='+d,unstable_db_type';
install soname 'ha_archive';
create table t1 (a int) engine=archive;
insert t1 values (1),(2),(3);
+create table t2 (a int) engine=archive partition by hash(a) partitions 3;
flush tables;
uninstall soname 'ha_archive';
-select table_schema, table_name from information_schema.tables where table_name like 't1';
-table_schema test
-table_name t1
-select table_schema, table_name, engine, version from information_schema.tables where table_name like 't1';
-table_schema test
-table_name t1
-engine ARCHIVE
-version NULL
+select table_schema, table_name from information_schema.tables where table_name like 't_' order by 1,2;
+table_schema table_name
+test t1
+test t2
+select table_schema, table_name, engine, version from information_schema.tables where table_name like 't_' order by 1,2;
+table_schema table_name engine version
+test t1 ARCHIVE NULL
+test t2 NULL NULL
Warnings:
-Level Warning
-Code 1286
-Message Unknown storage engine 'ARCHIVE'
-select table_schema, table_name, engine, row_format from information_schema.tables where table_name like 't1';
-table_schema test
-table_name t1
-engine ARCHIVE
-row_format NULL
+Warning 1033 Incorrect information in file: './test/t2.frm'
+Warning 1286 Unknown storage engine 'ARCHIVE'
+select table_schema, table_name, engine, row_format from information_schema.tables where table_name like 't_' order by 1,2;
+table_schema table_name engine row_format
+test t1 ARCHIVE NULL
+test t2 NULL NULL
Warnings:
-Level Warning
-Code 1286
-Message Unknown storage engine 'ARCHIVE'
+Warning 1033 Incorrect information in file: './test/t2.frm'
+Warning 1286 Unknown storage engine 'ARCHIVE'
install soname 'ha_archive';
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ARCHIVE DEFAULT CHARSET=latin1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ARCHIVE DEFAULT CHARSET=latin1
+ PARTITION BY HASH (`a`)
+PARTITIONS 3
db.opt
t1.ARZ
t1.frm
+t2#P#p0.ARZ
+t2#P#p1.ARZ
+t2#P#p2.ARZ
+t2.frm
+t2.par
drop table t1;
+drop table t2;
db.opt
uninstall soname 'ha_archive';
SET debug_dbug=@saved_dbug;
diff --git a/mysql-test/main/drop_bad_db_type.test b/mysql-test/main/drop_bad_db_type.test
index ebc732104d3..0fb5fe5edf4 100644
--- a/mysql-test/main/drop_bad_db_type.test
+++ b/mysql-test/main/drop_bad_db_type.test
@@ -1,4 +1,4 @@
-
+--source include/have_partition.inc
--source include/have_debug.inc
if (!$HA_ARCHIVE_SO) {
@@ -13,18 +13,25 @@ SET debug_dbug='+d,unstable_db_type';
install soname 'ha_archive';
create table t1 (a int) engine=archive;
insert t1 values (1),(2),(3);
+
+create table t2 (a int) engine=archive partition by hash(a) partitions 3;
+
flush tables;
uninstall soname 'ha_archive';
---vertical_results
-select table_schema, table_name from information_schema.tables where table_name like 't1';
-select table_schema, table_name, engine, version from information_schema.tables where table_name like 't1';
-select table_schema, table_name, engine, row_format from information_schema.tables where table_name like 't1';
---horizontal_results
+select table_schema, table_name from information_schema.tables where table_name like 't_' order by 1,2;
+--replace_result $mysqld_datadir ./
+select table_schema, table_name, engine, version from information_schema.tables where table_name like 't_' order by 1,2;
+--replace_result $mysqld_datadir ./
+select table_schema, table_name, engine, row_format from information_schema.tables where table_name like 't_' order by 1,2;
install soname 'ha_archive';
+show create table t1;
+show create table t2;
+
--list_files $mysqld_datadir/test
drop table t1;
+drop table t2;
--list_files $mysqld_datadir/test
uninstall soname 'ha_archive';
diff --git a/mysql-test/main/error_simulation.result b/mysql-test/main/error_simulation.result
index 457e5c8ec9c..680937accfd 100644
--- a/mysql-test/main/error_simulation.result
+++ b/mysql-test/main/error_simulation.result
@@ -128,3 +128,13 @@ SELECT f1(1);
Got one of the listed errors
DROP FUNCTION f1;
SET debug_dbug= @saved_dbug;
+#
+# MDEV-27978 wrong option name in error when exceeding max_session_mem_used
+#
+SET SESSION max_session_mem_used = 8192;
+SELECT * FROM information_schema.processlist;
+ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
+SET SESSION max_session_mem_used = DEFAULT;
+#
+# End of 10.2 tests
+#
diff --git a/mysql-test/main/error_simulation.test b/mysql-test/main/error_simulation.test
index f713e2da6ba..2c155bc9a22 100644
--- a/mysql-test/main/error_simulation.test
+++ b/mysql-test/main/error_simulation.test
@@ -158,3 +158,16 @@ SET SESSION debug_dbug="+d,simulate_create_virtual_tmp_table_out_of_memory";
SELECT f1(1);
DROP FUNCTION f1;
SET debug_dbug= @saved_dbug;
+
+--echo #
+--echo # MDEV-27978 wrong option name in error when exceeding max_session_mem_used
+--echo #
+SET SESSION max_session_mem_used = 8192;
+--error ER_OPTION_PREVENTS_STATEMENT
+SELECT * FROM information_schema.processlist;
+SET SESSION max_session_mem_used = DEFAULT;
+
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
diff --git a/mysql-test/main/flush_block_commit_notembedded.test b/mysql-test/main/flush_block_commit_notembedded.test
index 5be9e50e58b..024640893d9 100644
--- a/mysql-test/main/flush_block_commit_notembedded.test
+++ b/mysql-test/main/flush_block_commit_notembedded.test
@@ -12,6 +12,10 @@
--echo # Save the initial number of concurrent sessions
--source include/count_sessions.inc
+--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");
+--enable_query_log
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
diff --git a/mysql-test/main/func_json_notembedded.result b/mysql-test/main/func_json_notembedded.result
index be879dfc9d6..756d2e85f7c 100644
--- a/mysql-test/main/func_json_notembedded.result
+++ b/mysql-test/main/func_json_notembedded.result
@@ -4,11 +4,11 @@ connect u,localhost,root;
# MDEV-24909 JSON functions don't respect KILL QUERY / max_statement_time limit
#
set group_concat_max_len= 4294967295;
-set @obj=concat_ws('','{', repeat('"a":"b",', 125000000/2), '"c":"d"}');
-set @arr=concat_ws('','[', repeat('1234567,', 125000000/2), '2345678]');
+set @obj=concat_ws('','{', repeat('"a":"b",', 1250000/2), '"c":"d"}');
+set @arr=concat_ws('','[', repeat('1234567,', 1250000/2), '2345678]');
select length(@obj), length(@arr);
length(@obj) length(@arr)
-500000009 500000009
+5000009 5000009
set max_statement_time=0.0001;
select json_array_append(@arr, '$[0]', 1);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
diff --git a/mysql-test/main/func_json_notembedded.test b/mysql-test/main/func_json_notembedded.test
index 328d9974c77..b33615060b4 100644
--- a/mysql-test/main/func_json_notembedded.test
+++ b/mysql-test/main/func_json_notembedded.test
@@ -9,8 +9,8 @@ connect u,localhost,root;
--echo #
set group_concat_max_len= 4294967295;
-set @obj=concat_ws('','{', repeat('"a":"b",', 125000000/2), '"c":"d"}');
-set @arr=concat_ws('','[', repeat('1234567,', 125000000/2), '2345678]');
+set @obj=concat_ws('','{', repeat('"a":"b",', 1250000/2), '"c":"d"}');
+set @arr=concat_ws('','[', repeat('1234567,', 1250000/2), '2345678]');
select length(@obj), length(@arr);
set max_statement_time=0.0001;
diff --git a/mysql-test/main/multi_update_innodb.result b/mysql-test/main/multi_update_innodb.result
index 2ec7eb3065e..52bbece4fa0 100644
--- a/mysql-test/main/multi_update_innodb.result
+++ b/mysql-test/main/multi_update_innodb.result
@@ -207,4 +207,19 @@ ERROR 23000: Duplicate entry '0000-00-00 00:00:00' for key 'f2k'
DROP VIEW v1;
DROP TABLE t3,t4;
SET @@sql_mode=@save_sql_mode;
+#
# End of 10.2 tests
+#
+#
+# MDEV-28095 crash in multi-update and implicit grouping
+#
+CREATE TABLE t1 (a int) engine=innodb;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b int);
+INSERT INTO t2 VALUES (1),(2);
+UPDATE t1 NATURAL JOIN t2 SET a = 1 ORDER BY AVG (a) ;
+ERROR HY000: Invalid use of group function
+DROP TABLE t1, t2;
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/main/multi_update_innodb.test b/mysql-test/main/multi_update_innodb.test
index 04736482011..02f6a7a3316 100644
--- a/mysql-test/main/multi_update_innodb.test
+++ b/mysql-test/main/multi_update_innodb.test
@@ -243,4 +243,23 @@ DROP VIEW v1;
DROP TABLE t3,t4;
SET @@sql_mode=@save_sql_mode;
+--echo #
--echo # End of 10.2 tests
+--echo #
+
+--echo #
+--echo # MDEV-28095 crash in multi-update and implicit grouping
+--echo #
+CREATE TABLE t1 (a int) engine=innodb;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b int);
+INSERT INTO t2 VALUES (1),(2);
+--error ER_INVALID_GROUP_FUNC_USE
+UPDATE t1 NATURAL JOIN t2 SET a = 1 ORDER BY AVG (a) ;
+DROP TABLE t1, t2;
+
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
+
diff --git a/mysql-test/main/opt_tvc.result b/mysql-test/main/opt_tvc.result
index 9752aa71bfb..9b6d97492cd 100644
--- a/mysql-test/main/opt_tvc.result
+++ b/mysql-test/main/opt_tvc.result
@@ -732,3 +732,30 @@ a b
4 4
drop table t1;
SET @@in_predicate_conversion_threshold= default;
+#
+# MDEV-27937: Prepared statement with ? in the list if IN predicate
+#
+set in_predicate_conversion_threshold=2;
+create table t1 (id int, a int, b int);
+insert into t1 values (1,3,30), (2,7,70), (3,1,10);
+prepare stmt from "
+select * from t1 where a in (7, ?, 5, 1);
+";
+execute stmt using 3;
+id a b
+1 3 30
+2 7 70
+3 1 10
+deallocate prepare stmt;
+prepare stmt from "
+select * from t1 where (a,b) in ((7,70), (3,?), (5,50), (1,10));
+";
+execute stmt using 30;
+id a b
+1 3 30
+2 7 70
+3 1 10
+deallocate prepare stmt;
+drop table t1;
+set in_predicate_conversion_threshold=default;
+# End of 10.3 tests
diff --git a/mysql-test/main/opt_tvc.test b/mysql-test/main/opt_tvc.test
index e4e8c6d7919..f8469f22aa1 100644
--- a/mysql-test/main/opt_tvc.test
+++ b/mysql-test/main/opt_tvc.test
@@ -428,3 +428,29 @@ eval $query;
drop table t1;
SET @@in_predicate_conversion_threshold= default;
+--echo #
+--echo # MDEV-27937: Prepared statement with ? in the list if IN predicate
+--echo #
+
+set in_predicate_conversion_threshold=2;
+
+create table t1 (id int, a int, b int);
+insert into t1 values (1,3,30), (2,7,70), (3,1,10);
+
+prepare stmt from "
+select * from t1 where a in (7, ?, 5, 1);
+";
+execute stmt using 3;
+deallocate prepare stmt;
+
+prepare stmt from "
+select * from t1 where (a,b) in ((7,70), (3,?), (5,50), (1,10));
+";
+execute stmt using 30;
+deallocate prepare stmt;
+
+drop table t1;
+
+set in_predicate_conversion_threshold=default;
+
+--echo # End of 10.3 tests
diff --git a/mysql-test/main/partition_not_blackhole.result b/mysql-test/main/partition_not_blackhole.result
index 6cb8dea80c8..9753cd2bae2 100644
--- a/mysql-test/main/partition_not_blackhole.result
+++ b/mysql-test/main/partition_not_blackhole.result
@@ -9,7 +9,7 @@ SHOW TABLES;
Tables_in_test
t1
SHOW CREATE TABLE t1;
-ERROR HY000: Failed to read from the .par file
+ERROR HY000: Incorrect information in file: './test/t1.frm'
DROP TABLE t1;
ERROR HY000: Got error 175 "File too short; Expected more data in file" from storage engine partition
t1.frm
diff --git a/mysql-test/main/partition_not_blackhole.test b/mysql-test/main/partition_not_blackhole.test
index d9e653b5252..fe7452432b2 100644
--- a/mysql-test/main/partition_not_blackhole.test
+++ b/mysql-test/main/partition_not_blackhole.test
@@ -17,7 +17,7 @@ let $MYSQLD_DATADIR= `SELECT @@datadir`;
--copy_file std_data/parts/t1_blackhole.par $MYSQLD_DATADIR/test/t1.par
SHOW TABLES;
--replace_result $MYSQLD_DATADIR ./
---error ER_FAILED_READ_FROM_PAR_FILE
+--error ER_NOT_FORM_FILE
SHOW CREATE TABLE t1;
# The replace is needed for Solaris
diff --git a/mysql-test/main/processlist.result b/mysql-test/main/processlist.result
index 2d3228a6d91..d99160f5c74 100644
--- a/mysql-test/main/processlist.result
+++ b/mysql-test/main/processlist.result
@@ -40,3 +40,23 @@ utf8mb4_string xxx😎yyy
#
# End of 10.1 tests
#
+#
+# Start of 10.3 tests
+#
+#
+# MDEV-28131 Unexpected warning while selecting from information_schema.processlist
+#
+connect conn1, localhost, root,,;
+connection conn1;
+SELECT SLEEP(1000);
+connection default;
+SELECT progress FROM information_schema.processlist WHERE info='SELECT SLEEP(1000)';
+progress
+0.000
+connection conn1;
+Got one of the listed errors
+connection default;
+disconnect conn1;
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/main/processlist.test b/mysql-test/main/processlist.test
index 8e98701459a..f419f57ea2f 100644
--- a/mysql-test/main/processlist.test
+++ b/mysql-test/main/processlist.test
@@ -70,3 +70,38 @@ SELECT INFO, INFO_BINARY, 'xxx😎yyy' AS utf8mb4_string FROM INFORMATION_SCHEMA
--echo #
--echo # End of 10.1 tests
--echo #
+
+--echo #
+--echo # Start of 10.3 tests
+--echo #
+
+--echo #
+--echo # MDEV-28131 Unexpected warning while selecting from information_schema.processlist
+--echo #
+
+connect (conn1, localhost, root,,);
+connection conn1;
+let $ID= `select connection_id()`;
+send SELECT SLEEP(1000);
+connection default;
+let $wait_timeout= 10;
+let $wait_condition=select count(*)=1 from information_schema.processlist
+where state='User sleep' and info='SELECT SLEEP(1000)';
+--source include/wait_condition.inc
+SELECT progress FROM information_schema.processlist WHERE info='SELECT SLEEP(1000)';
+disable_query_log;
+eval kill $ID;
+enable_query_log;
+let $wait_timeout= 10;
+let $wait_condition=select count(*)=0 from information_schema.processlist
+where state='User sleep' and info='SELECT SLEEP(1000)';
+--source include/wait_condition.inc
+connection conn1;
+--error 2013,ER_CONNECTION_KILLED
+reap;
+connection default;
+disconnect conn1;
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
diff --git a/mysql-test/main/sp-cursor.result b/mysql-test/main/sp-cursor.result
index dc38ad64069..2218f8c36fe 100644
--- a/mysql-test/main/sp-cursor.result
+++ b/mysql-test/main/sp-cursor.result
@@ -738,6 +738,69 @@ c
DROP PROCEDURE p1;
DROP TABLE t1;
#
+# MDEV-26009: Server crash when calling twice procedure using FOR-loop
+#
+CREATE TABLE t1 ( id int, name varchar(24));
+INSERT INTO t1 values (1, 'x'), (2, 'y'), (3, 'z');
+create function get_name(_id int) returns varchar(24)
+return (select name from t1 where id = _id);
+select get_name(id) from t1;
+get_name(id)
+x
+y
+z
+create procedure test_proc()
+begin
+declare _cur cursor for select get_name(id) from t1;
+for row in _cur do select 1; end for;
+end;
+^^
+call test_proc();
+1
+1
+1
+1
+1
+1
+call test_proc();
+1
+1
+1
+1
+1
+1
+drop procedure test_proc;
+drop function get_name;
+drop table t1;
+CREATE TABLE t1 (id int, name varchar(24));
+INSERT INTO t1 (id, name) VALUES (1, 'x'),(2, 'y'),(3, 'z');
+create function get_name(_id int) returns varchar(24)
+return (select name from t1 where id = _id);
+create view v1 as select get_name(id) from t1;
+create procedure test_proc()
+begin
+declare _cur cursor for select 1 from v1;
+for row in _cur do select 1; end for;
+end$$
+call test_proc();
+1
+1
+1
+1
+1
+1
+call test_proc();
+1
+1
+1
+1
+1
+1
+drop procedure test_proc;
+drop view v1;
+drop function get_name;
+drop table t1;
+#
# Start of 10.8 tests
#
#
diff --git a/mysql-test/main/sp-cursor.test b/mysql-test/main/sp-cursor.test
index f86721f41e8..44fe6ba51e8 100644
--- a/mysql-test/main/sp-cursor.test
+++ b/mysql-test/main/sp-cursor.test
@@ -747,6 +747,62 @@ DROP TABLE t1;
--echo #
+--echo # MDEV-26009: Server crash when calling twice procedure using FOR-loop
+--echo #
+
+
+CREATE TABLE t1 ( id int, name varchar(24));
+INSERT INTO t1 values (1, 'x'), (2, 'y'), (3, 'z');
+
+create function get_name(_id int) returns varchar(24)
+ return (select name from t1 where id = _id);
+
+select get_name(id) from t1;
+
+delimiter ^^;
+
+create procedure test_proc()
+begin
+ declare _cur cursor for select get_name(id) from t1;
+ for row in _cur do select 1; end for;
+end;
+^^
+delimiter ;^^
+
+call test_proc();
+call test_proc();
+
+drop procedure test_proc;
+drop function get_name;
+drop table t1;
+
+
+CREATE TABLE t1 (id int, name varchar(24));
+INSERT INTO t1 (id, name) VALUES (1, 'x'),(2, 'y'),(3, 'z');
+
+create function get_name(_id int) returns varchar(24)
+ return (select name from t1 where id = _id);
+
+create view v1 as select get_name(id) from t1;
+
+delimiter $$;
+create procedure test_proc()
+begin
+ declare _cur cursor for select 1 from v1;
+ for row in _cur do select 1; end for;
+end$$
+delimiter ;$$
+
+call test_proc();
+call test_proc();
+
+drop procedure test_proc;
+drop view v1;
+drop function get_name;
+drop table t1;
+
+
+--echo #
--echo # Start of 10.8 tests
--echo #
diff --git a/mysql-test/main/truncate_notembedded.result b/mysql-test/main/truncate_notembedded.result
index cf6498427d0..e8bf6c2575b 100644
--- a/mysql-test/main/truncate_notembedded.result
+++ b/mysql-test/main/truncate_notembedded.result
@@ -13,7 +13,7 @@ a
UNLOCK TABLES;
connection con1;
TRUNCATE TABLE t1;
-ERROR HY000: The MariaDB server is running with the --max-thread-mem-used=8192 option so it cannot execute this statement
+ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
disconnect con1;
connection default;
DROP TABLE t1;
diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result
index 075e50e1b0a..35471454cb4 100644
--- a/mysql-test/main/view.result
+++ b/mysql-test/main/view.result
@@ -6846,6 +6846,34 @@ id bar
Drop View v1;
Drop table t1;
#
+# MDEV-24281: Execution of PREPARE from CREATE VIEW statement
+#
+create table t1 (s1 int);
+insert into t1 values (3), (7), (1);
+prepare stmt from "
+create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
+";
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 's1' AS `My_exp_1_s1`,`t1`.`s1` AS `s1`,1 AS `My_exp_s1` from `t1` latin1 latin1_swedish_ci
+select * from v1;
+My_exp_1_s1 s1 My_exp_s1
+s1 3 1
+s1 7 1
+s1 1 1
+drop view v1;
+prepare stmt from "
+create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
+";
+execute stmt;
+execute stmt;
+ERROR 42S01: Table 'v1' already exists
+deallocate prepare stmt;
+drop view v1;
+drop table t1;
+#
# End of 10.3 tests
#
#
diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test
index 825274756a8..49b339c9f4c 100644
--- a/mysql-test/main/view.test
+++ b/mysql-test/main/view.test
@@ -6577,6 +6577,32 @@ Drop View v1;
Drop table t1;
--echo #
+--echo # MDEV-24281: Execution of PREPARE from CREATE VIEW statement
+--echo #
+
+create table t1 (s1 int);
+insert into t1 values (3), (7), (1);
+
+prepare stmt from "
+create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
+";
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "
+create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
+";
+execute stmt;
+--error ER_TABLE_EXISTS_ERROR
+execute stmt;
+deallocate prepare stmt;
+drop view v1;
+drop table t1;
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result b/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result
new file mode 100644
index 00000000000..71eecd881ca
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result
@@ -0,0 +1,6 @@
+ALTER TABLE mysql.gtid_slave_pos ENGINE=innodb;
+# Restart the server so mysqld reads the gtid_slave_pos using innodb
+# Set gtid_slave_pos should not hang
+SET GLOBAL gtid_slave_pos=@@gtid_binlog_pos;
+COMMIT;
+RESET MASTER;
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result
new file mode 100644
index 00000000000..9148f0e8c2b
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result
@@ -0,0 +1,7 @@
+CREATE TABLE t1 (a int);
+FLUSH LOGS;
+INSERT INTO t1 VALUES (1);
+# timeout TIMEOUT MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=MASTER_MYPORT --stop-never --result-file=MYSQLTEST_VARDIR/tmp/ master-bin.000001
+# MYSQL_BINLOG MYSQLTEST_VARDIR/tmp/master-bin.000002 > MYSQLTEST_VARDIR/tmp/local-bin.000002.out
+FOUND 1 /GTID 0-1-2/ in local-bin.000002.out
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang-master.opt b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang-master.opt
new file mode 100644
index 00000000000..e0fa81e6eeb
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang-master.opt
@@ -0,0 +1 @@
+--autocommit=0
diff --git a/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test
new file mode 100644
index 00000000000..8f1dbb2a2dd
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test
@@ -0,0 +1,45 @@
+#
+# Purpose:
+# When the mysql.gtid_slave_pos table uses the InnoDB engine, and mysqld
+# starts, it reads the table and begins a transaction. After mysqld reads the
+# value, it should end the transaction and release all associated locks.
+# The bug reported in DBAAS-7828 shows that when autocommit is off, the locks
+# are not released, resulting in indefinite hangs on future attempts to change
+# gtid_slave_pos. This test ensures its fix such that the locks are properly
+# released.
+#
+# References:
+# DBAAS-7828: Primary/replica: configuration change of "autocommit=0" can
+# not be applied
+#
+
+--source include/have_innodb.inc
+--source include/have_log_bin.inc
+
+# Reading gtid_slave_pos table is format independent so just use one for
+# reduced test time
+--source include/have_binlog_format_row.inc
+
+--let old_slave_pos_engine= query_get_value(SHOW TABLE STATUS FROM mysql LIKE 'gtid_slave_pos', Engine, 1)
+
+# Use a transactional engine
+ALTER TABLE mysql.gtid_slave_pos ENGINE=innodb;
+
+--echo # Restart the server so mysqld reads the gtid_slave_pos using innodb
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--shutdown_server
+--source include/wait_until_disconnected.inc
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+--echo # Set gtid_slave_pos should not hang
+SET GLOBAL gtid_slave_pos=@@gtid_binlog_pos;
+COMMIT;
+
+# Revert table type
+--disable_query_log
+--eval ALTER TABLE mysql.gtid_slave_pos ENGINE=$old_slave_pos_engine
+--enable_query_log
+
+RESET MASTER;
diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
new file mode 100644
index 00000000000..f95fc0137a2
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
@@ -0,0 +1,45 @@
+#
+# Purpose:
+# When using mariadb-binlog with options for --raw and --stop-never, events
+# from the master's currently active log file should be written to their
+# respective log file specified by --result-file, and shown on-disk. This test
+# ensures that the log files on disk, created by mariadb-binlog, have the most
+# up-to-date events from the master.
+#
+# Methodology:
+# On the master, rotate to a newly active binlog file and write an event to
+# it. Read the master's binlog using mariadb-binlog with --raw and --stop-never
+# and write the data to an intermediary binlog file (a timeout is used on this
+# command to ensure it exits). Read the local intermediary binlog file to ensure
+# that the master's most recent event exists in the local file.
+#
+# References:
+# MDEV-14608: mysqlbinlog lastest backupfile size is 0
+#
+
+--source include/linux.inc
+--source include/have_log_bin.inc
+
+# Create newly active log
+CREATE TABLE t1 (a int);
+FLUSH LOGS;
+INSERT INTO t1 VALUES (1);
+
+# Read binlog data from master to intermediary result file
+--let TIMEOUT=1
+--echo # timeout TIMEOUT MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=MASTER_MYPORT --stop-never --result-file=MYSQLTEST_VARDIR/tmp/ master-bin.000001
+--error 124 # Error 124 means timeout was reached
+--exec timeout $TIMEOUT $MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --stop-never --result-file=$MYSQLTEST_VARDIR/tmp/ master-bin.000001
+
+# Ensure the binlog output has the most recent events from the master
+--echo # MYSQL_BINLOG MYSQLTEST_VARDIR/tmp/master-bin.000002 > MYSQLTEST_VARDIR/tmp/local-bin.000002.out
+--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/tmp/master-bin.000002 > $MYSQLTEST_VARDIR/tmp/local-bin.000002.out
+--let SEARCH_PATTERN= GTID 0-1-2
+--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/local-bin.000002.out
+--source include/search_pattern_in_file.inc
+
+# Cleanup
+DROP TABLE t1;
+--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000001
+--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000002
+--remove_file $MYSQLTEST_VARDIR/tmp/local-bin.000002.out
diff --git a/mysql-test/suite/compat/oracle/r/sp-package.result b/mysql-test/suite/compat/oracle/r/sp-package.result
index 273c2f3ea7d..daa244a3c5a 100644
--- a/mysql-test/suite/compat/oracle/r/sp-package.result
+++ b/mysql-test/suite/compat/oracle/r/sp-package.result
@@ -2960,3 +2960,311 @@ END $$
CALL xyz.xyz123(17,18,@R);
DROP PACKAGE xyz;
DROP TABLE t1;
+#
+# MDEV-28166 sql_mode=ORACLE: fully qualified package function calls do not work: db.pkg.func()
+#
+SELECT `db `.pkg.func();
+ERROR 42000: Incorrect database name 'db '
+SELECT db.`pkg `.func();
+ERROR 42000: Incorrect routine name 'pkg '
+SELECT db.pkg.`func `();
+ERROR 42000: Incorrect routine name 'func '
+CREATE DATABASE db1;
+USE db1;
+CREATE PACKAGE pkg1 AS
+FUNCTION f1 RETURN TEXT;
+FUNCTION f2_db1_pkg1_f1 RETURN TEXT;
+FUNCTION f2_pkg1_f1 RETURN TEXT;
+FUNCTION f2_f1 RETURN TEXT;
+END;
+$$
+CREATE PACKAGE BODY pkg1
+AS
+FUNCTION f1 RETURN TEXT IS
+BEGIN
+RETURN 'This is db1.pkg1.f1';
+END;
+FUNCTION f2_db1_pkg1_f1 RETURN TEXT IS
+BEGIN
+RETURN db1.pkg1.f1();
+END;
+FUNCTION f2_pkg1_f1 RETURN TEXT IS
+BEGIN
+RETURN pkg1.f1();
+END;
+FUNCTION f2_f1 RETURN TEXT IS
+BEGIN
+RETURN f1();
+END;
+END;
+$$
+USE db1;
+SELECT pkg1.f2_db1_pkg1_f1();
+pkg1.f2_db1_pkg1_f1()
+This is db1.pkg1.f1
+SELECT pkg1.f2_pkg1_f1();
+pkg1.f2_pkg1_f1()
+This is db1.pkg1.f1
+SELECT pkg1.f2_f1();
+pkg1.f2_f1()
+This is db1.pkg1.f1
+SELECT db1.pkg1.f2_db1_pkg1_f1();
+db1.pkg1.f2_db1_pkg1_f1()
+This is db1.pkg1.f1
+SELECT db1.pkg1.f2_pkg1_f1();
+db1.pkg1.f2_pkg1_f1()
+This is db1.pkg1.f1
+SELECT db1.pkg1.f2_f1();
+db1.pkg1.f2_f1()
+This is db1.pkg1.f1
+USE test;
+SELECT db1.pkg1.f2_db1_pkg1_f1();
+db1.pkg1.f2_db1_pkg1_f1()
+This is db1.pkg1.f1
+SELECT db1.pkg1.f2_pkg1_f1();
+db1.pkg1.f2_pkg1_f1()
+This is db1.pkg1.f1
+SELECT db1.pkg1.f2_f1();
+db1.pkg1.f2_f1()
+This is db1.pkg1.f1
+DROP DATABASE db1;
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+CREATE PACKAGE db1.pkg1 AS
+FUNCTION f1 RETURN TEXT;
+END;
+$$
+CREATE PACKAGE BODY db1.pkg1 AS
+FUNCTION f1 RETURN TEXT AS
+BEGIN
+RETURN 'This is db1.pkg1.f1';
+END;
+END;
+$$
+CREATE PACKAGE db2.pkg1 AS
+FUNCTION f1 RETURN TEXT;
+FUNCTION var1 RETURN TEXT;
+FUNCTION var2 RETURN TEXT;
+END;
+$$
+CREATE PACKAGE BODY db2.pkg1 AS
+m_var1 TEXT;
+m_var2 TEXT;
+FUNCTION f1 RETURN TEXT AS
+BEGIN
+RETURN 'This is db2.pkg1.f1';
+END;
+FUNCTION var1 RETURN TEXT AS
+BEGIN
+RETURN m_var1;
+END;
+FUNCTION var2 RETURN TEXT AS
+BEGIN
+RETURN m_var2;
+END;
+BEGIN
+m_var1:= db1.pkg1.f1();
+m_var2:= db2.pkg1.f1();
+END;
+$$
+SELECT db2.pkg1.var1(), db2.pkg1.var2();
+db2.pkg1.var1() db2.pkg1.var2()
+This is db1.pkg1.f1 This is db2.pkg1.f1
+DROP DATABASE db1;
+DROP DATABASE db2;
+CREATE PACKAGE pkg1 AS
+FUNCTION f1(a TEXT) RETURN TEXT;
+END;
+$$
+CREATE PACKAGE BODY pkg1 AS
+FUNCTION f1(a TEXT) RETURN TEXT AS
+BEGIN
+RETURN a;
+END;
+END;
+$$
+SELECT test.pkg1.f1('xxx');
+test.pkg1.f1('xxx')
+xxx
+SELECT test.pkg1.f1('xxx' AS a);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'AS a)' at line 1
+DROP PACKAGE pkg1;
+#
+# MDEV-19328 sql_mode=ORACLE: Package function in VIEW
+#
+SET sql_mode=ORACLE;
+CREATE PACKAGE test1 AS
+FUNCTION f_test RETURN number;
+END test1;
+$$
+CREATE PACKAGE BODY test1
+AS
+FUNCTION f_test RETURN NUMBER IS
+BEGIN
+RETURN 1;
+END;
+END test1;
+$$
+SET sql_mode=ORACLE;
+CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test();
+SELECT * FROM v_test;
+c1
+1
+SHOW CREATE VIEW v_test;
+View v_test
+Create View CREATE VIEW "v_test" AS select 1 AS "c1" from DUAL where 1 = "test"."test1"."f_test"()
+character_set_client latin1
+collation_connection latin1_swedish_ci
+SET sql_mode=DEFAULT;
+SELECT * FROM v_test;
+c1
+1
+SHOW CREATE VIEW v_test;
+View v_test
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_test` AS select 1 AS `c1` from DUAL where 1 = `test`.`test1`.`f_test`()
+character_set_client latin1
+collation_connection latin1_swedish_ci
+DROP VIEW v_test;
+SET sql_mode=DEFAULT;
+CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test();
+ERROR 42000: FUNCTION test1.f_test does not exist
+SET sql_mode=ORACLE;
+CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test();
+SELECT * FROM v_test;
+c1
+1
+SHOW CREATE VIEW v_test;
+View v_test
+Create View CREATE VIEW "v_test" AS select 1 AS "c1" from DUAL where 1 = "test"."test1"."f_test"()
+character_set_client latin1
+collation_connection latin1_swedish_ci
+SET sql_mode=DEFAULT;
+SELECT * FROM v_test;
+c1
+1
+SHOW CREATE VIEW v_test;
+View v_test
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_test` AS select 1 AS `c1` from DUAL where 1 = `test`.`test1`.`f_test`()
+character_set_client latin1
+collation_connection latin1_swedish_ci
+DROP VIEW v_test;
+SET sql_mode=DEFAULT;
+CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test();
+SELECT * FROM v_test;
+c1
+1
+SHOW CREATE VIEW v_test;
+View v_test
+Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_test` AS select 1 AS `c1` from DUAL where 1 = `test`.`test1`.`f_test`()
+character_set_client latin1
+collation_connection latin1_swedish_ci
+SET sql_mode=ORACLE;
+SELECT * FROM v_test;
+c1
+1
+SHOW CREATE VIEW v_test;
+View v_test
+Create View CREATE VIEW "v_test" AS select 1 AS "c1" from DUAL where 1 = "test"."test1"."f_test"()
+character_set_client latin1
+collation_connection latin1_swedish_ci
+DROP VIEW v_test;
+SET sql_mode=ORACLE;
+DROP PACKAGE test1;
+#
+# MDEV-19804 sql_mode=ORACLE: call procedure in packages
+#
+CALL `db1 `.pkg.p;
+ERROR 42000: Incorrect database name 'db1 '
+CALL db1.`pkg `.p;
+ERROR 42000: Incorrect routine name 'pkg '
+CALL db1.pkg.`p `;
+ERROR 42000: Incorrect routine name 'p '
+SET sql_mode=ORACLE;
+CREATE PACKAGE pkg1 as
+PROCEDURE p1();
+END;
+$$
+CREATE PACKAGE BODY pkg1 as
+PROCEDURE p1() as
+BEGIN
+SELECT 'test-function' AS c1;
+END;
+END;
+$$
+CALL pkg1.p1;
+c1
+test-function
+CALL test.pkg1.p1;
+c1
+test-function
+SET sql_mode=DEFAULT;
+CALL test.pkg1.p1;
+c1
+test-function
+SET sql_mode=ORACLE;
+BEGIN
+CALL pkg1.p1;
+CALL test.pkg1.p1;
+END
+$$
+c1
+test-function
+c1
+test-function
+BEGIN
+pkg1.p1;
+test.pkg1.p1;
+END
+$$
+c1
+test-function
+c1
+test-function
+DROP PACKAGE pkg1;
+CREATE DATABASE db1;
+CREATE PACKAGE db1.pkg1 AS
+PROCEDURE p1(a OUT TEXT);
+END;
+$$
+CREATE PACKAGE BODY db1.pkg1 AS
+PROCEDURE p1(a OUT TEXT) AS
+BEGIN
+a:= 'This is db1.pkg1.p1';
+END;
+END;
+$$
+CREATE DATABASE db2;
+CREATE PACKAGE db2.pkg1 AS
+FUNCTION var1 RETURN TEXT;
+PROCEDURE p1(a OUT TEXT);
+PROCEDURE p2_db1_pkg1_p1;
+END;
+$$
+CREATE PACKAGE BODY db2.pkg1 AS
+m_var1 TEXT;
+FUNCTION var1 RETURN TEXT AS
+BEGIN
+RETURN m_var1;
+END;
+PROCEDURE p1(a OUT TEXT) AS
+BEGIN
+a:= 'This is db2.pkg1.p1';
+END;
+PROCEDURE p2_db1_pkg1_p1 AS
+a TEXT;
+BEGIN
+db1.pkg1.p1(a);
+SELECT a;
+END;
+BEGIN
+db1.pkg1.p1(m_var1);
+END;
+$$
+SELECT db2.pkg1.var1();
+db2.pkg1.var1()
+This is db1.pkg1.p1
+CALL db2.pkg1.p2_db1_pkg1_p1;
+a
+This is db1.pkg1.p1
+DROP DATABASE db1;
+DROP DATABASE db2;
diff --git a/mysql-test/suite/compat/oracle/t/sp-package.test b/mysql-test/suite/compat/oracle/t/sp-package.test
index edad90e547f..615ce51e195 100644
--- a/mysql-test/suite/compat/oracle/t/sp-package.test
+++ b/mysql-test/suite/compat/oracle/t/sp-package.test
@@ -2689,3 +2689,330 @@ CALL xyz.xyz123(17,18,@R);
DROP PACKAGE xyz;
DROP TABLE t1;
--disable_prepare_warnings
+
+
+--echo #
+--echo # MDEV-28166 sql_mode=ORACLE: fully qualified package function calls do not work: db.pkg.func()
+--echo #
+
+--error ER_WRONG_DB_NAME
+SELECT `db `.pkg.func();
+--error ER_SP_WRONG_NAME
+SELECT db.`pkg `.func();
+--error ER_SP_WRONG_NAME
+SELECT db.pkg.`func `();
+
+
+CREATE DATABASE db1;
+USE db1;
+
+DELIMITER $$;
+CREATE PACKAGE pkg1 AS
+ FUNCTION f1 RETURN TEXT;
+ FUNCTION f2_db1_pkg1_f1 RETURN TEXT;
+ FUNCTION f2_pkg1_f1 RETURN TEXT;
+ FUNCTION f2_f1 RETURN TEXT;
+END;
+$$
+CREATE PACKAGE BODY pkg1
+AS
+ FUNCTION f1 RETURN TEXT IS
+ BEGIN
+ RETURN 'This is db1.pkg1.f1';
+ END;
+ FUNCTION f2_db1_pkg1_f1 RETURN TEXT IS
+ BEGIN
+ RETURN db1.pkg1.f1();
+ END;
+ FUNCTION f2_pkg1_f1 RETURN TEXT IS
+ BEGIN
+ RETURN pkg1.f1();
+ END;
+ FUNCTION f2_f1 RETURN TEXT IS
+ BEGIN
+ RETURN f1();
+ END;
+END;
+$$
+DELIMITER ;$$
+
+USE db1;
+SELECT pkg1.f2_db1_pkg1_f1();
+SELECT pkg1.f2_pkg1_f1();
+SELECT pkg1.f2_f1();
+
+SELECT db1.pkg1.f2_db1_pkg1_f1();
+SELECT db1.pkg1.f2_pkg1_f1();
+SELECT db1.pkg1.f2_f1();
+
+USE test;
+SELECT db1.pkg1.f2_db1_pkg1_f1();
+SELECT db1.pkg1.f2_pkg1_f1();
+SELECT db1.pkg1.f2_f1();
+
+DROP DATABASE db1;
+
+
+#
+# Testing db.pkg.func() in the package initialization section
+#
+
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+
+DELIMITER $$;
+CREATE PACKAGE db1.pkg1 AS
+ FUNCTION f1 RETURN TEXT;
+END;
+$$
+CREATE PACKAGE BODY db1.pkg1 AS
+ FUNCTION f1 RETURN TEXT AS
+ BEGIN
+ RETURN 'This is db1.pkg1.f1';
+ END;
+END;
+$$
+DELIMITER ;$$
+
+
+DELIMITER $$;
+CREATE PACKAGE db2.pkg1 AS
+ FUNCTION f1 RETURN TEXT;
+ FUNCTION var1 RETURN TEXT;
+ FUNCTION var2 RETURN TEXT;
+END;
+$$
+CREATE PACKAGE BODY db2.pkg1 AS
+ m_var1 TEXT;
+ m_var2 TEXT;
+ FUNCTION f1 RETURN TEXT AS
+ BEGIN
+ RETURN 'This is db2.pkg1.f1';
+ END;
+ FUNCTION var1 RETURN TEXT AS
+ BEGIN
+ RETURN m_var1;
+ END;
+ FUNCTION var2 RETURN TEXT AS
+ BEGIN
+ RETURN m_var2;
+ END;
+BEGIN
+ m_var1:= db1.pkg1.f1();
+ m_var2:= db2.pkg1.f1();
+END;
+$$
+DELIMITER ;$$
+
+SELECT db2.pkg1.var1(), db2.pkg1.var2();
+
+DROP DATABASE db1;
+DROP DATABASE db2;
+
+#
+# Make sure fully qualified package function call does not support AS syntax:
+# SELECT db.pkg.func(10 AS a);
+#
+
+DELIMITER $$;
+CREATE PACKAGE pkg1 AS
+ FUNCTION f1(a TEXT) RETURN TEXT;
+END;
+$$
+CREATE PACKAGE BODY pkg1 AS
+ FUNCTION f1(a TEXT) RETURN TEXT AS
+ BEGIN
+ RETURN a;
+ END;
+END;
+$$
+DELIMITER ;$$
+SELECT test.pkg1.f1('xxx');
+--error ER_PARSE_ERROR
+SELECT test.pkg1.f1('xxx' AS a);
+DROP PACKAGE pkg1;
+
+
+--echo #
+--echo # MDEV-19328 sql_mode=ORACLE: Package function in VIEW
+--echo #
+
+SET sql_mode=ORACLE;
+DELIMITER $$;
+CREATE PACKAGE test1 AS
+ FUNCTION f_test RETURN number;
+END test1;
+$$
+CREATE PACKAGE BODY test1
+AS
+ FUNCTION f_test RETURN NUMBER IS
+ BEGIN
+ RETURN 1;
+ END;
+END test1;
+$$
+DELIMITER ;$$
+
+
+SET sql_mode=ORACLE;
+CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test();
+SELECT * FROM v_test;
+--vertical_results
+SHOW CREATE VIEW v_test;
+--horizontal_results
+SET sql_mode=DEFAULT;
+SELECT * FROM v_test;
+--vertical_results
+SHOW CREATE VIEW v_test;
+--horizontal_results
+DROP VIEW v_test;
+
+
+SET sql_mode=DEFAULT;
+--error ER_SP_DOES_NOT_EXIST
+CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test();
+
+
+SET sql_mode=ORACLE;
+CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test();
+SELECT * FROM v_test;
+--vertical_results
+SHOW CREATE VIEW v_test;
+--horizontal_results
+SET sql_mode=DEFAULT;
+SELECT * FROM v_test;
+--vertical_results
+SHOW CREATE VIEW v_test;
+--horizontal_results
+DROP VIEW v_test;
+
+
+SET sql_mode=DEFAULT;
+CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test();
+SELECT * FROM v_test;
+--vertical_results
+SHOW CREATE VIEW v_test;
+--horizontal_results
+SET sql_mode=ORACLE;
+SELECT * FROM v_test;
+--vertical_results
+SHOW CREATE VIEW v_test;
+--horizontal_results
+DROP VIEW v_test;
+
+SET sql_mode=ORACLE;
+DROP PACKAGE test1;
+
+
+--echo #
+--echo # MDEV-19804 sql_mode=ORACLE: call procedure in packages
+--echo #
+
+--error ER_WRONG_DB_NAME
+CALL `db1 `.pkg.p;
+--error ER_SP_WRONG_NAME
+CALL db1.`pkg `.p;
+--error ER_SP_WRONG_NAME
+CALL db1.pkg.`p `;
+
+
+SET sql_mode=ORACLE;
+DELIMITER $$;
+CREATE PACKAGE pkg1 as
+ PROCEDURE p1();
+END;
+$$
+CREATE PACKAGE BODY pkg1 as
+ PROCEDURE p1() as
+ BEGIN
+ SELECT 'test-function' AS c1;
+ END;
+END;
+$$
+DELIMITER ;$$
+
+CALL pkg1.p1;
+CALL test.pkg1.p1;
+
+# In sql_mode=DEFAULT we support fully qualified package function names
+# (this is needed for VIEWs). Let's make sure we also support fully
+# qualified package procedure names, for symmetry
+
+SET sql_mode=DEFAULT;
+CALL test.pkg1.p1;
+SET sql_mode=ORACLE;
+
+DELIMITER $$;
+BEGIN
+ CALL pkg1.p1;
+ CALL test.pkg1.p1;
+END
+$$
+DELIMITER ;$$
+
+DELIMITER $$;
+BEGIN
+ pkg1.p1;
+ test.pkg1.p1;
+END
+$$
+DELIMITER ;$$
+
+DROP PACKAGE pkg1;
+
+
+#
+# Testing packages in different databases calling each other
+# in routines and in the initialization section.
+#
+
+CREATE DATABASE db1;
+DELIMITER $$;
+CREATE PACKAGE db1.pkg1 AS
+ PROCEDURE p1(a OUT TEXT);
+END;
+$$
+CREATE PACKAGE BODY db1.pkg1 AS
+ PROCEDURE p1(a OUT TEXT) AS
+ BEGIN
+ a:= 'This is db1.pkg1.p1';
+ END;
+END;
+$$
+DELIMITER ;$$
+
+CREATE DATABASE db2;
+DELIMITER $$;
+CREATE PACKAGE db2.pkg1 AS
+ FUNCTION var1 RETURN TEXT;
+ PROCEDURE p1(a OUT TEXT);
+ PROCEDURE p2_db1_pkg1_p1;
+END;
+$$
+CREATE PACKAGE BODY db2.pkg1 AS
+ m_var1 TEXT;
+ FUNCTION var1 RETURN TEXT AS
+ BEGIN
+ RETURN m_var1;
+ END;
+ PROCEDURE p1(a OUT TEXT) AS
+ BEGIN
+ a:= 'This is db2.pkg1.p1';
+ END;
+ PROCEDURE p2_db1_pkg1_p1 AS
+ a TEXT;
+ BEGIN
+ db1.pkg1.p1(a);
+ SELECT a;
+ END;
+BEGIN
+ db1.pkg1.p1(m_var1);
+END;
+$$
+DELIMITER ;$$
+
+SELECT db2.pkg1.var1();
+CALL db2.pkg1.p2_db1_pkg1_p1;
+
+DROP DATABASE db1;
+DROP DATABASE db2;
diff --git a/mysql-test/suite/encryption/t/innochecksum.test b/mysql-test/suite/encryption/t/innochecksum.test
index 0f44844c103..72e95de84e5 100644
--- a/mysql-test/suite/encryption/t/innochecksum.test
+++ b/mysql-test/suite/encryption/t/innochecksum.test
@@ -15,6 +15,11 @@ if (!$INNOCHECKSUM) {
--die Need innochecksum binary
}
+--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");
+--enable_query_log
+
let $checksum_algorithm = `SELECT @@innodb_checksum_algorithm`;
SET GLOBAL innodb_file_per_table = ON;
# zlib
diff --git a/mysql-test/suite/funcs_2/charset/charset_master.test b/mysql-test/suite/funcs_2/charset/charset_master.test
index 8f3ac64c753..099f44c9a02 100644
--- a/mysql-test/suite/funcs_2/charset/charset_master.test
+++ b/mysql-test/suite/funcs_2/charset/charset_master.test
@@ -38,7 +38,7 @@ if (`SELECT COUNT(*) <> 36 FROM information_schema.character_sets
'hp8' , 'keybcs2', 'koi8r' , 'koi8u' , 'latin1',
'latin2' , 'latin5' , 'latin7' , 'macce' , 'macroman',
'sjis' , 'swe7' , 'tis620' , 'ucs2' , 'ujis',
- 'utf8'
+ 'utf8mb3'
)`)
{
--skip Not all character sets required for this test are present
@@ -72,12 +72,12 @@ WHERE collation_name IN (
'ucs2_latvian_ci', 'ucs2_lithuanian_ci', 'ucs2_persian_ci', 'ucs2_polish_ci',
'ucs2_roman_ci', 'ucs2_romanian_ci', 'ucs2_slovak_ci', 'ucs2_slovenian_ci',
'ucs2_spanish2_ci', 'ucs2_spanish_ci', 'ucs2_swedish_ci', 'ucs2_turkish_ci',
-'ucs2_unicode_ci', 'ujis_bin', 'ujis_japanese_ci', 'utf8_bin',
-'utf8_czech_ci', 'utf8_danish_ci', 'utf8_estonian_ci', 'utf8_general_ci',
-'utf8_hungarian_ci', 'utf8_icelandic_ci', 'utf8_latvian_ci', 'utf8_lithuanian_ci',
-'utf8_persian_ci', 'utf8_polish_ci', 'utf8_roman_ci', 'utf8_romanian_ci',
-'utf8_slovak_ci', 'utf8_slovenian_ci', 'utf8_spanish2_ci', 'utf8_spanish_ci',
-'utf8_swedish_ci', 'utf8_turkish_ci', 'utf8_unicode_ci'
+'ucs2_unicode_ci', 'ujis_bin', 'ujis_japanese_ci', 'utf8mb3_bin',
+'utf8mb3_czech_ci', 'utf8mb3_danish_ci', 'utf8mb3_estonian_ci', 'utf8mb3_general_ci',
+'utf8mb3_hungarian_ci', 'utf8mb3_icelandic_ci', 'utf8mb3_latvian_ci', 'utf8mb3_lithuanian_ci',
+'utf8mb3_persian_ci', 'utf8mb3_polish_ci', 'utf8mb3_roman_ci', 'utf8mb3_romanian_ci',
+'utf8mb3_slovak_ci', 'utf8mb3_slovenian_ci', 'utf8mb3_spanish2_ci', 'utf8mb3_spanish_ci',
+'utf8mb3_swedish_ci', 'utf8mb3_turkish_ci', 'utf8mb3_unicode_ci'
)`)
{
--skip Not all collations required for this test are present
@@ -86,7 +86,7 @@ WHERE collation_name IN (
################################
let $check_std_csets= 1;
let $check_ucs2_csets= 1;
-let $check_utf8_csets= 1;
+let $check_utf8mb3_csets= 1;
# Bug#32784: Timeout in test "innodb_charset": InnoDB much slower
# than other handlers
@@ -104,7 +104,7 @@ SET autocommit=0;
################################
let $check_std_csets= 1;
let $check_ucs2_csets= 1;
-let $check_utf8_csets= 1;
+let $check_utf8mb3_csets= 1;
#
# Check all charsets/collation combinations
@@ -610,7 +610,7 @@ let $coll= ucs2_unicode_ci;
}
-if ($check_utf8_csets)
+if ($check_utf8mb3_csets)
{
# utf8
diff --git a/mysql-test/suite/funcs_2/r/innodb_charset.result b/mysql-test/suite/funcs_2/r/innodb_charset.result
index 1ce5972eccc..3f4e2af12e5 100644
--- a/mysql-test/suite/funcs_2/r/innodb_charset.result
+++ b/mysql-test/suite/funcs_2/r/innodb_charset.result
@@ -17563,7 +17563,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_bin;
@@ -20104,7 +20104,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_czech_ci;
@@ -22645,7 +22645,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_danish_ci;
@@ -25186,7 +25186,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_estonian_ci;
@@ -27727,7 +27727,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_general_ci;
@@ -30268,7 +30268,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_hungarian_ci;
@@ -32809,7 +32809,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_icelandic_ci;
@@ -35350,7 +35350,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_latvian_ci;
@@ -37891,7 +37891,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_lithuanian_ci;
@@ -40432,7 +40432,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_persian_ci;
@@ -42973,7 +42973,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_polish_ci;
@@ -45514,7 +45514,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_roman_ci;
@@ -48055,7 +48055,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_romanian_ci;
@@ -50596,7 +50596,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovak_ci;
@@ -53137,7 +53137,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovenian_ci;
@@ -55678,7 +55678,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish2_ci;
@@ -58219,7 +58219,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish_ci;
@@ -60760,7 +60760,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_swedish_ci;
@@ -63301,7 +63301,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_turkish_ci;
@@ -65842,7 +65842,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=InnoDB CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci;
@@ -68382,7 +68382,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_bin) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_bin # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_bin # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -70921,7 +70921,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_czech_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_czech_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_czech_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_czech_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -73460,7 +73460,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_danish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_danish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_danish_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_danish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -75999,7 +75999,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_estonian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_estonian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_estonian_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_estonian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -78538,7 +78538,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_general_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -81077,7 +81077,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_hungarian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_hungarian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_hungarian_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_hungarian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -83616,7 +83616,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_icelandic_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_icelandic_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_icelandic_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_icelandic_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -86155,7 +86155,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_latvian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_latvian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_latvian_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_latvian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -88694,7 +88694,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_lithuanian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_lithuanian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_lithuanian_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_lithuanian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -91233,7 +91233,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_persian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_persian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_persian_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_persian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -93772,7 +93772,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_polish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_polish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_polish_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_polish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -96311,7 +96311,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_roman_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_roman_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_roman_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_roman_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -98850,7 +98850,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_romanian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_romanian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_romanian_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_romanian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -101389,7 +101389,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovak_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_slovak_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_slovak_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_slovak_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -103928,7 +103928,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovenian_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_slovenian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_slovenian_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_slovenian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -106467,7 +106467,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish2_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_spanish2_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_spanish2_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_spanish2_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -109006,7 +109006,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_spanish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_spanish_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_spanish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -111545,7 +111545,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_swedish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_swedish_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_swedish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -114084,7 +114084,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_turkish_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_turkish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_turkish_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_turkish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -116623,7 +116623,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 InnoDB # # # # # # # # # # # # utf8_unicode_ci # # # 0 N
+t1 InnoDB # # # # # # # # # # # # utf8mb3_unicode_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
diff --git a/mysql-test/suite/funcs_2/r/memory_charset.result b/mysql-test/suite/funcs_2/r/memory_charset.result
index 66cdada9b61..bf21eac2a53 100644
--- a/mysql-test/suite/funcs_2/r/memory_charset.result
+++ b/mysql-test/suite/funcs_2/r/memory_charset.result
@@ -17563,7 +17563,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_bin;
@@ -20104,7 +20104,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_czech_ci;
@@ -22645,7 +22645,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_danish_ci;
@@ -25186,7 +25186,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_estonian_ci;
@@ -27727,7 +27727,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_general_ci;
@@ -30268,7 +30268,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_hungarian_ci;
@@ -32809,7 +32809,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_icelandic_ci;
@@ -35350,7 +35350,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_latvian_ci;
@@ -37891,7 +37891,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_lithuanian_ci;
@@ -40432,7 +40432,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_persian_ci;
@@ -42973,7 +42973,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_polish_ci;
@@ -45514,7 +45514,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_roman_ci;
@@ -48055,7 +48055,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_romanian_ci;
@@ -50596,7 +50596,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovak_ci;
@@ -53137,7 +53137,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovenian_ci;
@@ -55678,7 +55678,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish2_ci;
@@ -58219,7 +58219,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish_ci;
@@ -60760,7 +60760,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_swedish_ci;
@@ -63301,7 +63301,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_turkish_ci;
@@ -65842,7 +65842,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=Memory CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci;
@@ -68382,7 +68382,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_bin) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_bin;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_bin # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_bin # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -70921,7 +70921,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_czech_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_czech_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_czech_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_czech_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -73460,7 +73460,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_danish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_danish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_danish_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_danish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -75999,7 +75999,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_estonian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_estonian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_estonian_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_estonian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -78538,7 +78538,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_general_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_general_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_general_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_general_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -81077,7 +81077,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_hungarian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_hungarian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_hungarian_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_hungarian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -83616,7 +83616,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_icelandic_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_icelandic_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_icelandic_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_icelandic_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -86155,7 +86155,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_latvian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_latvian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_latvian_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_latvian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -88694,7 +88694,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_lithuanian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_lithuanian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_lithuanian_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_lithuanian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -91233,7 +91233,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_persian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_persian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_persian_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_persian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -93772,7 +93772,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_polish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_polish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_polish_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_polish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -96311,7 +96311,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_roman_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_roman_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_roman_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_roman_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -98850,7 +98850,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_romanian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_romanian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_romanian_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_romanian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -101389,7 +101389,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovak_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_slovak_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_slovak_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_slovak_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -103928,7 +103928,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovenian_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_slovenian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_slovenian_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_slovenian_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -106467,7 +106467,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish2_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_spanish2_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_spanish2_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_spanish2_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -109006,7 +109006,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_spanish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_spanish_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_spanish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -111545,7 +111545,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_swedish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_swedish_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_swedish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -114084,7 +114084,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_turkish_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_turkish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_turkish_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_turkish_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -116623,7 +116623,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci) ENGINE=Memory CHARACTER SET utf8 COLLATE utf8_unicode_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MEMORY # # # # # # # # # # # # utf8_unicode_ci # # # 0 N
+t1 MEMORY # # # # # # # # # # # # utf8mb3_unicode_ci # # # 0 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
diff --git a/mysql-test/suite/funcs_2/r/myisam_charset.result b/mysql-test/suite/funcs_2/r/myisam_charset.result
index 9950b446a63..b6cbebd4ec1 100644
--- a/mysql-test/suite/funcs_2/r/myisam_charset.result
+++ b/mysql-test/suite/funcs_2/r/myisam_charset.result
@@ -17563,7 +17563,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_bin;
@@ -20104,7 +20104,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_czech_ci;
@@ -22645,7 +22645,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_danish_ci;
@@ -25186,7 +25186,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_estonian_ci;
@@ -27727,7 +27727,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_general_ci;
@@ -30268,7 +30268,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_hungarian_ci;
@@ -32809,7 +32809,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_icelandic_ci;
@@ -35350,7 +35350,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_latvian_ci;
@@ -37891,7 +37891,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_lithuanian_ci;
@@ -40432,7 +40432,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_persian_ci;
@@ -42973,7 +42973,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_polish_ci;
@@ -45514,7 +45514,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_roman_ci;
@@ -48055,7 +48055,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_romanian_ci;
@@ -50596,7 +50596,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovak_ci;
@@ -53137,7 +53137,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_slovenian_ci;
@@ -55678,7 +55678,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish2_ci;
@@ -58219,7 +58219,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_spanish_ci;
@@ -60760,7 +60760,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_swedish_ci;
@@ -63301,7 +63301,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_turkish_ci;
@@ -65842,7 +65842,7 @@ SET NAMES utf8;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8) ENGINE=MyISAM CHARACTER SET utf8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
ALTER TABLE test.t1 CHANGE a a CHAR(4) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci;
@@ -68382,7 +68382,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_bin) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_bin;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_bin # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_bin # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -70921,7 +70921,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_czech_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_czech_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_czech_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_czech_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -73460,7 +73460,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_danish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_danish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_danish_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_danish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -75999,7 +75999,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_estonian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_estonian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_estonian_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_estonian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -78538,7 +78538,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_general_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_general_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_general_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -81077,7 +81077,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_hungarian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_hungarian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_hungarian_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_hungarian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -83616,7 +83616,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_icelandic_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_icelandic_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_icelandic_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_icelandic_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -86155,7 +86155,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_latvian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_latvian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_latvian_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_latvian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -88694,7 +88694,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_lithuanian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_lithuanian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_lithuanian_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_lithuanian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -91233,7 +91233,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_persian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_persian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_persian_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_persian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -93772,7 +93772,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_polish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_polish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_polish_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_polish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -96311,7 +96311,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_roman_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_roman_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_roman_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_roman_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -98850,7 +98850,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_romanian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_romanian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_romanian_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_romanian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -101389,7 +101389,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovak_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_slovak_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_slovak_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_slovak_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -103928,7 +103928,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_slovenian_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_slovenian_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_slovenian_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_slovenian_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -106467,7 +106467,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish2_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_spanish2_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_spanish2_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_spanish2_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -109006,7 +109006,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_spanish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_spanish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_spanish_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_spanish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -111545,7 +111545,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_swedish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_swedish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_swedish_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_swedish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -114084,7 +114084,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_turkish_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_turkish_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_turkish_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_turkish_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
@@ -116623,7 +116623,7 @@ USE test;
CREATE TABLE test.t1 (a CHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_unicode_ci;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
-t1 MyISAM # # # # # # # # # # # # utf8_unicode_ci # # # 17179868160 N
+t1 MyISAM # # # # # # # # # # # # utf8mb3_unicode_ci # # # 17179868160 N
LOAD DATA INFILE
'MYSQL_TEST_DIR/suite/funcs_2/data/charset_utf8.txt' INTO TABLE test.t1;
DELETE FROM test.t1 WHERE CHAR_LENGTH(a) <> 1;
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index eb1aba72162..76992e9d59b 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -44,3 +44,4 @@ pxc-421: wsrep_provider is read-only for security reasons
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_ps_bind : MDEV-28193 Galera test failure on galera_bf_abort_ps_bind
diff --git a/mysql-test/suite/galera/include/kill_galera.inc b/mysql-test/suite/galera/include/kill_galera.inc
index 98ebf4ff35d..56118df84f9 100644
--- a/mysql-test/suite/galera/include/kill_galera.inc
+++ b/mysql-test/suite/galera/include/kill_galera.inc
@@ -2,7 +2,7 @@
if (!$kill_signal)
{
---let $kill_signal = 9
+--let $kill_signal = KILL
}
# Write file to make mysql-test-run.pl expect the crash, but don't start it
diff --git a/mysql-test/suite/galera/r/MDEV-24143.result b/mysql-test/suite/galera/r/MDEV-24143.result
new file mode 100644
index 00000000000..860d8a35834
--- /dev/null
+++ b/mysql-test/suite/galera/r/MDEV-24143.result
@@ -0,0 +1,23 @@
+connection node_2;
+connection node_1;
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 BINARY (10), c3 DATETIME);
+SELECT get_lock ('test2', 0);
+get_lock ('test2', 0)
+1
+DROP TABLE t1;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL AUTO_INCREMENT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+SET SESSION wsrep_trx_fragment_size=10;
+SET SESSION autocommit=0;
+SELECT * FROM t1 WHERE c1 <=0 ORDER BY c1 DESC;
+c1
+INSERT INTO t1 VALUES (4),(3),(1),(2);
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=SEQUENCE;
+ERROR 42S01: Table 't1' already exists
+ALTER TABLE t1 DROP COLUMN c2;
+ERROR 42000: Can't DROP COLUMN `c2`; check that it exists
+SELECT get_lock ('test', 1.5);
+get_lock ('test', 1.5)
+1
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/MDEV-27713.result b/mysql-test/suite/galera/r/MDEV-27713.result
new file mode 100644
index 00000000000..14575cb484d
--- /dev/null
+++ b/mysql-test/suite/galera/r/MDEV-27713.result
@@ -0,0 +1,46 @@
+connection node_2;
+connection node_1;
+CREATE TABLE t1 (
+f1 INT,
+f2 VARCHAR(255) PRIMARY KEY
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES(1, 'abc');
+connection node_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES (2,'def');
+connection node_2;
+SET GLOBAL event_scheduler=ON;
+CREATE PROCEDURE update_table()
+BEGIN
+SET AUTOCOMMIT=OFF;
+DO GET_LOCK('local_lock', 0);
+SET DEBUG_SYNC = 'innodb_row_update_for_mysql_begin SIGNAL blocked WAIT_FOR continue';
+UPDATE t1 SET f2 = 'jkl' WHERE f1 != 2;
+DO RELEASE_LOCK('local_lock');
+END|
+CREATE DEFINER=current_user
+EVENT event
+ON SCHEDULE AT CURRENT_TIMESTAMP
+ON COMPLETION PRESERVE
+ENABLE
+DO CALL update_table();
+connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
+SET DEBUG_SYNC = 'now WAIT_FOR blocked';
+connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2;
+SET GLOBAL debug_dbug = "+d,sync.wsrep_apply_cb";
+connection node_1;
+COMMIT;
+connection node_2b;
+SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+connection node_2a;
+SET DEBUG_SYNC = 'now SIGNAL continue';
+connection node_2;
+SET GLOBAL event_scheduler=default;
+DROP PROCEDURE update_table;
+DROP EVENT event;
+SET DEBUG_SYNC='reset';
+SET GLOBAL debug_dbug = DEFAULT;
+connection node_1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_bf_abort_ps_bind.result b/mysql-test/suite/galera/r/galera_bf_abort_ps_bind.result
new file mode 100644
index 00000000000..adc7da58eae
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_bf_abort_ps_bind.result
@@ -0,0 +1,37 @@
+connection node_2;
+connection node_1;
+CREATE TABLE t (i int primary key auto_increment, j varchar(20) character set utf8);
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+connection node_1a;
+SET SESSION wsrep_sync_wait = 0;
+connection node_1;
+insert into t values (1, 'first');
+PS_prepare INSERT INTO t(j) VALUES (?);;
+PS_bind node1;
+PS_execute;
+PS_execute;
+select * from t;
+i j
+1 first
+3 node1
+5 node1
+PS_close;
+PS_prepare INSERT INTO t(j) VALUES (?);;
+PS_bind node1;
+begin;
+update t set j='node1' where i=1;
+connection node_2;
+update t set j='node2' where i=1;
+connection node_1a;
+connection node_1;
+PS_execute;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+PS_execute;
+commit;
+select * from t;
+i j
+1 node2
+3 node1
+5 node1
+7 node1
+drop table t;
diff --git a/mysql-test/suite/galera/r/galera_ist_restart_joiner.result b/mysql-test/suite/galera/r/galera_ist_restart_joiner.result
index 7cb6d90840e..2f78c475762 100644
--- a/mysql-test/suite/galera/r/galera_ist_restart_joiner.result
+++ b/mysql-test/suite/galera/r/galera_ist_restart_joiner.result
@@ -18,6 +18,7 @@ SET SESSION wsrep_on=ON;
connection node_1;
UPDATE t1 SET f2 = 'd' WHERE f1 > 3;
connection node_2;
+Killing server ...
connection node_1;
UPDATE t1 SET f2 = 'e' WHERE f1 > 4;
connection node_2;
diff --git a/mysql-test/suite/galera/r/galera_kill_applier.result b/mysql-test/suite/galera/r/galera_kill_applier.result
index 78a91d2638f..a47f486b5fb 100644
--- a/mysql-test/suite/galera/r/galera_kill_applier.result
+++ b/mysql-test/suite/galera/r/galera_kill_applier.result
@@ -5,9 +5,13 @@ SELECT @@wsrep_slave_threads;
@@wsrep_slave_threads
1
SET GLOBAL wsrep_slave_threads=2;
+KILL ID;
Got one of the listed errors
+KILL QUERY ID;
Got one of the listed errors
+KILL ID;
Got one of the listed errors
+KILL QUERY ID;
Got one of the listed errors
SET GLOBAL wsrep_slave_threads=DEFAULT;
connection node_1;
diff --git a/mysql-test/suite/galera/t/MDEV-24143.test b/mysql-test/suite/galera/t/MDEV-24143.test
new file mode 100644
index 00000000000..e58f147cb7c
--- /dev/null
+++ b/mysql-test/suite/galera/t/MDEV-24143.test
@@ -0,0 +1,20 @@
+--source include/galera_cluster.inc
+--source include/have_sequence.inc
+
+CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 BINARY (10), c3 DATETIME);
+SELECT get_lock ('test2', 0);
+DROP TABLE t1;
+CREATE TABLE t1 (c1 SMALLINT NOT NULL AUTO_INCREMENT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+SET SESSION wsrep_trx_fragment_size=10;
+SET SESSION autocommit=0;
+SELECT * FROM t1 WHERE c1 <=0 ORDER BY c1 DESC;
+--error ER_LOCK_DEADLOCK
+INSERT INTO t1 VALUES (4),(3),(1),(2);
+--error ER_TABLE_EXISTS_ERROR
+CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=SEQUENCE;
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1 DROP COLUMN c2;
+SELECT get_lock ('test', 1.5);
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/galera/t/MDEV-27713.test b/mysql-test/suite/galera/t/MDEV-27713.test
new file mode 100644
index 00000000000..4bfcd7e3d50
--- /dev/null
+++ b/mysql-test/suite/galera/t/MDEV-27713.test
@@ -0,0 +1,67 @@
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/big_test.inc
+
+CREATE TABLE t1 (
+ f1 INT,
+ f2 VARCHAR(255) PRIMARY KEY
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES(1, 'abc');
+
+--connection node_1
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES (2,'def');
+
+--connection node_2
+
+SET GLOBAL event_scheduler=ON;
+
+DELIMITER |;
+CREATE PROCEDURE update_table()
+BEGIN
+ SET AUTOCOMMIT=OFF;
+ DO GET_LOCK('local_lock', 0);
+ SET DEBUG_SYNC = 'innodb_row_update_for_mysql_begin SIGNAL blocked WAIT_FOR continue';
+ UPDATE t1 SET f2 = 'jkl' WHERE f1 != 2;
+ DO RELEASE_LOCK('local_lock');
+END|
+DELIMITER ;|
+
+CREATE DEFINER=current_user
+ EVENT event
+ ON SCHEDULE AT CURRENT_TIMESTAMP
+ ON COMPLETION PRESERVE
+ ENABLE
+ DO CALL update_table();
+
+--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
+SET DEBUG_SYNC = 'now WAIT_FOR blocked';
+
+# Applier control thread
+--connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2
+SET GLOBAL debug_dbug = "+d,sync.wsrep_apply_cb";
+
+--connection node_1
+COMMIT;
+
+# Applier control thread
+--connection node_2b
+SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+
+--connection node_2a
+SET DEBUG_SYNC = 'now SIGNAL continue';
+
+--connection node_2
+SET GLOBAL event_scheduler=default;
+DROP PROCEDURE update_table;
+DROP EVENT event;
+SET DEBUG_SYNC='reset';
+SET GLOBAL debug_dbug = DEFAULT;
+
+--connection node_1
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/MW-44.test b/mysql-test/suite/galera/t/MW-44.test
index a2acfc57f6c..7b479d45844 100644
--- a/mysql-test/suite/galera/t/MW-44.test
+++ b/mysql-test/suite/galera/t/MW-44.test
@@ -19,7 +19,11 @@ SET SESSION wsrep_osu_method=RSU;
ALTER TABLE t1 ADD COLUMN f2 INTEGER;
SET SESSION wsrep_osu_method=TOI;
---let $wait_condition = SELECT COUNT(*) = 2 FROM mysql.general_log WHERE argument LIKE "CREATE%" OR argument LIKE "ALTER%"
+--let $wait_condition = SELECT COUNT(*) = 1 FROM mysql.general_log WHERE argument LIKE "CREATE%" AND command_type != 'Prepare'
+--let $wait_condition_on_error_output = SELECT * FROM mysql.general_log
+--source include/wait_condition_with_debug.inc
+
+--let $wait_condition = SELECT COUNT(*) = 1 FROM mysql.general_log WHERE argument LIKE "ALTER%" AND command_type != 'Prepare'
--let $wait_condition_on_error_output = SELECT * FROM mysql.general_log
--source include/wait_condition_with_debug.inc
diff --git a/mysql-test/suite/galera/t/galera_bf_abort_ps_bind.cnf b/mysql-test/suite/galera/t/galera_bf_abort_ps_bind.cnf
new file mode 100644
index 00000000000..62cf1854032
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_bf_abort_ps_bind.cnf
@@ -0,0 +1,7 @@
+!include ../galera_2nodes.cnf
+
+[mysqld.1]
+wsrep-debug=1
+
+[mysqld.2]
+wsrep-debug=1
diff --git a/mysql-test/suite/galera/t/galera_bf_abort_ps_bind.test b/mysql-test/suite/galera/t/galera_bf_abort_ps_bind.test
new file mode 100644
index 00000000000..a840f612a82
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_bf_abort_ps_bind.test
@@ -0,0 +1,58 @@
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+CREATE TABLE t (i int primary key auto_increment, j varchar(20) character set utf8);
+
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+--connection node_1a
+SET SESSION wsrep_sync_wait = 0;
+
+--connection node_1
+insert into t values (1, 'first');
+
+# prepare a statement for inserting rows into table t
+--PS_prepare INSERT INTO t(j) VALUES (?);
+
+# bind parameter, to insert with column j having value 'node1'
+--PS_bind node1
+
+# insert two rows with the PS
+# this is for showing that two execute commands can follow a bind command
+--PS_execute
+--PS_execute
+select * from t;
+
+# close the prepared statement, and prepare a new PS,
+# this happens to be same as the first PS
+# also bind parameter for the PS
+--PS_close
+--PS_prepare INSERT INTO t(j) VALUES (?);
+--PS_bind node1
+
+# start a transaction and make one update
+# leaving the transaction open
+begin;
+update t set j='node1' where i=1;
+
+# replicate a transaction from node2, which BF aborts the open
+# transaction in node1
+--connection node_2
+update t set j='node2' where i=1;
+
+# wait until the BF has completed, and update from node_2 has committed
+--connection node_1a
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t WHERE j='node2'
+--source include/wait_condition.inc
+
+# continue the open transaction, trying to insert third row, deadlock is now observed
+--connection node_1
+--error ER_LOCK_DEADLOCK
+--PS_execute
+
+# try to insert one more row
+--PS_execute
+commit;
+
+select * from t;
+
+drop table t;
diff --git a/mysql-test/suite/galera/t/galera_ist_restart_joiner.test b/mysql-test/suite/galera/t/galera_ist_restart_joiner.test
index f56d0e657bd..c535ac455b9 100644
--- a/mysql-test/suite/galera/t/galera_ist_restart_joiner.test
+++ b/mysql-test/suite/galera/t/galera_ist_restart_joiner.test
@@ -61,19 +61,7 @@ UPDATE t1 SET f2 = 'd' WHERE f1 > 3;
# Kill node #2 while IST is in progress
--connection node_2
-
-# Kill the connected server
---disable_reconnect
-
---perl
- my $pid_filename = $ENV{'KILL_NODE_PIDFILE'};
- my $mysqld_pid = `cat $pid_filename`;
- chomp($mysqld_pid);
- system("kill -9 $mysqld_pid");
- exit(0);
-EOF
-
---source include/wait_until_disconnected.inc
+--source include/kill_galera.inc
--connection node_1
--source include/wait_until_connected_again.inc
diff --git a/mysql-test/suite/galera/t/galera_kill_applier.test b/mysql-test/suite/galera/t/galera_kill_applier.test
index 3a285822613..88ec55ed0c1 100644
--- a/mysql-test/suite/galera/t/galera_kill_applier.test
+++ b/mysql-test/suite/galera/t/galera_kill_applier.test
@@ -16,21 +16,23 @@ SET GLOBAL wsrep_slave_threads=2;
--let $applier_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle' LIMIT 1`
---disable_query_log
+--replace_result $applier_thread ID
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
--eval KILL $applier_thread
+--replace_result $applier_thread ID
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
--eval KILL QUERY $applier_thread
--let $aborter_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep aborter idle' LIMIT 1`
+--replace_result $aborter_thread ID
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
--eval KILL $aborter_thread
+--replace_result $aborter_thread ID
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
--eval KILL QUERY $aborter_thread
---enable_query_log
SET GLOBAL wsrep_slave_threads=DEFAULT;
diff --git a/mysql-test/suite/galera_3nodes/r/galera_garbd_backup.result b/mysql-test/suite/galera_3nodes/r/galera_garbd_backup.result
new file mode 100644
index 00000000000..f176ef1dd7f
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_garbd_backup.result
@@ -0,0 +1,41 @@
+connection node_1;
+connection node_1;
+connection node_2;
+connection node_3;
+connection node_1;
+SET GLOBAL innodb_max_dirty_pages_pct=99;
+SET GLOBAL innodb_max_dirty_pages_pct_lwm=99;
+connection node_1;
+CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
+CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
+INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+INSERT INTO t1 (f2) SELECT REPEAT('x', 1024) FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
+connection node_2;
+Killing node #3 to free ports for garbd ...
+connection node_3;
+connection node_1;
+SET GLOBAL debug_dbug = "+d,sync.wsrep_donor_state";
+Starting garbd ...
+SET SESSION debug_sync = "now WAIT_FOR sync.wsrep_donor_state_reached";
+SET GLOBAL innodb_max_dirty_pages_pct_lwm=0;
+SET GLOBAL innodb_max_dirty_pages_pct=0;
+SET SESSION debug_sync = "now SIGNAL signal.wsrep_donor_state";
+SET GLOBAL debug_dbug = "";
+SET debug_sync='RESET';
+connection node_2;
+Killing garbd ...
+connection node_1;
+connection node_2;
+DROP TABLE t1;
+DROP TABLE ten;
+Restarting node #3 to satisfy MTR's end-of-test checks
+connection node_3;
+connection node_1;
+SET GLOBAL innodb_max_dirty_pages_pct = 75.000000;
+SET GLOBAL innodb_max_dirty_pages_pct_lwm = 0.000000;
+connection node_1;
+CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
+connection node_2;
+CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
+connection node_3;
+CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
diff --git a/mysql-test/suite/galera_3nodes/t/galera_garbd_backup.cnf b/mysql-test/suite/galera_3nodes/t/galera_garbd_backup.cnf
new file mode 100644
index 00000000000..8b7cb948a87
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_garbd_backup.cnf
@@ -0,0 +1,13 @@
+!include ../galera_3nodes.cnf
+
+[mysqld]
+wsrep_sst_method=rsync
+
+[mysqld.1]
+wsrep_node_name=node1
+
+[mysqld.2]
+wsrep_node_name=node2
+
+[mysqld.3]
+wsrep_node_name=node3
diff --git a/mysql-test/suite/galera_3nodes/t/galera_garbd_backup.test b/mysql-test/suite/galera_3nodes/t/galera_garbd_backup.test
new file mode 100644
index 00000000000..302bf430dde
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_garbd_backup.test
@@ -0,0 +1,134 @@
+#
+# A very basic test for the galera arbitrator. We shut down node #3 and use its port allocation to start garbd.
+# As MTR does not allow multiple servers to be down at the same time, we are limited as to what we can test.
+#
+
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+--source include/have_garbd.inc
+--source include/big_test.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+--connection node_1
+# Save original auto_increment_offset values.
+--let $node_1=node_1
+--let $node_2=node_2
+--let $node_3=node_3
+
+--let $galera_connection_name = node_3
+--let $galera_server_number = 3
+--source include/galera_connect.inc
+--source suite/galera/include/galera_base_port.inc
+--let $NODE_GALERAPORT_3 = $_NODE_GALERAPORT
+
+--source ../galera/include/auto_increment_offset_save.inc
+
+# Save galera ports
+--connection node_1
+--source suite/galera/include/galera_base_port.inc
+--let $NODE_GALERAPORT_1 = $_NODE_GALERAPORT
+--let $datadir= `SELECT @@datadir`
+
+--let $innodb_max_dirty_pages_pct = `SELECT @@innodb_max_dirty_pages_pct`
+--let $innodb_max_dirty_pages_pct_lwm = `SELECT @@innodb_max_dirty_pages_pct_lwm`
+
+SET GLOBAL innodb_max_dirty_pages_pct=99;
+SET GLOBAL innodb_max_dirty_pages_pct_lwm=99;
+
+--connection node_1
+CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
+CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
+INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+INSERT INTO t1 (f2) SELECT REPEAT('x', 1024) FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
+
+--connection node_2
+--source suite/galera/include/galera_base_port.inc
+--let $NODE_GALERAPORT_2 = $_NODE_GALERAPORT
+
+--echo Killing node #3 to free ports for garbd ...
+--connection node_3
+--source include/shutdown_mysqld.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
+--source include/wait_condition.inc
+
+# stop SST donor thread when node is in donor state
+SET GLOBAL debug_dbug = "+d,sync.wsrep_donor_state";
+
+--echo Starting garbd ...
+--exec $MTR_GARBD_EXE --address "gcomm://127.0.0.1:$NODE_GALERAPORT_1" --group my_wsrep_cluster --donor node1 --sst backup --options 'base_port=$NODE_GALERAPORT_3' > $MYSQL_TMP_DIR/garbd.log 2>&1 &
+
+SET SESSION debug_sync = "now WAIT_FOR sync.wsrep_donor_state_reached";
+
+#
+# get hash of data directory contents before BP dirty page flushing
+#
+--exec find $datadir -type f ! -name tables_flushed ! -name backup_sst_complete -exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_before
+
+# this should force buffer pool flushing, if not already done by donor state change transfer
+SET GLOBAL innodb_max_dirty_pages_pct_lwm=0;
+SET GLOBAL innodb_max_dirty_pages_pct=0;
+
+--disable_query_log
+--disable_result_log
+select f1 from t1;
+select * from ten;
+--enable_result_log
+--enable_query_log
+
+#
+#
+# record the hash of data directory contents after BP dirty page flushing
+#
+--exec find $datadir -type f ! -name tables_flushed ! -name backup_sst_complete -exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_after
+
+# there should be no disk writes
+--diff_files $MYSQLTEST_VARDIR/tmp/innodb_before $MYSQLTEST_VARDIR/tmp/innodb_after
+
+SET SESSION debug_sync = "now SIGNAL signal.wsrep_donor_state";
+SET GLOBAL debug_dbug = "";
+SET debug_sync='RESET';
+
+--connection node_2
+
+#
+# garbd will die automatically, because of the backup SST script
+# but just to be sure, sending explicit kill here, as well
+#
+--echo Killing garbd ...
+# FreeBSD's /bin/pkill only supports short versions of the options:
+# -o Select only the oldest (least recently started)
+# -f Match against full argument lists
+--error 0,1
+--exec pkill -o -f garbd.*$NODE_GALERAPORT_3
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
+--source include/wait_condition.inc
+
+--connection node_2
+
+DROP TABLE t1;
+DROP TABLE ten;
+
+--echo Restarting node #3 to satisfy MTR's end-of-test checks
+--connection node_3
+let $restart_noprint=2;
+--source include/start_mysqld.inc
+
+--connection node_1
+--eval SET GLOBAL innodb_max_dirty_pages_pct = $innodb_max_dirty_pages_pct
+--eval SET GLOBAL innodb_max_dirty_pages_pct_lwm = $innodb_max_dirty_pages_pct_lwm
+
+--source ../galera/include/auto_increment_offset_restore.inc
+
+--connection node_1
+CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
+
+--connection node_2
+CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
+
+--connection node_3
+CALL mtr.add_suppression("WSREP: Protocol violation\. JOIN message sender 1\.0 \(.*\) is not in state transfer \(SYNCED\)");
diff --git a/mysql-test/suite/galera_sr/disabled.def b/mysql-test/suite/galera_sr/disabled.def
index 9f6ae2a51ef..e45118f6f0a 100644
--- a/mysql-test/suite/galera_sr/disabled.def
+++ b/mysql-test/suite/galera_sr/disabled.def
@@ -14,4 +14,5 @@ GCF-1018B : MDEV-18534 wsrep::transaction::adopt(): Assertion `transaction.is_st
GCF-1060 : MDEV-20848 galera_sr.GCF_1060
GCF-585 : MDEV-24698 galera_sr.GCF-585 MTR failed with SIGABRT: no such a transition REPLICATING -> APPLYING
galera-features#56 : MDEV-24896
+GCF-1060 : MDEV-26528 wrong usage of mutex LOCK_thd_kill and LOCK_thd_kill
galera_sr_shutdown_master : MDEV-23612: galera_sr.galera_sr_shutdown_master MTR failed: WSREP_SST: [ERROR] Possible timeout in receving first data from donor in gtid stage
diff --git a/mysql-test/suite/galera_sr/r/MDEV-27553.result b/mysql-test/suite/galera_sr/r/MDEV-27553.result
index f6f81bd13f1..5a6a5bd4956 100644
--- a/mysql-test/suite/galera_sr/r/MDEV-27553.result
+++ b/mysql-test/suite/galera_sr/r/MDEV-27553.result
@@ -1,23 +1,36 @@
connection node_2;
connection node_1;
-CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
connection node_1;
+connection node_2;
+connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
+connection node_2;
SET SESSION wsrep_trx_fragment_size=1;
START TRANSACTION;
INSERT INTO t1 VALUES (1);
+SELECT COUNT(*) `Expect 1` FROM mysql.wsrep_streaming_log;
+Expect 1
+1
SET @@global.debug_dbug="+d,ha_index_init_fail";
ROLLBACK;
-connection node_2;
+connection node_1;
+SET SESSION wsrep_sync_wait = 0;
SELECT COUNT(*) `Expect 0` FROM mysql.wsrep_streaming_log;
Expect 0
0
-connection node_1;
+connection node_2;
SET @@global.debug_dbug="";
+SET SESSION wsrep_sync_wait = 0;
SELECT COUNT(*) `Expect 1` FROM mysql.wsrep_streaming_log;
Expect 1
1
-SET SESSION wsrep_on=OFF;
-DELETE FROM mysql.wsrep_streaming_log;
-SET SESSION wsrep_on=ON;
+connection node_2;
+SET GLOBAL wsrep_on=OFF;
+# restart
+SELECT COUNT(*) `Expect 0` FROM mysql.wsrep_streaming_log;
+Expect 0
+0
DROP TABLE t1;
CALL mtr.add_suppression("WSREP: Failed to init table for index scan");
+CALL mtr.add_suppression("WSREP: Failed to apply write set");
+CALL mtr.add_suppression("Failed to report last committed");
diff --git a/mysql-test/suite/galera_sr/t/MDEV-27553.test b/mysql-test/suite/galera_sr/t/MDEV-27553.test
index d17af175512..5c557db9201 100644
--- a/mysql-test/suite/galera_sr/t/MDEV-27553.test
+++ b/mysql-test/suite/galera_sr/t/MDEV-27553.test
@@ -5,29 +5,76 @@
--source include/galera_cluster.inc
--source include/have_debug.inc
+--let $node_1=node_1
+--let $node_2=node_2
+--source suite/galera/include/auto_increment_offset_save.inc
+
+--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
+
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
---connection node_1
---let $wsrep_cluster_address_orig = `SELECT @@wsrep_cluster_address`
+--connection node_2
SET SESSION wsrep_trx_fragment_size=1;
START TRANSACTION;
INSERT INTO t1 VALUES (1);
-# This will result in failure to remove fragments
-# from streaming log, in the following ROLLBACK.
+SELECT COUNT(*) `Expect 1` FROM mysql.wsrep_streaming_log;
+
+#
+# Issue ROLLBACK and make sure it fails to clean up
+# the streaming log. Failure to remove fragments
+# results in apply failure of the rollback fragment.
+# The node should disconnect from the cluster.
+#
SET @@global.debug_dbug="+d,ha_index_init_fail";
ROLLBACK;
---connection node_2
+
+#
+# Expect the cluster to shrink
+#
+--connection node_1
+SET SESSION wsrep_sync_wait = 0;
+--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
+--source include/wait_condition.inc
+
+#
+# ROLLBACK should clean up the streaming log just fine in node 1
+#
SELECT COUNT(*) `Expect 0` FROM mysql.wsrep_streaming_log;
---connection node_1
+#
+# Expect the failure on ROLLBACK to leave a entry in streaming log
+#
+--connection node_2
SET @@global.debug_dbug="";
+SET SESSION wsrep_sync_wait = 0;
+# Expect node to be disconnected
+--let wait_condition = SELECT VARIABLE_VALUE = 'Disconnected' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
+--source include/wait_condition.inc
+
SELECT COUNT(*) `Expect 1` FROM mysql.wsrep_streaming_log;
-SET SESSION wsrep_on=OFF;
-DELETE FROM mysql.wsrep_streaming_log;
-SET SESSION wsrep_on=ON;
+
+#
+# Restart node 2, so that it joins the cluster back
+#
+--connection node_2
+SET GLOBAL wsrep_on=OFF;
+--source include/restart_mysqld.inc
+
+#
+# After restart, the streaming log is empty in node 2
+#
+SELECT COUNT(*) `Expect 0` FROM mysql.wsrep_streaming_log;
+
+#
+# Cleanup
+#
DROP TABLE t1;
CALL mtr.add_suppression("WSREP: Failed to init table for index scan");
+CALL mtr.add_suppression("WSREP: Failed to apply write set");
+CALL mtr.add_suppression("Failed to report last committed");
+
+--source suite/galera/include/auto_increment_offset_restore.inc
diff --git a/mysql-test/suite/gcol/inc/gcol_supported_sql_funcs_main.inc b/mysql-test/suite/gcol/inc/gcol_supported_sql_funcs_main.inc
index 90c562464fa..3bb44523e64 100644
--- a/mysql-test/suite/gcol/inc/gcol_supported_sql_funcs_main.inc
+++ b/mysql-test/suite/gcol/inc/gcol_supported_sql_funcs_main.inc
@@ -12,6 +12,9 @@
# Change Date: #
# Change: #
################################################################################
+
+--source include/have_des.inc
+
set time_zone="+03:00";
--echo #
--echo # NUMERIC FUNCTIONS
diff --git a/mysql-test/suite/innodb/include/innodb-page-compression.inc b/mysql-test/suite/innodb/include/innodb-page-compression.inc
index fec0f0cf01c..b16edcf2a28 100644
--- a/mysql-test/suite/innodb/include/innodb-page-compression.inc
+++ b/mysql-test/suite/innodb/include/innodb-page-compression.inc
@@ -1,5 +1,9 @@
# This test is slow on buildbot.
--source include/big_test.inc
+--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");
+--enable_query_log
create table innodb_normal (c1 int not null auto_increment primary key, b char(200)) engine=innodb;
create table innodb_page_compressed1 (c1 int not null auto_increment primary key, b char(200)) engine=innodb page_compressed=1 page_compression_level=1;
create table innodb_page_compressed2 (c1 int not null auto_increment primary key, b char(200)) engine=innodb page_compressed=1 page_compression_level=2;
diff --git a/mysql-test/suite/innodb/r/insert_into_empty.result b/mysql-test/suite/innodb/r/insert_into_empty.result
index 3f4d56e8245..6d50d25a982 100644
--- a/mysql-test/suite/innodb/r/insert_into_empty.result
+++ b/mysql-test/suite/innodb/r/insert_into_empty.result
@@ -240,3 +240,13 @@ SELECT length(f1) FROM t1;
length(f1)
8459264
DROP TABLE t1;
+#
+# MDEV-27858 Assertion `page_dir_get_n_heap(new_page) == 2U' failed in PageBulk::init
+#
+CREATE TABLE t1 (c INT) ENGINE=InnoDB;
+CREATE TABLE t2 (c INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1);
+LOCK TABLES t1 WRITE,t2 WRITE;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+DROP TABLE t2, t1;
diff --git a/mysql-test/suite/innodb/r/row_format_redundant.result b/mysql-test/suite/innodb/r/row_format_redundant.result
index 8a629d06dd8..b798832e96f 100644
--- a/mysql-test/suite/innodb/r/row_format_redundant.result
+++ b/mysql-test/suite/innodb/r/row_format_redundant.result
@@ -1,3 +1,4 @@
+SET GLOBAL innodb_fast_shutdown=0;
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
SET GLOBAL innodb_file_per_table=1;
#
@@ -8,25 +9,17 @@ SET GLOBAL innodb_file_per_table=ON;
create table t1 (a int not null, d varchar(15) not null, b
varchar(198) not null, c char(156)) engine=InnoDB
row_format=redundant;
-insert into t1 values(123, 'abcdef', 'jghikl', 'mnop');
-insert into t1 values(456, 'abcdef', 'jghikl', 'mnop');
-insert into t1 values(789, 'abcdef', 'jghikl', 'mnop');
-insert into t1 values(134, 'kasdfsdsadf', 'adfjlasdkfjasd', 'adfsadflkasdasdfljasdf');
-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;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
+create temporary table t like t1;
+insert into t values(123, 'abcdef', 'jghikl', 'mnop');
+insert into t values(456, 'abcdef', 'jghikl', 'mnop');
+insert into t values(789, 'abcdef', 'jghikl', 'mnop');
+insert into t values(134, 'kasdfsdsadf', 'adfjlasdkfjasd', 'adfsadflkasdasdfljasdf');
+insert into t1 select a,d,b,c from t, seq_1_to_1024;
SET GLOBAL innodb_file_per_table=OFF;
create table t2 (a int not null, d varchar(15) not null, b
varchar(198) not null, c char(156), fulltext ftsic(c)) engine=InnoDB
row_format=redundant;
-insert into t2 select * from t1;
+insert into t2 select a,d,b,c from t, seq_1_to_1024;
create table t3 (a int not null, d varchar(15) not null, b varchar(198),
c varchar(150), index k1(c(99), b(56)), index k2(b(5), c(10))) engine=InnoDB
row_format=redundant;
diff --git a/mysql-test/suite/innodb/t/alter_crash_rebuild.test b/mysql-test/suite/innodb/t/alter_crash_rebuild.test
new file mode 100644
index 00000000000..500cd28e5c5
--- /dev/null
+++ b/mysql-test/suite/innodb/t/alter_crash_rebuild.test
@@ -0,0 +1,26 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+CREATE TABLE t1 (a INT NOT NULL) ENGINE=InnoDB STATS_PERSISTENT=0;
+
+connect ddl,localhost,root;
+SET DEBUG_SYNC='after_trx_committed_in_memory SIGNAL stuck WAIT_FOR ever EXECUTE 2';
+send ALTER TABLE t1 ADD PRIMARY KEY(a);
+
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR stuck';
+SET DEBUG_SYNC='now SIGNAL ever';
+SET DEBUG_SYNC='now WAIT_FOR stuck';
+
+SET GLOBAL innodb_log_checkpoint_now=ON;
+
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
+
+disconnect ddl;
+
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+--source include/wait_all_purged.inc
diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_bzip2.test b/mysql-test/suite/innodb/t/innodb-page_compression_bzip2.test
index 391548d3e0c..8aa5addb960 100644
--- a/mysql-test/suite/innodb/t/innodb-page_compression_bzip2.test
+++ b/mysql-test/suite/innodb/t/innodb-page_compression_bzip2.test
@@ -2,6 +2,11 @@
-- source include/have_innodb_bzip2.inc
-- source include/not_embedded.inc
+--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");
+--enable_query_log
+
# bzip2
set global innodb_compression_algorithm = 5;
diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test b/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test
index a091eb6ac31..f0713a002ba 100644
--- a/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test
+++ b/mysql-test/suite/innodb/t/innodb-page_compression_lz4.test
@@ -4,6 +4,11 @@
# The test can take very long time with valgrind
--source include/not_valgrind.inc
+--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");
+--enable_query_log
+
# lz4
set global innodb_compression_algorithm = 2;
diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_lzma.test b/mysql-test/suite/innodb/t/innodb-page_compression_lzma.test
index 7fbe17d6206..58234169967 100644
--- a/mysql-test/suite/innodb/t/innodb-page_compression_lzma.test
+++ b/mysql-test/suite/innodb/t/innodb-page_compression_lzma.test
@@ -2,6 +2,11 @@
-- source include/have_innodb_lzma.inc
-- source include/not_embedded.inc
+--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");
+--enable_query_log
+
# lzma
set global innodb_compression_algorithm = 4;
diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_lzo.test b/mysql-test/suite/innodb/t/innodb-page_compression_lzo.test
index 91e966415b6..6cdb0856ba9 100644
--- a/mysql-test/suite/innodb/t/innodb-page_compression_lzo.test
+++ b/mysql-test/suite/innodb/t/innodb-page_compression_lzo.test
@@ -2,6 +2,11 @@
-- source include/have_innodb_lzo.inc
-- source include/not_embedded.inc
+--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");
+--enable_query_log
+
# lzo
set global innodb_compression_algorithm = 3;
diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_tables.test b/mysql-test/suite/innodb/t/innodb-page_compression_tables.test
index 312aa22edba..6e9d3388154 100644
--- a/mysql-test/suite/innodb/t/innodb-page_compression_tables.test
+++ b/mysql-test/suite/innodb/t/innodb-page_compression_tables.test
@@ -2,6 +2,10 @@
--source include/not_embedded.inc
let $innodb_compression_algorithm_orig=`SELECT @@innodb_compression_algorithm`;
+--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");
+--enable_query_log
# zlib
set global innodb_compression_algorithm = 1;
diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_zip.test b/mysql-test/suite/innodb/t/innodb-page_compression_zip.test
index c0079a0dab3..e147a23b7ec 100644
--- a/mysql-test/suite/innodb/t/innodb-page_compression_zip.test
+++ b/mysql-test/suite/innodb/t/innodb-page_compression_zip.test
@@ -3,6 +3,11 @@
# This test is slow on buildbot.
--source include/big_test.inc
+--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");
+--enable_query_log
+
# zlib
set global innodb_compression_algorithm = 1;
diff --git a/mysql-test/suite/innodb/t/insert_into_empty.test b/mysql-test/suite/innodb/t/insert_into_empty.test
index 1d4f79b3f44..79bf5cab227 100644
--- a/mysql-test/suite/innodb/t/insert_into_empty.test
+++ b/mysql-test/suite/innodb/t/insert_into_empty.test
@@ -250,3 +250,14 @@ CREATE TABLE t1(f1 MEDIUMTEXT)ENGINE=InnoDB;
INSERT INTO t1 VALUES(REPEAT(1, 8459264));
SELECT length(f1) FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-27858 Assertion `page_dir_get_n_heap(new_page) == 2U' failed in PageBulk::init
+--echo #
+CREATE TABLE t1 (c INT) ENGINE=InnoDB;
+CREATE TABLE t2 (c INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1);
+LOCK TABLES t1 WRITE,t2 WRITE;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+DROP TABLE t2, t1;
diff --git a/mysql-test/suite/innodb/t/row_format_redundant.test b/mysql-test/suite/innodb/t/row_format_redundant.test
index aadbfd2b773..6de7597e983 100644
--- a/mysql-test/suite/innodb/t/row_format_redundant.test
+++ b/mysql-test/suite/innodb/t/row_format_redundant.test
@@ -1,6 +1,7 @@
--source include/have_innodb.inc
# Embedded mode doesn't allow restarting
--source include/not_embedded.inc
+--source include/have_sequence.inc
--disable_query_log
call mtr.add_suppression("InnoDB: Table `mysql`\\.`innodb_table_stats` not found");
@@ -21,6 +22,8 @@ let bugdir= $MYSQLTEST_VARDIR/tmp/row_format_redundant;
--let $d=$d --innodb-data-file-path=ibdata1:1M:autoextend
--let $d=$d --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
--let $restart_parameters= $d
+# Ensure that any DDL records from previous tests have been purged.
+SET GLOBAL innodb_fast_shutdown=0;
--source include/restart_mysqld.inc
SET GLOBAL innodb_file_per_table=1;
@@ -35,27 +38,21 @@ create table t1 (a int not null, d varchar(15) not null, b
varchar(198) not null, c char(156)) engine=InnoDB
row_format=redundant;
-insert into t1 values(123, 'abcdef', 'jghikl', 'mnop');
-insert into t1 values(456, 'abcdef', 'jghikl', 'mnop');
-insert into t1 values(789, 'abcdef', 'jghikl', 'mnop');
-insert into t1 values(134, 'kasdfsdsadf', 'adfjlasdkfjasd', 'adfsadflkasdasdfljasdf');
-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;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
+create temporary table t like t1;
+
+insert into t values(123, 'abcdef', 'jghikl', 'mnop');
+insert into t values(456, 'abcdef', 'jghikl', 'mnop');
+insert into t values(789, 'abcdef', 'jghikl', 'mnop');
+insert into t values(134, 'kasdfsdsadf', 'adfjlasdkfjasd', 'adfsadflkasdasdfljasdf');
+
+insert into t1 select a,d,b,c from t, seq_1_to_1024;
SET GLOBAL innodb_file_per_table=OFF;
create table t2 (a int not null, d varchar(15) not null, b
varchar(198) not null, c char(156), fulltext ftsic(c)) engine=InnoDB
row_format=redundant;
-insert into t2 select * from t1;
+insert into t2 select a,d,b,c from t, seq_1_to_1024;
create table t3 (a int not null, d varchar(15) not null, b varchar(198),
c varchar(150), index k1(c(99), b(56)), index k2(b(5), c(10))) engine=InnoDB
diff --git a/mysql-test/suite/innodb/t/undo_truncate.test b/mysql-test/suite/innodb/t/undo_truncate.test
index 437103de787..d954ff28307 100644
--- a/mysql-test/suite/innodb/t/undo_truncate.test
+++ b/mysql-test/suite/innodb/t/undo_truncate.test
@@ -6,6 +6,9 @@
--disable_query_log
call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool");
+--disable_query_log
+# This may be triggered on a slow system.
+call mtr.add_suppression("InnoDB: Trying to delete tablespace.*pending operations");
--enable_query_log
SET GLOBAL innodb_undo_log_truncate = 0;
diff --git a/mysql-test/suite/innodb_zip/r/innochecksum.result b/mysql-test/suite/innodb_zip/r/innochecksum.result
index e6525af4b52..bb94de7a369 100644
--- a/mysql-test/suite/innodb_zip/r/innochecksum.result
+++ b/mysql-test/suite/innodb_zip/r/innochecksum.result
@@ -14,7 +14,8 @@ FOUND 1 /Error: --no-check must be associated with --write option./ in my_restar
FOUND 1 /unknown variable 'strict-check=innodb'/ in my_restart.err
[7]: check the innochecksum with short form strict-check & no-check , an error is expected
FOUND 1 /unknown option '-C'/ in my_restart.err
-FOUND 1 /unknown variable 'write=crc32'/ in my_restart.err
+FOUND 1 /ignoring option '--write' due to invalid value 'crc32'/ in my_restart.err
+FOUND 1 /Error: --no-check must be associated with --write option/ in my_restart.err
# restart
SELECT * FROM tab1;
c1 c2
diff --git a/mysql-test/suite/innodb_zip/r/innochecksum_2.result b/mysql-test/suite/innodb_zip/r/innochecksum_2.result
index 7be6f6f9af3..681d8e1f4c7 100644
--- a/mysql-test/suite/innodb_zip/r/innochecksum_2.result
+++ b/mysql-test/suite/innodb_zip/r/innochecksum_2.result
@@ -27,6 +27,7 @@ end-page 0
page 0
no-check FALSE
allow-mismatches 0
+write FALSE
page-type-summary FALSE
page-type-dump MYSQLTEST_VARDIR/tmp/dump.txt
per-page-details FALSE
@@ -54,6 +55,7 @@ See https://mariadb.com/kb/en/library/innochecksum/ for usage hints.
-n, --no-check Ignore the checksum verification.
-a, --allow-mismatches=#
Maximum checksum mismatch allowed.
+ -w, --write Rewrite the checksum.
-S, --page-type-summary
Display a count of each page type in a tablespace.
-D, --page-type-dump=name
@@ -75,6 +77,7 @@ end-page 0
page 0
no-check FALSE
allow-mismatches 0
+write FALSE
page-type-summary FALSE
page-type-dump (No default value)
per-page-details FALSE
diff --git a/mysql-test/suite/innodb_zip/r/innochecksum_3.result b/mysql-test/suite/innodb_zip/r/innochecksum_3.result
index 280528f4200..03a31194c63 100644
--- a/mysql-test/suite/innodb_zip/r/innochecksum_3.result
+++ b/mysql-test/suite/innodb_zip/r/innochecksum_3.result
@@ -133,6 +133,7 @@ end-page 0
page 0
no-check FALSE
allow-mismatches 0
+write FALSE
page-type-summary FALSE
page-type-dump MYSQLTEST_VARDIR/tmp/dump.txt
per-page-details FALSE
diff --git a/mysql-test/suite/innodb_zip/t/innochecksum.test b/mysql-test/suite/innodb_zip/t/innochecksum.test
index 60860adeac8..b78cd4329de 100644
--- a/mysql-test/suite/innodb_zip/t/innochecksum.test
+++ b/mysql-test/suite/innodb_zip/t/innochecksum.test
@@ -57,9 +57,15 @@ let SEARCH_PATTERN= unknown option '-C';
--error 1
--exec $INNOCHECKSUM --no-check --write=crc32 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
-let SEARCH_PATTERN= unknown variable 'write=crc32';
+--let SEARCH_PATTERN= ignoring option '--write' due to invalid value 'crc32'
--source include/search_pattern_in_file.inc
+--error 1
+--exec $INNOCHECKSUM --no-check $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+--let SEARCH_PATTERN= Error: --no-check must be associated with --write option
+--source include/search_pattern_in_file.inc
+
+--exec $INNOCHECKSUM --no-check --write $MYSQLD_DATADIR/test/tab1.ibd
--source include/start_mysqld.inc
SELECT * FROM tab1;
diff --git a/mysql-test/suite/parts/r/partition_alter_innodb.result b/mysql-test/suite/parts/r/partition_alter_innodb.result
index f3921a1db26..fad8434989f 100644
--- a/mysql-test/suite/parts/r/partition_alter_innodb.result
+++ b/mysql-test/suite/parts/r/partition_alter_innodb.result
@@ -48,3 +48,11 @@ alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
drop table t1;
+#
+# MDEV-28079 Shutdown hangs after altering innodb partition fts table
+#
+CREATE TABLE t1(f1 INT, f2 CHAR(100))ENGINE=InnoDB PARTITION BY HASH(f1) PARTITIONS 2;
+ALTER TABLE t1 ADD FULLTEXT(f2);
+InnoDB 0 transactions not purged
+DROP TABLE t1;
+# End of 10.6 tests
diff --git a/mysql-test/suite/parts/t/partition_alter_innodb.test b/mysql-test/suite/parts/t/partition_alter_innodb.test
index 4ea3a0da88c..844b2084531 100644
--- a/mysql-test/suite/parts/t/partition_alter_innodb.test
+++ b/mysql-test/suite/parts/t/partition_alter_innodb.test
@@ -9,3 +9,11 @@ SET GLOBAL innodb_read_only_compressed=OFF;
--disable_query_log
SET GLOBAL innodb_read_only_compressed=@save_innodb_read_only_compressed;
--enable_query_log
+--echo #
+--echo # MDEV-28079 Shutdown hangs after altering innodb partition fts table
+--echo #
+CREATE TABLE t1(f1 INT, f2 CHAR(100))ENGINE=InnoDB PARTITION BY HASH(f1) PARTITIONS 2;
+ALTER TABLE t1 ADD FULLTEXT(f2);
+--source ../innodb/include/wait_all_purged.inc
+DROP TABLE t1;
+--echo # End of 10.6 tests
diff --git a/mysql-test/suite/perfschema/include/program_nested_setup.inc b/mysql-test/suite/perfschema/include/program_nested_setup.inc
index 1f96fa28f93..bbf885988dd 100644
--- a/mysql-test/suite/perfschema/include/program_nested_setup.inc
+++ b/mysql-test/suite/perfschema/include/program_nested_setup.inc
@@ -3,7 +3,6 @@
#
--source include/no_protocol.inc
---source include/have_innodb.inc
--echo # SET-UP
CREATE DATABASE nested_sp;
@@ -17,7 +16,7 @@ CREATE TABLE t1(
CREATE TABLE t2(
n INT UNSIGNED NOT NULL,
f BIGINT UNSIGNED
-) engine=innodb;
+);
--echo ############################
--echo # Creating Stored Programs #
diff --git a/mysql-test/suite/perfschema/r/max_program_zero.result b/mysql-test/suite/perfschema/r/max_program_zero.result
index 50e2824a105..f236f149a77 100644
--- a/mysql-test/suite/perfschema/r/max_program_zero.result
+++ b/mysql-test/suite/perfschema/r/max_program_zero.result
@@ -167,7 +167,7 @@ data INT NOT NULL
CREATE TABLE t2(
n INT UNSIGNED NOT NULL,
f BIGINT UNSIGNED
-) engine=innodb;
+);
############################
# Creating Stored Programs #
############################
diff --git a/mysql-test/suite/perfschema/r/statement_program_lost_inst.result b/mysql-test/suite/perfschema/r/statement_program_lost_inst.result
index 1ad238128f4..264778c06e4 100644
--- a/mysql-test/suite/perfschema/r/statement_program_lost_inst.result
+++ b/mysql-test/suite/perfschema/r/statement_program_lost_inst.result
@@ -167,7 +167,7 @@ data INT NOT NULL
CREATE TABLE t2(
n INT UNSIGNED NOT NULL,
f BIGINT UNSIGNED
-) engine=innodb;
+);
############################
# Creating Stored Programs #
############################
diff --git a/mysql-test/suite/perfschema/r/statement_program_nested.result b/mysql-test/suite/perfschema/r/statement_program_nested.result
index 95cbdc81a1f..8ed6a81947f 100644
--- a/mysql-test/suite/perfschema/r/statement_program_nested.result
+++ b/mysql-test/suite/perfschema/r/statement_program_nested.result
@@ -13,7 +13,7 @@ data INT NOT NULL
CREATE TABLE t2(
n INT UNSIGNED NOT NULL,
f BIGINT UNSIGNED
-) engine=innodb;
+);
############################
# Creating Stored Programs #
############################
@@ -67,6 +67,7 @@ END WHILE;
END|
CREATE TRIGGER trg AFTER INSERT ON t1 FOR EACH ROW
CALL ifac(10)|
+ALTER TABLE t2 ENGINE=InnoDB;
#####################
# Executing queries #
#####################
@@ -1199,7 +1200,7 @@ data INT NOT NULL
CREATE TABLE t2(
n INT UNSIGNED NOT NULL,
f BIGINT UNSIGNED
-) engine=innodb;
+);
############################
# Creating Stored Programs #
############################
diff --git a/mysql-test/suite/perfschema/r/statement_program_nesting_event_check.result b/mysql-test/suite/perfschema/r/statement_program_nesting_event_check.result
index e045ff7db01..5e376a12a18 100644
--- a/mysql-test/suite/perfschema/r/statement_program_nesting_event_check.result
+++ b/mysql-test/suite/perfschema/r/statement_program_nesting_event_check.result
@@ -101,6 +101,7 @@ CREATE TRIGGER trg4 BEFORE DELETE ON t1 FOR EACH ROW
SET @del:= @del + 1|
CREATE TRIGGER trg5 AFTER DELETE ON t1 FOR EACH ROW
SET @del:= @del + 8 + old.j|
+ALTER TABLE t2 ENGINE=InnoDB;
#####################
# Executing queries #
#####################
@@ -159,6 +160,7 @@ WHERE CURRENT_SCHEMA='stored_programs' AND
ORDER BY OBJECT_NAME,NESTING_EVENT_LEVEL,SQL_TEXT;
EVENT_NAME SQL_TEXT OBJECT_NAME NESTING_EVENT_TYPE NESTING_EVENT_LEVEL
statement/scheduler/event NULL NULL NULL 0
+statement/sql/alter_table ALTER TABLE t2 ENGINE=InnoDB NULL NULL 0
statement/sql/call_procedure CALL SampleProc1(30,40,50) NULL NULL 0
statement/sql/call_procedure CALL SampleProc2("Jwalamukhi",34) NULL NULL 0
statement/sql/call_procedure CALL SampleProc3() NULL NULL 0
@@ -375,7 +377,7 @@ data INT NOT NULL
CREATE TABLE t2(
n INT UNSIGNED NOT NULL,
f BIGINT UNSIGNED
-) engine=innodb;
+);
############################
# Creating Stored Programs #
############################
@@ -429,6 +431,7 @@ END WHILE;
END|
CREATE TRIGGER trg AFTER INSERT ON t1 FOR EACH ROW
CALL ifac(10)|
+ALTER TABLE t2 ENGINE=InnoDB;
#####################
# Executing queries #
#####################
diff --git a/mysql-test/suite/perfschema/t/statement_program_nested.test b/mysql-test/suite/perfschema/t/statement_program_nested.test
index e6649704bbf..183e9858226 100644
--- a/mysql-test/suite/perfschema/t/statement_program_nested.test
+++ b/mysql-test/suite/perfschema/t/statement_program_nested.test
@@ -4,6 +4,7 @@
--source include/not_embedded.inc
--source include/have_perfschema.inc
+--source include/have_innodb.inc
TRUNCATE TABLE performance_schema.events_statements_summary_by_program;
TRUNCATE TABLE performance_schema.events_statements_history_long;
@@ -13,6 +14,7 @@ TRUNCATE TABLE performance_schema.events_statements_history_long;
--echo #################################################
--source suite/perfschema/include/program_nested_setup.inc
+ALTER TABLE t2 ENGINE=InnoDB;
--source suite/perfschema/include/program_nested_execution.inc
SELECT EVENT_NAME, SQL_TEXT, CURRENT_SCHEMA, OBJECT_TYPE, OBJECT_SCHEMA,
diff --git a/mysql-test/suite/perfschema/t/statement_program_nesting_event_check.test b/mysql-test/suite/perfschema/t/statement_program_nesting_event_check.test
index 20c59e9a3a8..73829be8b42 100644
--- a/mysql-test/suite/perfschema/t/statement_program_nesting_event_check.test
+++ b/mysql-test/suite/perfschema/t/statement_program_nesting_event_check.test
@@ -7,6 +7,7 @@
--source include/not_embedded.inc
--source include/have_perfschema.inc
+--source include/have_innodb.inc
TRUNCATE TABLE performance_schema.events_statements_history_long;
@@ -14,6 +15,7 @@ TRUNCATE TABLE performance_schema.events_statements_history_long;
--echo # Non-nested Stored programs.
--echo #----------------------------
--source suite/perfschema/include/program_setup.inc
+ALTER TABLE t2 ENGINE=InnoDB;
--source suite/perfschema/include/program_execution.inc
SELECT EVENT_NAME, SQL_TEXT, OBJECT_NAME, NESTING_EVENT_TYPE, NESTING_EVENT_LEVEL
@@ -31,6 +33,7 @@ TRUNCATE TABLE performance_schema.events_statements_history_long;
--echo # Nested stored programs.
--echo #------------------------
--source suite/perfschema/include/program_nested_setup.inc
+ALTER TABLE t2 ENGINE=InnoDB;
--source suite/perfschema/include/program_nested_execution.inc
SELECT EVENT_NAME, SQL_TEXT, OBJECT_NAME, NESTING_EVENT_TYPE, NESTING_EVENT_LEVEL
diff --git a/mysql-test/suite/rpl/r/mdev_24667.result b/mysql-test/suite/rpl/r/mdev_24667.result
new file mode 100644
index 00000000000..7c7342d63d6
--- /dev/null
+++ b/mysql-test/suite/rpl/r/mdev_24667.result
@@ -0,0 +1,30 @@
+include/rpl_init.inc [topology=1->2->3]
+call mtr.add_suppression('Unsafe statement written to the binary log using ');
+connection server_1;
+set binlog_format=statement;
+#first bug
+create table t1 (a int);
+create temporary table tmp like t1;
+load data local infile 'MYSQLTEST_VARDIR/load_data' INTO TABLE tmp;
+insert into t1 select * from tmp;
+#second bug
+create table t2 (a int);
+create temporary table tmp2 like t2;
+insert into tmp2 values(10);
+update tmp2 set a = 20 limit 1;
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted
+insert into t2 select * from tmp2;
+connection server_2;
+connection server_3;
+#t1 should have 2 rows
+select count(*) = 2 from t1;
+count(*) = 2
+1
+#t2 should have 1 rows with a = 20
+select * from t2;
+a
+20
+connection server_1;
+drop table t1, t2, tmp, tmp2;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result b/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result
new file mode 100644
index 00000000000..dcced9833ca
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result
@@ -0,0 +1,76 @@
+include/master-slave.inc
+[connection master]
+# Master server_1 and Slave server_2 initialiation ...
+connection server_2;
+include/stop_slave.inc
+connection server_1;
+set @@sql_log_bin = off;
+call mtr.add_suppression("Slave: An attempt was made to binlog GTID 10-1-1 which would create an out-of-order sequence number with existing GTID");
+set @@sql_log_bin = on;
+RESET MASTER;
+set @@session.gtid_domain_id=10;
+set @@global.rpl_semi_sync_master_enabled = 1;
+set @@global.rpl_semi_sync_master_wait_point=AFTER_SYNC;
+connection server_2;
+RESET MASTER;
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+set @@session.gtid_domain_id=20;
+set @@global.rpl_semi_sync_slave_enabled = 1;
+# a 1948 warning is expected
+set @@global.gtid_slave_pos = "";
+Warnings:
+Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-1. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos
+CHANGE MASTER TO master_use_gtid= slave_pos;
+include/start_slave.inc
+# ... server_1 -> server_2 is set up
+connection server_1;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Innodb;
+INSERT INTO t1 VALUES (1);
+connection server_2;
+# Circular configuration server_2 -> server_1 initialiation ...
+connection server_1;
+# A. ... first when server_1 is in gtid strict mode...
+set @@global.gtid_strict_mode = true;
+set @@global.rpl_semi_sync_slave_enabled = 1;
+CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root', master_use_gtid=SLAVE_POS;
+# ... only for it to fail 'cos if its inconsistent (empty) slave's gtid state:
+SELECT @@global.gtid_slave_pos;
+@@global.gtid_slave_pos
+
+START SLAVE;
+include/wait_for_slave_sql_error.inc [errno=1950]
+# B. ... Resume on the circular setup with the server_id now in the non-strict mode ...
+set @@global.gtid_strict_mode = false;
+include/start_slave.inc
+# ... to have succeeded.
+connection server_2;
+INSERT INTO t1 VALUES (2);
+connection server_1;
+INSERT INTO t1 VALUES (3);
+connection server_2;
+# The gtid states on server_2 must be equal to ...
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+Variable_name Value
+gtid_binlog_pos 0-2-1,10-1-3,20-2-1
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+Variable_name Value
+gtid_slave_pos 0-2-1,10-1-3,20-2-1
+connection server_1;
+# ... the gtid states on server_1
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+Variable_name Value
+gtid_slave_pos 0-2-1,10-1-3,20-2-1
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+Variable_name Value
+gtid_binlog_pos 0-2-1,10-1-3,20-2-1
+# Cleanup
+connection server_1;
+include/stop_slave.inc
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+set @@global.rpl_semi_sync_master_wait_point=default;
+DROP TABLE t1;
+connection server_2;
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/mdev_24667.cnf b/mysql-test/suite/rpl/t/mdev_24667.cnf
new file mode 100644
index 00000000000..58b605ad928
--- /dev/null
+++ b/mysql-test/suite/rpl/t/mdev_24667.cnf
@@ -0,0 +1,8 @@
+!include ../my.cnf
+
+[mysqld.3]
+log-slave-updates
+
+[ENV]
+SERVER_MYPORT_3= @mysqld.3.port
+SERVER_MYSOCK_3= @mysqld.3.socket
diff --git a/mysql-test/suite/rpl/t/mdev_24667.test b/mysql-test/suite/rpl/t/mdev_24667.test
new file mode 100644
index 00000000000..d8490b335db
--- /dev/null
+++ b/mysql-test/suite/rpl/t/mdev_24667.test
@@ -0,0 +1,56 @@
+#
+# MDEV-24667 LOAD DATA INFILE/inserted rows not written to binlog
+#
+# In this test we will have a replication configuration like 1->2->3
+# 1 will have statement format
+# 2 and 3 will have mixed format
+# We will make some updates on temporary table which are unsafe , So 2 must
+# Log these queries in row format, Since it is on tmp table , It wont be logged
+# So the next query which copies the data from tmp table to normal must be logged
+# into the row format. Instead of checking for the binlog We will compare the
+# results on the 3, If no binlog is lost(ie it is logged into row format), There
+# should not be any data loss.
+--let $rpl_topology=1->2->3
+--source include/rpl_init.inc
+--source include/have_binlog_format_mixed.inc
+call mtr.add_suppression('Unsafe statement written to the binary log using ');
+--connection server_1
+
+set binlog_format=statement;
+--echo #first bug
+create table t1 (a int);
+create temporary table tmp like t1;
+--write_file $MYSQLTEST_VARDIR/load_data
+1
+2
+EOF
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval load data local infile '$MYSQLTEST_VARDIR/load_data' INTO TABLE tmp;
+insert into t1 select * from tmp;
+
+--echo #second bug
+create table t2 (a int);
+#insert into t2 values(10);
+create temporary table tmp2 like t2;
+insert into tmp2 values(10);
+update tmp2 set a = 20 limit 1;
+insert into t2 select * from tmp2;
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+--save_master_pos
+
+--connection server_3
+--sync_with_master
+--echo #t1 should have 2 rows
+select count(*) = 2 from t1;
+--echo #t2 should have 1 rows with a = 20
+select * from t2;
+
+
+# cleanup
+--connection server_1
+drop table t1, t2, tmp, tmp2;
+--remove_file $MYSQLTEST_VARDIR/load_data
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf
new file mode 100644
index 00000000000..be39fea91d8
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf
@@ -0,0 +1,11 @@
+!include suite/rpl/rpl_1slave_base.cnf
+!include include/default_client.cnf
+
+
+[mysqld.1]
+log-slave-updates
+sync-binlog=1
+
+[mysqld.2]
+log-slave-updates
+sync-binlog=1
diff --git a/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test
new file mode 100644
index 00000000000..51fa5a242ea
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test
@@ -0,0 +1,115 @@
+# ==== References ====
+#
+# MDEV-27760 event may non stop replicate in circular semisync setup
+#
+--source include/have_innodb.inc
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+# The following tests prove
+# A. out-of-order gtid error when the stict gtid mode semisync slave
+# receives the same server-id gtid event inconsistent
+# (rpl_semi_sync_fail_over tests the consistent case) with its state;
+# B. in the non-strict mode the same server-id events remains ignored
+# by default as usual.
+#
+--echo # Master server_1 and Slave server_2 initialiation ...
+--connection server_2
+--source include/stop_slave.inc
+
+# Initial master
+--connection server_1
+set @@sql_log_bin = off;
+call mtr.add_suppression("Slave: An attempt was made to binlog GTID 10-1-1 which would create an out-of-order sequence number with existing GTID");
+set @@sql_log_bin = on;
+
+RESET MASTER;
+
+set @@session.gtid_domain_id=10;
+
+set @@global.rpl_semi_sync_master_enabled = 1;
+set @@global.rpl_semi_sync_master_wait_point=AFTER_SYNC;
+
+--connection server_2
+RESET MASTER;
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+
+set @@session.gtid_domain_id=20;
+
+set @@global.rpl_semi_sync_slave_enabled = 1;
+--echo # a 1948 warning is expected
+set @@global.gtid_slave_pos = "";
+CHANGE MASTER TO master_use_gtid= slave_pos;
+--source include/start_slave.inc
+--echo # ... server_1 -> server_2 is set up
+
+--connection server_1
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Innodb;
+INSERT INTO t1 VALUES (1);
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+
+--echo # Circular configuration server_2 -> server_1 initialiation ...
+--connection server_1
+--echo # A. ... first when server_1 is in gtid strict mode...
+set @@global.gtid_strict_mode = true;
+set @@global.rpl_semi_sync_slave_enabled = 1;
+
+evalp CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root', master_use_gtid=SLAVE_POS;
+
+--echo # ... only for it to fail 'cos if its inconsistent (empty) slave's gtid state:
+SELECT @@global.gtid_slave_pos;
+START SLAVE;
+# ER_GTID_STRICT_OUT_OF_ORDER
+--let $slave_sql_errno = 1950
+--source include/wait_for_slave_sql_error.inc
+
+--echo # B. ... Resume on the circular setup with the server_id now in the non-strict mode ...
+set @@global.gtid_strict_mode = false;
+--source include/start_slave.inc
+
+--echo # ... to have succeeded.
+
+--connection server_2
+INSERT INTO t1 VALUES (2);
+--save_master_pos
+
+--connection server_1
+--sync_with_master
+
+INSERT INTO t1 VALUES (3);
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+--echo # The gtid states on server_2 must be equal to ...
+--let $wait_condition=select @@gtid_slave_pos=@@gtid_binlog_pos
+--source include/wait_condition.inc
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+
+--connection server_1
+--echo # ... the gtid states on server_1
+--let $wait_condition=select @@gtid_slave_pos=@@gtid_binlog_pos
+--source include/wait_condition.inc
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+
+--echo # Cleanup
+--connection server_1
+--source include/stop_slave.inc
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+set @@global.rpl_semi_sync_master_wait_point=default;
+
+DROP TABLE t1;
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result
index 93a85ffbf43..d4ae7edb70e 100644
--- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result
@@ -4,6 +4,11 @@ SELECT @orig;
25
SET GLOBAL innodb_buffer_pool_dump_pct=3;
# Do the dump
+SELECT @@global.innodb_buffer_pool_dump_now;
+SELECT variable_value INTO @old_dump_status FROM information_schema.global_status
+WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
+SET GLOBAL innodb_buffer_pool_dump_now = ON;
+SELECT @@global.innodb_buffer_pool_dump_now;
SET GLOBAL innodb_buffer_pool_dump_pct=20;
SELECT @@global.innodb_buffer_pool_dump_pct;
@@global.innodb_buffer_pool_dump_pct
diff --git a/mysql-test/suite/versioning/common.inc b/mysql-test/suite/versioning/common.inc
index 25adf15dd50..0c65720fa1a 100644
--- a/mysql-test/suite/versioning/common.inc
+++ b/mysql-test/suite/versioning/common.inc
@@ -1,9 +1,9 @@
---disable_query_log
if (!$TEST_VERSIONING_SO)
{
--skip needs test_versioning plugin
}
source include/have_innodb.inc;
+--disable_query_log
set @@session.time_zone='+00:00';
select ifnull(max(transaction_id), 0) into @start_trx_id from mysql.transaction_registry;
diff --git a/mysys/my_rename.c b/mysys/my_rename.c
index 93a59342b6c..73fc2fbe47c 100644
--- a/mysys/my_rename.c
+++ b/mysys/my_rename.c
@@ -46,12 +46,15 @@ static BOOL win_rename_with_retries(const char *from, const char *to)
for (int retry= RENAME_MAX_RETRIES; retry--;)
{
- DWORD ret = MoveFileEx(from, to,
+ BOOL ret= MoveFileEx(from, to,
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
- DBUG_ASSERT(fp == NULL || (ret == FALSE && GetLastError() == ERROR_SHARING_VIOLATION));
+ if (ret)
+ return ret;
- if (!ret && (GetLastError() == ERROR_SHARING_VIOLATION))
+ DWORD last_error= GetLastError();
+ if (last_error == ERROR_SHARING_VIOLATION ||
+ last_error == ERROR_ACCESS_DENIED)
{
#ifndef DBUG_OFF
/*
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index eac7f77fb6b..e8eacc2bd5d 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -2368,6 +2368,9 @@ int get_db_mysql57(MYSQL_THD thd, char **name, size_t *len)
#ifdef __x86_64__
db_off= 608;
db_len_off= 616;
+#elif __aarch64__
+ db_off= 632;
+ db_len_off= 640;
#else
db_off= 0;
db_len_off= 0;
@@ -2378,6 +2381,9 @@ int get_db_mysql57(MYSQL_THD thd, char **name, size_t *len)
#ifdef __x86_64__
db_off= 536;
db_len_off= 544;
+#elif __aarch64__
+ db_off= 552;
+ db_len_off= 560;
#else
db_off= 0;
db_len_off= 0;
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index 92611b18267..aca78f38322 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -297,6 +297,7 @@ ELSE()
wsrep_sst_mysqldump
wsrep_sst_rsync
wsrep_sst_mariabackup
+ wsrep_sst_backup
)
# The following script is sourced from other SST scripts, so it should
# not be made executable.
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 4f499d8e577..face88c7e29 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -554,7 +554,7 @@ mysqld_install_cmd_line()
{
"$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap $silent_startup\
"--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \
- "--plugin-dir=${plugindir}" --loose-disable-plugin-file-key-management \
+ "--plugin-dir=${plugindir}" \
$args --max_allowed_packet=8M \
--net_buffer_length=16K
}
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index 172fe46ae7e..4a29b94e6f5 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -1,5 +1,5 @@
-- Copyright (C) 2003, 2013 Oracle and/or its affiliates.
--- Copyright (C) 2010, 2018 MariaDB Corporation
+-- Copyright (C) 2010, 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
@@ -31,6 +31,13 @@ set alter_algorithm=DEFAULT;
set @have_innodb= (select count(engine) from information_schema.engines where engine='INNODB' and support != 'NO');
+# MDEV-21873: 10.2 to 10.3 upgrade doesn't remove semi-sync reference from
+# mysql.plugin table.
+# As per suggested fix, check INFORMATION_SCHEMA.PLUGINS
+# and if semisync plugins aren't there, delete them from mysql.plugin.
+DELETE FROM mysql.plugin WHERE name="rpl_semi_sync_master" AND NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME="rpl_semi_sync_master");
+DELETE FROM mysql.plugin WHERE name="rpl_semi_sync_slave" AND NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME="rpl_semi_sync_slave");
+
--
-- Ensure that all tables are of type Aria and transactional
--
diff --git a/scripts/wsrep_sst_backup.sh b/scripts/wsrep_sst_backup.sh
new file mode 100644
index 00000000000..55e11ddffc0
--- /dev/null
+++ b/scripts/wsrep_sst_backup.sh
@@ -0,0 +1,112 @@
+#!/usr/bin/env bash
+
+set -ue
+
+# Copyright (C) 2017-2021 MariaDB
+# Copyright (C) 2010-2014 Codership Oy
+#
+# 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; see the file COPYING. If not, write to the
+# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
+# MA 02110-1335 USA.
+
+# This is a reference script for rsync-based state snapshot transfer
+
+RSYNC_REAL_PID=0 # rsync process id
+STUNNEL_REAL_PID=0 # stunnel process id
+
+OS="$(uname)"
+[ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH
+
+# Setting the path for lsof on CentOS
+export PATH="/usr/sbin:/sbin:$PATH"
+
+. $(dirname "$0")/wsrep_sst_common
+
+MAGIC_FILE="$WSREP_SST_OPT_DATA/backup_sst_complete"
+rm -rf "$MAGIC_FILE"
+
+WSREP_LOG_DIR=${WSREP_LOG_DIR:-""}
+# if WSREP_LOG_DIR env. variable is not set, try to get it from my.cnf
+if [ -z "$WSREP_LOG_DIR" ]; then
+ WSREP_LOG_DIR=$(parse_cnf mysqld innodb-log-group-home-dir '')
+fi
+
+if [ -n "$WSREP_LOG_DIR" ]; then
+ # handle both relative and absolute paths
+ WSREP_LOG_DIR=$(cd $WSREP_SST_OPT_DATA; mkdir -p "$WSREP_LOG_DIR"; cd $WSREP_LOG_DIR; pwd -P)
+else
+ # default to datadir
+ WSREP_LOG_DIR=$(cd $WSREP_SST_OPT_DATA; pwd -P)
+fi
+
+if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]
+then
+
+ [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
+
+ RC=0
+
+ if [ $WSREP_SST_OPT_BYPASS -eq 0 ]; then
+
+ FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed"
+ ERROR="$WSREP_SST_OPT_DATA/sst_error"
+
+ [ -f "$FLUSHED" ] && rm -f "$FLUSHED"
+ [ -f "$ERROR" ] && rm -f "$ERROR"
+
+ echo "flush tables"
+
+ # Wait for :
+ # (a) Tables to be flushed, AND
+ # (b) Cluster state ID & wsrep_gtid_domain_id to be written to the file, OR
+ # (c) ERROR file, in case flush tables operation failed.
+
+ while [ ! -r "$FLUSHED" ] && \
+ ! grep -q -F ':' '--' "$FLUSHED" >/dev/null 2>&1
+ do
+ # Check whether ERROR file exists.
+ if [ -f "$ERROR" ]; then
+ # Flush tables operation failed.
+ rm -f "$ERROR"
+ exit 255
+ fi
+ sleep 0.2
+ done
+
+ STATE=$(cat "$FLUSHED")
+ rm -f "$FLUSHED"
+
+
+ else # BYPASS
+
+ wsrep_log_info "Bypassing state dump."
+ fi
+
+ echo 'continue' # now server can resume updating data
+
+ echo "$STATE" > "$MAGIC_FILE"
+
+ echo "done $STATE"
+
+elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
+then
+ wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"
+ exit 22 # EINVAL
+
+
+else
+ wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"
+ exit 22 # EINVAL
+fi
+
+exit 0
diff --git a/sql/contributors.h b/sql/contributors.h
index e16448ee985..bc8ba4eabbb 100644
--- a/sql/contributors.h
+++ b/sql/contributors.h
@@ -42,6 +42,8 @@ struct show_table_contributors_st show_table_contributors[]= {
{"Microsoft", "https://microsoft.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
{"ServiceNow", "https://servicenow.com", "Platinum Sponsor of the MariaDB Foundation"},
+ {"Intel", "https://www.intel.com", "Platinum Sponsor of the MariaDB Foundation"},
+ {"SIT", "https://sit.org", "Platinum Sponsor of the MariaDB Foundation"},
{"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
{"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
{"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"},
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 40c00945bec..453446eb85d 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -3198,11 +3198,12 @@ err1:
@retval true Failure
*/
-bool ha_partition::setup_engine_array(MEM_ROOT *mem_root)
+bool ha_partition::setup_engine_array(MEM_ROOT *mem_root,
+ handlerton* first_engine)
{
uint i;
uchar *buff;
- handlerton **engine_array, *first_engine;
+ handlerton **engine_array;
enum legacy_db_type db_type, first_db_type;
DBUG_ASSERT(!m_file);
@@ -3212,11 +3213,8 @@ bool ha_partition::setup_engine_array(MEM_ROOT *mem_root)
DBUG_RETURN(true);
buff= (uchar *) (m_file_buffer + PAR_ENGINES_OFFSET);
- first_db_type= (enum legacy_db_type) buff[0];
- first_engine= ha_resolve_by_legacy_type(ha_thd(), first_db_type);
- if (!first_engine)
- goto err;
+ first_db_type= (enum legacy_db_type) buff[0];
if (!(m_engine_array= (plugin_ref*)
alloc_root(&m_mem_root, m_tot_parts * sizeof(plugin_ref))))
goto err;
@@ -3257,6 +3255,75 @@ err:
}
+handlerton *ha_partition::get_def_part_engine(const char *name)
+{
+ if (table_share)
+ {
+ if (table_share->default_part_plugin)
+ return plugin_data(table_share->default_part_plugin, handlerton *);
+ }
+ else
+ {
+ // DROP TABLE, for example
+ char buff[FN_REFLEN];
+ File file;
+ MY_STAT state;
+ uchar *frm_image= 0;
+ handlerton *hton= 0;
+ bool use_legacy_type= false;
+
+ fn_format(buff, name, "", reg_ext, MY_APPEND_EXT);
+
+ file= mysql_file_open(key_file_frm, buff, O_RDONLY | O_SHARE, MYF(0));
+ if (file < 0)
+ return NULL;
+
+ if (mysql_file_fstat(file, &state, MYF(MY_WME)))
+ goto err;
+ if (state.st_size <= 64)
+ goto err;
+ if (!(frm_image= (uchar*)my_malloc(key_memory_Partition_share,
+ state.st_size, MYF(MY_WME))))
+ goto err;
+ if (mysql_file_read(file, frm_image, state.st_size, MYF(MY_NABP)))
+ goto err;
+
+ if (frm_image[64] != '/')
+ {
+ const uchar *e2= frm_image + 64;
+ const uchar *e2end = e2 + uint2korr(frm_image + 4);
+ if (e2end > frm_image + state.st_size)
+ goto err;
+ while (e2 + 3 < e2end)
+ {
+ uchar type= *e2++;
+ size_t length= extra2_read_len(&e2, e2end);
+ if (!length)
+ goto err;
+ if (type == EXTRA2_DEFAULT_PART_ENGINE)
+ {
+ LEX_CSTRING name= { (char*)e2, length };
+ plugin_ref plugin= ha_resolve_by_name(ha_thd(), &name, false);
+ if (plugin)
+ hton= plugin_data(plugin, handlerton *);
+ goto err;
+ }
+ e2+= length;
+ }
+ }
+ use_legacy_type= true;
+err:
+ my_free(frm_image);
+ mysql_file_close(file, MYF(0));
+ if (!use_legacy_type)
+ return hton;
+ }
+
+ return ha_resolve_by_legacy_type(ha_thd(),
+ (enum legacy_db_type)m_file_buffer[PAR_ENGINES_OFFSET]);
+}
+
+
/**
Get info about partition engines and their names from the .par file
@@ -3284,7 +3351,11 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root,
if (read_par_file(name))
DBUG_RETURN(true);
- if (!is_clone && setup_engine_array(mem_root))
+ handlerton *default_engine= get_def_part_engine(name);
+ if (!default_engine)
+ DBUG_RETURN(true);
+
+ if (!is_clone && setup_engine_array(mem_root, default_engine))
DBUG_RETURN(true);
DBUG_RETURN(false);
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 14f68b36c0b..dd14cd7a6d4 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -590,8 +590,9 @@ private:
And one method to read it in.
*/
bool create_handler_file(const char *name);
- bool setup_engine_array(MEM_ROOT *mem_root);
+ bool setup_engine_array(MEM_ROOT *mem_root, handlerton *first_engine);
bool read_par_file(const char *name);
+ handlerton *get_def_part_engine(const char *name);
bool get_from_handler_file(const char *name, MEM_ROOT *mem_root,
bool is_clone);
bool new_handlers_from_part_info(MEM_ROOT *mem_root);
diff --git a/sql/handler.h b/sql/handler.h
index 56e828e5465..1f96c35ed6b 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -2,7 +2,7 @@
#define HANDLER_INCLUDED
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2021, MariaDB
+ Copyright (c) 2009, 2022, MariaDB
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -5253,7 +5253,7 @@ static inline const char *ha_resolve_storage_engine_name(const handlerton *db_ty
static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
{
- return db_type == NULL ? FALSE : MY_TEST(db_type->flags & flag);
+ return db_type && (db_type->flags & flag);
}
static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
diff --git a/sql/item.cc b/sql/item.cc
index 09c83a341c6..f515dd3924d 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2018, Oracle and/or its affiliates.
- Copyright (c) 2010, 2021, MariaDB Corporation.
+ Copyright (c) 2010, 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
@@ -2758,9 +2758,11 @@ LEX_CSTRING Item_sp::func_name_cstring(THD *thd) const
/* Calculate length to avoid reallocation of string for sure */
size_t len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
m_name->m_name.length)*2 + //characters*quoting
- 2 + // ` and `
+ 2 + // quotes for the function name
+ 2 + // quotes for the package name
(m_name->m_explicit_name ?
3 : 0) + // '`', '`' and '.' for the db
+ 1 + // '.' between package and function
1 + // end of string
ALIGN_SIZE(1)); // to avoid String reallocation
String qname((char *)alloc_root(thd->mem_root, len), len,
@@ -2772,7 +2774,21 @@ LEX_CSTRING Item_sp::func_name_cstring(THD *thd) const
append_identifier(thd, &qname, &m_name->m_db);
qname.append('.');
}
- append_identifier(thd, &qname, &m_name->m_name);
+ if (m_sp && m_sp->m_handler == &sp_handler_package_function)
+ {
+ /*
+ In case of a package function split `pkg.func` and print
+ quoted `pkg` and `func` separately, so the entire result looks like:
+ `db`.`pkg`.`func`
+ */
+ Database_qualified_name tmp= Database_qualified_name::split(m_name->m_name);
+ DBUG_ASSERT(tmp.m_db.length);
+ append_identifier(thd, &qname, &tmp.m_db);
+ qname.append('.');
+ append_identifier(thd, &qname, &tmp.m_name);
+ }
+ else
+ append_identifier(thd, &qname, &m_name->m_name);
return { qname.c_ptr_safe(), qname.length() };
}
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 0d22465af6b..034833a0ba2 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -4711,10 +4711,11 @@ void Item_func_in::mark_as_condition_AND_part(TABLE_LIST *embedding)
Query_arena *arena, backup;
arena= thd->activate_stmt_arena_if_needed(&backup);
- if (to_be_transformed_into_in_subq(thd))
+ if (!transform_into_subq_checked)
{
- transform_into_subq= true;
- thd->lex->current_select->in_funcs.push_back(this, thd->mem_root);
+ if ((transform_into_subq= to_be_transformed_into_in_subq(thd)))
+ thd->lex->current_select->in_funcs.push_back(this, thd->mem_root);
+ transform_into_subq_checked= true;
}
if (arena)
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 3767c2172e8..fe55f524f89 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -2490,6 +2490,7 @@ protected:
SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
Field *field, Item *value) override;
bool transform_into_subq;
+ bool transform_into_subq_checked;
public:
/// An array of values, created when the bisection lookup method is used
in_vector *array;
@@ -2512,6 +2513,7 @@ public:
Item_func_opt_neg(thd, list),
Predicant_to_list_comparator(thd, arg_count - 1),
transform_into_subq(false),
+ transform_into_subq_checked(false),
array(0), have_null(0),
arg_types_compatible(FALSE), emb_on_expr_nest(0)
{ }
diff --git a/sql/log.cc b/sql/log.cc
index a4c0da2ab70..c928934faa9 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -6000,6 +6000,8 @@ THD::binlog_start_trans_and_stmt()
}
Gtid_log_event gtid_event(this, seqno, domain_id, true,
LOG_EVENT_SUPPRESS_USE_F, true, 0);
+ // Replicated events in writeset doesn't have checksum
+ gtid_event.checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
gtid_event.server_id= server_id;
writer.write(&gtid_event);
wsrep_write_cache_buf(&tmp_io_cache, &buf, &len);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 27432489a00..9a333c856c9 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3675,13 +3675,18 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
/* Ensure we don't get called here again */
char buf[50], *buf2;
thd->set_killed(KILL_QUERY);
- my_snprintf(buf, sizeof(buf), "--max-thread-mem-used=%llu",
+ my_snprintf(buf, sizeof(buf), "--max-session-mem-used=%llu",
thd->variables.max_mem_used);
if ((buf2= (char*) thd->alloc(256)))
{
my_snprintf(buf2, 256, ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf);
thd->set_killed(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT, buf2);
}
+ else
+ {
+ thd->set_killed(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT,
+ "--max-session-mem-used");
+ }
}
DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0 ||
!debug_assert_on_not_freed_memory);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 94b1db74637..88a0e346245 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1673,7 +1673,7 @@ end:
{
table->file->ha_index_or_rnd_end();
ha_commit_trans(thd, FALSE);
- ha_commit_trans(thd, TRUE);
+ trans_commit(thd);
}
if (table_opened)
{
diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc
index 2480eebf8d7..cfe29824328 100644
--- a/sql/semisync_master.cc
+++ b/sql/semisync_master.cc
@@ -1229,6 +1229,7 @@ int Repl_semi_sync_master::flush_net(THD *thd,
net_clear(net, 0);
net->pkt_nr++;
+ net->compress_pkt_nr++;
result = 0;
rpl_semi_sync_master_net_wait_num++;
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 7b530ee4f16..dea48833b20 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -2234,30 +2234,30 @@ ER_NO_SUCH_THREAD
swe "Finns ingen tråd med id %lu"
ukr "Невідомий ідентифікатор гілки: %lu"
ER_KILL_DENIED_ERROR
- cze "Nejste vlastníkem threadu %lu"
- dan "Du er ikke ejer af tråden %lu"
- nla "U bent geen bezitter van thread %lu"
- eng "You are not owner of thread %lu"
- est "Ei ole lõime %lu omanik"
- fre "Vous n'êtes pas propriétaire de la tâche no: %lu"
- ger "Sie sind nicht Eigentümer von Thread %lu"
- greek "Δεν είσθε owner του thread %lu"
- hindi "आप थ्रेड %lu के OWNER नहीं हैं"
- hun "A %lu thread-nek mas a tulajdonosa"
- ita "Utente non proprietario del thread %lu"
- jpn "スレッド %lu のオーナーではありません。"
- kor "쓰레드(Thread) %lu의 소유자가 아닙니다."
- nor "Du er ikke eier av tråden %lu"
- norwegian-ny "Du er ikkje eigar av tråd %lu"
- pol "Nie jeste? wła?cicielem w?tku %lu"
- por "Você não é proprietário da 'thread' %lu"
- rum "Nu sinteti proprietarul threadului %lu"
- rus "Вы не являетесь владельцем потока %lu"
- serbian "Vi niste vlasnik thread-a %lu"
- slo "Nie ste vlastníkom vlákna %lu"
- spa "No eres el propietario del hilo (thread) %lu"
- swe "Du är inte ägare till tråd %lu"
- ukr "Ви не володар гілки %lu"
+ cze "Nejste vlastníkem threadu %lld"
+ dan "Du er ikke ejer af tråden %lld"
+ nla "U bent geen bezitter van thread %lld"
+ eng "You are not owner of thread %lld"
+ est "Ei ole lõime %lld omanik"
+ fre "Vous n'êtes pas propriétaire de la tâche no: %lld"
+ ger "Sie sind nicht Eigentümer von Thread %lld"
+ greek "Δεν είσθε owner του thread %lld"
+ hindi "आप थ्रेड %lld के OWNER नहीं हैं"
+ hun "A %lld thread-nek mas a tulajdonosa"
+ ita "Utente non proprietario del thread %lld"
+ jpn "スレッド %lld のオーナーではありません。"
+ kor "쓰레드(Thread) %lld의 소유자가 아닙니다."
+ nor "Du er ikke eier av tråden %lld"
+ norwegian-ny "Du er ikkje eigar av tråd %lld"
+ pol "Nie jeste? wła?cicielem w?tku %lld"
+ por "Você não é proprietário da 'thread' %lld"
+ rum "Nu sinteti proprietarul threadului %lld"
+ rus "Вы не являетесь владельцем потока %lld"
+ serbian "Vi niste vlasnik thread-a %lld"
+ slo "Nie ste vlastníkom vlákna %lld"
+ spa "No eres el propietario del hilo (thread) %lld"
+ swe "Du är inte ägare till tråd %lld"
+ ukr "Ви не володар гілки %lld"
ER_NO_TABLES_USED
cze "Nejsou použity žádné tabulky"
dan "Ingen tabeller i brug"
diff --git a/sql/slave.cc b/sql/slave.cc
index 3b03eed1741..23a35c5805f 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -6241,13 +6241,13 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
bool is_rows_event= false;
/*
The flag has replicate_same_server_id semantics and is raised to accept
- a same-server-id event on the semisync slave, for both the gtid and legacy
- connection modes.
- Such events can appear as result of this server recovery so the event
- was created there and replicated elsewhere right before the crash. At recovery
- it could be evicted from the server's binlog.
- */
- bool do_accept_own_server_id= false;
+ a same-server-id event group by the gtid strict mode semisync slave.
+ Own server-id events can appear as result of this server crash-recovery:
+ the transaction was created on this server then being master, got replicated
+ elsewhere right before the crash before commit;
+ finally at recovery the transaction gets evicted from the server's binlog.
+ */
+ bool do_accept_own_server_id;
/*
FD_q must have been prepared for the first R_a event
inside get_master_version_and_clock()
@@ -6336,6 +6336,8 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
dbug_rows_event_count = 0;
};);
#endif
+ s_id= uint4korr(buf + SERVER_ID_OFFSET);
+
mysql_mutex_lock(&mi->data_lock);
switch (buf[EVENT_TYPE_OFFSET]) {
@@ -6795,6 +6797,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
++mi->events_queued_since_last_gtid;
inc_pos= event_len;
+
}
break;
/*
@@ -6937,6 +6940,10 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
break;
}
+ do_accept_own_server_id= (s_id == global_system_variables.server_id
+ && rpl_semi_sync_slave_enabled && opt_gtid_strict_mode
+ && mi->using_gtid != Master_info::USE_GTID_NO);
+
/*
Integrity of Rows- event group check.
A sequence of Rows- events must end with STMT_END_F flagged one.
@@ -6982,7 +6989,6 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
*/
mysql_mutex_lock(log_lock);
- s_id= uint4korr(buf + SERVER_ID_OFFSET);
/*
Write the event to the relay log, unless we reconnected in the middle
of an event group and now need to skip the initial part of the group that
@@ -7028,7 +7034,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
else
if ((s_id == global_system_variables.server_id &&
!(mi->rli.replicate_same_server_id ||
- (do_accept_own_server_id= rpl_semi_sync_slave_enabled))) ||
+ do_accept_own_server_id)) ||
event_that_should_be_ignored(buf) ||
/*
the following conjunction deals with IGNORE_SERVER_IDS, if set
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 88c1a38aa45..baf4d7d1d82 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -3608,6 +3608,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
lex_query_tables_own_last= m_lex->query_tables_own_last;
prelocking_tables= *lex_query_tables_own_last;
*lex_query_tables_own_last= NULL;
+ m_lex->query_tables_last= m_lex->query_tables_own_last;
m_lex->mark_as_requiring_prelocking(NULL);
}
thd->rollback_item_tree_changes();
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 9737083e900..27875e3837b 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -707,6 +707,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
wsrep_was_on(false),
wsrep_ignore_table(false),
wsrep_aborter(0),
+ wsrep_delayed_BF_abort(false),
/* wsrep-lib */
m_wsrep_next_trx_id(WSREP_UNDEFINED_TRX_ID),
@@ -2354,6 +2355,58 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
/*
+ Reinterpret a binary string to a character string
+
+ @param[OUT] to The result will be written here,
+ either the original string as is,
+ or a newly alloced fixed string with
+ some zero bytes prepended.
+ @param cs The destination character set
+ @param str The binary string
+ @param length The length of the binary string
+
+ @return false on success
+ @return true on error
+*/
+
+bool THD::reinterpret_string_from_binary(LEX_CSTRING *to, CHARSET_INFO *cs,
+ const char *str, size_t length)
+{
+ /*
+ When reinterpreting from binary to tricky character sets like
+ UCS2, UTF16, UTF32, we may need to prepend some zero bytes.
+ This is possible in scenarios like this:
+ SET COLLATION_CONNECTION=utf32_general_ci, CHARACTER_SET_CLIENT=binary;
+ This code is similar to String::copy_aligned().
+ */
+ size_t incomplete= length % cs->mbminlen; // Bytes in an incomplete character
+ if (incomplete)
+ {
+ size_t zeros= cs->mbminlen - incomplete;
+ size_t aligned_length= zeros + length;
+ char *dst= (char*) alloc(aligned_length + 1);
+ if (!dst)
+ {
+ to->str= NULL; // Safety
+ to->length= 0;
+ return true;
+ }
+ bzero(dst, zeros);
+ memcpy(dst + zeros, str, length);
+ dst[aligned_length]= '\0';
+ to->str= dst;
+ to->length= aligned_length;
+ }
+ else
+ {
+ to->str= str;
+ to->length= length;
+ }
+ return check_string_for_wellformedness(to->str, to->length, cs);
+}
+
+
+/*
Convert a string between two character sets.
dstcs and srccs cannot be &my_charset_bin.
*/
diff --git a/sql/sql_class.h b/sql/sql_class.h
index ab04e17fdfd..f7f646e8310 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4162,6 +4162,8 @@ public:
bool convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
const char *from, size_t from_length,
CHARSET_INFO *from_cs);
+ bool reinterpret_string_from_binary(LEX_CSTRING *to, CHARSET_INFO *to_cs,
+ const char *from, size_t from_length);
bool convert_string(LEX_CSTRING *to, CHARSET_INFO *to_cs,
const char *from, size_t from_length,
CHARSET_INFO *from_cs)
@@ -4178,6 +4180,8 @@ public:
{
if (!simple_copy_is_possible)
return unlikely(convert_string(to, tocs, from->str, from->length, fromcs));
+ if (fromcs == &my_charset_bin)
+ return reinterpret_string_from_binary(to, tocs, from->str, from->length);
*to= *from;
return false;
}
@@ -4613,13 +4617,13 @@ public:
*/
DBUG_PRINT("debug",
("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
- YESNO(has_thd_temporary_tables()), YESNO(in_sub_stmt),
+ YESNO(has_temporary_tables()), YESNO(in_sub_stmt),
show_system_thread(system_thread)));
if (in_sub_stmt == 0)
{
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
set_current_stmt_binlog_format_row();
- else if (!has_thd_temporary_tables())
+ else if (!has_temporary_tables())
set_current_stmt_binlog_format_stmt();
}
DBUG_VOID_RETURN;
@@ -5296,6 +5300,10 @@ public:
/* thread who has started kill for this THD protected by LOCK_thd_data*/
my_thread_id wsrep_aborter;
+ /* true if BF abort is observed in do_command() right after reading
+ client's packet, and if the client has sent PS execute command. */
+ bool wsrep_delayed_BF_abort;
+
/*
Transaction id:
* m_wsrep_next_trx_id is assigned on the first query after
@@ -5327,7 +5335,10 @@ public:
{
return m_wsrep_next_trx_id;
}
-
+ /*
+ If node is async slave and have parallel execution, wait for prior commits.
+ */
+ bool wsrep_parallel_slave_wait_for_prior_commit();
private:
wsrep_trx_id_t m_wsrep_next_trx_id; /* cast from query_id_t */
/* wsrep-lib */
@@ -7541,6 +7552,19 @@ public:
}
void copy(MEM_ROOT *mem_root, const LEX_CSTRING &db,
const LEX_CSTRING &name);
+
+ static Database_qualified_name split(const LEX_CSTRING &txt)
+ {
+ DBUG_ASSERT(txt.str[txt.length] == '\0'); // Expect 0-terminated input
+ const char *dot= strchr(txt.str, '.');
+ if (!dot)
+ return Database_qualified_name(NULL, 0, txt.str, txt.length);
+ size_t dblen= dot - txt.str;
+ Lex_cstring db(txt.str, dblen);
+ Lex_cstring name(txt.str + dblen + 1, txt.length - dblen - 1);
+ return Database_qualified_name(db, name);
+ }
+
// Export db and name as a qualified name string: 'db.name'
size_t make_qname(char *dst, size_t dstlen) const
{
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 86d4040a9be..8c99deaad10 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -9239,6 +9239,43 @@ bool LEX::call_statement_start(THD *thd, const Lex_ident_sys_st *name1,
}
+bool LEX::call_statement_start(THD *thd,
+ const Lex_ident_sys_st *db,
+ const Lex_ident_sys_st *pkg,
+ const Lex_ident_sys_st *proc)
+{
+ Database_qualified_name q_db_pkg(db, pkg);
+ Database_qualified_name q_pkg_proc(pkg, proc);
+ sp_name *spname;
+
+ sql_command= SQLCOM_CALL;
+
+ if (check_db_name(reinterpret_cast<LEX_STRING*>
+ (const_cast<LEX_CSTRING*>
+ (static_cast<const LEX_CSTRING*>(db)))))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
+ return NULL;
+ }
+ if (check_routine_name(pkg) ||
+ check_routine_name(proc))
+ return NULL;
+
+ // Concat `pkg` and `name` to `pkg.name`
+ LEX_CSTRING pkg_dot_proc;
+ if (q_pkg_proc.make_qname(thd->mem_root, &pkg_dot_proc) ||
+ check_ident_length(&pkg_dot_proc) ||
+ !(spname= new (thd->mem_root) sp_name(db, &pkg_dot_proc, true)))
+ return NULL;
+
+ sp_handler_package_function.add_used_routine(thd->lex, thd, spname);
+ sp_handler_package_body.add_used_routine(thd->lex, thd, &q_db_pkg);
+
+ return !(m_sql_cmd= new (thd->mem_root) Sql_cmd_call(spname,
+ &sp_handler_package_procedure));
+}
+
+
sp_package *LEX::get_sp_package() const
{
return sphead ? sphead->get_package() : NULL;
@@ -9513,6 +9550,56 @@ Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cdb,
}
+/*
+ Create a 3-step qualified function call.
+ Currently it's possible for package routines only, e.g.:
+ SELECT db.pkg.func();
+*/
+Item *LEX::make_item_func_call_generic(THD *thd,
+ Lex_ident_cli_st *cdb,
+ Lex_ident_cli_st *cpkg,
+ Lex_ident_cli_st *cfunc,
+ List<Item> *args)
+{
+ static Lex_cstring dot(".", 1);
+ Lex_ident_sys db(thd, cdb), pkg(thd, cpkg), func(thd, cfunc);
+ Database_qualified_name q_db_pkg(db, pkg);
+ Database_qualified_name q_pkg_func(pkg, func);
+ sp_name *qname;
+
+ if (db.is_null() || pkg.is_null() || func.is_null())
+ return NULL; // EOM
+
+ if (check_db_name((LEX_STRING*) static_cast<LEX_CSTRING*>(&db)))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
+ return NULL;
+ }
+ if (check_routine_name(&pkg) ||
+ check_routine_name(&func))
+ return NULL;
+
+ // Concat `pkg` and `name` to `pkg.name`
+ LEX_CSTRING pkg_dot_func;
+ if (q_pkg_func.make_qname(thd->mem_root, &pkg_dot_func) ||
+ check_ident_length(&pkg_dot_func) ||
+ !(qname= new (thd->mem_root) sp_name(&db, &pkg_dot_func, true)))
+ return NULL;
+
+ sp_handler_package_function.add_used_routine(thd->lex, thd, qname);
+ sp_handler_package_body.add_used_routine(thd->lex, thd, &q_db_pkg);
+
+ thd->lex->safe_to_cache_query= 0;
+
+ if (args && args->elements > 0)
+ return new (thd->mem_root) Item_func_sp(thd, thd->lex->current_context(),
+ qname, &sp_handler_package_function,
+ *args);
+ return new (thd->mem_root) Item_func_sp(thd, thd->lex->current_context(),
+ qname, &sp_handler_package_function);
+}
+
+
Item *LEX::make_item_func_call_native_or_parse_error(THD *thd,
Lex_ident_cli_st &name,
List<Item> *args)
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 3dfc7845a28..4432abcaac8 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3862,6 +3862,10 @@ public:
bool call_statement_start(THD *thd, const Lex_ident_sys_st *name);
bool call_statement_start(THD *thd, const Lex_ident_sys_st *name1,
const Lex_ident_sys_st *name2);
+ bool call_statement_start(THD *thd,
+ const Lex_ident_sys_st *db,
+ const Lex_ident_sys_st *pkg,
+ const Lex_ident_sys_st *proc);
sp_variable *find_variable(const LEX_CSTRING *name,
sp_pcontext **ctx,
const Sp_rcontext_handler **rh) const;
@@ -4106,6 +4110,11 @@ public:
Item *make_item_func_sysdate(THD *thd, uint fsp);
Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db,
Lex_ident_cli_st *name, List<Item> *args);
+ Item *make_item_func_call_generic(THD *thd,
+ Lex_ident_cli_st *db,
+ Lex_ident_cli_st *pkg,
+ Lex_ident_cli_st *name,
+ List<Item> *args);
Item *make_item_func_call_native_or_parse_error(THD *thd,
Lex_ident_cli_st &name,
List<Item> *args);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 44902f0f162..400caf6b4c0 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1141,8 +1141,7 @@ static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables)
static bool wsrep_command_no_result(char command)
{
- return (command == COM_STMT_PREPARE ||
- command == COM_STMT_FETCH ||
+ return (command == COM_STMT_FETCH ||
command == COM_STMT_SEND_LONG_DATA ||
command == COM_STMT_CLOSE);
}
@@ -1340,7 +1339,13 @@ dispatch_command_return do_command(THD *thd, bool blocking)
DBUG_ASSERT(!thd->mdl_context.has_locks());
DBUG_ASSERT(!thd->get_stmt_da()->is_set());
/* We let COM_QUIT and COM_STMT_CLOSE to execute even if wsrep aborted. */
- if (command != COM_STMT_CLOSE &&
+ if (command == COM_STMT_EXECUTE)
+ {
+ WSREP_DEBUG("PS BF aborted at do_command");
+ thd->wsrep_delayed_BF_abort= true;
+ }
+ if (command != COM_STMT_CLOSE &&
+ command != COM_STMT_EXECUTE &&
command != COM_QUIT)
{
my_error(ER_LOCK_DEADLOCK, MYF(0));
@@ -1423,6 +1428,17 @@ out:
if (unlikely(wsrep_service_started))
wsrep_after_command_after_result(thd);
}
+
+ if (thd->wsrep_delayed_BF_abort)
+ {
+ my_error(ER_LOCK_DEADLOCK, MYF(0));
+ WSREP_DEBUG("Deadlock error for PS query: %s", thd->query());
+ thd->reset_killed();
+ thd->mysys_var->abort = 0;
+ thd->wsrep_retry_counter = 0;
+
+ thd->wsrep_delayed_BF_abort= false;
+ }
#endif /* WITH_WSREP */
DBUG_RETURN(return_value);
}
@@ -9391,15 +9407,17 @@ sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
{
uint error;
ha_rows rows;
- if (likely(!(error= kill_threads_for_user(thd, user, state, &rows))))
- my_ok(thd, rows);
- else
+ switch (error= kill_threads_for_user(thd, user, state, &rows))
{
- /*
- This is probably ER_OUT_OF_RESOURCES, but in the future we may
- want to write the name of the user we tried to kill
- */
- my_error(error, MYF(0), user->host.str, user->user.str);
+ case 0:
+ my_ok(thd, rows);
+ break;
+ case ER_KILL_DENIED_ERROR:
+ my_error(error, MYF(0), (long long) thd->thread_id);
+ break;
+ case ER_OUT_OF_RESOURCES:
+ default:
+ my_error(error, MYF(0));
}
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index e025147c71e..83c064c63c6 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2463,6 +2463,10 @@ static bool check_prepared_statement(Prepared_statement *stmt)
goto error;
}
+#ifdef WITH_WSREP
+ if (wsrep_sync_wait(thd, sql_command))
+ goto error;
+#endif
switch (sql_command) {
case SQLCOM_REPLACE:
case SQLCOM_INSERT:
@@ -4612,7 +4616,13 @@ Prepared_statement::execute_loop(String *expanded_query,
if (set_parameters(expanded_query, packet, packet_end))
return TRUE;
-
+#ifdef WITH_WSREP
+ if (thd->wsrep_delayed_BF_abort)
+ {
+ WSREP_DEBUG("delayed BF abort, quitting execute_loop, stmt: %d", id);
+ return TRUE;
+ }
+#endif /* WITH_WSREP */
reexecute:
// Make sure that reprepare() did not create any new Items.
DBUG_ASSERT(thd->free_list == NULL);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 2fec59fcbf3..0625705c48e 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2009, 2021, MariaDB
+ Copyright (c) 2009, 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
@@ -3331,6 +3331,16 @@ static my_bool processlist_callback(THD *tmp, processlist_callback_arg *arg)
arg->table->field[11]->store((double) tmp->progress.counter /
(double) max_counter*100.0);
}
+ else
+ {
+ /*
+ This is a DECIMAL column without DEFAULT.
+ restore_record() fills its Field::ptr to zero bytes,
+ according to pack_length(). But an array of zero bytes
+ is not a valid decimal. Set it explicitly to 0.
+ */
+ arg->table->field[11]->store((longlong) 0, true);
+ }
mysql_mutex_unlock(&tmp->LOCK_thd_data);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 3186cd0b0db..1d5b1d4b59e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2038,17 +2038,13 @@ bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db,
const char *table_path)
{
char path[FN_REFLEN + 1];
+ const size_t pathmax = sizeof(path) - 1 - reg_ext_length;
int error= 0;
DBUG_ENTER("quick_rm_table");
size_t path_length= table_path ?
- (strxnmov(path, sizeof(path) - 1, table_path, reg_ext, NullS) - path) :
- build_table_filename(path, sizeof(path)-1, db->str, table_name->str,
- reg_ext, flags);
- if (!(flags & NO_FRM_RENAME))
- if (mysql_file_delete(key_file_frm, path, MYF(0)))
- error= 1; /* purecov: inspected */
- path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
+ (strxnmov(path, pathmax, table_path, NullS) - path) :
+ build_table_filename(path, pathmax, db->str, table_name->str, "", flags);
if ((flags & (NO_HA_TABLE | NO_PAR_TABLE)) == NO_HA_TABLE)
{
handler *file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base);
@@ -2058,8 +2054,14 @@ bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db,
delete file;
}
if (!(flags & (FRM_ONLY|NO_HA_TABLE)))
- if (ha_delete_table(thd, base, path, db, table_name, 0) > 0)
- error= 1;
+ error|= ha_delete_table(thd, base, path, db, table_name, 0) > 0;
+
+ if (!(flags & NO_FRM_RENAME))
+ {
+ memcpy(path + path_length, reg_ext, reg_ext_length + 1);
+ if (mysql_file_delete(key_file_frm, path, MYF(0)))
+ error= 1; /* purecov: inspected */
+ }
if (likely(error == 0))
{
@@ -9771,7 +9773,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
{
bool engine_changed, error, frm_is_created= false, error_handler_pushed= false;
bool no_ha_table= true; /* We have not created table in storage engine yet */
- TABLE *table, *new_table;
+ TABLE *table, *new_table= nullptr;
DDL_LOG_STATE ddl_log_state;
Turn_errors_to_warnings_handler errors_to_warnings;
@@ -9805,7 +9807,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
bool varchar= create_info->varchar, table_creation_was_logged= 0;
bool binlog_as_create_select= 0, log_if_exists= 0;
uint tables_opened;
- handlerton *new_db_type, *old_db_type= nullptr;
+ handlerton *new_db_type= create_info->db_type, *old_db_type;
ha_rows copied=0, deleted=0;
LEX_CUSTRING frm= {0,0};
LEX_CSTRING backup_name;
@@ -10156,22 +10158,24 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
}
+ old_db_type= table->s->db_type();
+ new_db_type= create_info->db_type;
+
DBUG_PRINT("info", ("old type: %s new type: %s",
- ha_resolve_storage_engine_name(table->s->db_type()),
- ha_resolve_storage_engine_name(create_info->db_type)));
- if (ha_check_storage_engine_flag(table->s->db_type(), HTON_ALTER_NOT_SUPPORTED))
+ ha_resolve_storage_engine_name(old_db_type),
+ ha_resolve_storage_engine_name(new_db_type)));
+ if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED))
{
DBUG_PRINT("info", ("doesn't support alter"));
- my_error(ER_ILLEGAL_HA, MYF(0), hton_name(table->s->db_type())->str,
+ my_error(ER_ILLEGAL_HA, MYF(0), hton_name(old_db_type)->str,
alter_ctx.db.str, alter_ctx.table_name.str);
DBUG_RETURN(true);
}
- if (ha_check_storage_engine_flag(create_info->db_type,
- HTON_ALTER_NOT_SUPPORTED))
+ if (ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
{
DBUG_PRINT("info", ("doesn't support alter"));
- my_error(ER_ILLEGAL_HA, MYF(0), hton_name(create_info->db_type)->str,
+ my_error(ER_ILLEGAL_HA, MYF(0), hton_name(new_db_type)->str,
alter_ctx.new_db.str, alter_ctx.new_name.str);
DBUG_RETURN(true);
}
@@ -10335,6 +10339,17 @@ do_continue:;
if (parse_engine_part_options(thd, table))
DBUG_RETURN(true);
}
+ /*
+ If the old table had partitions and we are doing ALTER TABLE ...
+ engine= <new_engine>, the new table must preserve the original
+ partitioning. This means that the new engine is still the
+ partitioning engine, not the engine specified in the parser.
+ This is discovered in prep_alter_part_table, which in such case
+ updates create_info->db_type.
+ It's therefore important that the assignment below is done
+ after prep_alter_part_table.
+ */
+ new_db_type= create_info->db_type;
#endif
if (mysql_prepare_alter_table(thd, table, create_info, alter_info,
@@ -10413,7 +10428,7 @@ do_continue:;
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|| is_inplace_alter_impossible(table, create_info, alter_info)
|| IF_PARTITIONING((partition_changed &&
- !(table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)), 0))
+ !(old_db_type->partition_flags() & HA_USE_AUTO_PARTITION)), 0))
{
if (alter_info->algorithm(thd) ==
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
@@ -10431,25 +10446,11 @@ do_continue:;
request table rebuild. Set ALTER_RECREATE flag to force table
rebuild.
*/
- if (create_info->db_type == table->s->db_type() &&
+ if (new_db_type == old_db_type &&
create_info->used_fields & HA_CREATE_USED_ENGINE)
alter_info->flags|= ALTER_RECREATE;
/*
- If the old table had partitions and we are doing ALTER TABLE ...
- engine= <new_engine>, the new table must preserve the original
- partitioning. This means that the new engine is still the
- partitioning engine, not the engine specified in the parser.
- This is discovered in prep_alter_part_table, which in such case
- updates create_info->db_type.
- It's therefore important that the assignment below is done
- after prep_alter_part_table.
- */
- new_db_type= create_info->db_type;
- old_db_type= table->s->db_type();
- new_table= NULL;
-
- /*
Handling of symlinked tables:
If no rename:
Create new data file and index file on the same disk as the
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index bdaf6829fbd..6efdf5f9471 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, 2020, MariaDB
+/* Copyright (c) 2017, 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
@@ -929,13 +929,11 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
{
if (!transform_into_subq)
return this;
-
+
Json_writer_object trace_wrapper(thd);
Json_writer_object trace_conv(thd, "in_to_subquery_conversion");
trace_conv.add("item", this);
- transform_into_subq= false;
-
List<List_item> values;
LEX *lex= thd->lex;
@@ -1109,15 +1107,38 @@ uint32 Item_func_in::max_length_of_left_expr()
bool Item_func_in::to_be_transformed_into_in_subq(THD *thd)
{
+ bool is_row_list= args[1]->type() == Item::ROW_ITEM;
uint values_count= arg_count-1;
- if (args[1]->type() == Item::ROW_ITEM)
+ if (is_row_list)
values_count*= ((Item_row *)(args[1]))->cols();
if (thd->variables.in_subquery_conversion_threshold == 0 ||
thd->variables.in_subquery_conversion_threshold > values_count)
return false;
+ if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE))
+ return true;
+
+ /* Occurence of '?' in IN list is checked only for PREPARE <stmt> commands */
+ for (uint i=1; i < arg_count; i++)
+ {
+ if (!is_row_list)
+ {
+ if (args[i]->type() == Item::PARAM_ITEM)
+ return false;
+ }
+ else
+ {
+ Item_row *row_list= (Item_row *)(args[i]);
+ for (uint j=0; j < row_list->cols(); j++)
+ {
+ if (row_list->element_index(j)->type() == Item::PARAM_ITEM)
+ return false;
+ }
+ }
+ }
+
return true;
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 6a5f1f39e6d..843966f13c8 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -2296,6 +2296,11 @@ multi_update::initialize_tables(JOIN *join)
if (unlikely((thd->variables.option_bits & OPTION_SAFE_UPDATES) &&
error_if_full_join(join)))
DBUG_RETURN(1);
+ if (join->implicit_grouping)
+ {
+ my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0));
+ DBUG_RETURN(1);
+ }
main_table=join->join_tab->table;
table_to_update= 0;
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index e5bea13896a..9f9ef6335f3 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -100,7 +100,8 @@ static void make_unique_view_field_name(THD *thd, Item *target,
itc.rewind();
}
- target->orig_name= target->name.str;
+ if (!target->orig_name)
+ target->orig_name= target->name.str;
target->set_name(thd, buff, name_len, system_charset_info);
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index be51b4120f5..d1c2a01fc39 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2010, 2020, 2021, MariaDB
+ Copyright (c) 2010, 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
@@ -2991,9 +2991,29 @@ sp_suid:
;
call:
- CALL_SYM sp_name
+ CALL_SYM ident
{
- if (unlikely(Lex->call_statement_start(thd, $2)))
+ if (unlikely(Lex->call_statement_start(thd, &$2)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
+ | CALL_SYM ident '.' ident
+ {
+ if (unlikely(Lex->call_statement_start(thd, &$2, &$4)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
+ | CALL_SYM ident '.' ident '.' ident
+ {
+ if (unlikely(Lex->call_statement_start(thd, &$2, &$4, &$6)))
MYSQL_YYABORT;
}
opt_sp_cparam_list
@@ -10463,6 +10483,11 @@ function_call_generic:
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5))))
MYSQL_YYABORT;
}
+ | ident_cli '.' ident_cli '.' ident_cli '(' opt_expr_list ')'
+ {
+ if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, &$5, $7))))
+ MYSQL_YYABORT;
+ }
;
fulltext_options:
@@ -18325,6 +18350,10 @@ sp_statement:
MYSQL_YYABORT;
}
opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
| ident_cli_directly_assignable '.' ident
{
Lex_ident_sys tmp(thd, &$1);
@@ -18333,6 +18362,21 @@ sp_statement:
MYSQL_YYABORT;
}
opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
+ | ident_cli_directly_assignable '.' ident '.' ident
+ {
+ Lex_ident_sys tmp(thd, &$1);
+ if (unlikely(Lex->call_statement_start(thd, &tmp, &$3, &$5)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
;
sp_if_then_statements:
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 4a10e5e2c7f..0303cf8308b 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -5142,7 +5142,7 @@ static Sys_var_have Sys_have_symlink(
# ifdef __SANITIZE_ADDRESS__
# ifdef WITH_UBSAN
-# define SANITIZER_MODE "ASAN+UBSAN"
+# define SANITIZER_MODE "ASAN,UBSAN"
# else
# define SANITIZER_MODE "ASAN"
# endif
@@ -6705,7 +6705,7 @@ static Sys_var_ulong Sys_log_tc_size(
DEFAULT(my_getpagesize() * 6), BLOCK_SIZE(my_getpagesize()));
#endif
-static Sys_var_ulonglong Sys_max_thread_mem(
+static Sys_var_ulonglong Sys_max_session_mem_used(
"max_session_mem_used", "Amount of memory a single user session "
"is allowed to allocate. This limits the value of the "
"session variable MEM_USED", SESSION_VAR(max_mem_used),
diff --git a/sql/table.cc b/sql/table.cc
index a683a78ff49..474299e059e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
- Copyright (c) 2008, 2021, MariaDB
+ Copyright (c) 2008, 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
@@ -1553,21 +1553,6 @@ bool TABLE_SHARE::init_period_from_extra2(period_info_t *period,
}
-static size_t extra2_read_len(const uchar **extra2, const uchar *extra2_end)
-{
- size_t length= *(*extra2)++;
- if (length)
- return length;
-
- if ((*extra2) + 2 >= extra2_end)
- return 0;
- length= uint2korr(*extra2);
- (*extra2)+= 2;
- if (length < 256 || *extra2 + length > extra2_end)
- return 0;
- return length;
-}
-
static
bool read_extra2_section_once(const uchar *extra2, size_t len, LEX_CUSTRING *section)
{
@@ -1795,6 +1780,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
Field_data_type_info_array field_data_type_info_array;
MEM_ROOT *old_root= thd->mem_root;
Virtual_column_info **table_check_constraints;
+ bool *interval_unescaped= NULL;
extra2_fields extra2;
bool extra_index_flags_present= FALSE;
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
@@ -1867,7 +1853,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (frm_image[61] && !share->default_part_plugin)
{
enum legacy_db_type db_type= (enum legacy_db_type) (uint) frm_image[61];
- share->default_part_plugin= ha_lock_engine(NULL, ha_checktype(thd, db_type));
+ share->default_part_plugin= ha_lock_engine(NULL, ha_checktype(thd, db_type, 1));
if (!share->default_part_plugin)
goto err;
}
@@ -2257,6 +2243,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
goto err;
+ if (interval_count)
+ {
+ if (!(interval_unescaped= (bool*) my_alloca(interval_count * sizeof(bool))))
+ goto err;
+ bzero(interval_unescaped, interval_count * sizeof(bool));
+ }
+
field_ptr= share->field;
table_check_constraints= share->check_constraints;
read_length=(uint) (share->fields * field_pack_length +
@@ -2611,11 +2604,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (share->mysql_version < 100200)
attr.pack_flag&= ~FIELDFLAG_LONG_DECIMAL;
- if (interval_nr && attr.charset->mbminlen > 1)
+ if (interval_nr && attr.charset->mbminlen > 1 &&
+ !interval_unescaped[interval_nr - 1])
{
- /* Unescape UCS2 intervals from HEX notation */
+ /*
+ Unescape UCS2/UTF16/UTF32 intervals from HEX notation.
+ Note, ENUM/SET columns with equal value list share a single
+ copy of TYPELIB. Unescape every TYPELIB only once.
+ */
TYPELIB *interval= share->intervals + interval_nr - 1;
unhex_type2(interval);
+ interval_unescaped[interval_nr - 1]= true;
}
#ifndef TO_BE_DELETED_ON_PRODUCTION
@@ -3363,6 +3362,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
share->error= OPEN_FRM_OK;
thd->status_var.opened_shares++;
thd->mem_root= old_root;
+ my_afree(interval_unescaped);
DBUG_RETURN(0);
err:
@@ -3390,6 +3390,7 @@ err:
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
thd->mem_root= old_root;
+ my_afree(interval_unescaped);
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
}
diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc
index c582bf70e30..73f1f9f7a99 100644
--- a/sql/temporary_tables.cc
+++ b/sql/temporary_tables.cc
@@ -698,9 +698,7 @@ bool THD::rm_temporary_table(handlerton *base, const char *path)
char frm_path[FN_REFLEN + 1];
strxnmov(frm_path, sizeof(frm_path) - 1, path, reg_ext, NullS);
- if (mysql_file_delete(key_file_frm, frm_path,
- MYF(MY_WME | MY_IGNORE_ENOENT)))
- error= true;
+
if (base->drop_table(base, path) > 0)
{
error= true;
@@ -708,6 +706,10 @@ bool THD::rm_temporary_table(handlerton *base, const char *path)
path, my_errno);
}
+ if (mysql_file_delete(key_file_frm, frm_path,
+ MYF(MY_WME | MY_IGNORE_ENOENT)))
+ error= true;
+
DBUG_RETURN(error);
}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 7f120af73d3..e6f52cd953e 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -988,7 +988,16 @@ static uint get_interval_id(uint *int_count,List<Create_field> &create_fields,
while ((field=it++) != last_field)
{
- if (field->interval_id && field->interval->count == interval->count)
+ /*
+ ENUM/SET columns with equal value lists share a single
+ copy of the underlying TYPELIB.
+ Fields with different mbminlen can't reuse TYPELIBs, because:
+ - mbminlen==1 are written to FRM as is
+ - mbminlen>1 are written to FRM in hex-encoded format
+ */
+ if (field->interval_id &&
+ field->interval->count == interval->count &&
+ field->charset->mbminlen == last_field->charset->mbminlen)
{
const char **a,**b;
for (a=field->interval->type_names, b=interval->type_names ;
diff --git a/sql/unireg.h b/sql/unireg.h
index 0edb0a50ebd..01c1a5a284e 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -192,6 +192,22 @@ enum extra2_index_flags {
EXTRA2_IGNORED_KEY
};
+
+static inline size_t extra2_read_len(const uchar **extra2, const uchar *end)
+{
+ size_t length= *(*extra2)++;
+ if (length)
+ return length;
+
+ if ((*extra2) + 2 >= end)
+ return 0;
+ length= uint2korr(*extra2);
+ (*extra2)+= 2;
+ if (length < 256 || *extra2 + length > end)
+ return 0;
+ return length;
+}
+
LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table,
HA_CREATE_INFO *create_info,
List<Create_field> &create_fields,
diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc
index 6ab2834a219..ab746dfa1fb 100644
--- a/sql/wsrep_client_service.cc
+++ b/sql/wsrep_client_service.cc
@@ -340,6 +340,7 @@ int Wsrep_client_service::bf_rollback()
m_thd->global_read_lock.unlock_global_read_lock(m_thd);
}
m_thd->release_transactional_locks();
+ mysql_ull_cleanup(m_thd);
m_thd->mdl_context.release_explicit_locks();
DBUG_RETURN(ret);
diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc
index 1f6537a1351..db6ba43edec 100644
--- a/sql/wsrep_high_priority_service.cc
+++ b/sql/wsrep_high_priority_service.cc
@@ -380,6 +380,7 @@ int Wsrep_high_priority_service::rollback(const wsrep::ws_handle& ws_handle,
}
int ret= (trans_rollback_stmt(m_thd) || trans_rollback(m_thd));
m_thd->release_transactional_locks();
+ mysql_ull_cleanup(m_thd);
m_thd->mdl_context.release_explicit_locks();
free_root(m_thd->mem_root, MYF(MY_KEEP_PREALLOC));
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index df0d715650f..2bdda806e99 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1599,6 +1599,73 @@ wsrep_sync_wait_upto (THD* thd,
return ret;
}
+bool wsrep_is_show_query(enum enum_sql_command command)
+{
+ DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
+ return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0;
+}
+
+static bool wsrep_is_diagnostic_query(enum enum_sql_command command)
+{
+ assert(command >= 0 && command <= SQLCOM_END);
+ return (sql_command_flags[command] & CF_DIAGNOSTIC_STMT) != 0;
+}
+
+static enum enum_wsrep_sync_wait
+wsrep_sync_wait_mask_for_command(enum enum_sql_command command)
+{
+ switch (command)
+ {
+ case SQLCOM_SELECT:
+ case SQLCOM_CHECKSUM:
+ return WSREP_SYNC_WAIT_BEFORE_READ;
+ case SQLCOM_DELETE:
+ case SQLCOM_DELETE_MULTI:
+ case SQLCOM_UPDATE:
+ case SQLCOM_UPDATE_MULTI:
+ return WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE;
+ case SQLCOM_REPLACE:
+ case SQLCOM_INSERT:
+ case SQLCOM_REPLACE_SELECT:
+ case SQLCOM_INSERT_SELECT:
+ return WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE;
+ default:
+ if (wsrep_is_diagnostic_query(command))
+ {
+ return WSREP_SYNC_WAIT_NONE;
+ }
+ if (wsrep_is_show_query(command))
+ {
+ switch (command)
+ {
+ case SQLCOM_SHOW_PROFILE:
+ case SQLCOM_SHOW_PROFILES:
+ case SQLCOM_SHOW_SLAVE_HOSTS:
+ case SQLCOM_SHOW_RELAYLOG_EVENTS:
+ case SQLCOM_SHOW_SLAVE_STAT:
+ case SQLCOM_SHOW_BINLOG_STAT:
+ case SQLCOM_SHOW_ENGINE_STATUS:
+ case SQLCOM_SHOW_ENGINE_MUTEX:
+ case SQLCOM_SHOW_ENGINE_LOGS:
+ case SQLCOM_SHOW_PROCESSLIST:
+ case SQLCOM_SHOW_PRIVILEGES:
+ return WSREP_SYNC_WAIT_NONE;
+ default:
+ return WSREP_SYNC_WAIT_BEFORE_SHOW;
+ }
+ }
+ }
+ return WSREP_SYNC_WAIT_NONE;
+}
+
+bool wsrep_sync_wait(THD* thd, enum enum_sql_command command)
+{
+ bool res = false;
+ if (WSREP_CLIENT(thd) && thd->variables.wsrep_sync_wait)
+ res = wsrep_sync_wait(thd, wsrep_sync_wait_mask_for_command(command));
+ return res;
+}
+
void wsrep_keys_free(wsrep_key_arr_t* key_arr)
{
for (size_t i= 0; i < key_arr->keys_len; ++i)
@@ -2794,6 +2861,12 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
return 0;
}
+ if (thd->wsrep_parallel_slave_wait_for_prior_commit())
+ {
+ WSREP_WARN("TOI: wait_for_prior_commit() returned error.");
+ return -1;
+ }
+
int ret= 0;
mysql_mutex_lock(&thd->LOCK_thd_data);
@@ -3324,11 +3397,6 @@ extern bool wsrep_thd_ignore_table(THD *thd)
return thd->wsrep_ignore_table;
}
-bool wsrep_is_show_query(enum enum_sql_command command)
-{
- DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
- return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0;
-}
bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
TABLE_LIST* src_table,
HA_CREATE_INFO *create_info)
@@ -3599,6 +3667,15 @@ enum wsrep::streaming_context::fragment_unit wsrep_fragment_unit(ulong unit)
}
}
+bool THD::wsrep_parallel_slave_wait_for_prior_commit()
+{
+ if (rgi_slave && rgi_slave->is_parallel_exec && wait_for_prior_commit())
+ {
+ return 1;
+ }
+ return 0;
+}
+
/***** callbacks for wsrep service ************/
my_bool get_wsrep_recovery()
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index e5aacadf2b6..6d01dc09bfb 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -226,6 +226,7 @@ extern bool wsrep_check_mode_after_open_table (THD *thd, const handlerton *hton,
extern bool wsrep_check_mode_before_cmd_execute (THD *thd);
extern bool wsrep_must_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_READ);
extern bool wsrep_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_READ);
+extern bool wsrep_sync_wait (THD* thd, enum enum_sql_command command);
extern enum wsrep::provider::status
wsrep_sync_wait_upto (THD* thd, wsrep_gtid_t* upto, int timeout);
extern int wsrep_check_opts();
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 3062890a8e4..e07cc37f610 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -1,4 +1,4 @@
-/* Copyright 2008-2020 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2022 Codership Oy <http://www.codership.com>
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
@@ -33,6 +33,7 @@
#include <cstdio>
#include <cstdlib>
+#include "debug_sync.h"
#include <my_service_manager.h>
@@ -1590,6 +1591,33 @@ static int run_sql_command(THD *thd, const char *query)
return 0;
}
+static void sst_disallow_writes (THD* thd, bool yes)
+{
+ char query_str[64]= { 0, };
+ ssize_t const query_max= sizeof(query_str) - 1;
+ CHARSET_INFO *current_charset;
+
+ current_charset= thd->variables.character_set_client;
+
+ if (!is_supported_parser_charset(current_charset))
+ {
+ /* Do not use non-supported parser character sets */
+ WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->cs_name.str);
+ thd->variables.character_set_client= &my_charset_latin1;
+ WSREP_WARN("For SST temporally setting character set to : %s",
+ my_charset_latin1.cs_name.str);
+ }
+
+ snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
+ yes ? 1 : 0);
+
+ if (run_sql_command(thd, query_str))
+ {
+ WSREP_ERROR("Failed to disallow InnoDB writes");
+ }
+ thd->variables.character_set_client= current_charset;
+}
+
static int sst_flush_tables(THD* thd)
{
@@ -1651,6 +1679,11 @@ static int sst_flush_tables(THD* thd)
else
{
WSREP_INFO("Tables flushed.");
+
+ /* disable further disk IO */
+ sst_disallow_writes(thd, true);
+ WSREP_INFO("Disabled further disk IO.");
+
/*
Tables have been flushed. Create a file with cluster state ID and
wsrep_gtid_domain_id.
@@ -1660,6 +1693,9 @@ static int sst_flush_tables(THD* thd)
(long long)wsrep_locked_seqno, wsrep_gtid_server.domain_id);
err= sst_create_file(flush_success, content);
+ if (err)
+ WSREP_INFO("Creating file for flush_success failed %d",err);
+
const char base_name[]= "tables_flushed";
ssize_t const full_len= strlen(mysql_real_data_home) + strlen(base_name)+2;
char *real_name= (char*) malloc(full_len);
@@ -1699,34 +1735,6 @@ static int sst_flush_tables(THD* thd)
return err;
}
-
-static void sst_disallow_writes (THD* thd, bool yes)
-{
- char query_str[64]= { 0, };
- ssize_t const query_max= sizeof(query_str) - 1;
- CHARSET_INFO *current_charset;
-
- current_charset= thd->variables.character_set_client;
-
- if (!is_supported_parser_charset(current_charset))
- {
- /* Do not use non-supported parser character sets */
- WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->cs_name.str);
- thd->variables.character_set_client= &my_charset_latin1;
- WSREP_WARN("For SST temporally setting character set to : %s",
- my_charset_latin1.cs_name.str);
- }
-
- snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
- yes ? 1 : 0);
-
- if (run_sql_command(thd, query_str))
- {
- WSREP_ERROR("Failed to disallow InnoDB writes");
- }
- thd->variables.character_set_client= current_charset;
-}
-
static void* sst_donor_thread (void* a)
{
sst_thread_arg* arg= (sst_thread_arg*)a;
@@ -1796,8 +1804,7 @@ wait_signal:
err= sst_flush_tables (thd.ptr);
if (!err)
{
- sst_disallow_writes (thd.ptr, true);
- /*
+ /*
Lets also keep statements that modify binary logs (like RESET LOGS,
RESET MASTER) from proceeding until the files have been transferred
to the joiner node.
@@ -1808,6 +1815,18 @@ wait_signal:
}
locked= true;
+
+ WSREP_INFO("Donor state reached");
+
+ DBUG_EXECUTE_IF("sync.wsrep_donor_state",
+ {
+ const char act[]=
+ "now "
+ "SIGNAL sync.wsrep_donor_state_reached "
+ "WAIT_FOR signal.wsrep_donor_state";
+ assert(!debug_sync_set_action(thd.ptr,
+ STRING_WITH_LEN(act)));
+ };);
goto wait_signal;
}
}
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index 08a0ae55793..9998fe52fc4 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2014, 2021, MariaDB Corporation.
+Copyright (c) 2014, 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 the Free Software
@@ -1334,11 +1334,23 @@ static void btr_page_reorganize_low(page_cur_t *cursor, dict_index_t *index,
else
ut_ad(cursor->rec == page_get_infimum_rec(block->page.frame));
- if (block->page.id().page_no() == index->page &&
- fil_page_get_type(old->page.frame) == FIL_PAGE_TYPE_INSTANT)
+ mtr->set_log_mode(log_mode);
+
+ if (block->page.id().page_no() != index->page ||
+ fil_page_get_type(old->page.frame) != FIL_PAGE_TYPE_INSTANT)
+ ut_ad(!memcmp(old->page.frame, block->page.frame, PAGE_HEADER));
+ else if (!index->is_instant())
+ {
+ ut_ad(!memcmp(old->page.frame, block->page.frame, FIL_PAGE_TYPE));
+ ut_ad(!memcmp(old->page.frame + FIL_PAGE_TYPE + 2,
+ block->page.frame + FIL_PAGE_TYPE + 2,
+ PAGE_HEADER - FIL_PAGE_TYPE - 2));
+ mtr->write<2,mtr_t::FORCED>(*block, FIL_PAGE_TYPE + block->page.frame,
+ FIL_PAGE_INDEX);
+ }
+ else
{
/* Preserve the PAGE_INSTANT information. */
- ut_ad(index->is_instant());
memcpy_aligned<2>(FIL_PAGE_TYPE + block->page.frame,
FIL_PAGE_TYPE + old->page.frame, 2);
memcpy_aligned<2>(PAGE_HEADER + PAGE_INSTANT + block->page.frame,
@@ -1358,9 +1370,10 @@ static void btr_page_reorganize_low(page_cur_t *cursor, dict_index_t *index,
memcpy(PAGE_OLD_SUPREMUM + block->page.frame,
PAGE_OLD_SUPREMUM + old->page.frame, 8);
}
+
+ ut_ad(!memcmp(old->page.frame, block->page.frame, PAGE_HEADER));
}
- ut_ad(!memcmp(old->page.frame, block->page.frame, PAGE_HEADER));
ut_ad(!memcmp(old->page.frame + PAGE_MAX_TRX_ID + PAGE_HEADER,
block->page.frame + PAGE_MAX_TRX_ID + PAGE_HEADER,
PAGE_DATA - (PAGE_MAX_TRX_ID + PAGE_HEADER)));
@@ -1369,7 +1382,6 @@ static void btr_page_reorganize_low(page_cur_t *cursor, dict_index_t *index,
lock_move_reorganize_page(block, old);
/* Write log for the changes, if needed. */
- mtr->set_log_mode(log_mode);
if (log_mode == MTR_LOG_ALL)
{
/* Check and log the changes in the page header. */
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 688be3722bf..f9ee51e466b 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -630,10 +630,6 @@ bool buf_page_is_corrupted(bool check_lsn, const byte *read_buf,
return false;
}
-#ifndef UNIV_INNOCHECKSUM
- uint32_t crc32 = 0;
- bool crc32_inited = false;
-#endif /* !UNIV_INNOCHECKSUM */
const ulint zip_size = fil_space_t::zip_size(fsp_flags);
const uint16_t page_type = fil_page_get_type(read_buf);
@@ -728,6 +724,8 @@ bool buf_page_is_corrupted(bool check_lsn, const byte *read_buf,
return false;
}
+ const uint32_t crc32 = buf_calc_page_crc32(read_buf);
+
/* Very old versions of InnoDB only stored 8 byte lsn to the
start and the end of the page. */
@@ -738,18 +736,14 @@ bool buf_page_is_corrupted(bool check_lsn, const byte *read_buf,
!= mach_read_from_4(read_buf + FIL_PAGE_LSN)
&& checksum_field2 != BUF_NO_CHECKSUM_MAGIC) {
- crc32 = buf_calc_page_crc32(read_buf);
- crc32_inited = true;
-
DBUG_EXECUTE_IF(
"page_intermittent_checksum_mismatch", {
- static int page_counter;
- if (page_counter++ == 2) {
- crc32++;
- }
- });
+ static int page_counter;
+ if (page_counter++ == 2) return true;
+ });
- if (checksum_field2 != crc32
+ if ((checksum_field1 != crc32
+ || checksum_field2 != crc32)
&& checksum_field2
!= buf_calc_page_old_checksum(read_buf)) {
return true;
@@ -759,25 +753,11 @@ bool buf_page_is_corrupted(bool check_lsn, const byte *read_buf,
switch (checksum_field1) {
case 0:
case BUF_NO_CHECKSUM_MAGIC:
- break;
- default:
- if (!crc32_inited) {
- crc32 = buf_calc_page_crc32(read_buf);
- crc32_inited = true;
- }
-
- if (checksum_field1 != crc32
- && checksum_field1
- != buf_calc_page_new_checksum(read_buf)) {
- return true;
- }
+ return false;
}
-
- return crc32_inited
- && ((checksum_field1 == crc32
- && checksum_field2 != crc32)
- || (checksum_field1 != crc32
- && checksum_field2 == crc32));
+ return (checksum_field1 != crc32 || checksum_field2 != crc32)
+ && checksum_field1
+ != buf_calc_page_new_checksum(read_buf);
}
#endif /* !UNIV_INNOCHECKSUM */
}
@@ -2150,17 +2130,21 @@ void buf_pool_t::watch_unset(const page_id_t id, buf_pool_t::hash_chain &chain)
buf_page_t *w;
{
transactional_lock_guard<page_hash_latch> g{page_hash.lock_get(chain)};
- /* The page must exist because watch_set() increments buf_fix_count. */
+ /* The page must exist because watch_set() did fix(). */
w= page_hash.get(id, chain);
- const auto state= w->state();
- ut_ad(state >= buf_page_t::UNFIXED);
- ut_ad(~buf_page_t::LRU_MASK & state);
ut_ad(w->in_page_hash);
- if (state != buf_page_t::UNFIXED + 1 || !watch_is_sentinel(*w))
+ if (!watch_is_sentinel(*w))
{
- w->unfix();
+ no_watch:
+ ut_d(const auto s=) w->unfix();
+ ut_ad(~buf_page_t::LRU_MASK & s);
w= nullptr;
}
+ const auto state= w->state();
+ ut_ad(~buf_page_t::LRU_MASK & state);
+ ut_ad(state >= buf_page_t::UNFIXED);
+ if (state != buf_page_t::UNFIXED + 1)
+ goto no_watch;
}
if (!w)
@@ -2259,29 +2243,66 @@ buf_page_t* buf_page_get_zip(const page_id_t page_id, ulint zip_size)
lookup:
for (bool discard_attempted= false;;)
{
+#ifndef NO_ELISION
+ if (xbegin())
+ {
+ if (hash_lock.is_locked())
+ xabort();
+ bpage= buf_pool.page_hash.get(page_id, chain);
+ if (!bpage || buf_pool.watch_is_sentinel(*bpage))
+ {
+ xend();
+ goto must_read_page;
+ }
+ if (!bpage->zip.data)
+ {
+ /* There is no ROW_FORMAT=COMPRESSED page. */
+ xend();
+ return nullptr;
+ }
+ if (discard_attempted || !bpage->frame)
+ {
+ if (!bpage->lock.s_lock_try())
+ xabort();
+ xend();
+ break;
+ }
+ xend();
+ }
+ else
+#endif
{
- transactional_shared_lock_guard<page_hash_latch> g{hash_lock};
+ hash_lock.lock_shared();
bpage= buf_pool.page_hash.get(page_id, chain);
if (!bpage || buf_pool.watch_is_sentinel(*bpage))
+ {
+ hash_lock.unlock_shared();
goto must_read_page;
+ }
ut_ad(bpage->in_file());
ut_ad(page_id == bpage->id());
if (!bpage->zip.data)
+ {
/* There is no ROW_FORMAT=COMPRESSED page. */
+ hash_lock.unlock_shared();
return nullptr;
+ }
if (discard_attempted || !bpage->frame)
{
- /* Even when we are holding a page_hash latch, it should be
+ /* Even when we are holding a hash_lock, it should be
acceptable to wait for a page S-latch here, because
buf_page_t::read_complete() will not wait for buf_pool.mutex,
and because S-latch would not conflict with a U-latch
that would be protecting buf_page_t::write_complete(). */
bpage->lock.s_lock();
+ hash_lock.unlock_shared();
break;
}
+
+ hash_lock.unlock_shared();
}
discard_attempted= true;
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 29dceeb83b4..70b3bb0ce46 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1778,7 +1778,8 @@ inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept
else
#endif
{
- n_pending_checkpoint_writes++;
+ ut_ad(!checkpoint_pending);
+ checkpoint_pending= true;
latch.wr_unlock();
log_write_and_flush_prepare();
resizing= resize_lsn.load(std::memory_order_relaxed);
@@ -1797,11 +1798,12 @@ inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept
if (srv_file_flush_method != SRV_O_DSYNC)
ut_a(log.flush());
latch.wr_lock(SRW_LOCK_CALL);
- n_pending_checkpoint_writes--;
+ ut_ad(checkpoint_pending);
+ checkpoint_pending= false;
resizing= resize_lsn.load(std::memory_order_relaxed);
}
- ut_ad(!n_pending_checkpoint_writes);
+ ut_ad(!checkpoint_pending);
next_checkpoint_no++;
const lsn_t checkpoint_lsn{next_checkpoint_lsn};
last_checkpoint_lsn= checkpoint_lsn;
@@ -1938,7 +1940,7 @@ static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn)
ut_ad(log_sys.get_flushed_lsn() >= flush_lsn);
- if (log_sys.n_pending_checkpoint_writes)
+ if (log_sys.checkpoint_pending)
{
/* A checkpoint write is running */
log_sys.latch.wr_unlock();
diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
index f1cb34dd5f3..d3a221814ad 100644
--- a/storage/innobase/buf/buf0rea.cc
+++ b/storage/innobase/buf/buf0rea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2021, MariaDB Corporation.
+Copyright (c) 2015, 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 the Free Software
@@ -50,19 +50,30 @@ i/o-fixed buffer blocks */
/** Remove the sentinel block for the watch before replacing it with a
real block. watch_unset() or watch_occurred() will notice
that the block has been replaced with the real block.
-@param watch sentinel
-@param chain locked hash table chain */
-inline void buf_pool_t::watch_remove(buf_page_t *watch,
- buf_pool_t::hash_chain &chain)
+@param w sentinel
+@param chain locked hash table chain
+@return w->state() */
+inline uint32_t buf_pool_t::watch_remove(buf_page_t *w,
+ buf_pool_t::hash_chain &chain)
{
mysql_mutex_assert_owner(&buf_pool.mutex);
- ut_ad(page_hash.lock_get(chain).is_write_locked());
- ut_a(watch_is_sentinel(*watch));
- if (watch->buf_fix_count())
- page_hash.remove(chain, watch);
- ut_ad(!watch->in_page_hash);
- watch->set_state(buf_page_t::NOT_USED);
- watch->id_= page_id_t(~0ULL);
+ ut_ad(xtest() || page_hash.lock_get(chain).is_write_locked());
+ ut_ad(w >= &watch[0]);
+ ut_ad(w < &watch[array_elements(watch)]);
+ ut_ad(!w->in_zip_hash);
+ ut_ad(!w->zip.data);
+
+ uint32_t s{w->state()};
+ w->set_state(buf_page_t::NOT_USED);
+ ut_ad(s >= buf_page_t::UNFIXED);
+ ut_ad(s < buf_page_t::READ_FIX);
+
+ if (~buf_page_t::LRU_MASK & s)
+ page_hash.remove(chain, w);
+
+ ut_ad(!w->in_page_hash);
+ w->id_= page_id_t(~0ULL);
+ return s;
}
/** Initialize a page for read to the buffer buf_pool. If the page is
@@ -139,14 +150,8 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
{buf_pool.page_hash.lock_get(chain)};
if (hash_page)
- {
- /* Preserve the reference count. */
- uint32_t buf_fix_count= hash_page->state();
- ut_a(buf_fix_count >= buf_page_t::UNFIXED);
- ut_a(buf_fix_count < buf_page_t::READ_FIX);
- buf_pool.watch_remove(hash_page, chain);
- block->page.fix(buf_fix_count - buf_page_t::UNFIXED);
- }
+ bpage->set_state(buf_pool.watch_remove(hash_page, chain) +
+ (buf_page_t::READ_FIX - buf_page_t::UNFIXED));
buf_pool.page_hash.append(chain, &block->page);
}
@@ -209,16 +214,8 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
{buf_pool.page_hash.lock_get(chain)};
if (hash_page)
- {
- /* Preserve the reference count. It can be 0 if
- buf_pool_t::watch_unset() is executing concurrently,
- waiting for buf_pool.mutex, which we are holding. */
- uint32_t buf_fix_count= hash_page->state();
- ut_a(buf_fix_count >= buf_page_t::UNFIXED);
- ut_a(buf_fix_count < buf_page_t::READ_FIX);
- bpage->fix(buf_fix_count - buf_page_t::UNFIXED);
- buf_pool.watch_remove(hash_page, chain);
- }
+ bpage->set_state(buf_pool.watch_remove(hash_page, chain) +
+ (buf_page_t::READ_FIX - buf_page_t::UNFIXED));
buf_pool.page_hash.append(chain, bpage);
}
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index 68bb2c44d3f..47e9d9cff0c 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2021, MariaDB Corporation.
+Copyright (c) 2017, 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 the Free Software
@@ -849,7 +849,7 @@ uint32_t dict_drop_index_tree(btr_pcur_t *pcur, trx_t *trx, mtr_t *mtr)
len > DICT_NUM_FIELDS__SYS_INDEXES)
{
rec_corrupted:
- ib::error() << "Corrupted SYS_INDEXES record";
+ sql_print_error("InnoDB: Corrupted SYS_INDEXES record");
return 0;
}
@@ -1331,7 +1331,7 @@ bool dict_sys_t::load_sys_tables()
{
sys_foreign= nullptr;
mismatch= true;
- ib::error() << "Invalid definition of SYS_FOREIGN";
+ sql_print_error("InnoDB: Invalid definition of SYS_FOREIGN");
}
if (!(sys_foreign_cols= load_table(SYS_TABLE[SYS_FOREIGN_COLS],
DICT_ERR_IGNORE_FK_NOKEY)));
@@ -1343,7 +1343,7 @@ bool dict_sys_t::load_sys_tables()
{
sys_foreign_cols= nullptr;
mismatch= true;
- ib::error() << "Invalid definition of SYS_FOREIGN_COLS";
+ sql_print_error("InnoDB: Invalid definition of SYS_FOREIGN_COLS");
}
if (!(sys_virtual= load_table(SYS_TABLE[SYS_VIRTUAL],
DICT_ERR_IGNORE_FK_NOKEY)));
@@ -1354,7 +1354,7 @@ bool dict_sys_t::load_sys_tables()
{
sys_virtual= nullptr;
mismatch= true;
- ib::error() << "Invalid definition of SYS_VIRTUAL";
+ sql_print_error("InnoDB: Invalid definition of SYS_VIRTUAL");
}
unlock();
return mismatch;
@@ -1370,8 +1370,8 @@ dberr_t dict_sys_t::create_or_check_sys_tables()
if (load_sys_tables())
{
- ib::info() << "Set innodb_read_only=1 or innodb_force_recovery=3"
- " to start up";
+ sql_print_information("InnoDB: Set innodb_read_only=1 "
+ "or innodb_force_recovery=3 to start up");
return DB_CORRUPTION;
}
@@ -1403,7 +1403,7 @@ dberr_t dict_sys_t::create_or_check_sys_tables()
const auto srv_file_per_table_backup= srv_file_per_table;
srv_file_per_table= 0;
dberr_t error;
- const char *tablename;
+ span<const char> tablename;
if (!sys_foreign)
{
@@ -1421,9 +1421,11 @@ dberr_t dict_sys_t::create_or_check_sys_tables()
"END;\n", trx);
if (UNIV_UNLIKELY(error != DB_SUCCESS))
{
- tablename= SYS_TABLE[SYS_FOREIGN].data();
+ tablename= SYS_TABLE[SYS_FOREIGN];
err_exit:
- ib::error() << "Creation of " << tablename << " failed: " << error;
+ sql_print_error("InnoDB: Creation of %.*s failed: %s",
+ int(tablename.size()), tablename.data(),
+ ut_strerr(error));
trx->rollback();
row_mysql_unlock_data_dictionary(trx);
trx->free();
@@ -1443,7 +1445,7 @@ err_exit:
"END;\n", trx);
if (UNIV_UNLIKELY(error != DB_SUCCESS))
{
- tablename= SYS_TABLE[SYS_FOREIGN_COLS].data();
+ tablename= SYS_TABLE[SYS_FOREIGN_COLS];
goto err_exit;
}
}
@@ -1458,7 +1460,7 @@ err_exit:
"END;\n", trx);
if (UNIV_UNLIKELY(error != DB_SUCCESS))
{
- tablename= SYS_TABLE[SYS_VIRTUAL].data();
+ tablename= SYS_TABLE[SYS_VIRTUAL];
goto err_exit;
}
}
@@ -1472,10 +1474,11 @@ err_exit:
if (sys_foreign);
else if (!(sys_foreign= load_table(SYS_TABLE[SYS_FOREIGN])))
{
- tablename= SYS_TABLE[SYS_FOREIGN].data();
+ tablename= SYS_TABLE[SYS_FOREIGN];
load_fail:
unlock();
- ib::error() << "Failed to CREATE TABLE " << tablename;
+ sql_print_error("InnoDB: Failed to CREATE TABLE %.*s",
+ int(tablename.size()), tablename.data());
return DB_TABLE_NOT_FOUND;
}
else
@@ -1484,7 +1487,7 @@ load_fail:
if (sys_foreign_cols);
else if (!(sys_foreign_cols= load_table(SYS_TABLE[SYS_FOREIGN_COLS])))
{
- tablename= SYS_TABLE[SYS_FOREIGN_COLS].data();
+ tablename= SYS_TABLE[SYS_FOREIGN_COLS];
goto load_fail;
}
else
@@ -1493,7 +1496,7 @@ load_fail:
if (sys_virtual);
else if (!(sys_virtual= load_table(SYS_TABLE[SYS_VIRTUAL])))
{
- tablename= SYS_TABLE[SYS_VIRTUAL].data();
+ tablename= SYS_TABLE[SYS_VIRTUAL];
goto load_fail;
}
else
@@ -1516,12 +1519,14 @@ dict_foreign_eval_sql(
const char* id, /*!< in: foreign key id */
trx_t* trx) /*!< in/out: transaction */
{
- dberr_t error;
FILE* ef = dict_foreign_err_file;
- error = que_eval_sql(info, sql, trx);
+ dberr_t error = que_eval_sql(info, sql, trx);
- if (error == DB_DUPLICATE_KEY) {
+ switch (error) {
+ case DB_SUCCESS:
+ break;
+ case DB_DUPLICATE_KEY:
mysql_mutex_lock(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
@@ -1541,15 +1546,11 @@ dict_foreign_eval_sql(
"names can occur. Workaround: name your constraints\n"
"explicitly with unique names.\n",
ef);
-
- mysql_mutex_unlock(&dict_foreign_err_mutex);
-
- return(error);
- }
-
- if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
- ib::error() << "Foreign key constraint creation failed: "
- << error;
+ goto release;
+ default:
+ sql_print_error("InnoDB: "
+ "Foreign key constraint creation failed: %s",
+ ut_strerr(error));
mysql_mutex_lock(&dict_foreign_err_mutex);
ut_print_timestamp(ef);
@@ -1559,12 +1560,11 @@ dict_foreign_eval_sql(
fputs(".\n"
"See the MariaDB .err log in the datadir"
" for more information.\n", ef);
+release:
mysql_mutex_unlock(&dict_foreign_err_mutex);
-
- return(error);
}
- return(DB_SUCCESS);
+ return error;
}
/********************************************************************//**
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index bcc63a5e38a..3d5e2434978 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2021, MariaDB Corporation.
+Copyright (c) 2016, 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 the Free Software
@@ -43,6 +43,7 @@ Created 4/24/1996 Heikki Tuuri
#include "srv0start.h"
#include "srv0srv.h"
#include "fts0opt.h"
+#include "row0vers.h"
/** Loads a table definition and also all its index definitions.
@@ -65,22 +66,20 @@ static dict_table_t *dict_load_table_one(const span<const char> &name,
dict_names_t &fk_tables);
/** Load an index definition from a SYS_INDEXES record to dict_index_t.
-If allocate=TRUE, we will create a dict_index_t structure and fill it
-accordingly. If allocated=FALSE, the dict_index_t will be supplied by
-the caller and filled with information read from the record.
@return error message
@retval NULL on success */
static
const char*
dict_load_index_low(
byte* table_id, /*!< in/out: table id (8 bytes),
- an "in" value if allocate=TRUE
- and "out" when allocate=FALSE */
+ an "in" value if mtr
+ and "out" when !mtr */
mem_heap_t* heap, /*!< in/out: temporary memory heap */
const rec_t* rec, /*!< in: SYS_INDEXES record */
- ibool allocate, /*!< in: TRUE=allocate *index,
- FALSE=fill in a pre-allocated
- *index */
+ mtr_t* mtr, /*!< in/out: mini-transaction,
+ or nullptr if a pre-allocated
+ *index is to be filled in */
+ dict_table_t* table, /*!< in/out: table, or NULL */
dict_index_t** index); /*!< out,own: index, or NULL */
/** Load a table column definition from a SYS_COLUMNS record to dict_table_t.
@@ -100,6 +99,7 @@ dict_load_column_low(
table_id_t* table_id, /*!< out: table id */
const char** col_name, /*!< out: column name */
const rec_t* rec, /*!< in: SYS_COLUMNS record */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
ulint* nth_v_col); /*!< out: if not NULL, this
records the "n" of "nth" virtual
column */
@@ -143,6 +143,7 @@ dict_load_field_low(
byte* last_index_id, /*!< in: last index id */
mem_heap_t* heap, /*!< in/out: memory heap
for temporary storage */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
const rec_t* rec); /*!< in: SYS_FIELDS record */
#ifdef UNIV_DEBUG
@@ -179,7 +180,7 @@ dict_getnext_system_low(
{
rec_t* rec = NULL;
- while (!rec || rec_get_deleted_flag(rec, 0)) {
+ while (!rec) {
btr_pcur_move_to_next_user_rec(pcur, mtr);
rec = btr_pcur_get_rec(pcur);
@@ -209,9 +210,13 @@ dict_startscan_system(
mtr_t* mtr, /*!< in: the mini-transaction */
dict_table_t* table) /*!< in: system table */
{
- btr_pcur_open_at_index_side(true, table->indexes.start,
- BTR_SEARCH_LEAF, pcur, true, 0, mtr);
- return dict_getnext_system_low(pcur, mtr);
+ btr_pcur_open_at_index_side(true, table->indexes.start, BTR_SEARCH_LEAF,
+ pcur, true, 0, mtr);
+ const rec_t *rec;
+ do
+ rec= dict_getnext_system_low(pcur, mtr);
+ while (rec && rec_get_deleted_flag(rec, 0));
+ return rec;
}
/********************************************************************//**
@@ -230,7 +235,9 @@ dict_getnext_system(
pcur->restore_position(BTR_SEARCH_LEAF, mtr);
/* Get the next record */
- rec = dict_getnext_system_low(pcur, mtr);
+ do {
+ rec = dict_getnext_system_low(pcur, mtr);
+ } while (rec && rec_get_deleted_flag(rec, 0));
return(rec);
}
@@ -249,14 +256,13 @@ dict_process_sys_indexes_rec(
table_id_t* table_id) /*!< out: index table id */
{
const char* err_msg;
- byte* buf;
+ byte buf[8];
ut_d(index->is_dummy = true);
ut_d(index->in_instant_init = false);
- buf = static_cast<byte*>(mem_heap_alloc(heap, 8));
/* Parse the record, and get "dict_index_t" struct filled */
- err_msg = dict_load_index_low(buf, heap, rec, FALSE, &index);
+ err_msg = dict_load_index_low(buf, heap, rec, nullptr, nullptr, &index);
*table_id = mach_read_from_8(buf);
@@ -282,7 +288,8 @@ dict_process_sys_columns_rec(
/* Parse the record, and get "dict_col_t" struct filled */
err_msg = dict_load_column_low(NULL, heap, column,
- table_id, col_name, rec, nth_v_col);
+ table_id, col_name, rec, nullptr,
+ nth_v_col);
return(err_msg);
}
@@ -301,13 +308,7 @@ dict_process_sys_virtual_rec(
ulint* pos,
ulint* base_pos)
{
- const char* err_msg;
-
- /* Parse the record, and get "dict_col_t" struct filled */
- err_msg = dict_load_virtual_low(NULL, NULL, table_id,
- pos, base_pos, rec);
-
- return(err_msg);
+ return dict_load_virtual_low(nullptr, nullptr, table_id, pos, base_pos, rec);
}
/********************************************************************//**
@@ -325,17 +326,14 @@ dict_process_sys_fields_rec(
index_id_t* index_id, /*!< out: current index id */
index_id_t last_id) /*!< in: previous index id */
{
- byte* buf;
- byte* last_index_id;
+ byte buf[8];
+ byte last_index_id[8];
const char* err_msg;
- buf = static_cast<byte*>(mem_heap_alloc(heap, 8));
-
- last_index_id = static_cast<byte*>(mem_heap_alloc(heap, 8));
mach_write_to_8(last_index_id, last_id);
err_msg = dict_load_field_low(buf, NULL, sys_field,
- pos, last_index_id, heap, rec);
+ pos, last_index_id, heap, nullptr, rec);
*index_id = mach_read_from_8(buf);
@@ -507,10 +505,6 @@ dict_sys_tables_rec_check(
ut_ad(dict_sys.locked());
- if (rec_get_deleted_flag(rec, 0)) {
- return("delete-marked record in SYS_TABLES");
- }
-
if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_TABLES) {
return("wrong number of columns in SYS_TABLES record");
}
@@ -636,29 +630,77 @@ uint32_t dict_sys_tables_type_to_tf(uint32_t type, bool not_redundant)
return(flags);
}
+/** Outcome of dict_sys_tables_rec_read() */
+enum table_read_status { READ_OK= 0, READ_ERROR, READ_NOT_FOUND };
+
/** Read and return 5 integer fields from a SYS_TABLES record.
@param[in] rec A record of SYS_TABLES
-@param[in] name SYS_TABLES.NAME
+@param[in] mtr mini-transaction
@param[out] table_id Pointer to the table_id for this table
@param[out] space_id Pointer to the space_id for this table
@param[out] n_cols Pointer to number of columns for this table.
@param[out] flags Pointer to table flags
@param[out] flags2 Pointer to table flags2
-@return true if the record was read correctly, false if not. */
+@param[out] trx_id DB_TRX_ID of the committed SYS_TABLES record,
+ or nullptr to perform READ UNCOMMITTED
+@return whether the record was read correctly */
MY_ATTRIBUTE((warn_unused_result))
static
-bool
+table_read_status
dict_sys_tables_rec_read(
const rec_t* rec,
- const span<const char>& name,
+ mtr_t* mtr,
table_id_t* table_id,
uint32_t* space_id,
uint32_t* n_cols,
uint32_t* flags,
- uint32_t* flags2)
+ uint32_t* flags2,
+ trx_id_t* trx_id)
{
const byte* field;
ulint len;
+ mem_heap_t* heap = nullptr;
+
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLES__DB_TRX_ID, &len);
+ ut_ad(len == 6 || len == UNIV_SQL_NULL);
+ trx_id_t id = len == 6 ? trx_read_trx_id(field) : 0;
+ if (id && trx_sys.find(nullptr, id, false)) {
+ const auto savepoint = mtr->get_savepoint();
+ heap = mem_heap_create(1024);
+ dict_index_t* index = UT_LIST_GET_FIRST(
+ dict_sys.sys_tables->indexes);
+ rec_offs* offsets = rec_get_offsets(
+ rec, index, nullptr, true, ULINT_UNDEFINED, &heap);
+ const rec_t* old_vers;
+ row_vers_build_for_semi_consistent_read(
+ nullptr, rec, mtr, index, &offsets, &heap,
+ heap, &old_vers, nullptr);
+ mtr->rollback_to_savepoint(savepoint);
+ rec = old_vers;
+ if (!rec) {
+ mem_heap_free(heap);
+ return READ_NOT_FOUND;
+ }
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_TABLES__DB_TRX_ID, &len);
+ if (UNIV_UNLIKELY(len != 6)) {
+ mem_heap_free(heap);
+ return READ_ERROR;
+ }
+ id = trx_read_trx_id(field);
+ }
+
+ if (rec_get_deleted_flag(rec, 0)) {
+ ut_ad(id);
+ if (trx_id) {
+ return READ_NOT_FOUND;
+ }
+ }
+
+ if (trx_id) {
+ *trx_id = id;
+ }
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_TABLES__ID, &len);
@@ -767,8 +809,13 @@ dict_sys_tables_rec_read(
" data dictionary contains invalid flags."
" SYS_TABLES.TYPE=" UINT32PF
" SYS_TABLES.N_COLS=" UINT32PF,
- int(name.size()), name.data(), type, *n_cols);
- return(false);
+ int(rec_get_field_start_offs(rec, 1)), rec,
+ type, *n_cols);
+err_exit:
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+ return READ_ERROR;
}
*flags = dict_sys_tables_type_to_tf(type, not_redundant);
@@ -792,9 +839,10 @@ dict_sys_tables_rec_read(
" contains invalid flags."
" SYS_TABLES.TYPE=" UINT32PF
" SYS_TABLES.MIX_LEN=" UINT32PF,
- int(name.size()), name.data(),
+ int(rec_get_field_start_offs(rec, 1)),
+ rec,
type, *flags2);
- return(false);
+ goto err_exit;
}
/* DICT_TF2_FTS will be set when indexes are being loaded */
@@ -806,7 +854,11 @@ dict_sys_tables_rec_read(
*flags2 = 0;
}
- return(true);
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+
+ return READ_OK;
}
/** Load and check each non-predefined tablespace mentioned in SYS_TABLES.
@@ -842,7 +894,6 @@ static uint32_t dict_check_sys_tables()
continue;
}
- /* Copy the table name from rec */
const char *field = reinterpret_cast<const char*>(
rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__NAME,
&len));
@@ -850,10 +901,9 @@ static uint32_t dict_check_sys_tables()
DBUG_PRINT("dict_check_sys_tables",
("name: %*.s", static_cast<int>(len), field));
- const span<const char> name{field, len};
-
- if (!dict_sys_tables_rec_read(rec, name, &table_id, &space_id,
- &n_cols, &flags, &flags2)
+ if (dict_sys_tables_rec_read(rec, &mtr, &table_id, &space_id,
+ &n_cols, &flags, &flags2, nullptr)
+ != READ_OK
|| space_id == TRX_SYS_SPACE) {
continue;
}
@@ -878,13 +928,18 @@ static uint32_t dict_check_sys_tables()
continue;
}
+ const span<const char> name{field, len};
+
char* filepath = fil_make_filepath(nullptr, name,
IBD, false);
+ const bool not_dropped{!rec_get_deleted_flag(rec, 0)};
+
/* Check that the .ibd file exists. */
- if (fil_ibd_open(false, FIL_TYPE_TABLESPACE,
+ if (fil_ibd_open(not_dropped, FIL_TYPE_TABLESPACE,
space_id, dict_tf_to_fsp_flags(flags),
name, filepath)) {
+ } else if (!not_dropped) {
} else if (srv_operation == SRV_OPERATION_NORMAL
&& srv_start_after_restore
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND
@@ -897,8 +952,7 @@ static uint32_t dict_check_sys_tables()
sql_print_warning("InnoDB: Ignoring tablespace for"
" %.*s because it"
" could not be opened.",
- static_cast<int>(name.size()),
- name.data());
+ static_cast<int>(len), field);
}
max_space_id = ut_max(max_space_id, space_id);
@@ -970,6 +1024,7 @@ dict_load_column_low(
table_id_t* table_id, /*!< out: table id */
const char** col_name, /*!< out: column name */
const rec_t* rec, /*!< in: SYS_COLUMNS record */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
ulint* nth_v_col) /*!< out: if not NULL, this
records the "n" of "nth" virtual
column */
@@ -985,10 +1040,6 @@ dict_load_column_low(
ut_ad(!table == !!column);
- if (rec_get_deleted_flag(rec, 0)) {
- return(dict_load_column_del);
- }
-
if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_COLUMNS) {
return("wrong number of columns in SYS_COLUMNS record");
}
@@ -1020,7 +1071,30 @@ err_len:
goto err_len;
}
- const trx_id_t trx_id = mach_read_from_6(field);
+ const trx_id_t trx_id = trx_read_trx_id(field);
+
+ if (trx_id && mtr && trx_sys.find(nullptr, trx_id, false)) {
+ const auto savepoint = mtr->get_savepoint();
+ dict_index_t* index = UT_LIST_GET_FIRST(
+ dict_sys.sys_columns->indexes);
+ rec_offs* offsets = rec_get_offsets(
+ rec, index, nullptr, true, ULINT_UNDEFINED, &heap);
+ const rec_t* old_vers;
+ row_vers_build_for_semi_consistent_read(
+ nullptr, rec, mtr, index, &offsets, &heap,
+ heap, &old_vers, nullptr);
+ mtr->rollback_to_savepoint(savepoint);
+ rec = old_vers;
+ if (!old_vers) {
+ return dict_load_column_none;
+ }
+ ut_ad(!rec_get_deleted_flag(rec, 0));
+ }
+
+ if (rec_get_deleted_flag(rec, 0)) {
+ ut_ad(trx_id);
+ return dict_load_column_del;
+ }
rec_get_nth_field_offs_old(
rec, DICT_FLD__SYS_COLUMNS__DB_ROLL_PTR, &len);
@@ -1034,11 +1108,7 @@ err_len:
goto err_len;
}
- name = mem_heap_strdupl(heap, (const char*) field, len);
-
- if (col_name) {
- *col_name = name;
- }
+ *col_name = name = mem_heap_strdupl(heap, (const char*) field, len);
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_COLUMNS__MTYPE, &len);
@@ -1153,10 +1223,6 @@ dict_load_virtual_low(
ulint len;
ulint base;
- if (rec_get_deleted_flag(rec, 0)) {
- return(dict_load_virtual_del);
- }
-
if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_VIRTUAL) {
return("wrong number of columns in SYS_VIRTUAL record");
}
@@ -1196,7 +1262,7 @@ err_len:
*base_pos = base;
}
- rec_get_nth_field_offs_old(
+ field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_VIRTUAL__DB_TRX_ID, &len);
if (len != DATA_TRX_ID_LEN && len != UNIV_SQL_NULL) {
goto err_len;
@@ -1208,6 +1274,17 @@ err_len:
goto err_len;
}
+ const trx_id_t trx_id = trx_read_trx_id(field);
+
+ if (trx_id && column && trx_sys.find(nullptr, trx_id, false)) {
+ if (!rec_get_deleted_flag(rec, 0)) {
+ return dict_load_virtual_none;
+ }
+ } else if (rec_get_deleted_flag(rec, 0)) {
+ ut_ad(trx_id != 0);
+ return dict_load_virtual_del;
+ }
+
if (column != NULL) {
*column = dict_table_get_nth_col(table, base);
}
@@ -1272,7 +1349,7 @@ dict_load_columns(
err_msg = btr_pcur_is_on_user_rec(&pcur)
? dict_load_column_low(table, heap, NULL, NULL,
- &name, rec, &nth_v_col)
+ &name, rec, &mtr, &nth_v_col)
: dict_load_column_none;
if (!err_msg) {
@@ -1280,8 +1357,8 @@ dict_load_columns(
n_skipped++;
goto next_rec;
} else if (err_msg == dict_load_column_none
- && strstr(table->name.m_name,
- "/" TEMP_FILE_PREFIX_INNODB)) {
+ && strstr(table->name.m_name,
+ "/" TEMP_FILE_PREFIX_INNODB)) {
break;
} else {
ib::fatal() << err_msg << " for table " << table->name;
@@ -1461,6 +1538,7 @@ dict_load_field_low(
byte* last_index_id, /*!< in: last index id */
mem_heap_t* heap, /*!< in/out: memory heap
for temporary storage */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
const rec_t* rec) /*!< in: SYS_FIELDS record */
{
const byte* field;
@@ -1472,11 +1550,8 @@ dict_load_field_low(
ulint position;
/* Either index or sys_field is supplied, not both */
- ut_a((!index) || (!sys_field));
-
- if (rec_get_deleted_flag(rec, 0)) {
- return(dict_load_field_del);
- }
+ ut_ad((!index) != (!sys_field));
+ ut_ad((!index) == !mtr);
if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_FIELDS) {
return("wrong number of columns in SYS_FIELDS record");
@@ -1532,7 +1607,7 @@ err_len:
position = pos_and_prefix_len & 0xFFFFUL;
}
- rec_get_nth_field_offs_old(
+ field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FIELDS__DB_TRX_ID, &len);
if (len != DATA_TRX_ID_LEN && len != UNIV_SQL_NULL) {
goto err_len;
@@ -1543,6 +1618,31 @@ err_len:
goto err_len;
}
+ const trx_id_t trx_id = trx_read_trx_id(field);
+
+ if (!trx_id) {
+ ut_ad(!rec_get_deleted_flag(rec, 0));
+ } else if (mtr && trx_sys.find(nullptr, trx_id, false)) {
+ const auto savepoint = mtr->get_savepoint();
+ dict_index_t* sys_field = UT_LIST_GET_FIRST(
+ dict_sys.sys_fields->indexes);
+ rec_offs* offsets = rec_get_offsets(
+ rec, sys_field, nullptr, true, ULINT_UNDEFINED, &heap);
+ const rec_t* old_vers;
+ row_vers_build_for_semi_consistent_read(
+ nullptr, rec, mtr, sys_field, &offsets, &heap,
+ heap, &old_vers, nullptr);
+ mtr->rollback_to_savepoint(savepoint);
+ rec = old_vers;
+ if (!old_vers || rec_get_deleted_flag(rec, 0)) {
+ return dict_load_field_none;
+ }
+ }
+
+ if (rec_get_deleted_flag(rec, 0)) {
+ return(dict_load_field_del);
+ }
+
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FIELDS__COL_NAME, &len);
if (len == 0 || len == UNIV_SQL_NULL) {
@@ -1554,9 +1654,6 @@ err_len:
index, mem_heap_strdupl(heap, (const char*) field, len),
prefix_len, descending);
} else {
- ut_a(sys_field);
- ut_a(pos);
-
sys_field->name = mem_heap_strdupl(
heap, (const char*) field, len);
sys_field->prefix_len = prefix_len & ((1U << 12) - 1);
@@ -1608,7 +1705,8 @@ dict_load_fields(
for (i = 0; i < index->n_fields; i++) {
const char *err_msg = btr_pcur_is_on_user_rec(&pcur)
? dict_load_field_low(buf, index, NULL, NULL, NULL,
- heap, btr_pcur_get_rec(&pcur))
+ heap, &mtr,
+ btr_pcur_get_rec(&pcur))
: dict_load_field_none;
if (!err_msg) {
@@ -1647,36 +1745,30 @@ static const char *dict_load_index_none= "SYS_INDEXES record not found";
static const char *dict_load_table_flags= "incorrect flags in SYS_TABLES";
/** Load an index definition from a SYS_INDEXES record to dict_index_t.
-If allocate=TRUE, we will create a dict_index_t structure and fill it
-accordingly. If allocated=FALSE, the dict_index_t will be supplied by
-the caller and filled with information read from the record.
@return error message
@retval NULL on success */
static
const char*
dict_load_index_low(
byte* table_id, /*!< in/out: table id (8 bytes),
- an "in" value if allocate=TRUE
- and "out" when allocate=FALSE */
+ an "in" value if mtr
+ and "out" when !mtr */
mem_heap_t* heap, /*!< in/out: temporary memory heap */
const rec_t* rec, /*!< in: SYS_INDEXES record */
- ibool allocate, /*!< in: TRUE=allocate *index,
- FALSE=fill in a pre-allocated
- *index */
+ mtr_t* mtr, /*!< in/out: mini-transaction,
+ or nullptr if a pre-allocated
+ *index is to be filled in */
+ dict_table_t* table, /*!< in/out: table, or NULL */
dict_index_t** index) /*!< out,own: index, or NULL */
{
const byte* field;
ulint len;
- ulint name_len;
- char* name_buf;
index_id_t id;
ulint n_fields;
ulint type;
unsigned merge_threshold;
- if (allocate) {
- /* If allocate=TRUE, no dict_index_t will
- be supplied. Initialize "*index" to NULL */
+ if (mtr) {
*index = NULL;
}
@@ -1711,7 +1803,7 @@ err_len:
return("incorrect column length in SYS_INDEXES");
}
- if (!allocate) {
+ if (!mtr) {
/* We are reading a SYS_INDEXES record. Copy the table_id */
memcpy(table_id, (const char*) field, 8);
} else if (memcmp(field, table_id, 8)) {
@@ -1728,7 +1820,7 @@ err_len:
id = mach_read_from_8(field);
- rec_get_nth_field_offs_old(
+ field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_INDEXES__DB_TRX_ID, &len);
if (len != DATA_TRX_ID_LEN && len != UNIV_SQL_NULL) {
goto err_len;
@@ -1739,15 +1831,31 @@ err_len:
goto err_len;
}
- field = rec_get_nth_field_old(
- rec, DICT_FLD__SYS_INDEXES__NAME, &name_len);
- if (name_len == 0 || name_len == UNIV_SQL_NULL) {
- goto err_len;
+ const trx_id_t trx_id = trx_read_trx_id(field);
+ if (!trx_id) {
+ ut_ad(!rec_get_deleted_flag(rec, 0));
+ } else if (!mtr) {
+ } else if (trx_sys.find(nullptr, trx_id, false)) {
+ const auto savepoint = mtr->get_savepoint();
+ dict_index_t* sys_index = UT_LIST_GET_FIRST(
+ dict_sys.sys_indexes->indexes);
+ rec_offs* offsets = rec_get_offsets(
+ rec, sys_index, nullptr, true, ULINT_UNDEFINED, &heap);
+ const rec_t* old_vers;
+ row_vers_build_for_semi_consistent_read(
+ nullptr, rec, mtr, sys_index, &offsets, &heap,
+ heap, &old_vers, nullptr);
+ mtr->rollback_to_savepoint(savepoint);
+ rec = old_vers;
+ if (!old_vers || rec_get_deleted_flag(rec, 0)) {
+ return dict_load_index_none;
+ }
+ } else if (rec_get_deleted_flag(rec, 0)
+ && rec[8 + 8 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN]
+ != static_cast<byte>(*TEMP_INDEX_PREFIX_STR)
+ && table->def_trx_id < trx_id) {
+ table->def_trx_id = trx_id;
}
- ut_ad(field == &rec[8 + 8 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN]);
-
- name_buf = mem_heap_strdupl(heap, (const char*) field,
- name_len);
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_INDEXES__N_FIELDS, &len);
@@ -1772,16 +1880,27 @@ err_len:
goto err_len;
}
+ ut_d(const auto name_offs =)
+ rec_get_nth_field_offs_old(rec, DICT_FLD__SYS_INDEXES__NAME, &len);
+ ut_ad(name_offs == 8 + 8 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
+
+ if (len == 0 || len == UNIV_SQL_NULL) {
+ goto err_len;
+ }
+
if (rec_get_deleted_flag(rec, 0)) {
- return(dict_load_index_del);
+ return dict_load_index_del;
}
- if (allocate) {
- *index = dict_mem_index_create(NULL, name_buf, type, n_fields);
- } else {
- ut_a(*index);
+ char* name = mem_heap_strdupl(heap, reinterpret_cast<const char*>(rec)
+ + (8 + 8 + DATA_TRX_ID_LEN
+ + DATA_ROLL_PTR_LEN),
+ len);
- dict_mem_fill_index_struct(*index, NULL, name_buf,
+ if (mtr) {
+ *index = dict_mem_index_create(table, name, type, n_fields);
+ } else {
+ dict_mem_fill_index_struct(*index, nullptr, name,
type, n_fields);
}
@@ -1813,7 +1932,7 @@ dict_load_indexes(
dtuple_t* tuple;
dfield_t* dfield;
const rec_t* rec;
- byte* buf;
+ byte buf[8];
mtr_t mtr;
dberr_t error = DB_SUCCESS;
@@ -1831,7 +1950,6 @@ dict_load_indexes(
tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0);
- buf = static_cast<byte*>(mem_heap_alloc(heap, 8));
mach_write_to_8(buf, table->id);
dfield_set_data(dfield, buf, 8);
@@ -1867,7 +1985,8 @@ dict_load_indexes(
}
}
- err_msg = dict_load_index_low(buf, heap, rec, TRUE, &index);
+ err_msg = dict_load_index_low(buf, heap, rec, &mtr, table,
+ &index);
ut_ad(!index == !!err_msg);
if (err_msg == dict_load_index_none) {
@@ -1877,10 +1996,6 @@ dict_load_indexes(
}
if (err_msg == dict_load_index_del) {
- const trx_id_t id = mach_read_from_6(rec + 8 + 8);
- if (id > table->def_trx_id) {
- table->def_trx_id = id;
- }
goto next_rec;
} else if (err_msg) {
ib::error() << err_msg;
@@ -1893,7 +2008,7 @@ dict_load_indexes(
== static_cast<byte>(*TEMP_INDEX_PREFIX_STR)) {
goto next_rec;
} else {
- const trx_id_t id = mach_read_from_6(rec + 8 + 8);
+ const trx_id_t id = trx_read_trx_id(rec + 8 + 8);
if (id > table->def_trx_id) {
table->def_trx_id = id;
}
@@ -1955,7 +2070,6 @@ corrupted:
dictionary cache for such metadata corruption,
since we would always be able to set it
when loading the dictionary cache */
- index->table = table;
dict_set_corrupted_index_cache_only(index);
} else if (!dict_index_is_clust(index)
&& NULL == dict_table_get_first_index(table)) {
@@ -1974,7 +2088,6 @@ corrupted:
of the database server */
dict_mem_index_free(index);
} else {
- index->table = table;
dict_load_fields(index, heap);
/* The data dictionary tables should never contain
@@ -2036,114 +2149,64 @@ func_exit:
/** Load a table definition from a SYS_TABLES record to dict_table_t.
Do not load any columns or indexes.
-@param[in] name Table name
+@param[in,out] mtr mini-transaction
@param[in] rec SYS_TABLES record
@param[out,own] table table, or nullptr
@return error message
@retval nullptr on success */
-const char *dict_load_table_low(const span<const char> &name,
+const char *dict_load_table_low(mtr_t *mtr,
const rec_t *rec, dict_table_t **table)
{
table_id_t table_id;
uint32_t space_id, t_num, flags, flags2;
ulint n_cols, n_v_col;
+ trx_id_t trx_id;
if (const char* error_text = dict_sys_tables_rec_check(rec)) {
*table = NULL;
return(error_text);
}
- if (!dict_sys_tables_rec_read(rec, name, &table_id, &space_id,
- &t_num, &flags, &flags2)) {
+ if (auto r = dict_sys_tables_rec_read(rec, mtr, &table_id, &space_id,
+ &t_num, &flags, &flags2,
+ &trx_id)) {
*table = NULL;
- return(dict_load_table_flags);
+ return r == READ_ERROR ? dict_load_table_flags : nullptr;
}
dict_table_decode_n_col(t_num, &n_cols, &n_v_col);
- *table = dict_table_t::create(name, nullptr, n_cols + n_v_col,
- n_v_col, flags, flags2);
+ *table = dict_table_t::create(
+ span<const char>(reinterpret_cast<const char*>(rec),
+ rec_get_field_start_offs(rec, 1)),
+ nullptr, n_cols + n_v_col, n_v_col, flags, flags2);
(*table)->space_id = space_id;
(*table)->id = table_id;
(*table)->file_unreadable = !!(flags2 & DICT_TF2_DISCARDED);
-
- ulint len;
- (*table)->def_trx_id = mach_read_from_6(
- rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__DB_TRX_ID,
- &len));
- ut_ad(len == DATA_TRX_ID_LEN);
- static_assert(DATA_TRX_ID_LEN == 6, "compatibility");
+ (*table)->def_trx_id = trx_id;
return(NULL);
}
-/********************************************************************//**
-Using the table->heap, copy the null-terminated filepath into
-table->data_dir_path and replace the 'databasename/tablename.ibd'
-portion with 'tablename'.
-This allows SHOW CREATE TABLE to return the correct DATA DIRECTORY path.
-Make this data directory path only if it has not yet been saved. */
-static
-void
-dict_save_data_dir_path(
-/*====================*/
- dict_table_t* table, /*!< in/out: table */
- const char* filepath) /*!< in: filepath of tablespace */
-{
- ut_ad(dict_sys.frozen());
- ut_a(DICT_TF_HAS_DATA_DIR(table->flags));
-
- ut_a(!table->data_dir_path);
- ut_a(filepath);
-
- /* Be sure this filepath is not the default filepath. */
- if (char* default_filepath = fil_make_filepath(nullptr, table->name,
- IBD, false)) {
- if (0 != strcmp(filepath, default_filepath)) {
- ulint pathlen = strlen(filepath);
- ut_a(pathlen < OS_FILE_MAX_PATH);
- ut_a(0 == strcmp(filepath + pathlen - 4, DOT_IBD));
-
- table->data_dir_path = mem_heap_strdup(
- table->heap, filepath);
- os_file_make_data_dir_path(table->data_dir_path);
- }
-
- ut_free(default_filepath);
- }
-}
-
/** Make sure the data_file_name is saved in dict_table_t if needed.
-@param[in,out] table Table object
-@param[in] dict_locked dict_sys.frozen() */
-void dict_get_and_save_data_dir_path(dict_table_t* table, bool dict_locked)
+@param[in,out] table Table object */
+void dict_get_and_save_data_dir_path(dict_table_t *table)
{
- ut_ad(!table->is_temporary());
- ut_ad(!table->space || table->space->id == table->space_id);
-
- if (!table->data_dir_path && table->space_id && table->space) {
- if (!dict_locked) {
- dict_sys.freeze(SRW_LOCK_CALL);
- }
+ ut_ad(!table->is_temporary());
+ ut_ad(!table->space || table->space->id == table->space_id);
- table->flags |= 1 << DICT_TF_POS_DATA_DIR
- & ((1U << DICT_TF_BITS) - 1);
- dict_save_data_dir_path(table,
- table->space->chain.start->name);
-
- if (table->data_dir_path == NULL) {
- /* Since we did not set the table data_dir_path,
- unset the flag. This does not change
- SYS_TABLES or FSP_SPACE_FLAGS on the header page
- of the tablespace, but it makes dict_table_t
- consistent. */
- table->flags &= ~DICT_TF_MASK_DATA_DIR
- & ((1U << DICT_TF_BITS) - 1);
- }
-
- if (!dict_locked) {
- dict_sys.unfreeze();
- }
- }
+ if (!table->data_dir_path && table->space_id && table->space)
+ {
+ const char *filepath= table->space->chain.start->name;
+ if (strncmp(fil_path_to_mysql_datadir, filepath,
+ strlen(fil_path_to_mysql_datadir)))
+ {
+ table->lock_mutex_lock();
+ table->flags|= 1 << DICT_TF_POS_DATA_DIR & ((1U << DICT_TF_BITS) - 1);
+ table->data_dir_path= mem_heap_strdup(table->heap, filepath);
+ os_file_make_data_dir_path(table->data_dir_path);
+ table->lock_mutex_unlock();
+ }
+ }
}
/** Opens a tablespace for dict_load_table_one()
@@ -2197,7 +2260,7 @@ dict_load_tablespace(
char* filepath = NULL;
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
/* This will set table->data_dir_path from fil_system */
- dict_get_and_save_data_dir_path(table, true);
+ dict_get_and_save_data_dir_path(table);
if (table->data_dir_path) {
filepath = fil_make_filepath(
@@ -2206,7 +2269,7 @@ dict_load_tablespace(
}
table->space = fil_ibd_open(
- true, FIL_TYPE_TABLESPACE, table->space_id,
+ 2, FIL_TYPE_TABLESPACE, table->space_id,
dict_tf_to_fsp_flags(table->flags),
{table->name.m_name, strlen(table->name.m_name)}, filepath);
@@ -2244,8 +2307,6 @@ static dict_table_t *dict_load_table_one(const span<const char> &name,
mem_heap_t* heap;
dfield_t* dfield;
const rec_t* rec;
- const byte* field;
- ulint len;
mtr_t mtr;
DBUG_ENTER("dict_load_table_one");
@@ -2281,8 +2342,7 @@ static dict_table_t *dict_load_table_one(const span<const char> &name,
BTR_SEARCH_LEAF, &pcur, &mtr);
rec = btr_pcur_get_rec(&pcur);
- if (!btr_pcur_is_on_user_rec(&pcur)
- || rec_get_deleted_flag(rec, 0)) {
+ if (!btr_pcur_is_on_user_rec(&pcur)) {
/* Not found */
err_exit:
btr_pcur_close(&pcur);
@@ -2292,21 +2352,22 @@ err_exit:
DBUG_RETURN(NULL);
}
- field = rec_get_nth_field_old(
- rec, DICT_FLD__SYS_TABLES__NAME, &len);
-
/* Check if the table name in record is the searched one */
- if (len != name.size() || memcmp(name.data(), field, len)) {
+ if (rec_get_field_start_offs(rec, 1) != name.size()
+ || memcmp(name.data(), rec, name.size())) {
goto err_exit;
}
dict_table_t* table;
- if (const char* err_msg = dict_load_table_low(name, rec, &table)) {
+ if (const char* err_msg = dict_load_table_low(&mtr, rec, &table)) {
if (err_msg != dict_load_table_flags) {
ib::error() << err_msg;
}
goto err_exit;
}
+ if (!table) {
+ goto err_exit;
+ }
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -2339,7 +2400,7 @@ err_exit:
err = dict_load_indexes(table, heap, index_load_err);
- if (err == DB_INDEX_CORRUPT) {
+ if (err == DB_INDEX_CORRUPT || !UT_LIST_GET_FIRST(table->indexes)) {
/* Refuse to load the table if the table has a corrupted
cluster index */
ut_ad(index_load_err != DICT_ERR_IGNORE_DROP);
@@ -2410,9 +2471,8 @@ corrupted:
if (!table->is_readable()) {
/* Don't attempt to load the indexes from disk. */
} else if (err == DB_SUCCESS) {
- err = dict_load_foreigns(table->name.m_name, NULL,
- true, true,
- ignore_err, fk_tables);
+ err = dict_load_foreigns(table->name.m_name, nullptr,
+ 0, true, ignore_err, fk_tables);
if (err != DB_SUCCESS) {
ib::warn() << "Load table " << table->name
@@ -2534,11 +2594,16 @@ check_rec:
/* Check if the table id in record is the one searched for */
if (table_id == mach_read_from_8(field)) {
- if (rec_get_deleted_flag(rec, 0)) {
- /* Until purge has completed, there
- may be delete-marked duplicate records
- for the same SYS_TABLES.ID, but different
- SYS_TABLES.NAME. */
+ field = rec_get_nth_field_old(rec,
+ DICT_FLD__SYS_TABLE_IDS__NAME, &len);
+ table = dict_sys.load_table(
+ {reinterpret_cast<const char*>(field),
+ len}, ignore_err);
+ if (table && table->id != table_id) {
+ ut_ad(rec_get_deleted_flag(rec, 0));
+ table = nullptr;
+ }
+ if (!table) {
while (btr_pcur_move_to_next(&pcur, &mtr)) {
rec = btr_pcur_get_rec(&pcur);
@@ -2546,13 +2611,6 @@ check_rec:
goto check_rec;
}
}
- } else {
- /* Now we get the table name from the record */
- field = rec_get_nth_field_old(rec,
- DICT_FLD__SYS_TABLE_IDS__NAME, &len);
- table = dict_sys.load_table(
- {reinterpret_cast<const char*>(field),
- len}, ignore_err);
}
}
}
@@ -2593,11 +2651,7 @@ Members that will be created and set by this function:
foreign->foreign_col_names[i]
foreign->referenced_col_names[i]
(for i=0..foreign->n_fields-1) */
-static
-void
-dict_load_foreign_cols(
-/*===================*/
- dict_foreign_t* foreign)/*!< in/out: foreign constraint object */
+static void dict_load_foreign_cols(dict_foreign_t *foreign, trx_id_t trx_id)
{
btr_pcur_t pcur;
dtuple_t* tuple;
@@ -2632,14 +2686,47 @@ dict_load_foreign_cols(
dfield_set_data(dfield, foreign->id, id_len);
dict_index_copy_types(tuple, sys_index, 1);
+ mem_heap_t* heap = nullptr;
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr);
for (i = 0; i < foreign->n_fields; i++) {
+retry:
+ ut_a(btr_pcur_is_on_user_rec(&pcur));
rec = btr_pcur_get_rec(&pcur);
- ut_a(btr_pcur_is_on_user_rec(&pcur));
- ut_a(!rec_get_deleted_flag(rec, 0));
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_FOREIGN_COLS__DB_TRX_ID, &len);
+ ut_a(len == DATA_TRX_ID_LEN);
+
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_empty(heap);
+ }
+
+ const trx_id_t id = trx_read_trx_id(field);
+ if (!id) {
+ } else if (id != trx_id && trx_sys.find(nullptr, id, false)) {
+ const auto savepoint = mtr.get_savepoint();
+ rec_offs* offsets = rec_get_offsets(
+ rec, sys_index, nullptr, true, ULINT_UNDEFINED,
+ &heap);
+ const rec_t* old_vers;
+ row_vers_build_for_semi_consistent_read(
+ nullptr, rec, &mtr, sys_index, &offsets, &heap,
+ heap, &old_vers, nullptr);
+ mtr.rollback_to_savepoint(savepoint);
+ rec = old_vers;
+ if (!rec || rec_get_deleted_flag(rec, 0)) {
+ goto next;
+ }
+ }
+
+ if (rec_get_deleted_flag(rec, 0)) {
+ ut_ad(id);
+next:
+ btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+ goto retry;
+ }
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN_COLS__ID, &len);
@@ -2700,23 +2787,26 @@ dict_load_foreign_cols(
}
btr_pcur_close(&pcur);
- mtr_commit(&mtr);
+ mtr.commit();
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
}
/***********************************************************************//**
Loads a foreign key constraint to the dictionary cache. If the referenced
table is not yet loaded, it is added in the output parameter (fk_tables).
@return DB_SUCCESS or error code */
-static MY_ATTRIBUTE((nonnull(1), warn_unused_result))
+static MY_ATTRIBUTE((warn_unused_result))
dberr_t
dict_load_foreign(
/*==============*/
- const char* id,
- /*!< in: foreign constraint id, must be
- '\0'-terminated */
+ const char* table_name, /*!< in: table name */
const char** col_names,
/*!< in: column names, or NULL
to use foreign->foreign_table->col_names */
+ trx_id_t trx_id,
+ /*!< in: current transaction id, or 0 */
bool check_recursive,
/*!< in: whether to record the foreign table
parent count to avoid unlimited recursive
@@ -2724,6 +2814,8 @@ dict_load_foreign(
bool check_charsets,
/*!< in: whether to check charset
compatibility */
+ span<const char> id,
+ /*!< in: foreign constraint id */
dict_err_ignore_t ignore_err,
/*!< in: error to be ignored */
dict_names_t& fk_tables)
@@ -2736,81 +2828,82 @@ dict_load_foreign(
{
dict_foreign_t* foreign;
btr_pcur_t pcur;
- dtuple_t* tuple;
- mem_heap_t* heap2;
- dfield_t* dfield;
- const rec_t* rec;
const byte* field;
ulint len;
mtr_t mtr;
dict_table_t* for_table;
dict_table_t* ref_table;
- size_t id_len;
+ byte dtuple_buf[DTUPLE_EST_ALLOC(1)];
DBUG_ENTER("dict_load_foreign");
DBUG_PRINT("dict_load_foreign",
- ("id: '%s', check_recursive: %d", id, check_recursive));
+ ("id: '%.*s', check_recursive: %d",
+ int(id.size()), id.data(), check_recursive));
ut_ad(dict_sys.locked());
- id_len = strlen(id);
-
- heap2 = mem_heap_create(1000);
-
- mtr_start(&mtr);
-
dict_index_t* sys_index = dict_sys.sys_foreign->indexes.start;
ut_ad(!dict_sys.sys_foreign->not_redundant());
- tuple = dtuple_create(heap2, 1);
- dfield = dtuple_get_nth_field(tuple, 0);
-
- dfield_set_data(dfield, id, id_len);
+ dtuple_t* tuple = dtuple_create_from_mem(dtuple_buf, sizeof dtuple_buf,
+ 1, 0);
+ dfield_set_data(dtuple_get_nth_field(tuple, 0), id.data(), id.size());
dict_index_copy_types(tuple, sys_index, 1);
+ mtr.start();
+
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr);
- rec = btr_pcur_get_rec(&pcur);
-
- if (!btr_pcur_is_on_user_rec(&pcur)
- || rec_get_deleted_flag(rec, 0)) {
- /* Not found */
-
- ib::error() << "Cannot load foreign constraint " << id
- << ": could not find the relevant record in "
- "SYS_FOREIGN";
+ const rec_t* rec = btr_pcur_get_rec(&pcur);
+ mem_heap_t* heap = nullptr;
+ if (!btr_pcur_is_on_user_rec(&pcur)) {
+ not_found:
btr_pcur_close(&pcur);
- mtr_commit(&mtr);
- mem_heap_free(heap2);
-
- DBUG_RETURN(DB_ERROR);
+ mtr.commit();
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+ DBUG_RETURN(DB_NOT_FOUND);
}
+ static_assert(DICT_FLD__SYS_FOREIGN__ID == 0, "compatibility");
field = rec_get_nth_field_old(rec, DICT_FLD__SYS_FOREIGN__ID, &len);
/* Check if the id in record is the searched one */
- if (len != id_len || memcmp(id, field, len)) {
- {
- ib::error err;
- err << "Cannot load foreign constraint " << id
- << ": found ";
- err.write(field, len);
- err << " instead in SYS_FOREIGN";
- }
+ if (len != id.size() || memcmp(id.data(), field, id.size())) {
+ goto not_found;
+ }
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
- mem_heap_free(heap2);
+ field = rec_get_nth_field_old(
+ rec, DICT_FLD__SYS_FOREIGN__DB_TRX_ID, &len);
+ ut_a(len == DATA_TRX_ID_LEN);
+
+ const trx_id_t tid = trx_read_trx_id(field);
+
+ if (tid && tid != trx_id && trx_sys.find(nullptr, tid, false)) {
+ const auto savepoint = mtr.get_savepoint();
+ rec_offs* offsets = rec_get_offsets(
+ rec, sys_index, nullptr, true, ULINT_UNDEFINED, &heap);
+ const rec_t* old_vers;
+ row_vers_build_for_semi_consistent_read(
+ nullptr, rec, &mtr, sys_index, &offsets, &heap,
+ heap, &old_vers, nullptr);
+ mtr.rollback_to_savepoint(savepoint);
+ rec = old_vers;
+ if (!rec) {
+ goto not_found;
+ }
+ }
- DBUG_RETURN(DB_ERROR);
+ if (rec_get_deleted_flag(rec, 0)) {
+ ut_ad(tid);
+ goto not_found;
}
/* Read the table names and the number of columns associated
with the constraint */
- mem_heap_free(heap2);
-
foreign = dict_mem_foreign_create();
uint32_t n_fields_and_type = mach_read_from_4(
@@ -2824,7 +2917,7 @@ dict_load_foreign(
foreign->type = (n_fields_and_type >> 24) & ((1U << 6) - 1);
foreign->n_fields = n_fields_and_type & dict_index_t::MAX_N_FIELDS;
- foreign->id = mem_heap_strdupl(foreign->heap, id, id_len);
+ foreign->id = mem_heap_strdupl(foreign->heap, id.data(), id.size());
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN__FOR_NAME, &len);
@@ -2833,18 +2926,34 @@ dict_load_foreign(
foreign->heap, (char*) field, len);
dict_mem_foreign_table_name_lookup_set(foreign, TRUE);
- const ulint foreign_table_name_len = len;
+ const size_t foreign_table_name_len = len;
+ const size_t table_name_len = strlen(table_name);
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN__REF_NAME, &len);
+
+ if (!my_charset_latin1.strnncoll(table_name, table_name_len,
+ foreign->foreign_table_name,
+ foreign_table_name_len)) {
+ } else if (!check_recursive
+ && !my_charset_latin1.strnncoll(table_name, table_name_len,
+ (const char*) field, len)) {
+ } else {
+ dict_foreign_free(foreign);
+ goto not_found;
+ }
+
foreign->referenced_table_name = mem_heap_strdupl(
- foreign->heap, (char*) field, len);
+ foreign->heap, (const char*) field, len);
dict_mem_referenced_table_name_lookup_set(foreign, TRUE);
btr_pcur_close(&pcur);
- mtr_commit(&mtr);
+ mtr.commit();
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
- dict_load_foreign_cols(foreign);
+ dict_load_foreign_cols(foreign, trx_id);
ref_table = dict_sys.find_table(
{foreign->referenced_table_name_lookup,
@@ -2899,7 +3008,8 @@ dict_load_foreigns(
const char* table_name, /*!< in: table name */
const char** col_names, /*!< in: column names, or NULL
to use table->col_names */
- bool check_recursive,/*!< in: Whether to check
+ trx_id_t trx_id, /*!< in: DDL transaction id,
+ or 0 to check
recursive load of tables
chained by FK */
bool check_charsets, /*!< in: whether to check
@@ -2916,10 +3026,6 @@ dict_load_foreigns(
btr_pcur_t pcur;
dtuple_t* tuple;
dfield_t* dfield;
- const rec_t* rec;
- const byte* field;
- ulint len;
- dberr_t err;
mtr_t mtr;
DBUG_ENTER("dict_load_foreigns");
@@ -2936,12 +3042,14 @@ dict_load_foreigns(
}
ut_ad(!dict_sys.sys_foreign->not_redundant());
- mtr_start(&mtr);
dict_index_t *sec_index = dict_table_get_next_index(
dict_table_get_first_index(dict_sys.sys_foreign));
ut_ad(!strcmp(sec_index->fields[0].name, "FOR_NAME"));
+ bool check_recursive = !trx_id;
+
start_load:
+ mtr.start();
tuple = dtuple_create_from_mem(tuple_buf, sizeof(tuple_buf), 1, 0);
dfield = dtuple_get_nth_field(tuple, 0);
@@ -2952,7 +3060,9 @@ start_load:
btr_pcur_open_on_user_rec(sec_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr);
loop:
- rec = btr_pcur_get_rec(&pcur);
+ const rec_t* rec = btr_pcur_get_rec(&pcur);
+ const byte* field;
+ const auto maybe_deleted = rec_get_deleted_flag(rec, 0);
if (!btr_pcur_is_on_user_rec(&pcur)) {
/* End of index */
@@ -2963,6 +3073,7 @@ loop:
/* Now we have the record in the secondary index containing a table
name and a foreign constraint ID */
+ ulint len;
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN_FOR_NAME__NAME, &len);
@@ -2986,10 +3097,6 @@ loop:
may not be the same case, but the previous comparison showed that they
match with no-case. */
- if (rec_get_deleted_flag(rec, 0)) {
- goto next_rec;
- }
-
if (lower_case_table_names != 2 && memcmp(field, table_name, len)) {
goto next_rec;
}
@@ -3004,26 +3111,33 @@ loop:
ut_a(len <= MAX_TABLE_NAME_LEN);
memcpy(fk_id, field, len);
- fk_id[len] = '\0';
btr_pcur_store_position(&pcur, &mtr);
- mtr_commit(&mtr);
+ mtr.commit();
/* Load the foreign constraint definition to the dictionary cache */
- err = dict_load_foreign(fk_id, col_names,
- check_recursive, check_charsets, ignore_err,
- fk_tables);
-
- if (err != DB_SUCCESS) {
+ switch (dberr_t err
+ = dict_load_foreign(table_name, col_names, trx_id,
+ check_recursive, check_charsets,
+ {fk_id, len}, ignore_err, fk_tables)) {
+ case DB_SUCCESS:
+ break;
+ case DB_NOT_FOUND:
+ if (maybe_deleted) {
+ break;
+ }
+ sql_print_error("InnoDB: Cannot load foreign constraint %.*s:"
+ " could not find the relevant record in "
+ "SYS_FOREIGN", int(len), fk_id);
+ /* fall through */
+ default:
btr_pcur_close(&pcur);
-
DBUG_RETURN(err);
}
- mtr_start(&mtr);
-
+ mtr.start();
pcur.restore_position(BTR_SEARCH_LEAF, &mtr);
next_rec:
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
@@ -3036,15 +3150,11 @@ load_next_index:
sec_index = dict_table_get_next_index(sec_index);
- if (sec_index != NULL) {
-
- mtr_start(&mtr);
-
+ if (sec_index) {
/* Switch to scan index on REF_NAME, fk_max_recusive_level
already been updated when scanning FOR_NAME index, no need to
update again */
- check_recursive = FALSE;
-
+ check_recursive = false;
goto start_load;
}
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 329d2bdd179..b9f653b4f09 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1718,9 +1718,10 @@ char* fil_make_filepath(const char *path, const fil_space_t::name_type &name,
if (path != NULL) {
memcpy(full_name, path, path_len);
len = path_len;
- full_name[len] = '\0';
}
+ full_name[len] = '\0';
+
if (trim_name) {
/* Find the offset of the last DIR separator and set it to
null in order to strip off the old basename from this path. */
@@ -2078,7 +2079,7 @@ a remote tablespace is found it will be changed to true.
If the fix_dict boolean is set, then it is safe to use an internal SQL
statement to update the dictionary tables if they are incorrect.
-@param[in] validate true if we should validate the tablespace
+@param[in] validate 0=maybe missing, 1=do not validate, 2=validate
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
@param[in] id tablespace ID
@param[in] flags expected FSP_SPACE_FLAGS
@@ -2090,7 +2091,7 @@ If file-per-table, it is the table name in the databasename/tablename format
@retval NULL if the tablespace could not be opened */
fil_space_t*
fil_ibd_open(
- bool validate,
+ unsigned validate,
fil_type_t purpose,
uint32_t id,
uint32_t flags,
@@ -2102,7 +2103,7 @@ fil_ibd_open(
fil_space_t* space = fil_space_get_by_id(id);
mysql_mutex_unlock(&fil_system.mutex);
if (space) {
- if (validate && !srv_read_only_mode) {
+ if (validate > 1 && !srv_read_only_mode) {
fsp_flags_try_adjust(space,
flags & ~FSP_FLAGS_MEM_MASK);
}
@@ -2139,8 +2140,9 @@ func_exit:
/* Look for a filepath embedded in an ISL where the default file
would be. */
- if (df_remote.open_link_file(name)) {
- validate = true;
+ bool must_validate = df_remote.open_link_file(name);
+
+ if (must_validate) {
if (df_remote.open_read_only(true) == DB_SUCCESS) {
ut_ad(df_remote.is_open());
++tablespaces_found;
@@ -2153,15 +2155,12 @@ func_exit:
<< df_remote.filepath()
<< "' could not be opened read-only.";
}
- }
-
- /* Attempt to open the tablespace at the dictionary filepath. */
- if (path_in) {
- if (!df_default.same_filepath_as(path_in)) {
- /* Dict path is not the default path. Always validate
- remote files. If default is opened, it was moved. */
- validate = true;
- }
+ } else if (path_in && !df_default.same_filepath_as(path_in)) {
+ /* Dict path is not the default path. Always validate
+ remote files. If default is opened, it was moved. */
+ must_validate = true;
+ } else if (validate > 1) {
+ must_validate = true;
}
/* Always look for a file at the default location. But don't log
@@ -2173,7 +2172,7 @@ func_exit:
the first server startup. The tables ought to be dropped by
drop_garbage_tables_after_restore() a little later. */
- const bool strict = !tablespaces_found
+ const bool strict = validate && !tablespaces_found
&& !(srv_operation == SRV_OPERATION_NORMAL
&& srv_start_after_restore
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND
@@ -2199,7 +2198,7 @@ func_exit:
normal, we only found 1. */
/* For encrypted tablespace, we need to check the
encryption in header of first page. */
- if (!validate && tablespaces_found == 1) {
+ if (!must_validate && tablespaces_found == 1) {
goto skip_validate;
}
@@ -2215,7 +2214,8 @@ func_exit:
First, bail out if no tablespace files were found. */
if (valid_tablespaces_found == 0) {
if (!strict
- && IF_WIN(GetLastError() == ERROR_FILE_NOT_FOUND,
+ && IF_WIN(GetLastError() == ERROR_FILE_NOT_FOUND
+ || GetLastError() == ERROR_PATH_NOT_FOUND,
errno == ENOENT)) {
/* Suppress a message about a missing file. */
goto corrupted;
@@ -2228,7 +2228,7 @@ func_exit:
TROUBLESHOOT_DATADICT_MSG);
goto corrupted;
}
- if (!validate) {
+ if (!must_validate) {
goto skip_validate;
}
@@ -2311,7 +2311,7 @@ skip_validate:
df_remote.is_open() ? df_remote.filepath() :
df_default.filepath(), OS_FILE_CLOSED, 0, false, true);
- if (validate && !srv_read_only_mode) {
+ if (must_validate && !srv_read_only_mode) {
df_remote.close();
df_default.close();
if (space->acquire()) {
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index c7004e0c8e8..31c97ffcf42 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1567,10 +1567,13 @@ static void fts_table_no_ref_count(const char *table_name)
/** Stop the purge thread and check n_ref_count of all auxiliary
and common table associated with the fts table.
-@param table parent FTS table */
-void purge_sys_t::stop_FTS(const dict_table_t &table)
+@param table parent FTS table
+@param already_stopped True indicates purge threads were
+ already stopped*/
+void purge_sys_t::stop_FTS(const dict_table_t &table, bool already_stopped)
{
- purge_sys.stop_FTS();
+ if (!already_stopped)
+ purge_sys.stop_FTS();
fts_table_t fts_table;
char table_name[MAX_FULL_NAME_LEN];
@@ -2216,9 +2219,7 @@ fts_trx_table_create(
fts_trx_table_t* ftt;
ftt = static_cast<fts_trx_table_t*>(
- mem_heap_alloc(fts_trx->heap, sizeof(*ftt)));
-
- memset(ftt, 0x0, sizeof(*ftt));
+ mem_heap_zalloc(fts_trx->heap, sizeof *ftt));
ftt->table = table;
ftt->fts_trx = fts_trx;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index f1adfbe83a5..dab8d63f912 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -11361,7 +11361,7 @@ ha_innobase::update_create_info(
return;
}
- dict_get_and_save_data_dir_path(m_prebuilt->table, false);
+ dict_get_and_save_data_dir_path(m_prebuilt->table);
if (m_prebuilt->table->data_dir_path) {
create_info->data_file_name = m_prebuilt->table->data_dir_path;
@@ -12729,7 +12729,8 @@ int create_table_info_t::create_table(bool create_fk)
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
dict_names_t fk_tables;
- err = dict_load_foreigns(m_table_name, NULL, false, true,
+ err = dict_load_foreigns(m_table_name, nullptr,
+ m_trx->id, true,
DICT_ERR_IGNORE_NONE, fk_tables);
while (err == DB_SUCCESS && !fk_tables.empty()) {
dict_sys.load_table(
@@ -13181,9 +13182,7 @@ ha_innobase::create(
}
if (error) {
- /* Drop the being-created table before rollback,
- so that rollback can possibly rename back a table
- that could have been renamed before the failed creation. */
+ /* Rollback will drop the being-created table. */
trx_rollback_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
} else {
@@ -13483,29 +13482,26 @@ int ha_innobase::delete_table(const char *name)
dict_sys.unfreeze();
}
- auto &timeout= THDVAR(thd, lock_wait_timeout);
- const auto save_timeout= timeout;
- if (table->name.is_temporary())
- timeout= 0;
+ const bool skip_wait{table->name.is_temporary()};
if (table_stats && index_stats &&
!strcmp(table_stats->name.m_name, TABLE_STATS_NAME) &&
!strcmp(index_stats->name.m_name, INDEX_STATS_NAME) &&
- !(err= lock_table_for_trx(table_stats, trx, LOCK_X)))
- err= lock_table_for_trx(index_stats, trx, LOCK_X);
+ !(err= lock_table_for_trx(table_stats, trx, LOCK_X, skip_wait)))
+ err= lock_table_for_trx(index_stats, trx, LOCK_X, skip_wait);
- if (err != DB_SUCCESS && !timeout)
+ if (err != DB_SUCCESS && skip_wait)
{
/* We may skip deleting statistics if we cannot lock the tables,
when the table carries a temporary name. */
+ ut_ad(err == DB_LOCK_WAIT);
+ ut_ad(trx->error_state == DB_SUCCESS);
err= DB_SUCCESS;
dict_table_close(table_stats, false, thd, mdl_table);
dict_table_close(index_stats, false, thd, mdl_index);
table_stats= nullptr;
index_stats= nullptr;
}
-
- timeout= save_timeout;
}
if (err == DB_SUCCESS)
@@ -13778,7 +13774,7 @@ int ha_innobase::truncate()
mem_heap_t* heap = mem_heap_create(1000);
- dict_get_and_save_data_dir_path(ib_table, false);
+ 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);
@@ -14011,17 +14007,15 @@ ha_innobase::rename_table(
if (error == DB_SUCCESS && table_stats && index_stats
&& !strcmp(table_stats->name.m_name, TABLE_STATS_NAME)
&& !strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) {
- auto &timeout = THDVAR(thd, lock_wait_timeout);
- const auto save_timeout = timeout;
- if (from_temp) {
- timeout = 0;
- }
- error = lock_table_for_trx(table_stats, trx, LOCK_X);
+ error = lock_table_for_trx(table_stats, trx, LOCK_X,
+ from_temp);
if (error == DB_SUCCESS) {
error = lock_table_for_trx(index_stats, trx,
- LOCK_X);
+ LOCK_X, from_temp);
}
if (error != DB_SUCCESS && from_temp) {
+ ut_ad(error == DB_LOCK_WAIT);
+ ut_ad(trx->error_state == DB_SUCCESS);
error = DB_SUCCESS;
/* We may skip renaming statistics if
we cannot lock the tables, when the
@@ -14034,7 +14028,6 @@ ha_innobase::rename_table(
table_stats = nullptr;
index_stats = nullptr;
}
- timeout = save_timeout;
}
}
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 703e4379d8c..ab2e837d5f0 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -9749,7 +9749,7 @@ innobase_update_foreign_cache(
dict_names_t fk_tables;
err = dict_load_foreigns(user_table->name.m_name,
- ctx->col_names, false, true,
+ ctx->col_names, 1, true,
DICT_ERR_IGNORE_NONE,
fk_tables);
@@ -9760,7 +9760,7 @@ innobase_update_foreign_cache(
loaded with "foreign_key checks" off,
so let's retry the loading with charset_check is off */
err = dict_load_foreigns(user_table->name.m_name,
- ctx->col_names, false, false,
+ ctx->col_names, 1, false,
DICT_ERR_IGNORE_NONE,
fk_tables);
@@ -10922,12 +10922,14 @@ ha_innobase::commit_inplace_alter_table(
}
}
+ bool already_stopped= false;
for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) {
auto ctx = static_cast<ha_innobase_inplace_ctx*>(*pctx);
dberr_t error = DB_SUCCESS;
if (fts_exist) {
- purge_sys.stop_FTS(*ctx->old_table);
+ purge_sys.stop_FTS(*ctx->old_table, already_stopped);
+ already_stopped = true;
}
if (new_clustered && ctx->old_table->fts) {
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 175b07551b0..97f7013465c 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -4808,12 +4808,13 @@ i_s_dict_fill_sys_tables(
/** Convert one SYS_TABLES record to dict_table_t.
@param pcur persistent cursor position on SYS_TABLES record
+@param mtr mini-transaction (nullptr=use the dict_sys cache)
@param rec record to read from (nullptr=use the dict_sys cache)
@param table the converted dict_table_t
@return error message
@retval nullptr on success */
-static const char *i_s_sys_tables_rec(const btr_pcur_t &pcur, const rec_t *rec,
- dict_table_t **table)
+static const char *i_s_sys_tables_rec(const btr_pcur_t &pcur, mtr_t *mtr,
+ const rec_t *rec, dict_table_t **table)
{
static_assert(DICT_FLD__SYS_TABLES__NAME == 0, "compatibility");
size_t len;
@@ -4831,12 +4832,11 @@ static const char *i_s_sys_tables_rec(const btr_pcur_t &pcur, const rec_t *rec,
return "corrupted SYS_TABLES.NAME";
}
- const span<const char>name{reinterpret_cast<const char*>(pcur.old_rec), len};
-
if (rec)
- return dict_load_table_low(name, rec, table);
+ return dict_load_table_low(mtr, rec, table);
- *table= dict_sys.load_table(name);
+ *table= dict_sys.load_table
+ (span<const char>{reinterpret_cast<const char*>(pcur.old_rec), len});
return *table ? nullptr : "Table not found in cache";
}
@@ -4878,7 +4878,7 @@ i_s_sys_tables_fill_table(
/* Create and populate a dict_table_t structure with
information from SYS_TABLES row */
- err_msg = i_s_sys_tables_rec(pcur, rec, &table_rec);
+ err_msg = i_s_sys_tables_rec(pcur, &mtr, rec, &table_rec);
mtr.commit();
dict_sys.unlock();
@@ -5116,7 +5116,8 @@ i_s_sys_tables_fill_table_stats(
mtr.commit();
/* Fetch the dict_table_t structure corresponding to
this SYS_TABLES record */
- err_msg = i_s_sys_tables_rec(pcur, nullptr, &table_rec);
+ err_msg = i_s_sys_tables_rec(pcur, nullptr, nullptr,
+ &table_rec);
if (UNIV_LIKELY(!err_msg)) {
bool evictable = dict_sys.prevent_eviction(table_rec);
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index e2b226b9e5c..f8b960910af 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1526,9 +1526,10 @@ public:
/** Remove the sentinel block for the watch before replacing it with a
real block. watch_unset() or watch_occurred() will notice
that the block has been replaced with the real block.
- @param watch sentinel
- @param chain locked hash table chain */
- inline void watch_remove(buf_page_t *watch, hash_chain &chain);
+ @param w sentinel
+ @param chain locked hash table chain
+ @return w->state() */
+ inline uint32_t watch_remove(buf_page_t *w, hash_chain &chain);
/** @return whether less than 1/4 of the buffer pool is available */
TPOOL_SUPPRESS_TSAN
diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h
index 072773694a9..33095eb8dbc 100644
--- a/storage/innobase/include/dict0load.h
+++ b/storage/innobase/include/dict0load.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2021, MariaDB Corporation.
+Copyright (c) 2017, 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 the Free Software
@@ -53,9 +53,8 @@ We also scan the biggest space id, and store it to fil_system. */
void dict_check_tablespaces_and_store_max_id();
/** Make sure the data_file_name is saved in dict_table_t if needed.
-@param[in,out] table Table object
-@param[in] dict_locked dict_sys.frozen() */
-void dict_get_and_save_data_dir_path(dict_table_t* table, bool dict_locked);
+@param[in,out] table Table object */
+void dict_get_and_save_data_dir_path(dict_table_t* table);
/***********************************************************************//**
Loads a table object based on the table id.
@@ -90,7 +89,8 @@ dict_load_foreigns(
const char* table_name, /*!< in: table name */
const char** col_names, /*!< in: column names, or NULL
to use table->col_names */
- bool check_recursive,/*!< in: Whether to check
+ trx_id_t trx_id, /*!< in: DDL transaction id,
+ or 0 to check
recursive load of tables
chained by FK */
bool check_charsets, /*!< in: whether to check
@@ -124,12 +124,12 @@ dict_getnext_system(
/** Load a table definition from a SYS_TABLES record to dict_table_t.
Do not load any columns or indexes.
-@param[in] name Table name
+@param[in,out] mtr mini-transaction
@param[in] rec SYS_TABLES record
@param[out,own] table table, or nullptr
@return error message
@retval nullptr on success */
-const char *dict_load_table_low(const span<const char> &name,
+const char *dict_load_table_low(mtr_t *mtr,
const rec_t *rec, dict_table_t **table)
MY_ATTRIBUTE((nonnull, warn_unused_result));
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index a05485696f6..8a959402c0b 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1661,10 +1661,7 @@ file inode probably is much faster (the OS caches them) than accessing
the first page of the file. This boolean may be initially false, but if
a remote tablespace is found it will be changed to true.
-If the fix_dict boolean is set, then it is safe to use an internal SQL
-statement to update the dictionary tables if they are incorrect.
-
-@param[in] validate true if we should validate the tablespace
+@param[in] validate 0=maybe missing, 1=do not validate, 2=validate
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
@param[in] id tablespace ID
@param[in] flags expected FSP_SPACE_FLAGS
@@ -1676,7 +1673,7 @@ If file-per-table, it is the table name in the databasename/tablename format
@retval NULL if the tablespace could not be opened */
fil_space_t*
fil_ibd_open(
- bool validate,
+ unsigned validate,
fil_type_t purpose,
uint32_t id,
uint32_t flags,
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 28d75517d45..e4ceff6dec2 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -394,15 +394,13 @@ lock_table(
void lock_table_resurrect(dict_table_t *table, trx_t *trx, lock_mode mode);
/** Sets a lock on a table based on the given mode.
-@param[in] table table to lock
-@param[in,out] trx transaction
-@param[in] mode LOCK_X or LOCK_S
-@return error code or DB_SUCCESS. */
-dberr_t
-lock_table_for_trx(
- dict_table_t* table,
- trx_t* trx,
- enum lock_mode mode)
+@param table table to lock
+@param trx transaction
+@param mode LOCK_X or LOCK_S
+@param no_wait whether to skip handling DB_LOCK_WAIT
+@return error code */
+dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode,
+ bool no_wait= false)
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Exclusively lock the data dictionary tables.
@@ -915,10 +913,8 @@ public:
@param page whether to discard also from lock_sys.prdt_hash */
void prdt_page_free_from_discard(const page_id_t id, bool all= false);
-#ifdef WITH_WSREP
/** Cancel possible lock waiting for a transaction */
static void cancel_lock_wait_for_trx(trx_t *trx);
-#endif /* WITH_WSREP */
};
/** The lock system */
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 7e20fc12cda..11bc0684fe1 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -279,12 +279,12 @@ public:
new query step is started */
/** latest completed checkpoint (protected by latch.wr_lock()) */
Atomic_relaxed<lsn_t> last_checkpoint_lsn;
- lsn_t next_checkpoint_lsn;
- /*!< next checkpoint lsn */
+ /** next checkpoint LSN (protected by log_sys.mutex) */
+ lsn_t next_checkpoint_lsn;
/** next checkpoint number (protected by latch.wr_lock()) */
ulint next_checkpoint_no;
- /** number of pending checkpoint writes */
- ulint n_pending_checkpoint_writes;
+ /** whether a checkpoint is pending */
+ Atomic_relaxed<bool> checkpoint_pending;
/** buffer for checkpoint header */
byte *checkpoint_buf;
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 3707a693648..d595b58ad6f 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -100,6 +100,15 @@ struct mtr_t {
/** Commit the mini-transaction. */
void commit();
+ /** Release latches till savepoint. To simplify the code only
+ MTR_MEMO_S_LOCK and MTR_MEMO_PAGE_S_FIX slot types are allowed to be
+ released, otherwise it would be neccesary to add one more argument in the
+ function to point out what slot types are allowed for rollback, and this
+ would be overengineering as currently the function is used only in one place
+ in the code.
+ @param savepoint savepoint, can be obtained with get_savepoint */
+ void rollback_to_savepoint(ulint savepoint);
+
/** Commit a mini-transaction that is shrinking a tablespace.
@param space tablespace that is being shrunk */
ATTRIBUTE_COLD void commit_shrink(fil_space_t &space);
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index c2ebad91ecd..7faf0ca06bd 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2021, MariaDB Corporation.
+Copyright (c) 2017, 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 the Free Software
@@ -727,11 +727,9 @@ in the clustered index for instant ADD COLUMN or ALTER TABLE.
@param[in] rec leaf page record
@param[in] index index of the record
@return whether the record is the metadata pseudo-record */
-inline bool rec_is_metadata(const rec_t* rec, const dict_index_t& index)
+inline bool rec_is_metadata(const rec_t *rec, const dict_index_t &index)
{
- bool is = rec_is_metadata(rec, dict_table_is_comp(index.table));
- ut_ad(!is || index.is_instant());
- return is;
+ return rec_is_metadata(rec, index.table->not_redundant());
}
/** Determine if the record is the metadata pseudo-record
diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h
index dc032cdf73a..b3f2fbeedf3 100644
--- a/storage/innobase/include/trx0purge.h
+++ b/storage/innobase/include/trx0purge.h
@@ -286,8 +286,10 @@ public:
/** Stop the purge thread and check n_ref_count of all auxiliary
and common table associated with the fts table.
- @param table parent FTS table */
- void stop_FTS(const dict_table_t &table);
+ @param table parent FTS table
+ @param already_stopped True indicates purge threads were
+ already stopped */
+ void stop_FTS(const dict_table_t &table, bool already_stopped=false);
};
/** The global data structure coordinating a purge */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index fa1ea357fe6..f920ac1ac95 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -3627,52 +3627,50 @@ static void lock_table_dequeue(lock_t *in_lock, bool owns_wait_mutex)
}
}
-/** Sets a lock on a table based on the given mode.
-@param[in] table table to lock
-@param[in,out] trx transaction
-@param[in] mode LOCK_X or LOCK_S
-@return error code or DB_SUCCESS. */
-dberr_t
-lock_table_for_trx(
- dict_table_t* table,
- trx_t* trx,
- enum lock_mode mode)
-{
- mem_heap_t* heap;
- que_thr_t* thr;
- dberr_t err;
- sel_node_t* node;
- heap = mem_heap_create(512);
-
- node = sel_node_create(heap);
- thr = pars_complete_graph_for_exec(node, trx, heap, NULL);
- thr->graph->state = QUE_FORK_ACTIVE;
-
- /* We use the select query graph as the dummy graph needed
- in the lock module call */
- thr = static_cast<que_thr_t*>(
- que_fork_get_first_thr(
- static_cast<que_fork_t*>(que_node_get_parent(thr))));
+/** Sets a lock on a table based on the given mode.
+@param table table to lock
+@param trx transaction
+@param mode LOCK_X or LOCK_S
+@param no_wait whether to skip handling DB_LOCK_WAIT
+@return error code */
+dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode,
+ bool no_wait)
+{
+ mem_heap_t *heap= mem_heap_create(512);
+ sel_node_t *node= sel_node_create(heap);
+ que_thr_t *thr= pars_complete_graph_for_exec(node, trx, heap, nullptr);
+ thr->graph->state= QUE_FORK_ACTIVE;
+
+ thr= static_cast<que_thr_t*>
+ (que_fork_get_first_thr(static_cast<que_fork_t*>
+ (que_node_get_parent(thr))));
run_again:
- thr->run_node = thr;
- thr->prev_node = thr->common.parent;
-
- err = lock_table(table, mode, thr);
+ thr->run_node= thr;
+ thr->prev_node= thr->common.parent;
+ dberr_t err= lock_table(table, mode, thr);
- trx->error_state = err;
-
- if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
- if (row_mysql_handle_errors(&err, trx, thr, NULL)) {
- goto run_again;
- }
- }
+ switch (err) {
+ case DB_SUCCESS:
+ break;
+ case DB_LOCK_WAIT:
+ if (no_wait)
+ {
+ lock_sys.cancel_lock_wait_for_trx(trx);
+ break;
+ }
+ /* fall through */
+ default:
+ trx->error_state= err;
+ if (row_mysql_handle_errors(&err, trx, thr, nullptr))
+ goto run_again;
+ }
- que_graph_free(thr->graph);
- trx->op_info = "";
+ que_graph_free(thr->graph);
+ trx->op_info= "";
- return(err);
+ return err;
}
/** Exclusively lock the data dictionary tables.
@@ -5639,8 +5637,7 @@ static void lock_cancel_waiting_and_release(lock_t *lock)
lock_wait_end(trx);
trx->mutex_unlock();
}
-#ifdef WITH_WSREP
-TRANSACTIONAL_TARGET
+
void lock_sys_t::cancel_lock_wait_for_trx(trx_t *trx)
{
lock_sys.wr_lock(SRW_LOCK_CALL);
@@ -5654,7 +5651,6 @@ void lock_sys_t::cancel_lock_wait_for_trx(trx_t *trx)
lock_sys.wr_unlock();
mysql_mutex_unlock(&lock_sys.wait_mutex);
}
-#endif /* WITH_WSREP */
/** Cancel a waiting lock request.
@tparam check_victim whether to check for DB_DEADLOCK
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 64113301ad4..9529db0af06 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -131,7 +131,7 @@ void log_t::create()
max_modified_age_async= 0;
max_checkpoint_age= 0;
next_checkpoint_lsn= 0;
- n_pending_checkpoint_writes= 0;
+ checkpoint_pending= false;
buf_free= 0;
@@ -234,7 +234,9 @@ void log_t::attach(log_file_t file, os_offset_t size)
if (!block_size)
set_block_size(512);
# ifdef __linux__
- else if (srv_file_flush_method != SRV_O_DSYNC)
+ else if (srv_file_flush_method != SRV_O_DSYNC &&
+ srv_file_flush_method != SRV_O_DIRECT &&
+ srv_file_flush_method != SRV_O_DIRECT_NO_FSYNC)
sql_print_information("InnoDB: Buffered log writes (block size=%u bytes)",
block_size);
#endif
@@ -1136,22 +1138,6 @@ wait_suspend_loop:
buf_flush_buffer_pool();
}
- if (log_sys.is_initialised()) {
- log_sys.latch.rd_lock(SRW_LOCK_CALL);
- const ulint n_write = log_sys.n_pending_checkpoint_writes;
- log_sys.latch.rd_unlock();
-
- if (n_write) {
- if (srv_print_verbose_log && count > 600) {
- sql_print_information(
- "InnoDB: Pending checkpoint writes: "
- ULINTPF, n_write);
- count = 0;
- }
- goto loop;
- }
- }
-
if (srv_fast_shutdown == 2 || !srv_was_started) {
if (!srv_read_only_mode && srv_was_started) {
ib::info() << "Executing innodb_fast_shutdown=2."
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 0406e90a9b7..b68b820eb0c 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -296,6 +296,50 @@ struct ReleaseAll {
}
};
+/** Stops iteration is savepoint is reached */
+template <typename Functor> struct TillSavepoint
+{
+
+ /** Constructor
+ @param[in] functor functor which is called if savepoint is not reached
+ @param[in] savepoint savepoint value to rollback
+ @param[in] used current position in slots container */
+ TillSavepoint(const Functor &functor, ulint savepoint, ulint used)
+ : functor(functor),
+ m_slots_count((used - savepoint) / sizeof(mtr_memo_slot_t))
+ {
+ ut_ad(savepoint);
+ ut_ad(used >= savepoint);
+ }
+
+ /** @return true if savepoint is not reached, false otherwise */
+ bool operator()(mtr_memo_slot_t *slot)
+ {
+#ifdef UNIV_DEBUG
+ /** This check is added because the code is invoked only from
+ row_search_mvcc() to release latches acquired during clustered index search
+ for secondary index record. To make it more universal we could add one more
+ member in this functor for debug build to pass only certain slot types,
+ but this is currently not necessary. */
+ switch (slot->type)
+ {
+ case MTR_MEMO_S_LOCK:
+ case MTR_MEMO_PAGE_S_FIX:
+ break;
+ default:
+ ut_a(false);
+ }
+#endif
+ return m_slots_count-- && functor(slot);
+ }
+
+private:
+ /** functor to invoke */
+ const Functor &functor;
+ /** slots count left till savepoint */
+ ulint m_slots_count;
+};
+
#ifdef UNIV_DEBUG
/** Check that all slots have been handled. */
struct DebugCheck {
@@ -488,6 +532,21 @@ void mtr_t::commit()
release_resources();
}
+/** Release latches till savepoint. To simplify the code only
+MTR_MEMO_S_LOCK and MTR_MEMO_PAGE_S_FIX slot types are allowed to be
+released, otherwise it would be neccesary to add one more argument in the
+function to point out what slot types are allowed for rollback, and this
+would be overengineering as corrently the function is used only in one place
+in the code.
+@param savepoint savepoint, can be obtained with get_savepoint */
+void mtr_t::rollback_to_savepoint(ulint savepoint)
+{
+ Iterate<TillSavepoint<ReleaseLatches>> iteration(
+ TillSavepoint<ReleaseLatches>(ReleaseLatches(), savepoint,
+ get_savepoint()));
+ m_memo.for_each_block_in_reverse(iteration);
+}
+
/** Shrink a tablespace. */
struct Shrink
{
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index 902f3f2d5ca..bd572372aca 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2021, MariaDB Corporation.
+Copyright (c) 2017, 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 the Free Software
@@ -478,7 +478,7 @@ rec_offs_make_valid(
{
const bool is_alter_metadata = leaf
&& rec_is_alter_metadata(rec, *index);
- ut_ad(is_alter_metadata
+ ut_ad((leaf && rec_is_metadata(rec, *index))
|| index->is_dummy || index->is_ibuf()
|| (leaf
? rec_offs_n_fields(offsets)
@@ -572,7 +572,8 @@ rec_offs_validate(
}
/* index->n_def == 0 for dummy indexes if !comp */
ut_ad(!comp || index->n_def);
- ut_ad(!index->n_def || i <= max_n_fields);
+ ut_ad(!index->n_def || i <= max_n_fields
+ || rec_is_metadata(rec, *index));
}
while (i--) {
ulint curr = get_value(rec_offs_base(offsets)[1 + i]);
@@ -897,9 +898,7 @@ rec_get_offsets_func(
ut_ad(!is_user_rec || !n_core || index->is_dummy
|| dict_index_is_ibuf(index)
|| n == n_fields /* btr_pcur_restore_position() */
- || (n + (index->id == DICT_INDEXES_ID)
- >= n_core && n <= index->n_fields
- + unsigned(rec_is_alter_metadata(rec, false))));
+ || (n + (index->id == DICT_INDEXES_ID) >= n_core));
if (is_user_rec && n_core && n < index->n_fields) {
ut_ad(!index->is_dummy);
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 6cf099e204e..5eedb6a0ea7 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3114,7 +3114,7 @@ and apply it to dict_table_t
static dberr_t handle_instant_metadata(dict_table_t *table,
const row_import &cfg)
{
- dict_get_and_save_data_dir_path(table, false);
+ dict_get_and_save_data_dir_path(table);
char *filepath;
if (DICT_TF_HAS_DATA_DIR(table->flags))
@@ -4149,7 +4149,7 @@ fil_tablespace_iterate(
return(DB_CORRUPTION););
/* Make sure the data_dir_path is set. */
- dict_get_and_save_data_dir_path(table, false);
+ dict_get_and_save_data_dir_path(table);
ut_ad(!DICT_TF_HAS_DATA_DIR(table->flags) || table->data_dir_path);
@@ -4470,7 +4470,7 @@ row_import_for_mysql(
/* If the table is stored in a remote tablespace, we need to
determine that filepath from the link file and system tables.
Find the space ID in SYS_TABLES since this is an ALTER TABLE. */
- dict_get_and_save_data_dir_path(table, true);
+ dict_get_and_save_data_dir_path(table);
ut_ad(!DICT_TF_HAS_DATA_DIR(table->flags) || table->data_dir_path);
const char *data_dir_path = DICT_TF_HAS_DATA_DIR(table->flags)
@@ -4497,7 +4497,7 @@ row_import_for_mysql(
fil_space_t::set_imported() to declare it a persistent tablespace. */
table->space = fil_ibd_open(
- true, FIL_TYPE_IMPORT, table->space_id,
+ 2, FIL_TYPE_IMPORT, table->space_id,
dict_tf_to_fsp_flags(table->flags), name, filepath, &err);
ut_ad((table->space == NULL) == (err != DB_SUCCESS));
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 785b7b6070d..e3947403232 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -5205,7 +5205,11 @@ add_to_buf:
row_merge_dup_t dup{index, nullptr, nullptr, 0};
row_merge_buf_sort(buf, &dup);
if (dup.n_dup)
- return DB_DUPLICATE_KEY;
+ {
+ trx->error_info= index;
+ err= DB_DUPLICATE_KEY;
+ goto func_exit;
+ }
}
else
row_merge_buf_sort(buf, NULL);
@@ -5214,7 +5218,10 @@ add_to_buf:
file->n_rec+= buf->n_tuples;
err= write_to_tmp_file(i);
if (err != DB_SUCCESS)
- return err;
+ {
+ trx->error_info= index;
+ goto func_exit;
+ }
clean_bulk_buffer(i);
buf= &m_merge_buf[i];
goto add_to_buf;
@@ -5243,7 +5250,10 @@ dberr_t row_merge_bulk_t::write_to_index(ulint index_no, trx_t *trx)
{
row_merge_buf_sort(&buf, &dup);
if (dup.n_dup)
- return DB_DUPLICATE_KEY;
+ {
+ err= DB_DUPLICATE_KEY;
+ goto func_exit;
+ }
}
else row_merge_buf_sort(&buf, NULL);
if (file && file->fd != OS_FILE_CLOSED)
@@ -5276,6 +5286,8 @@ dberr_t row_merge_bulk_t::write_to_index(ulint index_no, trx_t *trx)
nullptr, &m_blob_file);
func_exit:
+ if (err != DB_SUCCESS)
+ trx->error_info= index;
err= btr_bulk.finish(err);
return err;
}
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index f064f39f7df..db586e8f266 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2912,7 +2912,7 @@ row_rename_table_for_mysql(
dict_names_t fk_tables;
err = dict_load_foreigns(
- new_name, NULL, false,
+ new_name, nullptr, trx->id,
!old_is_tmp || trx->check_foreigns,
use_fk
? DICT_ERR_IGNORE_NONE
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index 19870906df8..4cd1c3a4d26 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2021, MariaDB Corporation.
+Copyright (c) 2018, 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 the Free Software
@@ -531,7 +531,11 @@ row_build_low(
continue;
}
- ut_ad(ind_field < &index->fields[index->n_fields]);
+ if (UNIV_UNLIKELY(ind_field
+ >= &index->fields[index->n_fields])) {
+ ut_ad(rec_is_metadata(rec, *index));
+ continue;
+ }
const dict_col_t* col = dict_field_get_col(ind_field);
@@ -745,11 +749,15 @@ row_rec_to_index_entry_impl(
if (mblob == 2) {
ut_ad(info_bits == REC_INFO_METADATA_ALTER
|| info_bits == REC_INFO_METADATA_ADD);
- ut_ad(rec_len <= ulint(index->n_fields + got));
if (pad) {
+ ut_ad(rec_len <= ulint(index->n_fields + got));
rec_len = ulint(index->n_fields)
+ (info_bits == REC_INFO_METADATA_ALTER);
- } else if (!got && info_bits == REC_INFO_METADATA_ALTER) {
+ } else if (got) {
+ rec_len = std::min(rec_len,
+ ulint(index->n_fields + got));
+ } else if (info_bits == REC_INFO_METADATA_ALTER) {
+ ut_ad(rec_len <= index->n_fields);
rec_len++;
}
} else {
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index a599c387e60..52f9efa3957 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -3601,14 +3601,12 @@ record with the same ordering prefix in in the B-tree index
@param[in] latch_mode latch mode wished in restoration
@param[in] pcur cursor whose position has been stored
@param[in] moves_up true if the cursor moves up in the index
-@param[in] mtr mtr; CAUTION: may commit mtr temporarily!
-@param[in] select_lock_type select lock type
+@param[in,out] mtr mtr; CAUTION: may commit mtr temporarily!
@return true if we may need to process the record the cursor is now
positioned on (i.e. we should not go to the next record yet) */
static bool sel_restore_position_for_mysql(bool *same_user_rec,
ulint latch_mode, btr_pcur_t *pcur,
- bool moves_up, mtr_t *mtr,
- lock_mode select_lock_type)
+ bool moves_up, mtr_t *mtr)
{
auto status = pcur->restore_position(latch_mode, mtr);
@@ -3631,8 +3629,7 @@ static bool sel_restore_position_for_mysql(bool *same_user_rec,
switch (pcur->rel_pos) {
case BTR_PCUR_ON:
if (!*same_user_rec && moves_up) {
- if (status == btr_pcur_t::SAME_UNIQ
- && select_lock_type != LOCK_NONE)
+ if (status == btr_pcur_t::SAME_UNIQ)
return true;
next:
if (btr_pcur_move_to_next(pcur, mtr)
@@ -4325,7 +4322,7 @@ row_search_mvcc(
const rec_t* clust_rec;
Row_sel_get_clust_rec_for_mysql row_sel_get_clust_rec_for_mysql;
ibool unique_search = FALSE;
- ibool mtr_has_extra_clust_latch = FALSE;
+ ulint mtr_extra_clust_savepoint = 0;
bool moves_up = false;
/* if the returned record was locked and we did a semi-consistent
read (fetch the newest committed version), then this is set to
@@ -4697,7 +4694,7 @@ wait_table_again:
bool need_to_process = sel_restore_position_for_mysql(
&same_user_rec, BTR_SEARCH_LEAF,
- pcur, moves_up, &mtr, prebuilt->select_lock_type);
+ pcur, moves_up, &mtr);
if (UNIV_UNLIKELY(need_to_process)) {
if (UNIV_UNLIKELY(prebuilt->row_read_type
@@ -5445,7 +5442,7 @@ requires_clust_rec:
/* It was a non-clustered index and we must fetch also the
clustered index record */
- mtr_has_extra_clust_latch = TRUE;
+ mtr_extra_clust_savepoint = mtr.get_savepoint();
ut_ad(!vrow);
/* The following call returns 'offsets' associated with
@@ -5744,27 +5741,15 @@ next_rec:
/* No need to do store restore for R-tree */
mtr.commit();
mtr.start();
- mtr_has_extra_clust_latch = FALSE;
- } else if (mtr_has_extra_clust_latch) {
- /* If we have extra cluster latch, we must commit
- mtr if we are moving to the next non-clustered
+ mtr_extra_clust_savepoint = 0;
+ } else if (mtr_extra_clust_savepoint) {
+ /* We must release any clustered index latches
+ if we are moving to the next non-clustered
index record, because we could break the latching
order if we would access a different clustered
index page right away without releasing the previous. */
-
- btr_pcur_store_position(pcur, &mtr);
- mtr.commit();
- mtr_has_extra_clust_latch = FALSE;
-
- mtr.start();
-
- if (sel_restore_position_for_mysql(&same_user_rec,
- BTR_SEARCH_LEAF,
- pcur, moves_up, &mtr,
- prebuilt->select_lock_type)
- ) {
- goto rec_loop;
- }
+ mtr.rollback_to_savepoint(mtr_extra_clust_savepoint);
+ mtr_extra_clust_savepoint = 0;
}
if (moves_up) {
@@ -5824,7 +5809,7 @@ page_read_error:
lock_table_wait:
mtr.commit();
- mtr_has_extra_clust_latch = FALSE;
+ mtr_extra_clust_savepoint = 0;
trx->error_state = err;
thr->lock_state = QUE_THR_LOCK_ROW;
@@ -5846,7 +5831,7 @@ lock_table_wait:
if (!dict_index_is_spatial(index)) {
sel_restore_position_for_mysql(
&same_user_rec, BTR_SEARCH_LEAF, pcur,
- moves_up, &mtr, prebuilt->select_lock_type);
+ moves_up, &mtr);
}
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 4322f2a4e38..0c9dd566927 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1043,13 +1043,13 @@ dberr_t srv_start(bool create_new_db)
recv_sys.create();
lock_sys.create(srv_lock_table_size);
+ srv_startup_is_before_trx_rollback_phase = true;
+
if (!srv_read_only_mode) {
buf_flush_page_cleaner_init();
ut_ad(buf_page_cleaner_is_active);
}
- srv_startup_is_before_trx_rollback_phase = true;
-
/* Check if undo tablespaces and redo log files exist before creating
a new system tablespace */
if (create_new_db) {
@@ -1792,7 +1792,7 @@ srv_get_meta_data_filename(
char* path;
/* Make sure the data_dir_path is set. */
- dict_get_and_save_data_dir_path(table, false);
+ dict_get_and_save_data_dir_path(table);
const char* data_dir_path = DICT_TF_HAS_DATA_DIR(table->flags)
? table->data_dir_path : nullptr;
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index bfad53e691b..05333652a25 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -2055,7 +2055,8 @@ trx_undo_report_row_operation(
} else if (!m.second || !trx->bulk_insert) {
bulk = false;
} else if (index->table->is_temporary()) {
- } else if (trx_has_lock_x(*trx, *index->table)) {
+ } else if (trx_has_lock_x(*trx, *index->table)
+ && index->table->bulk_trx_id == trx->id) {
m.first->second.start_bulk_insert(index->table);
if (dberr_t err = m.first->second.bulk_insert_buffered(
diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt
index 9b2211503ff..13d8035bdc8 100644
--- a/storage/maria/CMakeLists.txt
+++ b/storage/maria/CMakeLists.txt
@@ -117,15 +117,14 @@ SET(S3_SOURCES s3_func.c
libmarias3/src/sha256-internal.c libmarias3/src/xml.c
libmarias3/src/assume_role.c)
-IF(NOT PLUGIN_S3 STREQUAL NO)
+IF(NOT PLUGIN_S3 STREQUAL NO AND NOT WIN32)
FIND_PACKAGE(CURL)
ENDIF()
IF (CURL_FOUND)
INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIRS})
- LINK_DIRECTORIES(${PC_CURL_LIBDIR})
MYSQL_ADD_PLUGIN(s3 ha_s3.cc ${S3_SOURCES} COMPONENT s3-engine
- LINK_LIBRARIES curl z STORAGE_ENGINE NOT_EMBEDDED CONFIG s3.cnf)
+ LINK_LIBRARIES ${CURL_LIBRARIES} z STORAGE_ENGINE NOT_EMBEDDED CONFIG s3.cnf)
ENDIF()
SET(CPACK_RPM_s3-engine_PACKAGE_SUMMARY "Amazon S3 archival storage engine for MariaDB" PARENT_SCOPE)
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 3e166e99b91..08579bd233f 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -1,5 +1,5 @@
/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
- Copyright (c) 2009, 2021, MariaDB Corporation Ab
+ Copyright (c) 2009, 2022, MariaDB Corporation Ab
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
@@ -271,7 +271,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
data_name[FN_REFLEN];
uchar *UNINIT_VAR(disk_cache), *disk_pos, *end_pos;
- MARIA_HA info, *UNINIT_VAR(m_info), *old_info;
+ MARIA_HA info, *UNINIT_VAR(m_info), *old_info= NULL;
MARIA_SHARE share_buff,*share;
double *rec_per_key_part;
ulong *nulls_per_key_part;
@@ -291,9 +291,9 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
#ifndef WITH_S3_STORAGE_ENGINE
DBUG_ASSERT(!s3);
-#endif /* WITH_S3_STORAGE_ENGINE */
-
+#else
if (!s3)
+#endif /* WITH_S3_STORAGE_ENGINE */
{
realpath_err= my_realpath(name_buff, fn_format(org_name, name, "",
MARIA_NAME_IEXT,
@@ -322,7 +322,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
}
#endif /* WITH_S3_STORAGE_ENGINE */
- old_info= 0;
if (!internal_table)
mysql_mutex_lock(&THR_LOCK_maria);
if ((open_flags & HA_OPEN_COPY) ||
diff --git a/storage/maria/s3_func.c b/storage/maria/s3_func.c
index 06178c1c0c2..491a8e0a323 100644
--- a/storage/maria/s3_func.c
+++ b/storage/maria/s3_func.c
@@ -1310,7 +1310,7 @@ my_bool set_database_and_table_from_path(S3_INFO *s3, const char *path)
if (path[length-1] == FN_LIBCHAR || path[length-1] == '/')
break;
#ifdef FN_DEVCHAR
- if (path[length-1] == FN_DECVHAR)
+ if (path[length-1] == FN_DEVCHAR)
break;
#endif
}
diff --git a/storage/perfschema/unittest/stub_pfs_global.h b/storage/perfschema/unittest/stub_pfs_global.h
index 4371523b014..6d10e29161d 100644
--- a/storage/perfschema/unittest/stub_pfs_global.h
+++ b/storage/perfschema/unittest/stub_pfs_global.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2008, 2021, Oracle and/or its affiliates.
+ Copyright (c) 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, version 2.0,
@@ -24,6 +25,9 @@
#include <my_sys.h>
#include <pfs_global.h>
#include <string.h>
+#ifdef HAVE_MEMALIGN
+# include <malloc.h>
+#endif
bool pfs_initialized= false;
size_t pfs_allocated_memory_size= 0;
@@ -45,7 +49,17 @@ void *pfs_malloc(PFS_builtin_memory_class *klass, size_t size, myf)
if (--stub_alloc_fails_after_count <= 0)
return NULL;
+#ifndef PFS_ALIGNEMENT
void *ptr= malloc(size);
+#elif defined HAVE_MEMALIGN
+ void *ptr= memalign(PFS_ALIGNEMENT, size);
+#elif defined HAVE_ALIGNED_MALLOC
+ void *ptr= _aligned_malloc(size, PFS_ALIGNEMENT);
+#else
+ void *ptr;
+ if (posix_memalign(&ptr, PFS_ALIGNEMENT, size))
+ ptr= NULL;
+#endif
if (ptr != NULL)
memset(ptr, 0, size);
return ptr;
diff --git a/strings/decimal.c b/strings/decimal.c
index b5ac9f4f069..7d4e183ef63 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1136,13 +1136,21 @@ int decimal2ulonglong(const decimal_t *from, ulonglong *to)
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
{
- ulonglong y=x;
- x=x*DIG_BASE + *buf++;
- if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
+ /*
+ Check that the decimal is bigger than any possible integer.
+ Do it before we do the x*=DIB_BASE to avoid integer
+ overflow.
+ */
+ if (unlikely (
+ x >= ULONGLONG_MAX/DIG_BASE &&
+ (x > ULONGLONG_MAX/DIG_BASE ||
+ *buf > (dec1) (ULONGLONG_MAX%DIG_BASE))))
{
*to=ULONGLONG_MAX;
return E_DEC_OVERFLOW;
}
+
+ x=x*DIG_BASE + *buf++;
}
*to=x;
for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1)
@@ -1159,23 +1167,29 @@ int decimal2longlong(const decimal_t *from, longlong *to)
for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1)
{
- longlong y=x;
/*
+ Check that the decimal is less than any possible integer.
+ Do it before we do the x*=DIB_BASE to avoid integer
+ overflow.
Attention: trick!
we're calculating -|from| instead of |from| here
because |LONGLONG_MIN| > LONGLONG_MAX
- so we can convert -9223372036854775808 correctly
+ so we can convert -9223372036854775808 correctly.
*/
- x=x*DIG_BASE - *buf++;
- if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
+ if (unlikely (
+ x <= LONGLONG_MIN/DIG_BASE &&
+ (x < LONGLONG_MIN/DIG_BASE ||
+ *buf > (dec1) (-(LONGLONG_MIN%DIG_BASE)))))
{
/*
- the decimal is bigger than any possible integer
- return border integer depending on the sign
+ the decimal is bigger than any possible integer
+ return border integer depending on the sign
*/
*to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
return E_DEC_OVERFLOW;
}
+
+ x=x*DIG_BASE - *buf++;
}
/* boundary case: 9223372036854775808 */
if (unlikely(from->sign==0 && x == LONGLONG_MIN))
diff --git a/tpool/aio_liburing.cc b/tpool/aio_liburing.cc
index b8666482193..8192a5b7fed 100644
--- a/tpool/aio_liburing.cc
+++ b/tpool/aio_liburing.cc
@@ -161,8 +161,7 @@ private:
}
io_uring_cqe_seen(&aio->uring_, cqe);
- if (iocb->m_ret_len != iocb->m_len && !iocb->m_err)
- finish_synchronous(iocb);
+ finish_synchronous(iocb);
// If we need to resubmit the IO operation, but the ring is full,
// we will follow the same path as for any other error codes.
diff --git a/tpool/aio_linux.cc b/tpool/aio_linux.cc
index fc6e5b53e1a..5d01c588a88 100644
--- a/tpool/aio_linux.cc
+++ b/tpool/aio_linux.cc
@@ -128,8 +128,7 @@ class aio_linux final : public aio
{
iocb->m_ret_len= event.res;
iocb->m_err= 0;
- if (iocb->m_ret_len != iocb->m_len)
- finish_synchronous(iocb);
+ finish_synchronous(iocb);
}
iocb->m_internal_task.m_func= iocb->m_callback;
iocb->m_internal_task.m_arg= iocb;
diff --git a/tpool/tpool.h b/tpool/tpool.h
index 2c61c2d62b2..87a0122adce 100644
--- a/tpool/tpool.h
+++ b/tpool/tpool.h
@@ -173,7 +173,17 @@ public:
protected:
static void synchronous(aiocb *cb);
/** finish a partial read/write callback synchronously */
- static void finish_synchronous(aiocb *cb);
+ static inline void finish_synchronous(aiocb *cb)
+ {
+ if (!cb->m_err && cb->m_ret_len != cb->m_len)
+ {
+ /* partial read/write */
+ cb->m_buffer= (char *) cb->m_buffer + cb->m_ret_len;
+ cb->m_len-= (unsigned int) cb->m_ret_len;
+ cb->m_offset+= cb->m_ret_len;
+ synchronous(cb);
+ }
+ }
};
class timer
diff --git a/tpool/tpool_generic.cc b/tpool/tpool_generic.cc
index a1b9a3ce945..5720c5b48aa 100644
--- a/tpool/tpool_generic.cc
+++ b/tpool/tpool_generic.cc
@@ -85,25 +85,12 @@ void aio::synchronous(aiocb *cb)
#endif
cb->m_ret_len = ret_len;
cb->m_err = err;
- if (!err && cb->m_ret_len != cb->m_len)
+ if (ret_len)
finish_synchronous(cb);
}
/**
- A partial read/write has occured, continue synchronously.
-*/
-void aio::finish_synchronous(aiocb *cb)
-{
- assert(cb->m_ret_len != (unsigned int) cb->m_len && !cb->m_err);
- /* partial read/write */
- cb->m_buffer= (char *) cb->m_buffer + cb->m_ret_len;
- cb->m_len-= (unsigned int) cb->m_ret_len;
- cb->m_offset+= cb->m_ret_len;
- synchronous(cb);
-}
-
-/**
Implementation of generic threadpool.
This threadpool consists of the following components