diff options
author | unknown <monty@mysql.com> | 2004-03-16 22:41:30 +0200 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-03-16 22:41:30 +0200 |
commit | a8aacf87648f64e7489220dab7d8729c5c01e13d (patch) | |
tree | af285d8080c003d1ecb1479ec43c9b6996fd567f /sql/log_event.cc | |
parent | 17f8d3d725f4b465a8a0dc8e96b04cd973c47fd5 (diff) | |
parent | 277cf702da7e6f0642742eb10582cfc382e537ec (diff) | |
download | mariadb-git-a8aacf87648f64e7489220dab7d8729c5c01e13d.tar.gz |
merge with 4.0
BitKeeper/etc/logging_ok:
auto-union
VC++Files/innobase/innobase.dsp:
Auto merged
VC++Files/libmysql/libmysql.dsp:
Auto merged
acinclude.m4:
Auto merged
configure.in:
Auto merged
BitKeeper/deleted/.del-com0shm.c~6a16f0c3d81de1f:
Auto merged
BitKeeper/deleted/.del-mysql_fix_privilege_tables.sql:
Auto merged
extra/replace.c:
Auto merged
include/my_sys.h:
Auto merged
innobase/btr/btr0btr.c:
Auto merged
innobase/btr/btr0cur.c:
Auto merged
innobase/btr/btr0pcur.c:
Auto merged
innobase/btr/btr0sea.c:
Auto merged
innobase/configure.in:
Auto merged
innobase/data/data0data.c:
Auto merged
innobase/dict/dict0boot.c:
Auto merged
innobase/dict/dict0crea.c:
Auto merged
innobase/dict/dict0dict.c:
Auto merged
innobase/dict/dict0load.c:
Auto merged
innobase/dict/dict0mem.c:
Auto merged
innobase/ha/ha0ha.c:
Auto merged
innobase/ha/hash0hash.c:
Auto merged
innobase/include/btr0btr.ic:
Auto merged
innobase/include/data0type.ic:
Auto merged
innobase/include/dict0mem.h:
Auto merged
innobase/include/log0log.ic:
Auto merged
innobase/include/mach0data.ic:
Auto merged
innobase/include/mtr0log.h:
Auto merged
innobase/include/mtr0mtr.h:
Auto merged
innobase/include/os0file.h:
Auto merged
innobase/include/row0upd.ic:
Auto merged
innobase/include/srv0srv.h:
Auto merged
innobase/include/sync0sync.h:
Auto merged
innobase/include/trx0rseg.ic:
Auto merged
innobase/lock/lock0lock.c:
Auto merged
innobase/log/log0recv.c:
Auto merged
innobase/mem/mem0dbg.c:
Auto merged
innobase/mtr/mtr0log.c:
Auto merged
innobase/mtr/mtr0mtr.c:
Auto merged
innobase/os/os0file.c:
Auto merged
innobase/page/page0cur.c:
Auto merged
innobase/page/page0page.c:
Auto merged
innobase/pars/lexyy.c:
Auto merged
innobase/read/read0read.c:
Auto merged
innobase/rem/rem0cmp.c:
Auto merged
innobase/rem/rem0rec.c:
Auto merged
innobase/row/row0ins.c:
Auto merged
innobase/row/row0mysql.c:
Auto merged
innobase/row/row0purge.c:
Auto merged
innobase/row/row0sel.c:
Auto merged
innobase/row/row0undo.c:
Auto merged
innobase/row/row0upd.c:
Auto merged
innobase/srv/srv0srv.c:
Auto merged
innobase/srv/srv0start.c:
Auto merged
innobase/sync/sync0rw.c:
Auto merged
innobase/thr/thr0loc.c:
Auto merged
innobase/trx/trx0purge.c:
Auto merged
innobase/trx/trx0rec.c:
Auto merged
innobase/trx/trx0roll.c:
Auto merged
innobase/trx/trx0trx.c:
Auto merged
innobase/trx/trx0undo.c:
Auto merged
myisam/mi_check.c:
Auto merged
myisam/myisamchk.c:
Auto merged
mysql-test/r/multi_update.result:
Auto merged
mysql-test/r/mysqlbinlog.result:
Auto merged
mysql-test/r/rpl_error_ignored_table.result:
Auto merged
mysql-test/t/multi_update.test:
Auto merged
mysql-test/t/rpl_error_ignored_table.test:
Auto merged
mysys/mf_iocache.c:
Auto merged
mysys/mf_pack.c:
Auto merged
mysys/my_getopt.c:
Auto merged
sql/ha_berkeley.cc:
Auto merged
sql/ha_myisam.cc:
Auto merged
sql/lock.cc:
Auto merged
sql/log.cc:
Auto merged
sql/opt_range.cc:
Auto merged
sql/set_var.h:
Auto merged
sql/sql_cache.cc:
Auto merged
sql/sql_cache.h:
Auto merged
sql/sql_delete.cc:
Auto merged
sql/sql_handler.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_list.h:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_update.cc:
Auto merged
tests/thread_test.c:
Auto merged
client/mysqldump.c:
Keep original indentation
mysql-test/r/merge.result:
keep old file
scripts/mysql_fix_privilege_tables.sh:
Keep old structure in merge with 4.0
sql/table.cc:
merge with 4.0 + simple optimizations
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r-- | sql/log_event.cc | 182 |
1 files changed, 109 insertions, 73 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc index a128b5809b2..049ee5c5808 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -56,11 +56,21 @@ static void pretty_print_str(FILE* file, char* str, int len) #endif /* MYSQL_CLIENT */ +#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) + +static void clear_all_errors(THD *thd, struct st_relay_log_info *rli) +{ + thd->query_error = 0; + thd->clear_error(); + *rli->last_slave_error = 0; + rli->last_slave_errno = 0; +} + + /* - ignored_error_code() + Ignore error code specified on command line */ -#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) inline int ignored_error_code(int err_code) { return ((err_code == ER_SLAVE_IGNORED_TABLE) || @@ -843,7 +853,9 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, 0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans), data_buf(0), query(query_arg), db(thd_arg->db), q_len((uint32) query_length), - error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno), + error_code(thd_arg->killed ? + ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? + 0 : ER_SERVER_SHUTDOWN) : thd_arg->net.last_errno), thread_id(thd_arg->thread_id), /* save the original thread id; we already know the server id */ slave_proxy_id(thd_arg->variables.pseudo_thread_id) @@ -944,17 +956,15 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) thd->db= (char*) rewrite_db(db); /* - InnoDB internally stores the master log position it has executed so far, - i.e. the position just after the COMMIT event. - When InnoDB will want to store, the positions in rli won't have - been updated yet, so group_master_log_* will point to old BEGIN - and event_master_log* will point to the beginning of current COMMIT. - So the position to store is event_master_log_pos + event_len - since we must store the pos of the END of the current log event (COMMIT). + InnoDB internally stores the master log position it has processed so far; + position to store is of the END of the current log event. */ - rli->event_len= get_event_len(); - thd->query_error= 0; // clear error - thd->clear_error(); +#if MYSQL_VERSION_ID < 50000 + rli->future_group_master_log_pos= log_pos + get_event_len(); +#else + rli->future_group_master_log_pos= log_pos; +#endif + clear_all_errors(thd, rli); if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { @@ -966,75 +976,85 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->variables.pseudo_thread_id= thread_id; // for temp tables - /* - Sanity check to make sure the master did not get a really bad - error on the query. - */ - if (ignored_error_code((expected_error = error_code)) || + mysql_log.write(thd,COM_QUERY,"%s",thd->query); + DBUG_PRINT("query",("%s",thd->query)); + if (ignored_error_code((expected_error= error_code)) || !check_expected_error(thd,rli,expected_error)) - { - mysql_log.write(thd,COM_QUERY,"%s",thd->query); - DBUG_PRINT("query",("%s",thd->query)); mysql_parse(thd, thd->query, q_len); - + else + { /* - If we expected a non-zero error code, and we don't get the same error - code, and none of them should be ignored. + The query got a really bad error on the master (thread killed etc), + which could be inconsistent. Parse it to test the table names: if the + replicate-*-do|ignore-table rules say "this query must be ignored" then + we exit gracefully; otherwise we warn about the bad error and tell DBA + to check/fix it. */ - DBUG_PRINT("info",("expected_error: %d last_errno: %d", - expected_error, thd->net.last_errno)); - if ((expected_error != (actual_error= thd->net.last_errno)) && - expected_error && - !ignored_error_code(actual_error) && - !ignored_error_code(expected_error)) + if (mysql_test_parse_for_slave(thd, thd->query, q_len)) + clear_all_errors(thd, rli); /* Can ignore query */ + else { - slave_print_error(rli, 0, + slave_print_error(rli,expected_error, "\ +Query '%s' partially completed on the master (error on master: %d) \ +and was aborted. There is a chance that your master is inconsistent at this \ +point. If you are sure that your master is ok, run this query manually on the \ +slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \ +START SLAVE; .", thd->query, expected_error); + thd->query_error= 1; + } + goto end; + } + + /* + If we expected a non-zero error code, and we don't get the same error + code, and none of them should be ignored. + */ + DBUG_PRINT("info",("expected_error: %d last_errno: %d", + expected_error, thd->net.last_errno)); + if ((expected_error != (actual_error= thd->net.last_errno)) && + expected_error && + !ignored_error_code(actual_error) && + !ignored_error_code(expected_error)) + { + slave_print_error(rli, 0, + "\ Query '%s' caused different errors on master and slave. \ Error on master: '%s' (%d), Error on slave: '%s' (%d). \ Default database: '%s'", - query, - ER_SAFE(expected_error), - expected_error, - actual_error ? thd->net.last_error: "no error", - actual_error, - print_slave_db_safe(db)); - thd->query_error= 1; - } - /* - If we get the same error code as expected, or they should be ignored. - */ - else if (expected_error == actual_error || - ignored_error_code(actual_error)) - { - DBUG_PRINT("info",("error ignored")); - thd->query_error= 0; - thd->clear_error(); - *rli->last_slave_error = 0; - rli->last_slave_errno = 0; - } - /* - Other cases: mostly we expected no error and get one. - */ - else if (thd->query_error || thd->is_fatal_error) - { - slave_print_error(rli,actual_error, - "Error '%s' on query '%s'. Default database: '%s'", - (actual_error ? thd->net.last_error : - "unexpected success or fatal error"), - query, - print_slave_db_safe(db)); - thd->query_error= 1; - } - } - /* - End of sanity check. If the test was wrong, the query got a really bad - error on the master, which could be inconsistent, abort and tell DBA to - check/fix it. check_expected_error() already printed the message to - stderr and rli, and set thd->query_error to 1. + query, + ER_SAFE(expected_error), + expected_error, + actual_error ? thd->net.last_error: "no error", + actual_error, + print_slave_db_safe(db)); + thd->query_error= 1; + } + /* + If we get the same error code as expected, or they should be ignored. + */ + else if (expected_error == actual_error || + ignored_error_code(actual_error)) + { + DBUG_PRINT("info",("error ignored")); + clear_all_errors(thd, rli); + } + /* + Other cases: mostly we expected no error and get one. */ + else if (thd->query_error || thd->is_fatal_error) + { + slave_print_error(rli,actual_error, + "Error '%s' on query '%s'. Default database: '%s'", + (actual_error ? thd->net.last_error : + "unexpected success or fatal error"), + query, + print_slave_db_safe(db)); + thd->query_error= 1; + } } /* End of if (db_ok(... */ +end: VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->db= 0; // prevent db from being freed thd->query= 0; // just to be sure @@ -1165,7 +1185,7 @@ int Start_log_event::exec_event(struct st_relay_log_info* rli) { slave_print_error(rli, 0, "\ Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. \ -Probably cause is that the master died while writing the transaction to it's \ +A probable cause is that the master died while writing the transaction to its \ binary log."); return(1); } @@ -1643,7 +1663,15 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, DBUG_ASSERT(thd->query == 0); thd->query= 0; // Should not be needed thd->query_error= 0; - thd->clear_error(); + clear_all_errors(thd, rli); + if (!use_rli_only_for_errors) + { +#if MYSQL_VERSION_ID < 50000 + rli->future_group_master_log_pos= log_pos + get_event_len(); +#else + rli->future_group_master_log_pos= log_pos; +#endif + } /* We test replicate_*_db rules. Note that we have already prepared the file @@ -2638,7 +2666,7 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len, We must make copy of 'buf' as this event may have to live over a rotate log entry when used in mysqlbinlog */ - if (!(event_buf= my_memdup(buf, len, MYF(MY_WME))) || + if (!(event_buf= my_memdup((byte*) buf, len, MYF(MY_WME))) || (copy_log_event(event_buf, len, old_format))) DBUG_VOID_RETURN; @@ -3103,6 +3131,14 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) lev->exec_event is the place where the table is loaded (it calls mysql_load()). */ + +#if MYSQL_VERSION_ID < 40100 + rli->future_master_log_pos= log_pos + get_event_len(); +#elif MYSQL_VERSION_ID < 50000 + rli->future_group_master_log_pos= log_pos + get_event_len(); +#else + rli->future_group_master_log_pos= log_pos; +#endif if (lev->exec_event(0,rli,1)) { /* |