diff options
author | Manish Kumar <manish.4.kumar@oracle.com> | 2012-06-12 12:59:13 +0530 |
---|---|---|
committer | Manish Kumar <manish.4.kumar@oracle.com> | 2012-06-12 12:59:13 +0530 |
commit | 1211b5d50bb00935d07fb9eda2dd6821d8f1cac5 (patch) | |
tree | 13654e7e8ad2169450fd3f44c20eddcfabc227ff /sql | |
parent | 0a8ae683297e494703c50d362e211d3ed1f3f5c3 (diff) | |
parent | 9aa79dc5966b6bba74c772d110265161a018cbf2 (diff) | |
download | mariadb-git-1211b5d50bb00935d07fb9eda2dd6821d8f1cac5.tar.gz |
BUG#12400221 - 60926: BINARY LOG EVENTS LARGER THAN MAX_ALLOWED_PACKET
Problem
========
Replication breaks in the cases if the event length exceeds
the size of master Dump thread's max_allowed_packet.
The reason why this failure is occuring is because the event length is
more than the total size of the max_allowed_packet, on addition of the
max_event_header length exceeds the max_allowed_packet of the DUMP thread.
This causes the Dump thread to break replication and throw an error.
That can happen e.g with row-based replication in Update_rows event.
Fix
====
The problem is fixed in 2 steps:
1.) The Dump thread limit to read event is increased to the upper limit
i.e. Dump thread reads whatever gets logged in the binary log.
2.) On the slave side we increase the the max_allowed_packet for the
slave's threads (IO/SQL) by increasing it to 1GB.
This is done using the new server option (slave_max_allowed_packet)
included, is used to regulate the max_allowed_packet of the
slave thread (IO/SQL) by the DBA, and facilitates the sending of
large packets from the master to the slave.
This causes the large packets to be received by the slave and apply
it successfully.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/log_event.cc | 2 | ||||
-rw-r--r-- | sql/log_event.h | 7 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/mysqld.cc | 7 | ||||
-rw-r--r-- | sql/set_var.cc | 2 | ||||
-rw-r--r-- | sql/slave.cc | 12 | ||||
-rw-r--r-- | sql/sql_repl.cc | 2 |
7 files changed, 25 insertions, 8 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc index a79797e4bc9..a47b3680d82 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1122,7 +1122,7 @@ failed my_b_read")); Log_event *res= 0; #ifndef max_allowed_packet THD *thd=current_thd; - uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0; + uint max_allowed_packet= thd ? slave_max_allowed_packet:~(ulong)0; #endif if (data_len > max_allowed_packet) diff --git a/sql/log_event.h b/sql/log_event.h index 4c80148458c..39cd55f313e 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -275,6 +275,13 @@ struct sql_ex_info MAX_SIZE_LOG_EVENT_STATUS + /* status */ \ NAME_LEN + 1) +/* + The new option is added to handle large packets that are sent from the master + to the slave. It is used to increase the thd(max_allowed) for both the + DUMP thread on the master and the SQL/IO thread on the slave. +*/ +#define MAX_MAX_ALLOWED_PACKET 1024*1024*1024 + /* Event header offsets; these point to places inside the fixed header. diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 359e84a3370..937617032dd 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1944,6 +1944,7 @@ extern ulong slave_net_timeout, slave_trans_retries; extern uint max_user_connections; extern ulong what_to_log,flush_time; extern ulong query_buff_size; +extern ulong slave_max_allowed_packet; extern ulong max_prepared_stmt_count, prepared_stmt_count; extern ulong binlog_cache_size, open_files_limit; extern ulonglong max_binlog_cache_size; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4a80fd043c8..db73504cb17 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -28,6 +28,7 @@ #include "mysys_err.h" #include "events.h" #include "debug_sync.h" +#include "log_event.h" #include "../storage/myisam/ha_myisam.h" @@ -574,6 +575,7 @@ static const char *slave_exec_mode_str= "STRICT"; ulong thread_cache_size=0, thread_pool_size= 0; ulong binlog_cache_size=0; ulonglong max_binlog_cache_size=0; +ulong slave_max_allowed_packet= 0; ulong query_cache_size=0; ulong refresh_version; /* Increments on each reload */ query_id_t global_query_id; @@ -5572,6 +5574,7 @@ enum options_mysqld OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD, OPT_LONG_QUERY_TIME, OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET, + OPT_SLAVE_MAX_ALLOWED_PACKET, OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE, OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS, OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE, @@ -6700,6 +6703,10 @@ thread is in the relay logs.", &global_system_variables.max_allowed_packet, &max_system_variables.max_allowed_packet, 0, GET_ULONG, REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, + {"slave_max_allowed_packet", OPT_SLAVE_MAX_ALLOWED_PACKET, + "The maximum packet length to sent successfully from the master to slave.", + &slave_max_allowed_packet, &slave_max_allowed_packet, 0, GET_ULONG, + REQUIRED_ARG, MAX_MAX_ALLOWED_PACKET, 1024, MAX_MAX_ALLOWED_PACKET, MALLOC_OVERHEAD, 1024, 0}, {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE, "Can be used to restrict the total size used to cache a multi-transaction query.", &max_binlog_cache_size, &max_binlog_cache_size, 0, diff --git a/sql/set_var.cc b/sql/set_var.cc index d9133a25d98..bbc47c2d7e8 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -366,6 +366,8 @@ static sys_var_const sys_lower_case_table_names(&vars, static sys_var_thd_ulong_session_readonly sys_max_allowed_packet(&vars, "max_allowed_packet", &SV::max_allowed_packet, check_max_allowed_packet); +static sys_var_long_ptr sys_slave_max_allowed_packet(&vars, "slave_max_allowed_packet", + &slave_max_allowed_packet); static sys_var_ulonglong_ptr sys_max_binlog_cache_size(&vars, "max_binlog_cache_size", &max_binlog_cache_size); static sys_var_long_ptr sys_max_binlog_size(&vars, "max_binlog_size", diff --git a/sql/slave.cc b/sql/slave.cc index 437762cc318..288077a6326 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1884,8 +1884,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) slave threads, since a replication event can become this much larger than the corresponding packet (query) sent from client to master. */ - thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet - + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */ + thd->variables.max_allowed_packet= slave_max_allowed_packet; thd->slave_thread = 1; thd->enable_slow_log= opt_log_slow_slave_statements; set_slave_thread_options(thd); @@ -2630,6 +2629,7 @@ pthread_handler_t handle_slave_io(void *arg) thread, since a replication event can become this much larger than the corresponding packet (query) sent from client to master. */ + thd->net.max_packet_size= slave_max_allowed_packet; mysql->net.max_packet_size= thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER; } else @@ -2761,12 +2761,12 @@ reading event")) switch (mysql_error_number) { case CR_NET_PACKET_TOO_LARGE: sql_print_error("\ -Log entry on master is longer than max_allowed_packet (%ld) on \ +Log entry on master is longer than slave_max_allowed_packet (%lu) on \ slave. If the entry is correct, restart the server with a higher value of \ -max_allowed_packet", - thd->variables.max_allowed_packet); +slave_max_allowed_packet", + slave_max_allowed_packet); mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE, - "%s", ER(ER_NET_PACKET_TOO_LARGE)); + "%s", "Got a packet bigger than 'slave_max_allowed_packet' bytes"); goto err; case ER_MASTER_FATAL_ERROR_READING_BINLOG: mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG, diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index c92d2db2c1e..7aa8176ae62 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -469,7 +469,7 @@ impossible position"; this larger than the corresponding packet (query) sent from client to master. */ - thd->variables.max_allowed_packet+= MAX_LOG_EVENT_HEADER; + thd->variables.max_allowed_packet= MAX_MAX_ALLOWED_PACKET; /* We can set log_lock now, it does not move (it's a member of |