Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions sql/handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1852,7 +1852,7 @@ int ha_commit_trans(THD *thd, bool all)
&no_rollback);
/* rw_trans is TRUE when we in a transaction changing data */
bool rw_trans= is_real_trans && rw_ha_count > 0;
MDL_request mdl_backup;
bool backup_commit_lock_acquired= false;
DBUG_PRINT("info", ("is_real_trans: %d rw_trans: %d rw_ha_count: %d",
is_real_trans, rw_trans, rw_ha_count));

Expand All @@ -1872,19 +1872,17 @@ int ha_commit_trans(THD *thd, bool all)
We allow the owner of FTWRL to COMMIT; we assume that it knows
what it does.
*/
MDL_REQUEST_INIT(&mdl_backup, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT);

if (!WSREP(thd))
{
if (thd->mdl_context.acquire_lock(&mdl_backup,
thd->variables.lock_wait_timeout))
if (!(thd->backup_commit_lock= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT, thd->variables.lock_wait_timeout)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), 1);
ha_rollback_trans(thd, all);
DBUG_RETURN(1);
}
thd->backup_commit_lock= &mdl_backup;
backup_commit_lock_acquired= true;
}
DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock");
}
Expand Down Expand Up @@ -2134,17 +2132,16 @@ int ha_commit_trans(THD *thd, bool all)
thd->rgi_slave->is_parallel_exec);
}
end:
// reset the pointer to the ticket when it's stack instantiated
if (thd->backup_commit_lock == &mdl_backup)
// release the backup commit lock if we acquired it in this function
if (backup_commit_lock_acquired && thd->backup_commit_lock)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backup_commit_lock_acquired == true implies valid thd->backup_commit_lock.

{
/*
We do not always immediately release transactional locks
after ha_commit_trans() (see uses of ha_enable_transaction()),
thus we release the commit blocker lock as soon as it's
not needed.
*/
if (mdl_backup.ticket)
thd->mdl_context.release_lock(mdl_backup.ticket);
thd->mdl_context.release_lock(thd->backup_commit_lock);
thd->backup_commit_lock= 0;
}
#ifdef WITH_WSREP
Expand Down
46 changes: 20 additions & 26 deletions sql/log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8811,19 +8811,15 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
}
else
{
MDL_request mdl_request;

MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT);
if (thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout))
if (!(thd->backup_commit_lock= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT, thd->variables.lock_wait_timeout)))
DBUG_RETURN(1);
thd->backup_commit_lock= &mdl_request;

if ((res= thd->wait_for_prior_commit()))
{
if (mdl_request.ticket)
thd->mdl_context.release_lock(mdl_request.ticket);
if (thd->backup_commit_lock)
thd->mdl_context.release_lock(thd->backup_commit_lock);
thd->backup_commit_lock= 0;
DBUG_RETURN(res);
}
Expand All @@ -8833,8 +8829,8 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
prev_binlog_id= current_binlog_id;
res= write_gtid_event(thd, nullptr, true, using_trans, commit_id,
false, false, false);
if (mdl_request.ticket)
thd->mdl_context.release_lock(mdl_request.ticket);
if (thd->backup_commit_lock)
thd->mdl_context.release_lock(thd->backup_commit_lock);
thd->backup_commit_lock= 0;
if (res)
goto err;
Expand Down Expand Up @@ -8944,7 +8940,6 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
&cache_data->engine_binlog_info;
engine_context->gtid_offset= my_b_tell(file);
my_off_t binlog_total_bytes;
MDL_request mdl_request;
int res;

if (engine_context->out_of_band_offset)
Expand All @@ -8957,17 +8952,15 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
goto engine_fail;
}

MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT);
if (thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout))
if (!(thd->backup_commit_lock= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT, thd->variables.lock_wait_timeout)))
goto engine_fail;
thd->backup_commit_lock= &mdl_request;

if (thd->wait_for_prior_commit())
{
if (mdl_request.ticket)
thd->mdl_context.release_lock(mdl_request.ticket);
if (thd->backup_commit_lock)
thd->mdl_context.release_lock(thd->backup_commit_lock);
thd->backup_commit_lock= 0;
goto engine_fail;
}
Expand All @@ -8985,8 +8978,8 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
mysql_mutex_lock(&LOCK_log);
res= write_gtid_event(thd, cache_data, true, using_trans, commit_id,
false, false, false);
if (mdl_request.ticket)
thd->mdl_context.release_lock(mdl_request.ticket);
if (thd->backup_commit_lock)
thd->mdl_context.release_lock(thd->backup_commit_lock);
thd->backup_commit_lock= 0;
if (res)
{
Expand Down Expand Up @@ -10258,12 +10251,12 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry)
yet have the MDL_BACKUP_COMMIT_LOCK) and any threads using
BACKUP LOCK BLOCK_COMMIT.
*/
if (thd->backup_commit_lock && thd->backup_commit_lock->ticket &&
if (thd->backup_commit_lock &&
!backup_lock_released)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to keep backup_lock_released check here? Looks like it was redundant: I don't see any loops and gotos around it.

{
backup_lock_released= 1;
thd->mdl_context.release_lock(thd->backup_commit_lock->ticket);
thd->backup_commit_lock->ticket= 0;
thd->mdl_context.release_lock(thd->backup_commit_lock);
thd->backup_commit_lock= 0;
}

/*
Expand Down Expand Up @@ -10527,8 +10520,9 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry)

end:
if (backup_lock_released)
thd->mdl_context.acquire_lock(thd->backup_commit_lock,
thd->variables.lock_wait_timeout);
thd->backup_commit_lock= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT, thd->variables.lock_wait_timeout);
DBUG_RETURN(result);
}

Expand Down
20 changes: 20 additions & 0 deletions sql/mdl.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,10 @@ typedef void (*mdl_cached_object_release_hook)(void *);
#define MDL_TRY_ACQUIRE_LOCK(NAMESPACE, DB, NAME, TYPE, DURATION, ERROR) \
try_acquire_lock(NAMESPACE, DB, NAME, TYPE, DURATION, ERROR, __FILE__, __LINE__)

#define MDL_REQUEST_LIST_ADD(LIST, MEM_ROOT, NAMESPACE, DB, NAME, TYPE, DURATION) \
mdl_request_list_add(LIST, MEM_ROOT, NAMESPACE, DB, NAME, TYPE, DURATION, \
__FILE__, __LINE__)


/**
An abstract class for inspection of a connected
Expand Down Expand Up @@ -794,6 +798,22 @@ typedef I_P_List<MDL_request, I_P_List_adapter<MDL_request,
I_P_List_counter>
MDL_request_list;

inline bool mdl_request_list_add(MDL_request_list *list, MEM_ROOT *mem_root,
MDL_key::enum_mdl_namespace mdl_namespace,
const char *db, const char *name,
enum_mdl_type mdl_type,
enum_mdl_duration mdl_duration,
const char *src_file, uint src_line)
{
MDL_request *r= new (mem_root) MDL_request;
if (!r)
return true;
r->init_with_source(mdl_namespace, db, name, mdl_type, mdl_duration,
src_file, src_line);
list->push_front(r);
return false;
}

/**
Context of the owner of metadata locks. I.e. each server
connection has such a context.
Expand Down
9 changes: 4 additions & 5 deletions sql/partition_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -926,12 +926,11 @@ bool vers_create_partitions(THD *thd, TABLE_LIST* tl, uint num_parts)
create_info.alter_info= &alter_info;
Alter_table_ctx alter_ctx(thd, tl, 1, &table->s->db, &table->s->table_name);

MDL_REQUEST_INIT(&tl->mdl_request, MDL_key::TABLE, tl->db.str,
tl->table_name.str, MDL_SHARED_NO_WRITE, MDL_TRANSACTION);
if (thd->mdl_context.acquire_lock(&tl->mdl_request,
thd->variables.lock_wait_timeout))
if (!(table->mdl_ticket= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::TABLE, tl->db.str, tl->table_name.str,
MDL_SHARED_NO_WRITE, MDL_TRANSACTION,
thd->variables.lock_wait_timeout)))
goto exit;
table->mdl_ticket= tl->mdl_request.ticket;

create_info.db_type= table->s->db_type();
create_info.options|= HA_VERSIONED_TABLE;
Expand Down
8 changes: 4 additions & 4 deletions sql/sp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1876,14 +1876,14 @@ bool lock_db_routines(THD *thd, const Lex_ident_db_normalized &db)
continue;

longlong sp_type= table->field[MYSQL_PROC_MYSQL_TYPE]->val_int();
MDL_request *mdl_request= new (thd->mem_root) MDL_request;
const Sp_handler *sph= Sp_handler::handler((enum_sp_type)
sp_type);
if (!sph)
sph= &sp_handler_procedure;
MDL_REQUEST_INIT(mdl_request, sph->get_mdl_type(), db.str, sp_name,
MDL_EXCLUSIVE, MDL_TRANSACTION);
mdl_requests.push_front(mdl_request);
if (MDL_REQUEST_LIST_ADD(&mdl_requests, thd->mem_root,
sph->get_mdl_type(), db.str, sp_name,
MDL_EXCLUSIVE, MDL_TRANSACTION))
goto error;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't just goto error here without calling ha_index_end().

} while (! (nxtres= table->file->ha_index_next_same(table->record[0], keybuf, key_len)));
}
table->file->ha_index_end();
Expand Down
8 changes: 3 additions & 5 deletions sql/sql_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4490,12 +4490,10 @@ lock_table_names(THD *thd, const DDL_options_st &options,
/* Scoped locks: Take intention exclusive locks on all involved schemas. */
if (!(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK))
{
MDL_request *schema_request= new (thd->mem_root) MDL_request;
if (schema_request == NULL)
if (MDL_REQUEST_LIST_ADD(&mdl_requests, thd->mem_root,
MDL_key::SCHEMA, table->db.str, "",
MDL_INTENTION_EXCLUSIVE, MDL_TRANSACTION))
DBUG_RETURN(TRUE);
MDL_REQUEST_INIT(schema_request, MDL_key::SCHEMA, table->db.str, "",
MDL_INTENTION_EXCLUSIVE, MDL_TRANSACTION);
mdl_requests.push_front(schema_request);
}

mdl_requests.push_front(&table->mdl_request);
Expand Down
16 changes: 9 additions & 7 deletions sql/sql_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8565,11 +8565,11 @@ wait_for_commit::wait_for_prior_commit2(THD *thd, bool allow_kill)
yet have the MDL_BACKUP_COMMIT_LOCK) and any threads using
BACKUP LOCK BLOCK_COMMIT.
*/
if (thd->backup_commit_lock && thd->backup_commit_lock->ticket)
if (thd->backup_commit_lock)
{
backup_lock_released= true;
thd->mdl_context.release_lock(thd->backup_commit_lock->ticket);
thd->backup_commit_lock->ticket= 0;
thd->mdl_context.release_lock(thd->backup_commit_lock);
thd->backup_commit_lock= 0;
}

mysql_mutex_lock(&LOCK_wait_commit);
Expand Down Expand Up @@ -8625,15 +8625,17 @@ wait_for_commit::wait_for_prior_commit2(THD *thd, bool allow_kill)
*/
DEBUG_SYNC(thd, "wait_for_prior_commit_killed");
if (unlikely(backup_lock_released))
thd->mdl_context.acquire_lock(thd->backup_commit_lock,
thd->variables.lock_wait_timeout);
thd->backup_commit_lock= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT, thd->variables.lock_wait_timeout);
return wakeup_error;

end:
thd->EXIT_COND(&old_stage);
if (unlikely(backup_lock_released))
thd->mdl_context.acquire_lock(thd->backup_commit_lock,
thd->variables.lock_wait_timeout);
thd->backup_commit_lock= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT, thd->variables.lock_wait_timeout);
return wakeup_error;
}

Expand Down
2 changes: 1 addition & 1 deletion sql/sql_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -3369,7 +3369,7 @@ class THD: public THD_count, /* this must be first */
/* Used for BACKUP LOCK */
MDL_ticket *mdl_backup_ticket, *mdl_backup_lock;
/* Used to register that thread has a MDL_BACKUP_WAIT_COMMIT lock */
MDL_request *backup_commit_lock;
MDL_ticket *backup_commit_lock;

