Bug #60926 | binary log events larger than max_allowed_packet | ||
---|---|---|---|
Submitted: | 19 Apr 2011 17:37 | Modified: | 12 Jun 2012 13:35 |
Reporter: | Devon Weller | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S1 (Critical) |
Version: | 5.5.8, 5.6.3, 5.1 | OS: | Linux |
Assigned to: | CPU Architecture: | Any | |
Tags: | binlog, max_allowed_packet |
[19 Apr 2011 17:37]
Devon Weller
[26 Apr 2011 18:27]
Sveta Smirnova
Thank you for the report. Verified as described. Can be considered feature request though. Test case for MTR: --source include/have_log_bin.inc set binlog_format='row'; drop table if exists t1; create table t1(f1 longtext); insert into t1 values(repeat('a', 1024*1022)); flush logs; drop table t1; set sql_log_bin=0; show master status; --let $MYSQLD_DATADIR=`select @@datadir` --exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 | $MYSQL test select count(*) from t1;
[26 Apr 2011 21:24]
Devon Weller
I would respectfully argue that if the MySQL server writes an event to the binlog that will break replication that this is a bug and not a feature request.
[16 Jul 2011 16:56]
Mark Callaghan
I think this is a serious bug, not a feature request. While debugging a local occurrence of the problem, I don't think there is code on the master to prevent creation of a binlog event that exceeds max_allowed_packet. I suspect this is a consequence of MyISAM -- as it is too late to fail when a binlog event has been created because MyISAM doesn't do undo. When I use cscope to show all references to max_allowed_packet, I find: * checks in slave code (log_event.cc, sql_repl.cc, slave.cc) * a few checks that might be used by the master in limited cases (item_strfunc.cc, item_geofunc.cc) * checks in client code (client.cc) So please tell me where the code is in the master that enforces this. Note that my clients are not friendly, but an unfriendly client could ignore max_allowed_packet and create even more problems. File Function Line 0 mysql.h <global> 188 unsigned long max_allowed_packet; 1 mysql.h <global> 374 #define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet) 2 libmysql.c <global> 66 #undef max_allowed_packet 3 libmysql.c <global> 69 ulong max_allowed_packet= 1024L*1024L*1024L; 4 libmysql.c <global> 229 {&max_allowed_packet, &net_buffer_length, 0}; 5 priv.cc <global> 34 unsigned long max_allowed_packet= 16384; 6 priv.h <global> 69 extern unsigned long max_allowed_packet; 7 client.c <global> 42 #undef max_allowed_packet 8 mysqld.cc <global> 7282 &global_system_variables.max_allowed_packet, 9 mysqld.cc <global> 7283 &max_system_variables.max_allowed_packet, 0, GET_ULONG, a set_var.cc <global> 384 &SV::max_allowed_packet); b sql_class.h <global> 402 ulong max_allowed_packet; c sql_client.cc <global> 38 global_system_variables.max_allowed_packet); d libmysql.c my_net_local_init 1576 net->max_packet_size= max(net_buffer_length, max_allowed_packet); e mysql_connection.cc my_net_local_init 68 net->max_packet_size= max_allowed_packet; f client.c mysql_read_default_options 1195 options->max_allowed_packet= atoi(opt_arg); g client.c CLI_MYSQL_REAL_CONNECT 2148 if (mysql->options.max_allowed_packet) h client.c CLI_MYSQL_REAL_CONNECT 2149 net->max_packet_size= mysql->options.max_allowed_packet; i item_geofunc.cc val_str 489 if (str->length() > current_thd->variables.max_allowed_packet) j item_geofunc.cc val_str 494 func_name(), current_thd->variables.max_allowed_packet); k item_strfunc.cc val_str 313 current_thd->variables.max_allowed_packet) l item_strfunc.cc val_str 318 current_thd->variables.max_allowed_packet); m item_strfunc.cc val_str 663 current_thd->variables.max_allowed_packet) n item_strfunc.cc val_str 668 current_thd->variables.max_allowed_packet); o item_strfunc.cc val_str 920 current_thd->variables.max_allowed_packet) p item_strfunc.cc val_str 926 current_thd->variables.max_allowed_packet); q item_strfunc.cc val_str 949 current_thd->variables.max_allowed_packet) r item_strfunc.cc val_str 954 current_thd->variables.max_allowed_packet); s item_strfunc.cc val_str 1027 (ulonglong) current_thd->variables.max_allowed_packet) t item_strfunc.cc val_str 1032 func_name(), current_thd->variables.max_allowed_packet); u item_strfunc.cc val_str 2435 if (length > current_thd->variables.max_allowed_packet / (uint) count) v item_strfunc.cc val_str 2440 func_name(), current_thd->variables.max_allowed_packet); w item_strfunc.cc val_str 2525 if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet) x item_strfunc.cc val_str 2530 func_name(), current_thd->variables.max_allowed_packet); y item_strfunc.cc val_str 2630 if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet) z item_strfunc.cc val_str 2635 func_name(), current_thd->variables.max_allowed_packet); A item_strfunc.cc val_str 2973 if (stat_info.st_size > (long ) current_thd->variables.max_allowed_packet) B item_strfunc.cc val_str 2978 func_name(), current_thd->variables.max_allowed_packet); C item_strfunc.cc val_str 3362 if (new_size > current_thd->variables.max_allowed_packet) D item_strfunc.cc val_str 3367 current_thd->variables.max_allowed_packet); E log_event.cc read_log_event 997 data_len > current_thd->variables.max_allowed_packet) F log_event.cc read_log_event 1098 #ifndef max_allowed_packet G log_event.cc read_log_event 1100 uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0; H log_event.cc read_log_event 1108 if (data_len > max_allowed_packet) I mysqld.cc get_options 9485 max_allowed_packet= global_system_variables.max_allowed_packet; J slave.cc init_slave_thread 1903 thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet K slave.cc handle_slave_io 2841 thd->variables.max_allowed_packet); L sql_repl.cc mysql_binlog_send 414 int old_max_allowed_packet= thd->variables.max_allowed_packet; M sql_repl.cc mysql_binlog_send 530 thd->variables.max_allowed_packet+= MAX_LOG_EVENT_HEADER; N sql_repl.cc mysql_binlog_send 882 thd->variables.max_allowed_packet= old_max_allowed_packet; O sql_repl.cc mysql_binlog_send 904 thd->variables.max_allowed_packet= old_max_allowed_packet; P sql_repl.cc mysql_show_binlog_events 1569 int old_max_allowed_packet= thd->variables.max_allowed_packet; Q sql_repl.cc mysql_show_binlog_events 1627 thd->variables.max_allowed_packet += MAX_LOG_EVENT_HEADER; R sql_repl.cc mysql_show_binlog_events 1708 thd->variables.max_allowed_packet= old_max_allowed_packet; S sql_repl.cc log_loaded_block 1881 uint max_event_size= current_thd->variables.max_allowed_packet; T sql_show.cc mysqld_list_processes 1801 ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
[16 Jul 2011 17:50]
Peter Laursen
I fully agree with Mark that this should be considered a bug. If some 'safe margin' is required when executing large statements to a master in order not to break replication. such 'safe margin' should be handled by the server by the way it uses 'max_allowed_packet. I alos have to ask for a reply (as soon as possible) to *how big* such safe margin should be (a constant, a formula .. whatever). This explains a nasty issue we had with one of our applications.
[16 Jul 2011 23:41]
Mark Callaghan
And to send a 1MB binlog event from master to slave, the value for max_allowed_packet on both the master and the slave must be >= 1MB. So there isn't an easy workaround for this. The easy workaround would have been to use a larger value on the slave.
[18 Jul 2011 19:09]
MySQL Verification Team
does it mean fix for bug #19402 was not good enough?
[20 Jul 2011 11:50]
James Day
The fix for bug#19402 already causes the master and slave to ignore max_allowed_packet by increasing their session setting based on the maximum known possible replication overhead. So how does the overhead become greater than the maximum we think is possible? Is it some custom version of replication that adds more overhead without also adjusting the calculation that allows for it? If not, what statements are being used that are causing the calculation to fail?
[12 Jun 2012 13:35]
Jon Stephens
Documented fix as follows in the 5.1.64, 5.5.26, and 5.6.6 changelogs: An event whose length exceeded the size of the master dump thread's max_allowed_packet caused replication to fail. This could occur when updating many large rows and using row-based replication. As part of the fix for this issue, a new server option --slave-max-allowed-packet is added, which permits max_allowed_packet to be exceeded by the slave SQL and I/O threads. Now the size of a packet transmitted from the master to the slave is checked only against this value (available as the value of the slave_max_allowed_packet server system variable), and not against the value of max_allowed_packet. Closed.
[12 Jun 2012 13:41]
Peter Laursen
@jon .. It should be added here as well http://dev.mysql.com/doc/refman/5.5/en/server-options.html if it is not already. Documenting in "Change History" is not enough.
[15 Jun 2012 11:27]
Peter Laursen
Since you don't reply I had to add a new bug: http://bugs.mysql.com/bug.php?id=65626
[10 Jan 2013 13:29]
Erlend Dahl
Bug #44690 was marked as a duplicate