summaryrefslogtreecommitdiff
path: root/sql/sql_servers.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_servers.cc')
-rw-r--r--sql/sql_servers.cc106
1 files changed, 95 insertions, 11 deletions
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index 7913a7d2b9f..d52d6071e89 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -93,6 +93,8 @@ static uchar *servers_cache_get_key(FOREIGN_SERVER *server, size_t *length,
DBUG_RETURN((uchar*) server->server_name);
}
+static PSI_memory_key key_memory_servers;
+
#ifdef HAVE_PSI_INTERFACE
static PSI_rwlock_key key_rwlock_THR_LOCK_servers;
@@ -101,6 +103,11 @@ static PSI_rwlock_info all_servers_cache_rwlocks[]=
{ &key_rwlock_THR_LOCK_servers, "THR_LOCK_servers", PSI_FLAG_GLOBAL}
};
+static PSI_memory_info all_servers_cache_memory[]=
+{
+ { &key_memory_servers, "servers_cache", PSI_FLAG_GLOBAL}
+};
+
static void init_servers_cache_psi_keys(void)
{
const char* category= "sql";
@@ -111,9 +118,87 @@ static void init_servers_cache_psi_keys(void)
count= array_elements(all_servers_cache_rwlocks);
PSI_server->register_rwlock(category, all_servers_cache_rwlocks, count);
+
+ count= array_elements(all_servers_cache_memory);
+ mysql_memory_register(category, all_servers_cache_memory, count);
}
#endif /* HAVE_PSI_INTERFACE */
+
+struct close_cached_connection_tables_arg
+{
+ THD *thd;
+ LEX_CSTRING *connection;
+ TABLE_LIST *tables;
+};
+
+
+static my_bool close_cached_connection_tables_callback(
+ TDC_element *element, close_cached_connection_tables_arg *arg)
+{
+ TABLE_LIST *tmp;
+
+ mysql_mutex_lock(&element->LOCK_table_share);
+ /* Ignore if table is not open or does not have a connect_string */
+ if (!element->share || !element->share->connect_string.length ||
+ !element->ref_count)
+ goto end;
+
+ /* Compare the connection string */
+ if (arg->connection &&
+ (arg->connection->length > element->share->connect_string.length ||
+ (arg->connection->length < element->share->connect_string.length &&
+ (element->share->connect_string.str[arg->connection->length] != '/' &&
+ element->share->connect_string.str[arg->connection->length] != '\\')) ||
+ strncasecmp(arg->connection->str, element->share->connect_string.str,
+ arg->connection->length)))
+ goto end;
+
+ /* close_cached_tables() only uses these elements */
+ if (!(tmp= (TABLE_LIST*) alloc_root(arg->thd->mem_root, sizeof(TABLE_LIST))) ||
+ !(arg->thd->make_lex_string(&tmp->db, element->share->db.str, element->share->db.length)) ||
+ !(arg->thd->make_lex_string(&tmp->table_name, element->share->table_name.str,
+ element->share->table_name.length)))
+ {
+ mysql_mutex_unlock(&element->LOCK_table_share);
+ return TRUE;
+ }
+
+ tmp->next_global= tmp->next_local= arg->tables;
+ MDL_REQUEST_INIT(&tmp->mdl_request, MDL_key::TABLE, tmp->db.str,
+ tmp->table_name.str, MDL_EXCLUSIVE, MDL_TRANSACTION);
+ arg->tables= tmp;
+
+end:
+ mysql_mutex_unlock(&element->LOCK_table_share);
+ return FALSE;
+}
+
+
+/**
+ Close all tables which match specified connection string or
+ if specified string is NULL, then any table with a connection string.
+
+ @return false ok
+ @return true error, some tables may keep using old server info
+*/
+
+static bool close_cached_connection_tables(THD *thd, LEX_CSTRING *connection)
+{
+ close_cached_connection_tables_arg argument= { thd, connection, 0 };
+ DBUG_ENTER("close_cached_connections");
+
+ if (tdc_iterate(thd,
+ (my_hash_walk_action) close_cached_connection_tables_callback,
+ &argument))
+ DBUG_RETURN(true);
+
+ DBUG_RETURN(argument.tables ?
+ close_cached_tables(thd, argument.tables, true,
+ thd->variables.lock_wait_timeout) : false);
+}
+
+
/*
Initialize structures responsible for servers used in federated
server scheme information for them from the server
@@ -148,7 +233,7 @@ bool servers_init(bool dont_read_servers_table)
DBUG_RETURN(TRUE);
/* initialise our servers cache */
- if (my_hash_init(&servers_cache, system_charset_info, 32, 0, 0,
+ if (my_hash_init(key_memory_servers, &servers_cache, system_charset_info, 32, 0, 0,
(my_hash_get_key) servers_cache_get_key, 0, 0))
{
return_val= TRUE; /* we failed, out of memory? */
@@ -156,7 +241,7 @@ bool servers_init(bool dont_read_servers_table)
}
/* Initialize the mem root for data */
- init_sql_alloc(&mem, "servers", ACL_ALLOC_BLOCK_SIZE, 0,
+ init_sql_alloc(key_memory_servers, &mem, ACL_ALLOC_BLOCK_SIZE, 0,
MYF(MY_THREAD_SPECIFIC));
if (dont_read_servers_table)
@@ -206,7 +291,7 @@ static bool servers_load(THD *thd, TABLE_LIST *tables)
my_hash_reset(&servers_cache);
free_root(&mem, MYF(0));
- init_sql_alloc(&mem, "servers_load", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
+ init_sql_alloc(key_memory_servers, &mem, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
if (init_read_record(&read_record_info,thd,table=tables[0].table, NULL, NULL,
1,0, FALSE))
@@ -394,6 +479,7 @@ insert_server(THD *thd, FOREIGN_SERVER *server)
/* need to open before acquiring THR_LOCK_plugin or it will deadlock */
if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
goto end;
+ table->file->row_logging= 0; // Don't log to binary log
/* insert the server into the table */
if (unlikely(error= insert_server_record(table, server)))
@@ -532,9 +618,9 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server)
{
int error;
DBUG_ENTER("insert_server_record");
- tmp_disable_binlog(table->in_use);
- table->use_all_columns();
+ DBUG_ASSERT(!table->file->row_logging);
+ table->use_all_columns();
empty_record(table);
/* set the field that's the PK to the value we're looking for */
@@ -567,8 +653,6 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server)
}
else
error= ER_FOREIGN_SERVER_EXISTS;
-
- reenable_binlog(table->in_use);
DBUG_RETURN(error);
}
@@ -885,7 +969,8 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server)
{
int error=0;
DBUG_ENTER("update_server_record");
- tmp_disable_binlog(table->in_use);
+ DBUG_ASSERT(!table->file->row_logging);
+
table->use_all_columns();
/* set the field that's the PK to the value we're looking for */
table->field[0]->store(server->server_name,
@@ -921,7 +1006,6 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server)
}
end:
- reenable_binlog(table->in_use);
DBUG_RETURN(error);
}
@@ -946,7 +1030,8 @@ delete_server_record(TABLE *table, LEX_CSTRING *name)
{
int error;
DBUG_ENTER("delete_server_record");
- tmp_disable_binlog(table->in_use);
+ DBUG_ASSERT(!table->file->row_logging);
+
table->use_all_columns();
/* set the field that's the PK to the value we're looking for */
@@ -970,7 +1055,6 @@ delete_server_record(TABLE *table, LEX_CSTRING *name)
table->file->print_error(error, MYF(0));
}
- reenable_binlog(table->in_use);
DBUG_RETURN(error);
}