Commit f8268f3c authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-17195 Speedup lock-ddl-per-table, if there is a large number of tables

Query INFORMATION_SCHEMA.INNODB_SYS_TABLES only once, and cache results.

As a small cleanup, remove  mdl_lock_con_mutex, the MDL handling
connection is never accessed by multiple threads at the same time.
parent dc91ea5b
...@@ -1758,62 +1758,63 @@ backup_cleanup() ...@@ -1758,62 +1758,63 @@ backup_cleanup()
} }
static pthread_mutex_t mdl_lock_con_mutex;
static MYSQL *mdl_con = NULL; static MYSQL *mdl_con = NULL;
std::map<ulint, std::string> spaceid_to_tablename;
void void
mdl_lock_init() mdl_lock_init()
{ {
pthread_mutex_init(&mdl_lock_con_mutex, NULL);
mdl_con = xb_mysql_connect(); mdl_con = xb_mysql_connect();
if (mdl_con) if (!mdl_con)
{ {
xb_mysql_query(mdl_con, "BEGIN", false, true); msg("FATAL: cannot create connection for MDL locks");
exit(1);
}
const char *query =
"SELECT NAME, SPACE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%%/%%'";
MYSQL_RES *mysql_result = xb_mysql_query(mdl_con, query, true, true);
while (MYSQL_ROW row = mysql_fetch_row(mysql_result)) {
int err;
ulint id = (ulint)my_strtoll10(row[1], 0, &err);
spaceid_to_tablename[id] = ut_get_name(0, row[0]);
} }
mysql_free_result(mysql_result);
xb_mysql_query(mdl_con, "BEGIN", false, true);
} }
void void
mdl_lock_table(ulint space_id) mdl_lock_table(ulint space_id)
{ {
std::ostringstream oss; if (space_id == 0)
oss << "SELECT NAME " return;
"FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES "
"WHERE SPACE = " << space_id << " AND NAME LIKE '%%/%%'";
pthread_mutex_lock(&mdl_lock_con_mutex); std::string full_table_name = spaceid_to_tablename[space_id];
MYSQL_RES *mysql_result = xb_mysql_query(mdl_con, oss.str().c_str(), true, true); DBUG_EXECUTE_IF("rename_during_mdl_lock_table",
if (full_table_name == "`test`.`t1`")
xb_mysql_query(mysql_connection, "RENAME TABLE test.t1 to test.t2", false, true);
);
while (MYSQL_ROW row = mysql_fetch_row(mysql_result)) { std::ostringstream lock_query;
lock_query << "SELECT 1 FROM " << full_table_name << " LIMIT 0";
DBUG_EXECUTE_IF("rename_during_mdl_lock_table", msg_ts("Locking MDL for %s\n", full_table_name.c_str());
if (strcmp(row[0], "test/t1") == 0) if (mysql_query(mdl_con, lock_query.str().c_str())) {
xb_mysql_query(mysql_connection, "RENAME TABLE test.t1 to test.t2", false, true
););
std::string full_table_name = ut_get_name(0,row[0]);
std::ostringstream lock_query;
lock_query << "SELECT 1 FROM " << full_table_name << " LIMIT 0";
msg_ts("Locking MDL for %s\n", full_table_name.c_str());
if (mysql_query(mdl_con, lock_query.str().c_str())) {
msg_ts("Warning : locking MDL failed for space id %zu, name %s\n", space_id, full_table_name.c_str()); msg_ts("Warning : locking MDL failed for space id %zu, name %s\n", space_id, full_table_name.c_str());
} else { } else {
MYSQL_RES *r = mysql_store_result(mdl_con); MYSQL_RES *r = mysql_store_result(mdl_con);
mysql_free_result(r); mysql_free_result(r);
}
} }
pthread_mutex_unlock(&mdl_lock_con_mutex);
mysql_free_result(mysql_result);
} }
void void
mdl_unlock_all() mdl_unlock_all()
{ {
msg_ts("Unlocking MDL for all tables\n"); msg_ts("Unlocking MDL for all tables\n");
xb_mysql_query(mdl_con, "COMMIT", false, true); xb_mysql_query(mdl_con, "COMMIT", false, true);
mysql_close(mdl_con); mysql_close(mdl_con);
pthread_mutex_destroy(&mdl_lock_con_mutex); spaceid_to_tablename.clear();
} }
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