summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field_conv.cc2
-rw-r--r--sql/handler.cc39
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_parse.cc18
-rw-r--r--sql/table.cc3
-rw-r--r--sql/table.h9
6 files changed, 57 insertions, 16 deletions
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 0c385efd10b..f718a3d778c 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -593,7 +593,7 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
do_cut_string : do_cut_string_complex);
else if (to_length > from_length)
{
- if ((to->flags & BINARY_FLAG) != 0)
+ if (to->charset() == &my_charset_bin)
return do_expand_binary;
else
return do_expand_string;
diff --git a/sql/handler.cc b/sql/handler.cc
index 76c3ebd3387..7b232f343c0 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -3150,16 +3150,47 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
declared static, but it works by putting it into an anonymous
namespace. */
namespace {
+ struct st_table_data {
+ char const *db;
+ char const *name;
+ };
+
+ int table_name_compare(void const *a, void const *b)
+ {
+ st_table_data const *x = (st_table_data const*) a;
+ st_table_data const *y = (st_table_data const*) b;
+
+ /* Doing lexical compare in order (db,name) */
+ int const res= strcmp(x->db, y->db);
+ return res != 0 ? res : strcmp(x->name, y->name);
+ }
+
bool check_table_binlog_row_based(THD *thd, TABLE *table)
{
+ static st_table_data const ignore[] = {
+ { "mysql", "event" },
+ { "mysql", "general_log" },
+ { "mysql", "slow_log" }
+ };
+
+ my_size_t const ignore_size = sizeof(ignore)/sizeof(*ignore);
+ st_table_data const item = { table->s->db.str, table->s->table_name.str };
+
+ if (table->s->cached_row_logging_check == -1)
+ table->s->cached_row_logging_check=
+ (table->s->tmp_table == NO_TMP_TABLE) &&
+ binlog_filter->db_ok(table->s->db.str) &&
+ bsearch(&item, ignore, ignore_size,
+ sizeof(st_table_data), table_name_compare) == NULL;
+
+ DBUG_ASSERT(table->s->cached_row_logging_check == 0 ||
+ table->s->cached_row_logging_check == 1);
+
return
thd->current_stmt_binlog_row_based &&
thd && (thd->options & OPTION_BIN_LOG) &&
- (table->s->tmp_table == NO_TMP_TABLE) &&
mysql_bin_log.is_open() &&
- binlog_filter->db_ok(table->s->db.str) &&
- (strcmp(table->s->db.str, "mysql") ||
- strcmp(table->s->table_name.str, "event"));
+ table->s->cached_row_logging_check;
}
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index f656f03ddc2..ee0f4e8ad1f 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -2602,7 +2602,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype,
moving back and forth between using RBR for replication of
system tables and not using it.
- Make sure to change in check_table_current_stmt_binlog_row_based according
+ Make sure to change in check_table_binlog_row_based() according
to how you treat this.
*/
case THD::ROW_QUERY_TYPE:
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 77dfcfe862a..a6a273f2e1b 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3144,8 +3144,8 @@ end_with_restore_list:
if (mysql_bin_log.is_open())
{
thd->clear_error(); // No binlog error generated
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ thd->query, thd->query_length, 0, FALSE);
}
}
select_lex->table_list.first= (byte*) first_table;
@@ -3178,8 +3178,8 @@ end_with_restore_list:
if (mysql_bin_log.is_open())
{
thd->clear_error(); // No binlog error generated
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ thd->query, thd->query_length, 0, FALSE);
}
}
select_lex->table_list.first= (byte*) first_table;
@@ -3203,8 +3203,8 @@ end_with_restore_list:
if (mysql_bin_log.is_open())
{
thd->clear_error(); // No binlog error generated
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ thd->query, thd->query_length, 0, FALSE);
}
}
select_lex->table_list.first= (byte*) first_table;
@@ -3865,10 +3865,8 @@ end_with_restore_list:
if (!(res= mysql_create_user(thd, lex->users_list)))
{
if (mysql_bin_log.is_open())
- {
thd->binlog_query(THD::MYSQL_QUERY_TYPE,
thd->query, thd->query_length, FALSE, FALSE);
- }
send_ok(thd);
}
break;
@@ -4058,8 +4056,8 @@ end_with_restore_list:
{
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ thd->query, thd->query_length, 0, FALSE);
}
}
send_ok(thd);
diff --git a/sql/table.cc b/sql/table.cc
index b7b235dc180..3cba2c163ea 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -146,6 +146,8 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
under the protection of the LOCK_open mutex.
*/
share->table_map_id= ~0UL;
+ share->cached_row_logging_check= -1;
+
#endif
memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root));
@@ -205,6 +207,7 @@ void init_tmp_table_share(TABLE_SHARE *share, const char *key,
*/
share->table_map_version= ~(ulonglong)0;
share->table_map_id= ~0UL;
+ share->cached_row_logging_check= -1;
#endif
DBUG_VOID_RETURN;
diff --git a/sql/table.h b/sql/table.h
index 688154dd8fc..736e4509cd8 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -191,6 +191,15 @@ typedef struct st_table_share
bool waiting_on_cond; /* Protection against free */
ulong table_map_id; /* for row-based replication */
ulonglong table_map_version;
+
+ /*
+ Cache for row-based replication table share checks that does not
+ need to be repeated. Possible values are: -1 when cache value is
+ not calculated yet, 0 when table *shall not* be replicated, 1 when
+ table *may* be replicated.
+ */
+ int cached_row_logging_check;
+
/*
TRUE if this is a system table like 'mysql.proc', which we want to be
able to open and lock even when we already have some tables open and