Commit 54c460ac authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.5 into 10.6

parents b728c3db df33b719
archive.archive
archive.archive_gis
archive.partition_archive
binlog.binlog_base64_flag
binlog.binlog_database
binlog.binlog_innodb
binlog.binlog_parallel_replication_marks_stm_mix
binlog.binlog_row_mix_innodb_myisam
binlog.flashback
binlog_encryption.encrypted_slave
connect.bin
connect.bson
connect.dbf
connect.dir
connect.endian
connect.general
connect.json
connect.mysql
connect.secure_file_priv
connect.tbl
csv.csv
disks.disks
encryption.encryption_force
encryption.innodb_encryption_tables
encryption.tempfiles_encrypted
federated.federated
federated.federatedx
gcol.gcol_select_innodb
handler.interface
heap.heap
innodb.innodb
innodb.autoinc_persist
innodb.innodb_defrag_binlog
innodb.innodb_mysql
innodb.monitor
innodb.purge
innodb.table_flags
innodb.xa_recovery
innodb_fts.fulltext
innodb_gis.geometry
innodb_gis.rtree
innodb_zip.innodb-zip
innodb_zip.page_size
json.json_no_table
main.blackhole
main.bootstrap
main.compress
main.connect
main.ctype_collate
main.ctype_utf8
main.default
main.dyncol
main.fulltext
main.function_defaults
main.gis
main.grant
main.handlersocket
main.information_schema
main.innodb_ext_key
main.log_tables
main.lowercase_fs_off
main.myisam
main.mysql_client_test
main.mysql_protocols
main.mysql_upgrade
main.mysqladmin
main.mysqlbinlog
main.mysqlcheck
main.mysqld--defaults-file
main.mysqldump
main.mysqlhotcopy_myisam
main.mysqlshow
main.mysqlslap
main.mysqltest
main.parser
main.partition
main.perror
main.plugin
main.plugin_auth
main.pool_of_threads
main.ps
main.repair
main.shutdown
main.sp
main.ssl
main.ssl_compress
main.stat_tables
main.statistics
main.subselect
main.symlink
main.temp_table
main.timezone
main.type_timestamp_hires
main.user_var
main.userstat
main.variables
main.view
main.win
main.xa
maria.maria
mariabackup.full_backup
metadata_lock_info.table_metadata_lock
mroonga/storage.variable_version
mroonga/wrapper.count_star
multi_source.multisource
oqgraph.general-innodb
parts.rpl_partition
perfschema.selects
plugins.auth_ed25519
plugins.cracklib_password_check
plugins.dialog
plugins.fulltext_plugin
plugins.locales
plugins.pam_cleartext
plugins.processlist
plugins.qc_info
plugins.server_audit
plugins.simple_password_check
plugins.sql_error_log
plugins.two_password_validations
plugins.unix_socket
query_response_time.basic
rocksdb.rocksdb
roles.definer
rpl.rpl_gtid_basic
rpl.rpl_relayrotate
rpl.rpl_row_blob_innodb
rpl.rpl_semi_sync_event
rpl.rpl_sp
rpl.rpl_stm_binlog_max_cache_size
rpl.rpl_switch_stm_row_mixed
sequence.simple
spider.basic_sql
spider.ha
sql_discovery.simple
sys_vars.sysvars_aria
sys_vars.sysvars_server_notembedded
wsrep.variables
compat/oracle.binlog_ptr_mysqlbinlog
compat/oracle.sp-package
compat/maxdb.rpl_mariadb_timestamp
sql_sequence.mysqldump
versioning.simple
versioning.trx_id
period.versioning
plugins.multiauth
client.mariadb-conv
innodb_i_s.innodb_sys_tables
SET GLOBAL innodb_flush_log_at_trx_commit= 1;
RESET MASTER;
CREATE TABLE t1 (a INT PRIMARY KEY, b MEDIUMTEXT) ENGINE=Innodb;
*** Test that FLUSH LOGS waits if a transaction ordered commit is in progress.
connect con1,localhost,root,,;
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL con1_ready WAIT_FOR con1_go";
INSERT INTO t1 VALUES (1, REPEAT("x", 1));
connection default;
SET DEBUG_SYNC= "now WAIT_FOR con1_ready";
SET DEBUG_SYNC= "rotate_after_rotate SIGNAL con_flush_ready WAIT_FOR default_go";
FLUSH LOGS;
connect con2,localhost,root,,;
Trx_1 is not yet committed:
SELECT count(*) as 'ZERO' from t1;
ZERO
0
Wait for Trx_2 has rotated binlog:
SET DEBUG_SYNC= "now WAIT_FOR con_flush_ready";
SET DEBUG_SYNC= "now SIGNAL default_go";
# restart
connection default;
Must be tree logs in the list:
show binary logs;
Log_name File_size
master-bin.000001 #
master-bin.000002 #
master-bin.000003 #
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Format_desc # # SERVER_VERSION, BINLOG_VERSION
master-bin.000001 # Gtid_list # # []
master-bin.000001 # Binlog_checkpoint # # master-bin.000001
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b MEDIUMTEXT) ENGINE=Innodb
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (1, REPEAT("x", 1))
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
Only one Binlog checkpoint must exist and point to master-bin.000001
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION
master-bin.000002 # Gtid_list # # [#-#-#]
master-bin.000002 # Binlog_checkpoint # # master-bin.000001
SELECT count(*) as 'ONE' from t1;
ONE
1
connection default;
DROP TABLE t1;
SET debug_sync = 'reset';
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/have_binlog_format_row.inc
# References:
#
# MDEV-24526 binlog rotate via FLUSH LOGS may obsolate binlog file too eary
#
# The test for MDEV-24526 proves the fixes correct observed race condition
# between a commiting transaction and FLUSH-LOGS.
# The plot.
# Trx_1 (con1) transaction binlogs first
# to yield its turn acquiring LOCK_commit_ordered to Trx_2 and stand
# still waiting of a signal that will never arrive.
# Trx_2 can't acquire it in the fixed version even though
# Trx_3 makes sure Trx_2 has reached a post-rotation execution point
# to signal it to proceed.
# Then the server gets crashed and Trx_1 must recover unlike
# in the OLD buggy version.
#
SET GLOBAL innodb_flush_log_at_trx_commit= 1;
RESET MASTER;
CREATE TABLE t1 (a INT PRIMARY KEY, b MEDIUMTEXT) ENGINE=Innodb;
--echo *** Test that FLUSH LOGS waits if a transaction ordered commit is in progress.
connect(con1,localhost,root,,); # Trx_1
# hang before doing acquiring Commit Ordered mutex
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL con1_ready WAIT_FOR con1_go";
--send INSERT INTO t1 VALUES (1, REPEAT("x", 1))
connection default; # Trx_2
SET DEBUG_SYNC= "now WAIT_FOR con1_ready";
SET DEBUG_SYNC= "rotate_after_rotate SIGNAL con_flush_ready WAIT_FOR default_go";
--send FLUSH LOGS
connect(con2,localhost,root,,); # Trx_3
--echo Trx_1 is not yet committed:
SELECT count(*) as 'ZERO' from t1;
--echo Wait for Trx_2 has rotated binlog:
SET DEBUG_SYNC= "now WAIT_FOR con_flush_ready";
# Useless signal to prove Trx_2 cannot race Trx_1's commit
# even though Trx_1 never received the being waited 'con1_go'.
SET DEBUG_SYNC= "now SIGNAL default_go";
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
connection default;
--enable_reconnect
--error 0,2013
--reap
--echo Must be tree logs in the list:
--source include/show_binary_logs.inc
--let $binlog_file= master-bin.000001
--let $binlog_start= 4
--source include/show_binlog_events.inc
--echo Only one Binlog checkpoint must exist and point to master-bin.000001
--let $binlog_file= master-bin.000002
--let $binlog_start= 4
--source include/show_binlog_events.inc
# In the buggy server version the following select may have
# resulted with ZERO:
SELECT count(*) as 'ONE' from t1;
# Clean up.
connection default;
DROP TABLE t1;
SET debug_sync = 'reset';
...@@ -194,6 +194,7 @@ Event_queue_element_for_exec::init(const LEX_CSTRING &db, const LEX_CSTRING &n) ...@@ -194,6 +194,7 @@ Event_queue_element_for_exec::init(const LEX_CSTRING &db, const LEX_CSTRING &n)
n.str, name.length= n.length, MYF(MY_WME)))) n.str, name.length= n.length, MYF(MY_WME))))
{ {
my_free(const_cast<char*>(dbname.str)); my_free(const_cast<char*>(dbname.str));
dbname.str= NULL;
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
......
...@@ -35,7 +35,7 @@ void init_scheduler_psi_keys(void); ...@@ -35,7 +35,7 @@ void init_scheduler_psi_keys(void);
class Event_queue_element_for_exec class Event_queue_element_for_exec
{ {
public: public:
Event_queue_element_for_exec(){}; Event_queue_element_for_exec() : dbname{nullptr, 0}, name{nullptr, 0} {}
~Event_queue_element_for_exec(); ~Event_queue_element_for_exec();
bool bool
......
...@@ -643,6 +643,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd, ...@@ -643,6 +643,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
if (!(*event_name= new Event_queue_element_for_exec()) || if (!(*event_name= new Event_queue_element_for_exec()) ||
(*event_name)->init(top->dbname, top->name)) (*event_name)->init(top->dbname, top->name))
{ {
delete *event_name;
ret= TRUE; ret= TRUE;
break; break;
} }
......
...@@ -7185,6 +7185,9 @@ int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate, ...@@ -7185,6 +7185,9 @@ int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate,
bool check_purge= false; bool check_purge= false;
mysql_mutex_lock(&LOCK_log); mysql_mutex_lock(&LOCK_log);
DEBUG_SYNC(current_thd, "rotate_after_acquire_LOCK_log");
prev_binlog_id= current_binlog_id; prev_binlog_id= current_binlog_id;
if ((err_gtid= do_delete_gtid_domain(domain_drop_lex))) if ((err_gtid= do_delete_gtid_domain(domain_drop_lex)))
...@@ -7195,11 +7198,22 @@ int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate, ...@@ -7195,11 +7198,22 @@ int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate,
} }
else if (unlikely((error= rotate(force_rotate, &check_purge)))) else if (unlikely((error= rotate(force_rotate, &check_purge))))
check_purge= false; check_purge= false;
DEBUG_SYNC(current_thd, "rotate_after_rotate");
/* /*
NOTE: Run purge_logs wo/ holding LOCK_log because it does not need NOTE: Run purge_logs wo/ holding LOCK_log because it does not need
the mutex. Otherwise causes various deadlocks. the mutex. Otherwise causes various deadlocks.
Explicit binlog rotation must be synchronized with a concurrent
binlog ordered commit, in particular not let binlog
checkpoint notification request until early binlogged
concurrent commits have has been completed.
*/ */
mysql_mutex_lock(&LOCK_after_binlog_sync);
mysql_mutex_unlock(&LOCK_log); mysql_mutex_unlock(&LOCK_log);
mysql_mutex_lock(&LOCK_commit_ordered);
mysql_mutex_unlock(&LOCK_after_binlog_sync);
mysql_mutex_unlock(&LOCK_commit_ordered);
if (check_purge) if (check_purge)
checkpoint_and_purge(prev_binlog_id); checkpoint_and_purge(prev_binlog_id);
...@@ -8403,7 +8417,12 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) ...@@ -8403,7 +8417,12 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
} }
DEBUG_SYNC(leader->thd, "commit_before_get_LOCK_commit_ordered"); DEBUG_SYNC(leader->thd, "commit_before_get_LOCK_commit_ordered");
mysql_mutex_lock(&LOCK_commit_ordered); mysql_mutex_lock(&LOCK_commit_ordered);
DBUG_EXECUTE_IF("crash_before_engine_commit",
{
DBUG_SUICIDE();
});
last_commit_pos_offset= commit_offset; last_commit_pos_offset= commit_offset;
/* /*
......
This diff is collapsed.
...@@ -7641,7 +7641,6 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex) ...@@ -7641,7 +7641,6 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
THD *thd= lex->thd; THD *thd= lex->thd;
bool new_select= select_lex == NULL; bool new_select= select_lex == NULL;
int old_nest_level= lex->current_select->nest_level; int old_nest_level= lex->current_select->nest_level;
Name_resolution_context *curr_context= lex->context_stack.head();
DBUG_ENTER("mysql_new_select"); DBUG_ENTER("mysql_new_select");
if (new_select) if (new_select)
...@@ -7671,8 +7670,7 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex) ...@@ -7671,8 +7670,7 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
By default we assume that it is usual subselect and we have outer name By default we assume that it is usual subselect and we have outer name
resolution context, if no we will assign it to 0 later resolution context, if no we will assign it to 0 later
*/ */
select_lex->context.outer_context= &select_lex->outer_select()->context;
select_lex->context.outer_context= curr_context;
} }
else else
{ {
......
...@@ -2073,7 +2073,7 @@ inline void buf_pool_t::resize() ...@@ -2073,7 +2073,7 @@ inline void buf_pool_t::resize()
static void buf_resize_callback(void *) static void buf_resize_callback(void *)
{ {
DBUG_ENTER("buf_resize_callback"); DBUG_ENTER("buf_resize_callback");
ut_a(srv_shutdown_state == SRV_SHUTDOWN_NONE); ut_ad(srv_shutdown_state < SRV_SHUTDOWN_CLEANUP);
mysql_mutex_lock(&buf_pool.mutex); mysql_mutex_lock(&buf_pool.mutex);
const auto size= srv_buf_pool_size; const auto size= srv_buf_pool_size;
const bool work= srv_buf_pool_old_size != size; const bool work= srv_buf_pool_old_size != size;
......
...@@ -5496,9 +5496,10 @@ ha_innobase::open(const char* name, int, uint) ...@@ -5496,9 +5496,10 @@ ha_innobase::open(const char* name, int, uint)
innobase_copy_frm_flags_from_table_share(ib_table, table->s); innobase_copy_frm_flags_from_table_share(ib_table, table->s);
const bool bk_thread = THDVAR(thd, background_thread);
/* No point to init any statistics if tablespace is still encrypted /* No point to init any statistics if tablespace is still encrypted
or if table is being opened by background thread */ or if table is being opened by background thread */
if (THDVAR(thd, background_thread)) { if (bk_thread) {
} else if (ib_table->is_readable()) { } else if (ib_table->is_readable()) {
dict_stats_init(ib_table); dict_stats_init(ib_table);
} else { } else {
...@@ -5697,11 +5698,14 @@ ha_innobase::open(const char* name, int, uint) ...@@ -5697,11 +5698,14 @@ ha_innobase::open(const char* name, int, uint)
} }
} }
if (table && m_prebuilt->table) { ut_ad(!m_prebuilt->table
ut_ad(table->versioned() == m_prebuilt->table->versioned()); || table->versioned() == m_prebuilt->table->versioned());
if (!bk_thread) {
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST
| HA_STATUS_OPEN);
} }
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_OPEN);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -154,7 +154,6 @@ bool PFS_table_context::initialize(void) ...@@ -154,7 +154,6 @@ bool PFS_table_context::initialize(void)
m_map= context->m_map; m_map= context->m_map;
DBUG_ASSERT(m_map_size == context->m_map_size); DBUG_ASSERT(m_map_size == context->m_map_size);
m_map_size= context->m_map_size; m_map_size= context->m_map_size;
m_word_size= context->m_word_size;
} }
} }
else else
...@@ -168,7 +167,6 @@ bool PFS_table_context::initialize(void) ...@@ -168,7 +167,6 @@ bool PFS_table_context::initialize(void)
/* Initialize a new context, store in TLS. */ /* Initialize a new context, store in TLS. */
m_last_version= m_current_version; m_last_version= m_current_version;
m_map= NULL; m_map= NULL;
m_word_size= sizeof(ulong) * 8;
/* Allocate a bitmap to record which threads are materialized. */ /* Allocate a bitmap to record which threads are materialized. */
if (m_map_size > 0) if (m_map_size > 0)
...@@ -190,7 +188,7 @@ bool PFS_table_context::initialize(void) ...@@ -190,7 +188,7 @@ bool PFS_table_context::initialize(void)
/* Constructor for global or single thread tables, map size = 0. */ /* Constructor for global or single thread tables, map size = 0. */
PFS_table_context::PFS_table_context(ulonglong current_version, bool restore, thread_local_key_t key) : PFS_table_context::PFS_table_context(ulonglong current_version, bool restore, thread_local_key_t key) :
m_thr_key(key), m_current_version(current_version), m_last_version(0), m_thr_key(key), m_current_version(current_version), m_last_version(0),
m_map(NULL), m_map_size(0), m_word_size(sizeof(ulong)), m_map(NULL), m_map_size(0),
m_restore(restore), m_initialized(false), m_last_item(0) m_restore(restore), m_initialized(false), m_last_item(0)
{ {
initialize(); initialize();
...@@ -199,7 +197,7 @@ PFS_table_context::PFS_table_context(ulonglong current_version, bool restore, th ...@@ -199,7 +197,7 @@ PFS_table_context::PFS_table_context(ulonglong current_version, bool restore, th
/* Constructor for by-thread or aggregate tables, map size = max thread/user/host/account. */ /* Constructor for by-thread or aggregate tables, map size = max thread/user/host/account. */
PFS_table_context::PFS_table_context(ulonglong current_version, ulong map_size, bool restore, thread_local_key_t key) : PFS_table_context::PFS_table_context(ulonglong current_version, ulong map_size, bool restore, thread_local_key_t key) :
m_thr_key(key), m_current_version(current_version), m_last_version(0), m_thr_key(key), m_current_version(current_version), m_last_version(0),
m_map(NULL), m_map_size(map_size), m_word_size(sizeof(ulong)), m_map(NULL), m_map_size(map_size),
m_restore(restore), m_initialized(false), m_last_item(0) m_restore(restore), m_initialized(false), m_last_item(0)
{ {
initialize(); initialize();
...@@ -220,7 +218,7 @@ void PFS_table_context::set_item(ulong n) ...@@ -220,7 +218,7 @@ void PFS_table_context::set_item(ulong n)
return; return;
ulong word= n / m_word_size; ulong word= n / m_word_size;
ulong bit= n % m_word_size; ulong bit= n % m_word_size;
m_map[word] |= (1 << bit); m_map[word] |= (1UL << bit);
m_last_item= n; m_last_item= n;
} }
......
...@@ -74,7 +74,7 @@ class PFS_table_context ...@@ -74,7 +74,7 @@ class PFS_table_context
ulonglong m_last_version; ulonglong m_last_version;
ulong *m_map; ulong *m_map;
ulong m_map_size; ulong m_map_size;
ulong m_word_size; static constexpr ulong m_word_size= 8 * sizeof(ulong);
bool m_restore; bool m_restore;
bool m_initialized; bool m_initialized;
ulong m_last_item; ulong m_last_item;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment