summaryrefslogtreecommitdiff
path: root/sql/sql_insert.cc
diff options
context:
space:
mode:
authorunknown <lars/lthalmann@mysql.com/dl145k.mysql.com>2007-02-28 22:30:40 +0100
committerunknown <lars/lthalmann@mysql.com/dl145k.mysql.com>2007-02-28 22:30:40 +0100
commitd5e983aafcd0dab59f8760bd76c6d350c22290ea (patch)
tree61efd2550a84baf4c5f283498e5a2611667a4d7c /sql/sql_insert.cc
parent3a520a785eeee973e79d1f6e482e270e24a20c56 (diff)
parenta2b4f52912491e1887fa25bab674cb71f5db6dc9 (diff)
downloadmariadb-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.cc43
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);