diff options
author | unknown <monty@mysql.com> | 2004-05-05 17:05:24 +0300 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-05-05 17:05:24 +0300 |
commit | 3b887983bfc19585825ec528a80118f2c93f2b04 (patch) | |
tree | 3238bd16530e02dbfef96513749a73b7294880f8 /sql/slave.cc | |
parent | f347b37403b7ca828537eaf2cc1d9efb363bf0b7 (diff) | |
parent | a58aa393f2d914e3eb4e422b25fd4ef3665151a3 (diff) | |
download | mariadb-git-3b887983bfc19585825ec528a80118f2c93f2b04.tar.gz |
Merge with 4.0.19
BitKeeper/etc/logging_ok:
auto-union
VC++Files/client/mysqlclient.dsp:
Auto merged
VC++Files/mysql.dsw:
Auto merged
extra/perror.c:
Auto merged
extra/replace.c:
Auto merged
innobase/configure.in:
Auto merged
innobase/include/lock0lock.h:
Auto merged
innobase/include/row0mysql.h:
Auto merged
innobase/include/sync0sync.h:
Auto merged
innobase/lock/lock0lock.c:
Auto merged
ltmain.sh:
Auto merged
BitKeeper/deleted/.del-libmysqld.def~8edf7b8780ce943c:
Auto merged
innobase/os/os0file.c:
Auto merged
innobase/pars/lexyy.c:
Auto merged
innobase/row/row0mysql.c:
Auto merged
innobase/srv/srv0srv.c:
Auto merged
innobase/srv/srv0start.c:
Auto merged
innobase/sync/sync0arr.c:
Auto merged
innobase/sync/sync0sync.c:
Auto merged
innobase/trx/trx0trx.c:
Auto merged
mysql-test/r/alias.result:
Auto merged
mysql-test/t/system_mysql_db_fix-master.opt:
Auto merged
mysql-test/r/func_time.result:
Automatic merge
mysql-test/r/innodb.result:
Automatic merge
mysql-test/t/alias.test:
Automatic merge
mysql-test/t/create.test:
Automatic merge
mysql-test/t/func_time.test:
Automatic merge
sql/ha_innodb.cc:
Automatic merge
sql/mysql_priv.h:
Automatic merge
mysql-test/r/rpl_multi_update.result:
Automatic merge
mysql-test/t/rpl_error_ignored_table.test:
Automatic merge
mysql-test/t/rpl_multi_update.test:
Automatic merge
sql/slave.h:
Automatic merge
sql/sql_base.cc:
Automatic merge
sql/sql_db.cc:
Automatic merge
sql/sql_insert.cc:
Automatic merge
sql/structs.h:
Automatic merge
sql/table.cc:
Automatic merge
strings/longlong2str-x86.s:
Automatic merge
strings/strings-x86.s:
Automatic merge
support-files/my-medium.cnf.sh:
Automatic merge
Diffstat (limited to 'sql/slave.cc')
-rw-r--r-- | sql/slave.cc | 71 |
1 files changed, 54 insertions, 17 deletions
diff --git a/sql/slave.cc b/sql/slave.cc index 61d5e956e6c..c8da53433d7 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -39,7 +39,7 @@ HASH replicate_do_table, replicate_ignore_table; DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table; bool do_table_inited = 0, ignore_table_inited = 0; bool wild_do_table_inited = 0, wild_ignore_table_inited = 0; -bool table_rules_on = 0; +bool table_rules_on= 0, replicate_same_server_id; ulonglong relay_log_space_limit = 0; /* @@ -747,7 +747,16 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len) Note that changing the order of the tables in the list can lead to different results. Note also the order of precedence of the do/ignore rules (see code below). For that reason, users should not set conflicting - rules because they may get unpredicted results. + rules because they may get unpredicted results (precedence order is + explained in the manual). + If no table of the list is marked "updating" (so far this can only happen + if the statement is a multi-delete (SQLCOM_DELETE_MULTI) and the "tables" + is the tables in the FROM): then we always return 0, because there is no + reason we play this statement on this slave if it updates nothing. In the + case of SQLCOM_DELETE_MULTI, there will be a second call to tables_ok(), + with tables having "updating==TRUE" (those after the DELETE), so this + second call will make the decision (because + all_tables_not_ok() = !tables_ok(1st_list) && !tables_ok(2nd_list)). RETURN VALUES 0 should not be logged/replicated @@ -756,6 +765,7 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len) int tables_ok(THD* thd, TABLE_LIST* tables) { + bool some_tables_updating= 0; DBUG_ENTER("tables_ok"); for (; tables; tables = tables->next) @@ -766,6 +776,7 @@ int tables_ok(THD* thd, TABLE_LIST* tables) if (!tables->updating) continue; + some_tables_updating= 1; end= strmov(hash_key, tables->db ? tables->db : thd->db); *end++= '.'; len= (uint) (strmov(end, tables->real_name) - hash_key); @@ -788,10 +799,13 @@ int tables_ok(THD* thd, TABLE_LIST* tables) } /* + If no table was to be updated, ignore statement (no reason we play it on + slave, slave is supposed to replicate _changes_ only). If no explicit rule found and there was a do list, do not replicate. If there was no do list, go ahead */ - DBUG_RETURN(!do_table_inited && !wild_do_table_inited); + DBUG_RETURN(some_tables_updating && + !do_table_inited && !wild_do_table_inited); } @@ -1529,13 +1543,13 @@ Failed to open the existing relay log info file '%s' (errno %d)", rli->info_fd = info_fd; int relay_log_pos, master_log_pos; if (init_strvar_from_file(rli->group_relay_log_name, - sizeof(rli->group_relay_log_name), &rli->info_file, - "") || + sizeof(rli->group_relay_log_name), + &rli->info_file, "") || init_intvar_from_file(&relay_log_pos, &rli->info_file, BIN_LOG_HEADER_SIZE) || init_strvar_from_file(rli->group_master_log_name, - sizeof(rli->group_master_log_name), &rli->info_file, - "") || + sizeof(rli->group_master_log_name), + &rli->info_file, "") || init_intvar_from_file(&master_log_pos, &rli->info_file, 0)) { msg="Error reading slave log configuration"; @@ -2232,7 +2246,8 @@ st_relay_log_info::st_relay_log_info() inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE), until_log_pos(0) { - group_relay_log_name[0]= event_relay_log_name[0]= group_master_log_name[0]= 0; + group_relay_log_name[0]= event_relay_log_name[0]= + group_master_log_name[0]= 0; last_slave_error[0]=0; until_log_name[0]= 0; bzero((char*) &info_file, sizeof(info_file)); @@ -2334,6 +2349,8 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, error= -2; //means improper arguments goto err; } + // Convert 0-3 to 4 + log_pos= max(log_pos, BIN_LOG_HEADER_SIZE); /* p points to '.' */ log_name_extension= strtoul(++p, &p_end, 10); /* @@ -2354,10 +2371,24 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, { bool pos_reached; int cmp_result= 0; - DBUG_ASSERT(*group_master_log_name || group_master_log_pos == 0); + + /* + group_master_log_name can be "", if we are just after a fresh + replication start or after a CHANGE MASTER TO MASTER_HOST/PORT + (before we have executed one Rotate event from the master) or + (rare) if the user is doing a weird slave setup (see next + paragraph). If group_master_log_name is "", we assume we don't + have enough info to do the comparison yet, so we just wait until + more data. In this case master_log_pos is always 0 except if + somebody (wrongly) sets this slave to be a slave of itself + without using --replicate-same-server-id (an unsupported + configuration which does nothing), then group_master_log_pos + will grow and group_master_log_name will stay "". + */ if (*group_master_log_name) { - char *basename= group_master_log_name + dirname_length(group_master_log_name); + char *basename= (group_master_log_name + + dirname_length(group_master_log_name)); /* First compare the parts before the extension. Find the dot in the master's log basename, @@ -2374,14 +2405,15 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, char *q_end; ulong group_master_log_name_extension= strtoul(q, &q_end, 10); if (group_master_log_name_extension < log_name_extension) - cmp_result = -1 ; + cmp_result= -1 ; else cmp_result= (group_master_log_name_extension > log_name_extension) ? 1 : 0 ; + + pos_reached= ((!cmp_result && group_master_log_pos >= (ulonglong)log_pos) || + cmp_result > 0); + if (pos_reached || thd->killed) + break; } - pos_reached = ((!cmp_result && group_master_log_pos >= (ulonglong)log_pos) || - cmp_result > 0); - if (pos_reached || thd->killed) - break; //wait for master update, with optional timeout. @@ -2801,7 +2833,12 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) log files themselves. */ - if (ev->server_id == (uint32) ::server_id || + /* + TODO: when this is merged into 4.1, one needs to update queue_event() to + add a similar test for replicate_same_server_id, because in 4.1 the I/O + thread is also filtering events based on the server id. + */ + if ((ev->server_id == (uint32) ::server_id && !replicate_same_server_id) || (rli->slave_skip_counter && type_code != ROTATE_EVENT)) { /* TODO: I/O thread should not even log events with the same server id */ @@ -3530,8 +3567,8 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, this end 0, which leads to segfault. */ tmp_buf[event_len++]=0; - buf = (const char*)tmp_buf; int4store(tmp_buf+EVENT_LEN_OFFSET, event_len); + buf = (const char*)tmp_buf; } /* This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to |