mirror of
https://github.com/MariaDB/server.git
synced 2025-09-11 05:52:26 +03:00
Mainly resolving Guilhem's 4.1 patch to 5.0
client/mysqlbinlog.cc: Resolveing merge client/mysqldump.c: resolving merge sql/handler.cc: resolving merge sql/lex.h: resolve merge sql/log.cc: resolving merge sql/log_event.cc: resolving merge sql/sql_parse.cc: resolving merge sql/sql_yacc.yy: resolving merge
This commit is contained in:
161
sql/log.cc
161
sql/log.cc
@@ -35,7 +35,7 @@
|
||||
#include "message.h"
|
||||
#endif
|
||||
|
||||
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
|
||||
MYSQL_LOG mysql_log, mysql_slow_log, mysql_bin_log;
|
||||
ulong sync_binlog_counter= 0;
|
||||
|
||||
static bool test_if_number(const char *str,
|
||||
@@ -129,7 +129,8 @@ static int find_uniq_filename(char *name)
|
||||
MYSQL_LOG::MYSQL_LOG()
|
||||
:bytes_written(0), last_time(0), query_start(0), name(0),
|
||||
file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0),
|
||||
need_start_event(1)
|
||||
need_start_event(1), description_event_for_exec(0),
|
||||
description_event_for_queue(0)
|
||||
{
|
||||
/*
|
||||
We don't want to initialize LOCK_Log here as such initialization depends on
|
||||
@@ -157,6 +158,8 @@ void MYSQL_LOG::cleanup()
|
||||
{
|
||||
inited= 0;
|
||||
close(LOG_CLOSE_INDEX);
|
||||
delete description_event_for_queue;
|
||||
delete description_event_for_exec;
|
||||
(void) pthread_mutex_destroy(&LOCK_log);
|
||||
(void) pthread_mutex_destroy(&LOCK_index);
|
||||
(void) pthread_cond_destroy(&update_cond);
|
||||
@@ -226,7 +229,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
||||
const char *new_name, const char *index_file_name_arg,
|
||||
enum cache_type io_cache_type_arg,
|
||||
bool no_auto_events_arg,
|
||||
ulong max_size_arg)
|
||||
ulong max_size_arg,
|
||||
bool null_created_arg)
|
||||
{
|
||||
char buff[512];
|
||||
File file= -1, index_file_nr= -1;
|
||||
@@ -324,8 +328,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
||||
if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC,
|
||||
BIN_LOG_HEADER_SIZE))
|
||||
goto err;
|
||||
bytes_written += BIN_LOG_HEADER_SIZE;
|
||||
write_file_name_to_index_file=1;
|
||||
bytes_written+= BIN_LOG_HEADER_SIZE;
|
||||
write_file_name_to_index_file= 1;
|
||||
}
|
||||
|
||||
if (!my_b_inited(&index_file))
|
||||
@@ -355,10 +359,50 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
||||
}
|
||||
if (need_start_event && !no_auto_events)
|
||||
{
|
||||
need_start_event=0;
|
||||
Start_log_event s;
|
||||
s.set_log_pos(this);
|
||||
s.write(&log_file);
|
||||
/*
|
||||
In 4.x we set need_start_event=0 here, but in 5.0 we want a Start event
|
||||
even if this is not the very first binlog.
|
||||
*/
|
||||
Format_description_log_event s(BINLOG_VERSION);
|
||||
if (!s.is_valid())
|
||||
goto err;
|
||||
if (null_created_arg)
|
||||
s.created= 0;
|
||||
if (s.write(&log_file))
|
||||
goto err;
|
||||
bytes_written+= s.data_written;
|
||||
}
|
||||
if (description_event_for_queue &&
|
||||
description_event_for_queue->binlog_version>=4)
|
||||
{
|
||||
/*
|
||||
This is a relay log written to by the I/O slave thread.
|
||||
Write the event so that others can later know the format of this relay
|
||||
log.
|
||||
Note that this event is very close to the original event from the
|
||||
master (it has binlog version of the master, event types of the
|
||||
master), so this is suitable to parse the next relay log's event. It
|
||||
has been produced by
|
||||
Format_description_log_event::Format_description_log_event(char*
|
||||
buf,).
|
||||
Why don't we want to write the description_event_for_queue if this
|
||||
event is for format<4 (3.23 or 4.x): this is because in that case, the
|
||||
description_event_for_queue describes the data received from the
|
||||
master, but not the data written to the relay log (*conversion*),
|
||||
which is in format 4 (slave's).
|
||||
*/
|
||||
/*
|
||||
Set 'created' to 0, so that in next relay logs this event does not
|
||||
trigger cleaning actions on the slave in
|
||||
Format_description_log_event::exec_event().
|
||||
*/
|
||||
description_event_for_queue->created= 0;
|
||||
/* Don't set log_pos in event header */
|
||||
description_event_for_queue->artificial_event=1;
|
||||
|
||||
if (description_event_for_queue->write(&log_file))
|
||||
goto err;
|
||||
bytes_written+= description_event_for_queue->data_written;
|
||||
}
|
||||
if (flush_io_cache(&log_file) ||
|
||||
my_sync(log_file.file, MYF(MY_WME)))
|
||||
@@ -654,7 +698,7 @@ bool MYSQL_LOG::reset_logs(THD* thd)
|
||||
if (!thd->slave_thread)
|
||||
need_start_event=1;
|
||||
open(save_name, save_log_type, 0, index_file_name,
|
||||
io_cache_type, no_auto_events, max_size);
|
||||
io_cache_type, no_auto_events, max_size, 0);
|
||||
my_free((gptr) save_name, MYF(0));
|
||||
|
||||
err:
|
||||
@@ -836,22 +880,18 @@ int MYSQL_LOG::purge_logs(const char *to_log,
|
||||
while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
|
||||
!log_in_use(log_info.log_file_name))
|
||||
{
|
||||
ulong tmp;
|
||||
LINT_INIT(tmp);
|
||||
ulong file_size= 0;
|
||||
if (decrease_log_space) //stat the file we want to delete
|
||||
{
|
||||
MY_STAT s;
|
||||
|
||||
/*
|
||||
If we could not stat, we can't know the amount
|
||||
of space that deletion will free. In most cases,
|
||||
deletion won't work either, so it's not a problem.
|
||||
*/
|
||||
if (my_stat(log_info.log_file_name,&s,MYF(0)))
|
||||
tmp= s.st_size;
|
||||
else
|
||||
{
|
||||
/*
|
||||
If we could not stat, we can't know the amount
|
||||
of space that deletion will free. In most cases,
|
||||
deletion won't work either, so it's not a problem.
|
||||
*/
|
||||
tmp= 0;
|
||||
}
|
||||
file_size= s.st_size;
|
||||
}
|
||||
/*
|
||||
It's not fatal if we can't delete a log file ;
|
||||
@@ -859,7 +899,7 @@ int MYSQL_LOG::purge_logs(const char *to_log,
|
||||
*/
|
||||
DBUG_PRINT("info",("purging %s",log_info.log_file_name));
|
||||
if (!my_delete(log_info.log_file_name, MYF(0)) && decrease_log_space)
|
||||
*decrease_log_space-= tmp;
|
||||
*decrease_log_space-= file_size;
|
||||
if (find_next_log(&log_info, 0) || exit_loop)
|
||||
break;
|
||||
}
|
||||
@@ -1024,9 +1064,8 @@ void MYSQL_LOG::new_file(bool need_lock)
|
||||
*/
|
||||
THD *thd = current_thd; /* may be 0 if we are reacting to SIGHUP */
|
||||
Rotate_log_event r(thd,new_name+dirname_length(new_name));
|
||||
r.set_log_pos(this);
|
||||
r.write(&log_file);
|
||||
bytes_written += r.get_event_len();
|
||||
bytes_written += r.data_written;
|
||||
}
|
||||
/*
|
||||
Update needs to be signalled even if there is no rotate event
|
||||
@@ -1044,8 +1083,17 @@ void MYSQL_LOG::new_file(bool need_lock)
|
||||
Note that at this point, log_type != LOG_CLOSED (important for is_open()).
|
||||
*/
|
||||
|
||||
/*
|
||||
new_file() is only used for rotation (in FLUSH LOGS or because size >
|
||||
max_binlog_size or max_relay_log_size).
|
||||
If this is a binary log, the Format_description_log_event at the beginning of
|
||||
the new file should have created=0 (to distinguish with the
|
||||
Format_description_log_event written at server startup, which should
|
||||
trigger temp tables deletion on slaves.
|
||||
*/
|
||||
|
||||
open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type,
|
||||
no_auto_events, max_size);
|
||||
no_auto_events, max_size, 1);
|
||||
if (this == &mysql_bin_log)
|
||||
report_pos_in_innodb();
|
||||
my_free(old_name,MYF(0));
|
||||
@@ -1076,7 +1124,7 @@ bool MYSQL_LOG::append(Log_event* ev)
|
||||
error=1;
|
||||
goto err;
|
||||
}
|
||||
bytes_written += ev->get_event_len();
|
||||
bytes_written+= ev->data_written;
|
||||
DBUG_PRINT("info",("max_size: %lu",max_size));
|
||||
if ((uint) my_b_append_tell(&log_file) > max_size)
|
||||
{
|
||||
@@ -1129,7 +1177,7 @@ err:
|
||||
|
||||
/*
|
||||
Write to normal (not rotable) log
|
||||
This is the format for the 'normal', 'slow' and 'update' logs.
|
||||
This is the format for the 'normal' log.
|
||||
*/
|
||||
|
||||
bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
|
||||
@@ -1220,11 +1268,15 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
|
||||
|
||||
inline bool sync_binlog(IO_CACHE *cache)
|
||||
{
|
||||
return (sync_binlog_period &&
|
||||
(sync_binlog_period == ++sync_binlog_counter) &&
|
||||
(sync_binlog_counter= 0, my_sync(cache->file, MYF(MY_WME))));
|
||||
if (sync_binlog_period == ++sync_binlog_counter && sync_binlog_period)
|
||||
{
|
||||
sync_binlog_counter= 0;
|
||||
return my_sync(cache->file, MYF(MY_WME));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Write an event to the binary log
|
||||
*/
|
||||
@@ -1292,7 +1344,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||
|
||||
if (thd)
|
||||
{
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
/* NOTE: CHARSET AND TZ REPL WILL BE REWRITTEN SHORTLY */
|
||||
/*
|
||||
To make replication of charsets working in 4.1 we are writing values
|
||||
of charset related variables before every statement in the binlog,
|
||||
@@ -1318,7 +1370,6 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
|
||||
(uint) thd->variables.collation_database->number,
|
||||
(uint) thd->variables.collation_server->number);
|
||||
Query_log_event e(thd, buf, written, 0);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
@@ -1334,31 +1385,26 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
|
||||
thd->variables.time_zone->get_name()->ptr(),
|
||||
"'", NullS);
|
||||
Query_log_event e(thd, buf, buf_end - buf, 0);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (thd->last_insert_id_used)
|
||||
{
|
||||
Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
|
||||
thd->current_insert_id);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
if (thd->insert_id_used)
|
||||
{
|
||||
Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
if (thd->rand_used)
|
||||
{
|
||||
Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
@@ -1374,7 +1420,6 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
|
||||
user_var_event->length,
|
||||
user_var_event->type,
|
||||
user_var_event->charset_number);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
@@ -1386,48 +1431,17 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
|
||||
p= strmov(strmov(buf, "SET CHARACTER SET "),
|
||||
thd->variables.convert_set->name);
|
||||
Query_log_event e(thd, buf, (ulong) (p - buf), 0);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
If the user has set FOREIGN_KEY_CHECKS=0 we wrap every SQL
|
||||
command in the binlog inside:
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
<command>;
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
*/
|
||||
|
||||
if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)
|
||||
{
|
||||
Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=0", 24, 0);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the SQL command */
|
||||
|
||||
event_info->set_log_pos(this);
|
||||
if (event_info->write(file))
|
||||
goto err;
|
||||
|
||||
/* Write log events to reset the 'run environment' of the SQL command */
|
||||
|
||||
if (thd)
|
||||
{
|
||||
if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)
|
||||
{
|
||||
Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Tell for transactional table handlers up to which position in the
|
||||
binlog file we wrote. The table handler can store this info, and
|
||||
@@ -1604,7 +1618,6 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback)
|
||||
master's binlog, which would result in wrong positions being shown to
|
||||
the user, MASTER_POS_WAIT undue waiting etc.
|
||||
*/
|
||||
qinfo.set_log_pos(this);
|
||||
if (qinfo.write(&log_file))
|
||||
goto err;
|
||||
}
|
||||
@@ -1630,7 +1643,6 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback)
|
||||
commit_or_rollback ? "COMMIT" : "ROLLBACK",
|
||||
commit_or_rollback ? 6 : 8,
|
||||
TRUE);
|
||||
qinfo.set_log_pos(this);
|
||||
if (qinfo.write(&log_file) || flush_io_cache(&log_file) ||
|
||||
sync_binlog(&log_file))
|
||||
goto err;
|
||||
@@ -1692,8 +1704,7 @@ err:
|
||||
|
||||
|
||||
/*
|
||||
Write update log in a format suitable for incremental backup
|
||||
This is also used by the slow query log.
|
||||
Write to the slow query log.
|
||||
*/
|
||||
|
||||
bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
||||
@@ -1877,8 +1888,8 @@ void MYSQL_LOG::close(uint exiting)
|
||||
(exiting & LOG_CLOSE_STOP_EVENT))
|
||||
{
|
||||
Stop_log_event s;
|
||||
s.set_log_pos(this);
|
||||
s.write(&log_file);
|
||||
bytes_written+= s.data_written;
|
||||
signal_update();
|
||||
}
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
Reference in New Issue
Block a user