Recently, I encountered a very bad BUG. I used the merge engine to copy data in row mode, which has a high probability of crash slave database.
My test environment is 5.1 master database and 5.5 slave Database
Test case:
- Create TableM1 (Int Primary Key, BInt) Engine = myisam;
- Create TableM2 (Int Primary Key, BInt) Engine = myisam;
- Create TableMm (Int Primary Key, BInt) Engine = mrg_myisam INSERT_METHOD =LAST UNION= (M1, m2 );
- Insert IntoMmValues(1, 2 );
The reason for crash is very simple. In fact, this bug was fixed a long time ago (MySQL Bug #47103), which may be caused by official negligence or a small number of people using the Merge storage engine, the patch is not backport to 5.5.
The following is a brief introduction.
We know that each row event of Binlog has a table_map_event.
In the Table_map_log_event: do_apply_event function, the table_list struct is initialized based on the content of the table map event, and table_list-> m_tabledef is constructed.
Here, table_list-> m_tabledef.m_field_metadata is allocated memory. Then, the table_list is mounted to rli-> tables_to_lock.
In the Rows_log_event: do_apply_event function, when open_and_lock_tables is called to actually open the table, the dependent child table is opened, and mount these table_list to rli-> tables_to_lock (the link pointer is next_global), but note that when you open the dependent word table here, its table_list-> m_tabledef.m_field_metadata is 0x0, no space is allocated.
Then, after opening the table, check whether the definition in table map is compatible with the definition of the actually opened table.
- 7663 RPL_TABLE_LIST * ptr = rli-> tables_to_lock;
- 7664For(; Ptr =Static_cast<RPL_TABLE_LIST *> (ptr-> next_global ))
- 7665 {
- 7666 TABLE * conv_table;
- 7667If(! Ptr-> m_tabledef.compatible_with (thd,Const_cast<Relay_log_info *> (rli ),
- 7668 ptr-> table, & conv_table ))
In table_def: compatible_with:
Can_convert_field_to (field, type (col), field_metadata (col), rli, m_flags, & order)
Both type and field_metadata involve references to m_field_metadata. Therefore, a segment error is generated directly, resulting in crash.
Official fix see http://lists.mysql.com/commits/86326