Commit 73411a2e authored by guilhem@mysql.com's avatar guilhem@mysql.com

WL#1595 "Optionally fsync() the binlog after every statement":

New option --sync-binlog=x (and global settable variable) which will fsync the binlog
after every x-th disk write to it. That is, if in autocommit mode, after every x-th statement
written to the binlog; if using transactions, after every x-th transaction written to the binlog.
x==0 means no fsync. x==1 is the slowest.
There is no test added for this, I have just checked that it works as --sync-binlog=1 dramatically
slows down mysqld.
Made sync-frm a global settable variable.
parent ec5b55f8
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <m_ctype.h> // For test_if_number #include <m_ctype.h> // For test_if_number
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
ulong sync_binlog_counter= 0;
static bool test_if_number(const char *str, static bool test_if_number(const char *str,
long *res, bool allow_wildcards); long *res, bool allow_wildcards);
...@@ -1164,6 +1165,13 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, ...@@ -1164,6 +1165,13 @@ 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))));
}
/* /*
Write an event to the binary log Write an event to the binary log
*/ */
...@@ -1369,7 +1377,7 @@ COLLATION_CONNECTION=%lu,COLLATION_DATABASE=%lu,COLLATION_SERVER=%lu", ...@@ -1369,7 +1377,7 @@ COLLATION_CONNECTION=%lu,COLLATION_DATABASE=%lu,COLLATION_SERVER=%lu",
if (file == &log_file) // we are writing to the real log (disk) if (file == &log_file) // we are writing to the real log (disk)
{ {
if (flush_io_cache(file)) if (flush_io_cache(file) || sync_binlog(file))
goto err; goto err;
if (opt_using_transactions && !my_b_tell(&thd->transaction.trans_log)) if (opt_using_transactions && !my_b_tell(&thd->transaction.trans_log))
...@@ -1529,7 +1537,8 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) ...@@ -1529,7 +1537,8 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback)
commit_or_rollback ? 6 : 8, commit_or_rollback ? 6 : 8,
TRUE); TRUE);
qinfo.set_log_pos(this); qinfo.set_log_pos(this);
if (qinfo.write(&log_file) || flush_io_cache(&log_file)) if (qinfo.write(&log_file) || flush_io_cache(&log_file) ||
sync_binlog(&log_file))
goto err; goto err;
} }
if (cache->error) // Error on read if (cache->error) // Error on read
......
...@@ -858,7 +858,7 @@ extern ulong max_binlog_size, max_relay_log_size; ...@@ -858,7 +858,7 @@ extern ulong max_binlog_size, max_relay_log_size;
extern ulong rpl_recovery_rank, thread_cache_size; extern ulong rpl_recovery_rank, thread_cache_size;
extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log; extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log;
extern ulong specialflag, current_pid; extern ulong specialflag, current_pid;
extern ulong expire_logs_days; extern ulong expire_logs_days, sync_binlog_period, sync_binlog_counter;
extern my_bool relay_log_purge; extern my_bool relay_log_purge;
extern uint test_flags,select_errors,ha_open_options; extern uint test_flags,select_errors,ha_open_options;
extern uint protocol_version, mysqld_port, dropping_tables; extern uint protocol_version, mysqld_port, dropping_tables;
......
...@@ -306,7 +306,7 @@ ulong binlog_cache_use= 0, binlog_cache_disk_use= 0; ...@@ -306,7 +306,7 @@ ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
ulong max_connections,max_used_connections, ulong max_connections,max_used_connections,
max_connect_errors, max_user_connections = 0; max_connect_errors, max_user_connections = 0;
ulong thread_id=1L,current_pid; ulong thread_id=1L,current_pid;
ulong slow_launch_threads = 0; ulong slow_launch_threads = 0, sync_binlog_period;
ulong expire_logs_days = 0; ulong expire_logs_days = 0;
ulong rpl_recovery_rank=0; ulong rpl_recovery_rank=0;
ulong my_bind_addr; /* the address we bind to */ ulong my_bind_addr; /* the address we bind to */
...@@ -3884,7 +3884,7 @@ enum options_mysqld ...@@ -3884,7 +3884,7 @@ enum options_mysqld
OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_RANGE_ALLOC_BLOCK_SIZE,
OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE, OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE, OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
OPT_SYNC_FRM, OPT_BDB_NOSYNC, OPT_SYNC_FRM, OPT_SYNC_BINLOG, OPT_BDB_NOSYNC,
OPT_ENABLE_SHARED_MEMORY, OPT_ENABLE_SHARED_MEMORY,
OPT_SHARED_MEMORY_BASE_NAME, OPT_SHARED_MEMORY_BASE_NAME,
OPT_OLD_PASSWORDS, OPT_OLD_PASSWORDS,
...@@ -4866,6 +4866,12 @@ The minimum value for this variable is 4096.", ...@@ -4866,6 +4866,12 @@ The minimum value for this variable is 4096.",
(gptr*) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG, (gptr*) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD,
1, 0}, 1, 0},
{"sync-binlog", OPT_SYNC_BINLOG,
"Sync the binlog to disk after every #th event. \
#=0 (the default) does no sync. Syncing slows MySQL down",
(gptr*) &sync_binlog_period,
(gptr*) &sync_binlog_period, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1,
0},
{"table_cache", OPT_TABLE_CACHE, {"table_cache", OPT_TABLE_CACHE,
"The number of open tables for all threads.", (gptr*) &table_cache_size, "The number of open tables for all threads.", (gptr*) &table_cache_size,
(gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 512*1024L, (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 512*1024L,
......
...@@ -325,6 +325,10 @@ sys_var_thd_table_type sys_table_type("table_type", ...@@ -325,6 +325,10 @@ sys_var_thd_table_type sys_table_type("table_type",
&SV::table_type); &SV::table_type);
sys_var_thd_storage_engine sys_storage_engine("storage_engine", sys_var_thd_storage_engine sys_storage_engine("storage_engine",
&SV::table_type); &SV::table_type);
#ifdef HAVE_REPLICATION
sys_var_sync_binlog_period sys_sync_binlog_period("sync_binlog", &sync_binlog_period);
#endif
sys_var_bool_ptr sys_sync_frm("sync_frm", &opt_sync_frm);
sys_var_long_ptr sys_table_cache_size("table_cache", sys_var_long_ptr sys_table_cache_size("table_cache",
&table_cache_size); &table_cache_size);
sys_var_long_ptr sys_thread_cache_size("thread_cache_size", sys_var_long_ptr sys_thread_cache_size("thread_cache_size",
...@@ -573,6 +577,10 @@ sys_var *sys_variables[]= ...@@ -573,6 +577,10 @@ sys_var *sys_variables[]=
&sys_sql_mode, &sys_sql_mode,
&sys_sql_warnings, &sys_sql_warnings,
&sys_storage_engine, &sys_storage_engine,
#ifdef HAVE_REPLICATION
&sys_sync_binlog_period,
#endif
&sys_sync_frm,
&sys_table_cache_size, &sys_table_cache_size,
&sys_table_type, &sys_table_type,
&sys_thread_cache_size, &sys_thread_cache_size,
...@@ -788,6 +796,10 @@ struct show_var_st init_vars[]= { ...@@ -788,6 +796,10 @@ struct show_var_st init_vars[]= {
{sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS}, {sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS},
{sys_sql_mode.name, (char*) &sys_sql_mode, SHOW_SYS}, {sys_sql_mode.name, (char*) &sys_sql_mode, SHOW_SYS},
{sys_storage_engine.name, (char*) &sys_storage_engine, SHOW_SYS}, {sys_storage_engine.name, (char*) &sys_storage_engine, SHOW_SYS},
#ifdef HAVE_REPLICATION
{sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period, SHOW_SYS},
#endif
{sys_sync_frm.name, (char*) &sys_sync_frm, SHOW_SYS},
{"table_cache", (char*) &table_cache_size, SHOW_LONG}, {"table_cache", (char*) &table_cache_size, SHOW_LONG},
{sys_table_type.name, (char*) &sys_table_type, SHOW_SYS}, {sys_table_type.name, (char*) &sys_table_type, SHOW_SYS},
{sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS}, {sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS},
...@@ -2309,6 +2321,22 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var) ...@@ -2309,6 +2321,22 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
pthread_mutex_unlock(&LOCK_active_mi); pthread_mutex_unlock(&LOCK_active_mi);
return 0; return 0;
} }
bool sys_var_sync_binlog_period::update(THD *thd, set_var *var)
{
pthread_mutex_t *lock_log= mysql_bin_log.get_log_lock();
sync_binlog_period= var->save_result.ulong_value;
/*
Must reset the counter otherwise it may already be beyond the new period
and so the new period will not be taken into account. Need mutex otherwise
might be cancelled by a simultanate ++ in MYSQL_LOG::write().
*/
pthread_mutex_lock(lock_log);
sync_binlog_counter= 0;
pthread_mutex_unlock(lock_log);
return 0;
}
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
bool sys_var_rand_seed1::update(THD *thd, set_var *var) bool sys_var_rand_seed1::update(THD *thd, set_var *var)
......
...@@ -462,7 +462,7 @@ public: ...@@ -462,7 +462,7 @@ public:
}; };
#ifndef EMBEDDED_LIBRARY #ifdef HAVE_REPLICATION
class sys_var_slave_skip_counter :public sys_var class sys_var_slave_skip_counter :public sys_var
{ {
public: public:
...@@ -475,6 +475,14 @@ public: ...@@ -475,6 +475,14 @@ public:
type() or value_ptr() type() or value_ptr()
*/ */
}; };
class sys_var_sync_binlog_period :public sys_var_long_ptr
{
public:
sys_var_sync_binlog_period(const char *name_arg, ulong *value_ptr)
:sys_var_long_ptr(name_arg,value_ptr) {}
bool update(THD *thd, set_var *var);
};
#endif #endif
class sys_var_rand_seed1 :public sys_var class sys_var_rand_seed1 :public sys_var
......
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