diff options
author | unknown <lars/lthalmann@mysql.com/dl145k.mysql.com> | 2007-02-28 22:30:40 +0100 |
---|---|---|
committer | unknown <lars/lthalmann@mysql.com/dl145k.mysql.com> | 2007-02-28 22:30:40 +0100 |
commit | d5e983aafcd0dab59f8760bd76c6d350c22290ea (patch) | |
tree | 61efd2550a84baf4c5f283498e5a2611667a4d7c /sql/sql_insert.cc | |
parent | 3a520a785eeee973e79d1f6e482e270e24a20c56 (diff) | |
parent | a2b4f52912491e1887fa25bab674cb71f5db6dc9 (diff) | |
download | mariadb-git-d5e983aafcd0dab59f8760bd76c6d350c22290ea.tar.gz |
Merge mysql.com:/nfsdisk1/lars/bkroot/mysql-5.0-rpl
into mysql.com:/nfsdisk1/lars/MERGE/mysql-5.0-merge
sql/mysql_priv.h:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f1edfb9d787..9b862219739 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -58,6 +58,7 @@ #include "sp_head.h" #include "sql_trigger.h" #include "sql_select.h" +#include "slave.h" #ifndef EMBEDDED_LIBRARY static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list); @@ -380,11 +381,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, List_item *values; Name_resolution_context *context; Name_resolution_context_state ctx_state; -#ifndef EMBEDDED_LIBRARY char *query= thd->query; bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->security_ctx->master_access & SUPER_ACL)); -#endif thr_lock_type lock_type = table_list->lock_type; Item *unused_conds= 0; DBUG_ENTER("mysql_insert"); @@ -405,6 +404,27 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, (duplic == DUP_UPDATE)) lock_type=TL_WRITE; #endif + if ((lock_type == TL_WRITE_DELAYED) && + log_on && mysql_bin_log.is_open() && + (values_list.elements > 1)) + { + /* + Statement-based binary logging does not work in this case, because: + a) two concurrent statements may have their rows intermixed in the + queue, leading to autoincrement replication problems on slave (because + the values generated used for one statement don't depend only on the + value generated for the first row of this statement, so are not + replicable) + b) if first row of the statement has an error the full statement is + not binlogged, while next rows of the statement may be inserted. + c) if first row succeeds, statement is binlogged immediately with a + zero error code (i.e. "no error"), if then second row fails, query + will fail on slave too and slave will stop (wrongly believing that the + master got no error). + So we fallback to non-delayed INSERT. + */ + lock_type= TL_WRITE; + } table_list->lock_type= lock_type; #ifndef EMBEDDED_LIBRARY @@ -519,6 +539,14 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, thd->cuted_fields = 0L; table->next_number_field=table->found_next_number_field; +#ifdef HAVE_REPLICATION + if (thd->slave_thread && + (info.handle_duplicates == DUP_UPDATE) && + (table->next_number_field != NULL) && + rpl_master_has_bug(&active_mi->rli, 24432)) + goto abort; +#endif + error=0; id=0; thd->proc_info="update"; @@ -1182,11 +1210,11 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (res == VIEW_CHECK_ERROR) goto before_trg_err; + table->file->restore_auto_increment(); if ((error=table->file->update_row(table->record[1],table->record[0]))) { if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore) { - table->file->restore_auto_increment(); goto ok_or_after_trg_err; } goto err; @@ -2444,6 +2472,15 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) } restore_record(table,s->default_values); // Get empty record table->next_number_field=table->found_next_number_field; + +#ifdef HAVE_REPLICATION + if (thd->slave_thread && + (info.handle_duplicates == DUP_UPDATE) && + (table->next_number_field != NULL) && + rpl_master_has_bug(&active_mi->rli, 24432)) + DBUG_RETURN(1); +#endif + thd->cuted_fields=0; if (info.ignore || info.handle_duplicates != DUP_ERROR) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); |