diff options
author | sergefp@mysql.com <> | 2005-09-07 19:39:47 +0400 |
---|---|---|
committer | sergefp@mysql.com <> | 2005-09-07 19:39:47 +0400 |
commit | e5b42524811c620ce9365c05bfb25586bade41b8 (patch) | |
tree | ba7b8bc9c0f63f3e1ee4affcb7925908a091e707 /sql/sp_head.cc | |
parent | bc6b03668496e558749e7e65c9b51aafefdbb8d0 (diff) | |
download | mariadb-git-e5b42524811c620ce9365c05bfb25586bade41b8.tar.gz |
Fix for BUG#12637: Make SPs+user variables replication work:
* Allocate thd->user_var_events elements on appropriate mem_root
* If several SP statements are binlogged as a single statement, collect all user var
accesses they make (grep for StoredRoutinesBinlogging for details)
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 14956138cbf..833a9209360 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -678,10 +678,35 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b) * If this function invocation is done from a statement that is written into the binary log. * If there were any attempts to write events to the binary log during - function execution. + function execution (grep for start_union_events and stop_union_events) + If the answers are No and Yes, we write the function call into the binary log as "DO spfunc(<param1value>, <param2value>, ...)" - + + + 4. Miscellaneous issues. + + 4.1 User variables. + + When we call mysql_bin_log.write() for an SP statement, thd->user_var_events + must hold set<{var_name, value}> pairs for all user variables used during + the statement execution. + This set is produced by tracking user variable reads during statement + execution. + + Fo SPs, this has the following implications: + 1) thd->user_var_events may contain events from several SP statements and + needs to be valid after exection of these statements was finished. In + order to achieve that, we + * Allocate user_var_events array elements on appropriate mem_root (grep + for user_var_events_alloc). + * Use is_query_in_union() to determine if user_var_event is created. + + 2) We need to empty thd->user_var_events after we have wrote a function + call. This is currently done by making + reset_dynamic(&thd->user_var_events); + calls in several different places. (TODO cosider moving this into + mysql_bin_log.write() function) */ @@ -897,6 +922,7 @@ int sp_head::execute(THD *thd) /* Don't change NOW() in FUNCTION or TRIGGER */ if (!thd->in_sub_stmt) thd->set_time(); // Make current_time() et al work + /* We have to set thd->stmt_arena before executing the instruction to store in the instruction free_list all new items, created @@ -904,6 +930,13 @@ int sp_head::execute(THD *thd) items made during other permanent subquery transformations). */ thd->stmt_arena= i; + + /* will binlog this separately */ + if (thd->prelocked_mode == NON_PRELOCKED) //TODO: change to event union? + { + thd->user_var_events_alloc= thd->mem_root; + } + ret= i->execute(thd, &ip); /* @@ -918,15 +951,6 @@ int sp_head::execute(THD *thd) /* we should cleanup free_list and memroot, used by instruction */ thd->free_items(); - /* - FIXME: we must free user var events only if the routine is executed - in non-prelocked mode and statement-by-statement replication is used. - But if we don't free them now, the server crashes because user var - events are allocated in execute_mem_root. This is Bug#12637, and when - it's fixed, please add if (thd->options & OPTION_BIN_LOG) here. - */ - if (opt_bin_log) - reset_dynamic(&thd->user_var_events); free_root(&execute_mem_root, MYF(0)); /* @@ -1084,7 +1108,10 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) binlog_save_options= thd->options; need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG); if (need_binlog_call) + { + reset_dynamic(&thd->user_var_events); mysql_bin_log.start_union_events(thd); + } thd->options&= ~OPTION_BIN_LOG; ret= execute(thd); @@ -1118,6 +1145,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) "Invoked ROUTINE modified a transactional table but MySQL " "failed to reflect this change in the binary log"); } + reset_dynamic(&thd->user_var_events); } if (m_type == TYPE_ENUM_FUNCTION && ret == 0) |