diff options
author | unknown <guilhem@gbichot3.local> | 2006-07-10 13:26:46 +0200 |
---|---|---|
committer | unknown <guilhem@gbichot3.local> | 2006-07-10 13:26:46 +0200 |
commit | 3a3a5622ab8509a90504faf7bddbd45800bdc3d3 (patch) | |
tree | 1929caa18f880e6bbde8eed0eeb1fe7ec477b3ae /sql/sql_base.cc | |
parent | 45f56813d562976bf67bb2ba9ce597333990eaab (diff) | |
parent | 9939a66beced3ce44a9c9ea6b1f453de454f2410 (diff) | |
download | mariadb-git-3a3a5622ab8509a90504faf7bddbd45800bdc3d3.tar.gz |
Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-5.1-rpl
into gbichot3.local:/home/mysql_src/mysql-5.1
mysql-test/mysql-test-run.pl:
Auto merged
sql/sql_base.cc:
Auto merged
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9b016ac5ecb..a938287ece3 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -49,6 +49,8 @@ static bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias, static void close_old_data_files(THD *thd, TABLE *table, bool abort_locks, bool send_refresh); static bool reopen_table(TABLE *table); +static bool +has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables); extern "C" byte *table_cache_key(const byte *record,uint *length, @@ -3314,6 +3316,18 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen) *need_reopen= FALSE; +#ifdef HAVE_ROW_BASED_REPLICATION + /* + CREATE ... SELECT UUID() locks no tables, we have to test here. + Note that we will not do the resetting if inside a stored + function/trigger, because the binlogging of those is decided earlier (by + the caller) and can't be changed afterwards. + */ + thd->reset_current_stmt_binlog_row_based(); + if (thd->lex->binlog_row_based_if_mixed) + thd->set_current_stmt_binlog_row_based_if_mixed(); +#endif /*HAVE_ROW_BASED_REPLICATION*/ + if (!tables) DBUG_RETURN(0); @@ -3344,6 +3358,19 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen) { thd->in_lock_tables=1; thd->options|= OPTION_TABLE_LOCK; +#ifdef HAVE_ROW_BASED_REPLICATION + /* + If we have >= 2 different tables to update with auto_inc columns, + statement-based binlogging won't work. We can solve this problem in + mixed mode by switching to row-based binlogging: + */ + if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED && + has_two_write_locked_tables_with_auto_increment(tables)) + { + thd->lex->binlog_row_based_if_mixed= TRUE; + thd->set_current_stmt_binlog_row_based_if_mixed(); + } +#endif } if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start), @@ -6476,3 +6503,46 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table DBUG_VOID_RETURN; } + +/* + Tells if two (or more) tables have auto_increment columns and we want to + lock those tables with a write lock. + + SYNOPSIS + has_two_write_locked_tables_with_auto_increment + tables Table list + + NOTES: + Call this function only when you have established the list of all tables + which you'll want to update (including stored functions, triggers, views + inside your statement). + + RETURN + 0 No + 1 Yes +*/ + +static bool +has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables) +{ + char *first_table_name= NULL, *first_db; + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + /* we must do preliminary checks as table->table may be NULL */ + if (!table->placeholder() && !table->schema_table && + table->table->found_next_number_field && + (table->lock_type >= TL_WRITE_ALLOW_WRITE)) + { + if (first_table_name == NULL) + { + first_table_name= table->table_name; + first_db= table->db; + DBUG_ASSERT(first_db); + } + else if (strcmp(first_db, table->db) || + strcmp(first_table_name, table->table_name)) + return 1; + } + } + return 0; +} |