Commit caa966cf authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Merge next-mr -> next-4284.

Cherry-pick a fix Bug#37148 from next-mr, to preserve
file ids of the added files, and ensure that all the necessary
changes have been pulled.

Since initially Bug#37148 was null-merged into 6.0,
the changeset that is now being cherry-picked was likewise
null merged into next-4284.

Now that Bug#37148 has been reapplied to 6.0, try to make
it work with next-4284. This is also necessary to be able
to pull other changes from 5.1-rep into next-4284.

To resolve the merge issues use this changeset applied
to 6.0:
revid:jperkin@sun.com-20091216103628-ylhqf7s6yegui2t9
revno: 3776.1.1
committer: He Zhenxing <zhenxing.he@sun.com>
branch nick: 6.0-codebase-bugfixing
timestamp: Thu 2009-12-17 17:02:50 +0800
message:
  Fix merge problem with Bug#37148


parent 9cd23662
#
# === Name
#
# binlog_inject_error.inc
#
# === Description
#
# Inject binlog write error when running the query, verifies that the
# query is ended with the proper error (ER_ERROR_ON_WRITE).
#
# === Usage
#
# let query= 'CREATE TABLE t1 (a INT)';
# source include/binlog_inject_error.inc;
#
SET GLOBAL debug='d,injecting_fault_writing';
--echo $query;
--replace_regex /(errno: .*)/(errno: #)/
--error ER_ERROR_ON_WRITE
--eval $query
SET GLOBAL debug='';
#
# Initialization
#
DROP TABLE IF EXISTS t1, t2;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP TRIGGER IF EXISTS tr1;
DROP TRIGGER IF EXISTS tr2;
DROP VIEW IF EXISTS v1, v2;
#
# Test injecting binlog write error when executing queries
#
SET GLOBAL debug='d,injecting_fault_writing';
CREATE TABLE t1 (a INT);
CREATE TABLE t1 (a INT);
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
INSERT INTO t1 VALUES (1),(2),(3);
SET GLOBAL debug='d,injecting_fault_writing';
INSERT INTO t1 VALUES (4),(5),(6);
INSERT INTO t1 VALUES (4),(5),(6);
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
UPDATE t1 set a=a+1;
UPDATE t1 set a=a+1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
DELETE FROM t1;
DELETE FROM t1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100);
CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100);
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
DROP TRIGGER tr1;
DROP TRIGGER tr1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
ALTER TABLE t1 ADD (b INT);
ALTER TABLE t1 ADD (b INT);
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
CREATE VIEW v1 AS SELECT a FROM t1;
CREATE VIEW v1 AS SELECT a FROM t1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
DROP VIEW v1;
DROP VIEW v1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1;
CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
DROP PROCEDURE p1;
DROP PROCEDURE p1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
DROP TABLE t1;
DROP TABLE t1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
CREATE FUNCTION f1() RETURNS INT return 1;
CREATE FUNCTION f1() RETURNS INT return 1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
DROP FUNCTION f1;
DROP FUNCTION f1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
CREATE USER user1;
CREATE USER user1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
SET GLOBAL debug='d,injecting_fault_writing';
DROP USER user1;
DROP USER user1;
ERROR HY000: Error writing file 'master-bin' ((errno: #)
SET GLOBAL debug='';
#
# Cleanup
#
DROP TABLE IF EXISTS t1, t2;
DROP FUNCTION IF EXISTS f1;
DROP PROCEDURE IF EXISTS p1;
DROP TRIGGER IF EXISTS tr1;
DROP VIEW IF EXISTS v1, v2;
#
# === Name ===
#
# binlog_write_error.test
#
# === Description ===
#
# This test case check if the error of writing binlog file is properly
# reported and handled when executing statements.
#
# === Related Bugs ===
#
# BUG#37148
#
source include/have_log_bin.inc;
source include/have_debug.inc;
--echo #
--echo # Initialization
--echo #
disable_warnings;
DROP TABLE IF EXISTS t1, t2;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP TRIGGER IF EXISTS tr1;
DROP TRIGGER IF EXISTS tr2;
DROP VIEW IF EXISTS v1, v2;
enable_warnings;
--echo #
--echo # Test injecting binlog write error when executing queries
--echo #
let $query= CREATE TABLE t1 (a INT);
source include/binlog_inject_error.inc;
INSERT INTO t1 VALUES (1),(2),(3);
let $query= INSERT INTO t1 VALUES (4),(5),(6);
source include/binlog_inject_error.inc;
let $query= UPDATE t1 set a=a+1;
source include/binlog_inject_error.inc;
let $query= DELETE FROM t1;
source include/binlog_inject_error.inc;
let $query= CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100);
source include/binlog_inject_error.inc;
let $query= DROP TRIGGER tr1;
source include/binlog_inject_error.inc;
let $query= ALTER TABLE t1 ADD (b INT);
source include/binlog_inject_error.inc;
let $query= CREATE VIEW v1 AS SELECT a FROM t1;
source include/binlog_inject_error.inc;
let $query= DROP VIEW v1;
source include/binlog_inject_error.inc;
let $query= CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1;
source include/binlog_inject_error.inc;
let $query= DROP PROCEDURE p1;
source include/binlog_inject_error.inc;
let $query= DROP TABLE t1;
source include/binlog_inject_error.inc;
let $query= CREATE FUNCTION f1() RETURNS INT return 1;
source include/binlog_inject_error.inc;
let $query= DROP FUNCTION f1;
source include/binlog_inject_error.inc;
let $query= CREATE USER user1;
source include/binlog_inject_error.inc;
let $query= REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1;
source include/binlog_inject_error.inc;
let $query= DROP USER user1;
source include/binlog_inject_error.inc;
--echo #
--echo # Cleanup
--echo #
disable_warnings;
DROP TABLE IF EXISTS t1, t2;
DROP FUNCTION IF EXISTS f1;
DROP PROCEDURE IF EXISTS p1;
DROP TRIGGER IF EXISTS tr1;
DROP VIEW IF EXISTS v1, v2;
enable_warnings;
......@@ -370,7 +370,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
}
/* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
will be written into the binary log as the definer for the SQL thread. */
write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
}
}
mysql_mutex_unlock(&LOCK_event_metadata);
......@@ -482,7 +482,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
new_element);
/* Binlog the alter event. */
DBUG_ASSERT(thd->query() && thd->query_length());
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
}
mysql_mutex_unlock(&LOCK_event_metadata);
......@@ -542,7 +542,7 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
event_queue->drop_event(thd, dbname, name);
/* Binlog the drop event. */
DBUG_ASSERT(thd->query() && thd->query_length());
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
mysql_mutex_unlock(&LOCK_event_metadata);
DBUG_RETURN(ret);
......
......@@ -1495,7 +1495,7 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
if (all || !thd->in_multi_stmt_transaction())
{
if (trx_data->has_incident())
mysql_bin_log.write_incident(thd, TRUE);
error= mysql_bin_log.write_incident(thd, TRUE);
trx_data->reset();
}
else // ...statement
......@@ -4809,7 +4809,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock)
Incident_log_event ev(thd, incident, write_error_msg);
if (lock)
mysql_mutex_lock(&LOCK_log);
ev.write(&log_file);
error= ev.write(&log_file);
if (lock)
{
if (!error && !(error= flush_and_sync(0)))
......
......@@ -5877,7 +5877,7 @@ Slave_log_event::Slave_log_event(const char* buf, uint event_len)
int Slave_log_event::do_apply_event(Relay_log_info const *rli)
{
if (mysql_bin_log.is_open())
mysql_bin_log.write(this);
return mysql_bin_log.write(this);
return 0;
}
#endif /* !MYSQL_CLIENT */
......@@ -7611,7 +7611,7 @@ static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
(assume the last master's transaction is ignored by the slave because of
replicate-ignore rules).
*/
thd->binlog_flush_pending_rows_event(true);
error= thd->binlog_flush_pending_rows_event(true);
/*
If this event is not in a transaction, the call below will, if some
......@@ -7622,7 +7622,7 @@ static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
are involved, commit the transaction and flush the pending event to the
binlog.
*/
error= trans_commit_stmt(thd);
error|= (error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
/*
Now what if this is not a transactional engine? we still need to
......
......@@ -1504,7 +1504,15 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
NOTE: For this new scheme there should be no pending event:
need to add code to assert that is the case.
*/
thd->binlog_flush_pending_rows_event(false);
error= thd->binlog_flush_pending_rows_event(false);
if (error)
{
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
ER(ER_SLAVE_FATAL_ERROR),
"call to binlog_flush_pending_rows_event() failed");
thd->is_slave_error= 1;
DBUG_RETURN(error);
}
TABLE_LIST *tables= rli->tables_to_lock;
close_tables_for_reopen(thd, &tables, NULL);
......@@ -1785,7 +1793,7 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
(assume the last master's transaction is ignored by the slave because of
replicate-ignore rules).
*/
thd->binlog_flush_pending_rows_event(true);
int binlog_error= thd->binlog_flush_pending_rows_event(true);
/*
If this event is not in a transaction, the call below will, if some
......@@ -1796,12 +1804,13 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
are involved, commit the transaction and flush the pending event to the
binlog.
*/
if ((error= trans_commit_stmt(thd)))
if ((error= (binlog_error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd))))
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
get_type_str(), m_table->s->db.str,
m_table->s->table_name.str);
error|= binlog_error;
/*
Now what if this is not a transactional engine? we still need to
......
......@@ -1029,8 +1029,8 @@ struct Query_cache_query_flags
#define query_cache_is_cacheable_query(L) 0
#endif /*HAVE_QUERY_CACHE*/
void write_bin_log(THD *thd, bool clear_error,
char const *query, ulong query_length);
int write_bin_log(THD *thd, bool clear_error,
char const *query, ulong query_length);
/* sql_connect.cc */
int check_user(THD *thd, enum enum_server_command command,
......
......@@ -59,10 +59,14 @@ injector::transaction::~transaction()
my_free(the_memory, MYF(0));
}
/**
@retval 0 transaction committed
@retval 1 transaction rolled back
*/
int injector::transaction::commit()
{
DBUG_ENTER("injector::transaction::commit()");
m_thd->binlog_flush_pending_rows_event(true);
int error= m_thd->binlog_flush_pending_rows_event(true);
/*
Cluster replication does not preserve statement or
transaction boundaries of the master. Instead, a new
......@@ -88,7 +92,7 @@ int injector::transaction::commit()
close_thread_tables(m_thd);
m_thd->mdl_context.release_transactional_locks();
}
DBUG_RETURN(0);
DBUG_RETURN(error);
}
......@@ -115,16 +119,16 @@ int injector::transaction::write_row (server_id_type sid, table tbl,
record_type record)
{
DBUG_ENTER("injector::transaction::write_row(...)");
if (int error= check_state(ROW_STATE))
int error= 0;
if (error= check_state(ROW_STATE))
DBUG_RETURN(error);
server_id_type save_id= m_thd->server_id;
m_thd->set_server_id(sid);
m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(),
cols, colcnt, record);
error= m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(),
cols, colcnt, record);
m_thd->set_server_id(save_id);
DBUG_RETURN(0);
DBUG_RETURN(error);
}
......@@ -134,15 +138,16 @@ int injector::transaction::delete_row(server_id_type sid, table tbl,
{
DBUG_ENTER("injector::transaction::delete_row(...)");
if (int error= check_state(ROW_STATE))
int error= 0;
if (error= check_state(ROW_STATE))
DBUG_RETURN(error);
server_id_type save_id= m_thd->server_id;
m_thd->set_server_id(sid);
m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(),
cols, colcnt, record);
error= m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(),
cols, colcnt, record);
m_thd->set_server_id(save_id);
DBUG_RETURN(0);
DBUG_RETURN(error);
}
......@@ -152,15 +157,16 @@ int injector::transaction::update_row(server_id_type sid, table tbl,
{
DBUG_ENTER("injector::transaction::update_row(...)");
if (int error= check_state(ROW_STATE))
int error= 0;
if (error= check_state(ROW_STATE))
DBUG_RETURN(error);
server_id_type save_id= m_thd->server_id;
m_thd->set_server_id(sid);
m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(),
cols, colcnt, before, after);
error= m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(),
cols, colcnt, before, after);
m_thd->set_server_id(save_id);
DBUG_RETURN(0);
DBUG_RETURN(error);
}
......
......@@ -1127,9 +1127,10 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
/* restore sql_mode when binloging */
thd->variables.sql_mode= saved_mode;
/* Such a statement can always go directly to binlog, no trans cache */
thd->binlog_query(THD::MYSQL_QUERY_TYPE,
log_query.c_ptr(), log_query.length(),
FALSE, FALSE, 0);
if (thd->binlog_query(THD::MYSQL_QUERY_TYPE,
log_query.c_ptr(), log_query.length(),
FALSE, FALSE, 0))
ret= SP_INTERNAL_ERROR;
thd->variables.sql_mode= 0;
}
}
......@@ -1192,7 +1193,8 @@ sp_drop_routine(THD *thd, int type, sp_name *name)
if (ret == SP_OK)
{
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
ret= SP_INTERNAL_ERROR;
sp_cache_invalidate();
/*
......@@ -1306,7 +1308,8 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
if (ret == SP_OK)
{
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
ret= SP_INTERNAL_ERROR;
sp_cache_invalidate();
}
err:
......
......@@ -1788,6 +1788,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
"Invoked ROUTINE modified a transactional table but MySQL "
"failed to reflect this change in the binary log");
err_status= TRUE;
}
reset_dynamic(&thd->user_var_events);
/* Forget those values, in case more function calls are binlogged: */
......
......@@ -1632,8 +1632,8 @@ bool change_password(THD *thd, const char *host, const char *user,
acl_user->host.hostname ? acl_user->host.hostname : "",
new_password));
thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length,
FALSE, FALSE, 0);
result= thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length,
FALSE, FALSE, 0);
}
end:
close_thread_tables(thd);
......@@ -3252,7 +3252,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
if (!result) /* success */
{
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
mysql_rwlock_unlock(&LOCK_grant);
......@@ -3419,7 +3419,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
if (write_to_binlog)
{
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
result= TRUE;
}
mysql_rwlock_unlock(&LOCK_grant);
......@@ -3539,7 +3540,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
if (!result)
{
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
mysql_rwlock_unlock(&LOCK_grant);
......@@ -5804,7 +5805,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe());
if (some_users_created)
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
mysql_rwlock_unlock(&LOCK_grant);
close_thread_tables(thd);
......@@ -5877,7 +5878,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
if (some_users_deleted)
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
mysql_rwlock_unlock(&LOCK_grant);
close_thread_tables(thd);
......@@ -5962,7 +5963,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
if (some_users_renamed && mysql_bin_log.is_open())
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
mysql_rwlock_unlock(&LOCK_grant);
close_thread_tables(thd);
......@@ -6144,15 +6145,17 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
mysql_mutex_unlock(&acl_cache->lock);
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
int binlog_error=
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
mysql_rwlock_unlock(&LOCK_grant);
close_thread_tables(thd);
if (result)
/* error for writing binary log has already been reported */
if (result && !binlog_error)
my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
DBUG_RETURN(result);
DBUG_RETURN(result || binlog_error);
}
......
......@@ -1505,7 +1505,7 @@ void close_thread_tables(THD *thd)
handled either before writing a query log event (inside
binlog_query()) or when preparing a pending event.
*/
thd->binlog_flush_pending_rows_event(TRUE);
(void)thd->binlog_flush_pending_rows_event(TRUE);
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
......@@ -1710,7 +1710,11 @@ void close_temporary_tables(THD *thd)
qinfo.db= db.ptr();
qinfo.db_len= db.length();
thd->variables.character_set_client= cs_save;
mysql_bin_log.write(&qinfo);
if (mysql_bin_log.write(&qinfo))
{
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, MYF(0),
"Failed to write the DROP statement for temporary tables to binary log");
}
thd->variables.pseudo_thread_id= save_pseudo_thread_id;
}
else
......@@ -3633,9 +3637,13 @@ static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry)
end = strxmov(strmov(query, "DELETE FROM `"),
share->db.str,"`.`",share->table_name.str,"`", NullS);
int errcode= query_error_code(thd, TRUE);
thd->binlog_query(THD::STMT_QUERY_TYPE,
query, (ulong)(end-query),
FALSE, FALSE, errcode);
if (thd->binlog_query(THD::STMT_QUERY_TYPE,
query, (ulong)(end-query),
FALSE, FALSE, errcode))
{
my_free(query, MYF(0));
return TRUE;
}
my_free(query, MYF(0));
}
else
......
......@@ -2892,7 +2892,7 @@ public:
{}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
void binlog_show_create_table(TABLE **tables, uint count);
int binlog_show_create_table(TABLE **tables, uint count);
void store_values(List<Item> &values);
void send_error(uint errcode,const char *err);
bool send_eof();
......
......@@ -178,13 +178,13 @@ uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
Helper function to write a query to binlog used by mysql_rm_db()
*/
static inline void write_to_binlog(THD *thd, char *query, uint q_len,
char *db, uint db_len)
static inline int write_to_binlog(THD *thd, char *query, uint q_len,
char *db, uint db_len)
{
Query_log_event qinfo(thd, query, q_len, 0, 0, 0);
qinfo.db= db;
qinfo.db_len= db_len;
mysql_bin_log.write(&qinfo);
return mysql_bin_log.write(&qinfo);
}
......@@ -774,7 +774,11 @@ not_silent:
qinfo.db_len = strlen(db);
/* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
if (mysql_bin_log.write(&qinfo))
{
error= -1;
goto exit;
}
}
my_ok(thd, result);
}
......@@ -851,7 +855,8 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
qinfo.db_len = strlen(db);
/* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
if (error= mysql_bin_log.write(&qinfo))
goto exit;
}
my_ok(thd, result);
......@@ -997,7 +1002,11 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
qinfo.db_len = strlen(db);
/* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
if (mysql_bin_log.write(&qinfo))
{
error= -1;
goto exit;
}
}
thd->clear_error();
thd->server_status|= SERVER_STATUS_DB_DROPPED;
......@@ -1025,7 +1034,11 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
if (query_pos + tbl_name_len + 1 >= query_end)
{
/* These DDL methods and logging protected with LOCK_mysql_create_db */
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
{
error= -1;
goto exit;
}
query_pos= query_data_start;
}
......@@ -1038,7 +1051,11 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
if (query_pos != query_data_start)
{
/* These DDL methods and logging protected with LOCK_mysql_create_db */
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
{
error= -1;
goto exit;
}
}
}
......@@ -1994,7 +2011,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
Query_log_event qinfo(thd, thd->query(), thd->query_length(),
0, TRUE, errcode);
thd->clear_error();
mysql_bin_log.write(&qinfo);
error|= mysql_bin_log.write(&qinfo);
}
/* Step9: Let's do "use newdb" if we renamed the current database */
......
......@@ -851,9 +851,10 @@ void multi_delete::abort()
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode);
/* possible error of writing binary log is ignored deliberately */
(void) thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode);
}
thd->transaction.all.modified_non_trans_table= true;
}
......@@ -1254,8 +1255,9 @@ end:
{
/* In RBR, the statement is not binlogged if the table is temporary. */
if (!is_temporary_table || !thd->current_stmt_binlog_row_based)
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
my_ok(thd); // This should return record count
error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
if (!error)
my_ok(thd); // This should return record count
}
if (has_mdl_lock)
thd->mdl_context.release_transactional_locks();
......
......@@ -2828,10 +2828,11 @@ bool Delayed_insert::handle_inserts(void)
will be binlogged together as one single Table_map event and one
single Rows event.
*/
thd.binlog_query(THD::ROW_QUERY_TYPE,
row->query.str, row->query.length,
FALSE, FALSE, errcode);
if (thd.binlog_query(THD::ROW_QUERY_TYPE,
row->query.str, row->query.length,
FALSE, FALSE, errcode))
goto err;
thd.time_zone_used = backup_time_zone_used;
thd.variables.time_zone = backup_time_zone;
}
......@@ -2905,8 +2906,9 @@ bool Delayed_insert::handle_inserts(void)
TODO: Move the logging to last in the sequence of rows.
*/
if (thd.current_stmt_binlog_row_based)
thd.binlog_flush_pending_rows_event(TRUE);
if (thd.current_stmt_binlog_row_based &&
thd.binlog_flush_pending_rows_event(TRUE))
goto err;
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
{ // This shouldn't happen
......@@ -3360,16 +3362,21 @@ bool select_insert::send_eof()
events are in the transaction cache and will be written when
ha_autocommit_or_rollback() is issued below.
*/
if (mysql_bin_log.is_open())
if (mysql_bin_log.is_open() &&
(!error || thd->transaction.stmt.modified_non_trans_table))
{
int errcode= 0;
if (!error)
thd->clear_error();
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
thd->binlog_query(THD::ROW_QUERY_TYPE,
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
trans_table, FALSE, errcode);
trans_table, FALSE, errcode))
{
table->file->ha_release_auto_increment();
DBUG_RETURN(1);
}
}
table->file->ha_release_auto_increment();
......@@ -3440,9 +3447,10 @@ void select_insert::abort() {
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
thd->query_length(),
transactional_table, FALSE, errcode);
/* error of writing binary log is ignored */
(void) thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
thd->query_length(),
transactional_table, FALSE, errcode);
}
if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
thd->transaction.all.modified_non_trans_table= TRUE;
......@@ -3712,7 +3720,8 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
!table->s->tmp_table &&
!ptr->get_create_info()->table_existed)
{
ptr->binlog_show_create_table(tables, count);
if (int error= ptr->binlog_show_create_table(tables, count))
return error;
}
return 0;
}
......@@ -3819,7 +3828,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DBUG_RETURN(0);
}
void
int
select_create::binlog_show_create_table(TABLE **tables, uint count)
{
/*
......@@ -3858,12 +3867,13 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
thd->binlog_query(THD::STMT_QUERY_TYPE,
query.ptr(), query.length(),
/* is_trans */ TRUE,
/* suppress_use */ FALSE,
errcode);
result= thd->binlog_query(THD::STMT_QUERY_TYPE,
query.ptr(), query.length(),
/* is_trans */ TRUE,
/* suppress_use */ FALSE,
errcode);
}
return result;
}
void select_create::store_values(List<Item> &values)
......@@ -3961,7 +3971,8 @@ void select_create::abort()
select_insert::abort();
thd->transaction.stmt.modified_non_trans_table= FALSE;
reenable_binlog(thd);
thd->binlog_flush_pending_rows_event(TRUE);
/* possible error of writing binary log is ignored deliberately */
(void)thd->binlog_flush_pending_rows_event(TRUE);
if (m_plock)
{
......
......@@ -155,7 +155,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
char name[FN_REFLEN];
File file;
TABLE *table= NULL;
int error;
int error= 0;
String *field_term=ex->field_term,*escaped=ex->escaped;
String *enclosed=ex->enclosed;
bool is_fifo=0;
......@@ -543,18 +543,20 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{
int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
/* since there is already an error, the possible error of
writing binary log will be ignored */
if (thd->transaction.stmt.modified_non_trans_table)
write_execute_load_query_log_event(thd, ex,
table_list->db,
table_list->table_name,
handle_duplicates, ignore,
transactional_table,
errcode);
(void) write_execute_load_query_log_event(thd, ex,
table_list->db,
table_list->table_name,
handle_duplicates, ignore,
transactional_table,
errcode);
else
{
Delete_file_log_event d(thd, db, transactional_table);
d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
mysql_bin_log.write(&d);
(void) mysql_bin_log.write(&d);
}
}
}
......@@ -581,7 +583,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
after this point.
*/
if (thd->current_stmt_binlog_row_based)
thd->binlog_flush_pending_rows_event(true);
error= thd->binlog_flush_pending_rows_event(true);
else
{
/*
......@@ -593,13 +595,15 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (lf_info.wrote_create_file)
{
int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
write_execute_load_query_log_event(thd, ex,
table_list->db, table_list->table_name,
handle_duplicates, ignore,
transactional_table,
errcode);
error= write_execute_load_query_log_event(thd, ex,
table_list->db, table_list->table_name,
handle_duplicates, ignore,
transactional_table,
errcode);
}
}
if (error)
goto err;
}
#endif /*!EMBEDDED_LIBRARY*/
......
......@@ -2766,7 +2766,7 @@ end_with_restore_list:
/*
Presumably, REPAIR and binlog writing doesn't require synchronization
*/
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
......@@ -2798,7 +2798,7 @@ end_with_restore_list:
/*
Presumably, ANALYZE and binlog writing doesn't require synchronization
*/
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
......@@ -2821,7 +2821,7 @@ end_with_restore_list:
/*
Presumably, OPTIMIZE and binlog writing doesn't require synchronization
*/
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
......@@ -2950,7 +2950,7 @@ end_with_restore_list:
if (incident)
{
Incident_log_event ev(thd, incident);
mysql_bin_log.write(&ev);
(void) mysql_bin_log.write(&ev); /* error is ignored */
mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
}
DBUG_PRINT("debug", ("Just after generate_incident()"));
......@@ -3753,7 +3753,8 @@ end_with_restore_list:
*/
if (!lex->no_write_to_binlog && write_to_binlog)
{
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
if (res= write_bin_log(thd, FALSE, thd->query(), thd->query_length()))
break;
}
my_ok(thd);
}
......@@ -4221,12 +4222,12 @@ create_sp_error:
case SP_KEY_NOT_FOUND:
if (lex->drop_if_exists)
{
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
SP_COM_STRING(lex), lex->spname->m_name.str);
res= FALSE;
my_ok(thd);
if (!res)
my_ok(thd);
break;
}
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
......
......@@ -4377,8 +4377,9 @@ static int fast_end_partition(THD *thd, ulonglong copied,
DBUG_RETURN(TRUE); /* The error has been reported */
if ((!is_empty) && (!written_bin_log) &&
(!thd->lex->no_write_to_binlog))
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
(!thd->lex->no_write_to_binlog) &&
write_bin_log(thd, FALSE, thd->query(), thd->query_length()))
DBUG_RETURN(TRUE);
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
(ulong) (copied + deleted),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment