Index: sql/sql_class.h =================================================================== --- sql/sql_class.h (revision 4660) +++ sql/sql_class.h (working copy) @@ -1896,7 +1896,31 @@ transaction cache. */ uint binlog_table_maps; + char m_trans_fixed_log_file[FN_REFLEN+1]; + my_off_t m_trans_end_pos; public: + void set_trans_pos(const char *file, my_off_t pos) + { + if (file) + strcpy(m_trans_fixed_log_file, file+dirname_length(file)); + else + m_trans_fixed_log_file[0]= '\0'; + + m_trans_end_pos= pos; + + return; + } + + void get_trans_fixed_pos(const char **file_var, my_off_t *pos_var) const + { + if (file_var) + *file_var = m_trans_fixed_log_file; + if (pos_var) + *pos_var= m_trans_end_pos; + + return; + } + void issue_unsafe_warnings(); uint get_binlog_table_maps() const { Index: sql/sql_class.cc =================================================================== --- sql/sql_class.cc (revision 4660) +++ sql/sql_class.cc (working copy) @@ -947,6 +947,8 @@ */ init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); filter_id= 0; + bzero(m_trans_fixed_log_file, FN_REFLEN+1); + m_trans_end_pos= 0; stmt_arena= this; thread_stack= 0; catalog= (char*)"std"; // the only catalog we have for now Index: sql/log.cc =================================================================== --- sql/log.cc (revision 4660) +++ sql/log.cc (working copy) @@ -5123,8 +5123,10 @@ if ((error= flush_and_sync(&synced))) goto unlock; + thd->set_trans_pos(log_file_name, file->pos_in_file); + const char *file_name_ptr= log_file_name + dirname_length(log_file_name); if ((error= RUN_HOOK(binlog_storage, after_flush, - (thd, log_file_name, file->pos_in_file, synced)))) + (thd, file_name_ptr, file->pos_in_file, synced)))) { sql_print_error("Failed to run 'after_flush' hooks"); goto unlock; @@ -5673,11 +5675,12 @@ } cache_data->commit_bin_log_file_pos= my_b_write_tell(&log_file); + current->thd->set_trans_pos(log_file_name, my_b_write_tell(&log_file)); + if (cache_data->using_xa && cache_data->xa_xid) xid_count++; } - if (write_count > 0) { bool synced= 0; @@ -5697,8 +5700,9 @@ update_binlog_end_pos(); } + const char *file_name_ptr= log_file_name + dirname_length(log_file_name); if (RUN_HOOK(binlog_storage, after_flush, - (leader->thd, log_file_name, log_file.pos_in_file, synced))) + (leader->thd, file_name_ptr, log_file.pos_in_file, synced))) { sql_print_error("Failed to run 'after_flush' hooks"); for (current= queue; current != NULL; current= current->next) Index: sql/sql_parse.cc =================================================================== --- sql/sql_parse.cc (revision 4660) +++ sql/sql_parse.cc (working copy) @@ -5794,6 +5794,7 @@ thd->reset_current_stmt_binlog_format_row(); thd->binlog_unsafe_warning_flags= 0; + thd->set_trans_pos(NULL, 0); DBUG_PRINT("debug", ("is_current_stmt_binlog_format_row(): %d", Index: sql/rpl_handler.cc =================================================================== --- sql/rpl_handler.cc (revision 4660) +++ sql/rpl_handler.cc (working copy) @@ -232,25 +232,18 @@ bool is_real_trans= (all || thd->transaction.all.ha_list == 0); param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0; + thd->get_trans_fixed_pos(¶m.log_file, ¶m.log_pos); - Trans_binlog_info *log_info= - my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO); - - param.log_file= log_info ? log_info->log_file : 0; - param.log_pos= log_info ? log_info->log_pos : 0; - int ret= 0; - FOREACH_OBSERVER(ret, after_commit, thd, (¶m)); - - /* - This is the end of a real transaction or autocommit statement, we - can free the memory allocated for binlog file and position. - */ - if (is_real_trans && log_info) + /*since the HOOK is only used by semisync ,It's safe to check is_real_trans + before enter into semisync*/ + if (is_real_trans && param.log_pos) { - my_pthread_setspecific_ptr(RPL_TRANS_BINLOG_INFO, NULL); - my_free(log_info); + FOREACH_OBSERVER(ret, after_commit, thd, (¶m)); + + thd->set_trans_pos(NULL, 0); } + return ret; } @@ -260,25 +253,16 @@ bool is_real_trans= (all || thd->transaction.all.ha_list == 0); param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0; + thd->get_trans_fixed_pos(¶m.log_file, ¶m.log_pos); - Trans_binlog_info *log_info= - my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO); - - param.log_file= log_info ? log_info->log_file : 0; - param.log_pos= log_info ? log_info->log_pos : 0; - int ret= 0; - FOREACH_OBSERVER(ret, after_rollback, thd, (¶m)); - - /* - This is the end of a real transaction or autocommit statement, we - can free the memory allocated for binlog file and position. - */ - if (is_real_trans && log_info) + if (is_real_trans && param.log_pos) { - my_pthread_setspecific_ptr(RPL_TRANS_BINLOG_INFO, NULL); - my_free(log_info); + FOREACH_OBSERVER(ret, after_rollback, thd, (¶m)); + + thd->set_trans_pos(NULL, 0); } + return ret; } @@ -292,23 +276,9 @@ if (synced) flags |= BINLOG_STORAGE_IS_SYNCED; - Trans_binlog_info *log_info= - my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO); - - if (!log_info) - { - if(!(log_info= - (Trans_binlog_info *)my_malloc(sizeof(Trans_binlog_info), MYF(0)))) - return 1; - my_pthread_setspecific_ptr(RPL_TRANS_BINLOG_INFO, log_info); - } - - strcpy(log_info->log_file, log_file+dirname_length(log_file)); - log_info->log_pos = log_pos; - int ret= 0; FOREACH_OBSERVER(ret, after_flush, thd, - (¶m, log_info->log_file, log_info->log_pos, flags)); + (¶m, log_file, log_pos, flags)); return ret; }