diff --git a/sql/handler.cc b/sql/handler.cc index 1be1b197663..050c68d0e0c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7243,39 +7243,6 @@ bool handler::check_table_binlog_row_based_internal() mysql_bin_log.is_open())); } - -#ifdef HAVE_REPLICATION -static int binlog_log_row_online_alter(TABLE* table, - const uchar *before_record, - const uchar *after_record, - Log_func *log_func) -{ - THD *thd= table->in_use; - - if (!table->online_alter_cache) - { - table->online_alter_cache= online_alter_binlog_get_cache_data(thd, table); - trans_register_ha(thd, false, binlog_hton, 0); - if (thd->in_multi_stmt_transaction_mode()) - trans_register_ha(thd, true, binlog_hton, 0); - } - - // We need to log all columns for the case if alter table changes primary key - DBUG_ASSERT(!before_record || bitmap_is_set_all(table->read_set)); - MY_BITMAP *old_rpl_write_set= table->rpl_write_set; - table->rpl_write_set= &table->s->all_set; - - int error= (*log_func)(thd, table, table->s->online_alter_binlog, - table->online_alter_cache, true, - before_record, after_record); - - table->rpl_write_set= old_rpl_write_set; - - return unlikely(error) ? HA_ERR_RBR_LOGGING_FAILED : 0; -} -#endif // HAVE_REPLICATION - - static int binlog_log_row_to_binlog(TABLE* table, const uchar *before_record, const uchar *after_record, diff --git a/sql/handler.h b/sql/handler.h index fe2625a8833..d3f0f844272 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -658,6 +658,7 @@ typedef ulonglong alter_table_operations; class Event_log; class Cache_flip_event_log; class binlog_cache_data; +class online_alter_cache_data; typedef bool Log_func(THD*, TABLE*, Event_log *, binlog_cache_data *, bool, const uchar*, const uchar*); diff --git a/sql/log.cc b/sql/log.cc index df04752de85..1f011e00e31 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -275,13 +275,11 @@ void make_default_log_name(char **out, const char* log_ext, bool once) Helper classes to store non-transactional and transactional data before copying it to the binary log. */ -class binlog_cache_data: public Sql_alloc, public ilist_node<> +class binlog_cache_data { public: - binlog_cache_data(): share(0), sv_list(0), m_pending(0), status(0), - before_stmt_pos(MY_OFF_T_UNDEF), - incident(FALSE), - saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0), + binlog_cache_data(): before_stmt_pos(MY_OFF_T_UNDEF), m_pending(0), status(0), + incident(FALSE), saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0), ptr_binlog_cache_disk_use(0) { } @@ -361,11 +359,6 @@ public: before_stmt_pos= pos; } - void store_prev_position() - { - before_stmt_pos= my_b_write_tell(&cache_log); - } - void restore_prev_position() { truncate(before_stmt_pos); @@ -418,8 +411,12 @@ public: */ IO_CACHE cache_log; - TABLE_SHARE *share; // for online alter table - SAVEPOINT *sv_list; +protected: + /* + Binlog position before the start of the current statement. + */ + my_off_t before_stmt_pos; + private: /* Pending binrows event. This event is the event where the rows are currently @@ -434,11 +431,6 @@ private: */ uint32 status; - /* - Binlog position before the start of the current statement. - */ - my_off_t before_stmt_pos; - /* This indicates that some events did not get into the cache and most likely it is corrupted. @@ -506,6 +498,19 @@ private: }; +class online_alter_cache_data: public Sql_alloc, public ilist_node<>, + public binlog_cache_data +{ +public: + void store_prev_position() + { + before_stmt_pos= my_b_write_tell(&cache_log); + } + + TABLE_SHARE *share; + SAVEPOINT *sv_list; +}; + void Log_event_writer::add_status(enum_logged_status status) { if (likely(cache_data)) @@ -2261,8 +2266,35 @@ static int binlog_commit_flush_xa_prepare(THD *thd, bool all, } #ifdef HAVE_REPLICATION +int binlog_log_row_online_alter(TABLE* table, const uchar *before_record, + const uchar *after_record, Log_func *log_func) +{ + THD *thd= table->in_use; + + if (!table->online_alter_cache) + { + table->online_alter_cache= online_alter_binlog_get_cache_data(thd, table); + trans_register_ha(thd, false, binlog_hton, 0); + if (thd->in_multi_stmt_transaction_mode()) + trans_register_ha(thd, true, binlog_hton, 0); + } + + // We need to log all columns for the case if alter table changes primary key + DBUG_ASSERT(!before_record || bitmap_is_set_all(table->read_set)); + MY_BITMAP *old_rpl_write_set= table->rpl_write_set; + table->rpl_write_set= &table->s->all_set; + + int error= (*log_func)(thd, table, table->s->online_alter_binlog, + table->online_alter_cache, true, + before_record, after_record); + + table->rpl_write_set= old_rpl_write_set; + + return unlikely(error) ? HA_ERR_RBR_LOGGING_FAILED : 0; +} + static void -binlog_online_alter_cleanup(ilist &list, bool ending_trans) +binlog_online_alter_cleanup(ilist &list, bool ending_trans) { if (ending_trans) { @@ -6382,9 +6414,9 @@ write_err: #ifdef HAVE_REPLICATION -static binlog_cache_data *binlog_setup_cache_data(MEM_ROOT *root, TABLE_SHARE *share) +static online_alter_cache_data *binlog_setup_cache_data(MEM_ROOT *root, TABLE_SHARE *share) { - auto cache= new (root) binlog_cache_data(); + auto cache= new (root) online_alter_cache_data(); if (!cache || open_cached_file(&cache->cache_log, mysql_tmpdir, LOG_PREFIX, (size_t)binlog_cache_size, MYF(MY_WME))) { @@ -6399,9 +6431,9 @@ static binlog_cache_data *binlog_setup_cache_data(MEM_ROOT *root, TABLE_SHARE *s return cache; } -binlog_cache_data *online_alter_binlog_get_cache_data(THD *thd, TABLE *table) +online_alter_cache_data *online_alter_binlog_get_cache_data(THD *thd, TABLE *table) { - ilist &list= thd->online_alter_cache_list; + ilist &list= thd->online_alter_cache_list; /* we assume it's very rare to have more than one online ALTER running */ for (auto &cache: list) diff --git a/sql/log.h b/sql/log.h index 49f37ac3c3e..606e7786db5 100644 --- a/sql/log.h +++ b/sql/log.h @@ -1320,7 +1320,9 @@ int binlog_flush_pending_rows_event(THD *thd, bool stmt_end, binlog_cache_data *cache_data); Rows_log_event* binlog_get_pending_rows_event(binlog_cache_mngr *cache_mngr, bool use_trans_cache); -binlog_cache_data *online_alter_binlog_get_cache_data(THD *thd, TABLE *table); +int binlog_log_row_online_alter(TABLE* table, const uchar *before_record, + const uchar *after_record, Log_func *log_func); +online_alter_cache_data *online_alter_binlog_get_cache_data(THD *thd, TABLE *table); binlog_cache_data* binlog_get_cache_data(binlog_cache_mngr *cache_mngr, bool use_trans_cache); diff --git a/sql/sql_class.h b/sql/sql_class.h index 7c98a3bd1dc..cb06a3ab777 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5556,7 +5556,7 @@ public: Item *sp_prepare_func_item(Item **it_addr, uint cols); bool sp_eval_expr(Field *result_field, Item **expr_item_ptr); - ilist online_alter_cache_list; + ilist online_alter_cache_list; bool sql_parser(LEX *old_lex, LEX *lex, char *str, uint str_len, bool stmt_prepare_mode); diff --git a/sql/table.h b/sql/table.h index 0ca8cb17c23..749af780f9a 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1630,7 +1630,7 @@ public: */ Item *notnull_cond; - binlog_cache_data *online_alter_cache; + online_alter_cache_data *online_alter_cache; inline void reset() { bzero((void*)this, sizeof(*this)); } void init(THD *thd, TABLE_LIST *tl);