1
0
mirror of https://github.com/MariaDB/server.git synced 2025-06-13 13:01:51 +03:00

MDEV-6156: Parallel replication incorrectly caches charset between worker threads

The previous patch for this bug was unfortunately completely wrong.

The purpose of cached_charset is to remember which character set we
have installed currently in the THD, so that in the common case where
charset does not change between queries, we do not need to update it
in the THD. Thus, it is important that the cached_charset field is
tightly coupled to the THD for which it handles caching.

Thus the right place to put cached_charset seems to be in the THD.
This patch introduces a field THD:system_thread_info where such info
in general can be placed without further inflating the THD with unused
data for other threads (THD is already far too big as it is). It then
moves the cached_charset into this slot for the SQL driver thread and
for the parallel replication worker threads.

The THD::rpl_filter field is also moved inside system_thread_info, to
keep the size of THD unchanged. Moving further fields in to reduce the
size of THD is a separate task, filed as MDEV-6164.
This commit is contained in:
unknown
2014-04-25 12:58:31 +02:00
parent d3d3a4b834
commit 64923bb653
9 changed files with 134 additions and 76 deletions

View File

@ -171,8 +171,9 @@ const char *xa_state_names[]={
*/
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
{
return thd->rpl_filter->is_on() && tables && !thd->spcont &&
!thd->rpl_filter->tables_ok(thd->db, tables);
Rpl_filter *rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
return rpl_filter->is_on() && tables && !thd->spcont &&
!rpl_filter->tables_ok(thd->db, tables);
}
#endif
@ -2233,7 +2234,7 @@ mysql_execute_command(THD *thd)
/* have table map for update for multi-update statement (BUG#37051) */
bool have_table_map_for_update= FALSE;
/* */
Rpl_filter *rpl_filter= thd->rpl_filter;
Rpl_filter *rpl_filter;
#endif
DBUG_ENTER("mysql_execute_command");
@ -3885,12 +3886,15 @@ end_with_restore_list:
above was not called. So we have to check rules again here.
*/
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
(!rpl_filter->db_ok(lex->name.str) ||
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
if (thd->slave_thread)
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
if (!rpl_filter->db_ok(lex->name.str) ||
!rpl_filter->db_ok_with_wild_table(lex->name.str))
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
}
#endif
if (check_access(thd, CREATE_ACL, lex->name.str, NULL, NULL, 1, 0))
@ -3913,12 +3917,15 @@ end_with_restore_list:
above was not called. So we have to check rules again here.
*/
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
(!rpl_filter->db_ok(lex->name.str) ||
!rpl_filter->db_ok_with_wild_table(lex->name.str)))
if (thd->slave_thread)
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
if (!rpl_filter->db_ok(lex->name.str) ||
!rpl_filter->db_ok_with_wild_table(lex->name.str))
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
}
#endif
if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0))
@ -3930,13 +3937,16 @@ end_with_restore_list:
{
LEX_STRING *db= & lex->name;
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
(!rpl_filter->db_ok(db->str) ||
!rpl_filter->db_ok_with_wild_table(db->str)))
if (thd->slave_thread)
{
res= 1;
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
if (!rpl_filter->db_ok(db->str) ||
!rpl_filter->db_ok_with_wild_table(db->str))
{
res= 1;
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
}
#endif
if (check_db_name(db))
@ -3973,12 +3983,15 @@ end_with_restore_list:
above was not called. So we have to check rules again here.
*/
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
(!rpl_filter->db_ok(db->str) ||
!rpl_filter->db_ok_with_wild_table(db->str)))
if (thd->slave_thread)
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
if (!rpl_filter->db_ok(db->str) ||
!rpl_filter->db_ok_with_wild_table(db->str))
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
}
#endif
if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0))