void reset_for_next_command(bool do_clear_errors= 1);

Expand Down
15 changes: 5 additions & 10 deletions sql/sql_reload.cc
Original file line number Diff line number Diff line change
Expand Up @@ -173,18 +173,13 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
tmp_write_to_binlog= 0;
if (mysql_bin_log.is_open())
{
MDL_request mdl_request;
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_START,
MDL_EXPLICIT);
if (thd &&
thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout))
!(thd->backup_commit_lock= thd->mdl_context.MDL_ACQUIRE_LOCK(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use thd->backup_commit_lock here, make local MDL_ticket *ticket instead.

MDL_key::BACKUP, "", "", MDL_BACKUP_START,
MDL_EXPLICIT, thd->variables.lock_wait_timeout)))
result= 1;
else
{
if (thd)
thd->backup_commit_lock= &mdl_request;

DYNAMIC_ARRAY *drop_gtid_domain=
(thd && (thd->lex->delete_gtid_domain.elements > 0)) ?
&thd->lex->delete_gtid_domain : NULL;
Expand All @@ -200,8 +195,8 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
}
if (thd)
{
if (mdl_request.ticket)
thd->mdl_context.release_lock(mdl_request.ticket);
if (thd->backup_commit_lock)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition looks redundant, you already check that ticket contains valid value when you acquire the lock.

thd->mdl_context.release_lock(thd->backup_commit_lock);
thd->backup_commit_lock= 0;
}
}
Expand Down
28 changes: 10 additions & 18 deletions sql/sql_repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -800,13 +800,11 @@ bool purge_master_logs(THD* thd, const char* to_log)
return FALSE;
}

MDL_request mdl_request;
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_START,
MDL_EXPLICIT);
if (thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout))
MDL_ticket *ticket;
if (!(ticket= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::BACKUP, "", "", MDL_BACKUP_START,
MDL_EXPLICIT, thd->variables.lock_wait_timeout)))
return TRUE;
thd->backup_commit_lock= &mdl_request;

int res;
if (!opt_binlog_engine_hton)
Expand Down Expand Up @@ -849,9 +847,7 @@ bool purge_master_logs(THD* thd, const char* to_log)
purge_info.nonpurge_filename, true);
}

if (mdl_request.ticket)
thd->mdl_context.release_lock(mdl_request.ticket);
thd->backup_commit_lock= 0;
thd->mdl_context.release_lock(ticket);

return purge_error_message(thd, res);
}
Expand Down Expand Up @@ -4904,23 +4900,19 @@ int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len,
#endif /* WITH_WSREP */
bool ret= 0;

MDL_request mdl_request;
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_START,
MDL_EXPLICIT);
Comment thread
svoj marked this conversation as resolved.
if (thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout))
MDL_ticket *ticket;
if (!(ticket= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::BACKUP, "", "", MDL_BACKUP_START,
MDL_EXPLICIT, thd->variables.lock_wait_timeout)))
return 1;
thd->backup_commit_lock= &mdl_request;

/* Temporarily disable master semisync before resetting master. */
repl_semisync_master.before_reset_master();
ret= mysql_bin_log.reset_logs(thd, 1, init_state, init_state_len,
next_log_number);
repl_semisync_master.after_reset_master();

if (mdl_request.ticket)
thd->mdl_context.release_lock(mdl_request.ticket);
thd->backup_commit_lock= 0;
thd->mdl_context.release_lock(ticket);

DBUG_EXECUTE_IF("crash_after_reset_master", DBUG_SUICIDE(););

Expand Down
Loading
Loading