diff --git a/.bzrignore b/.bzrignore index b34267b09f4..d3aba366fbe 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1135,3 +1135,5 @@ plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL libmysqld/libmysqld_exports_file.cc libmysqld/gcalc_slicescan.cc libmysqld/gcalc_tools.cc +sql/share/errmsg.sys +sql/share/mysql diff --git a/mysql-test/include/show_slave_status.inc b/mysql-test/include/show_slave_status.inc index 67b1c987954..d04c6354386 100644 --- a/mysql-test/include/show_slave_status.inc +++ b/mysql-test/include/show_slave_status.inc @@ -69,6 +69,7 @@ while ($_show_slave_status_items) --let $_show_slave_status_name= `SELECT SUBSTRING_INDEX('$_show_slave_status_items', ',', 1)` --let $_show_slave_status_items= `SELECT LTRIM(SUBSTRING('$_show_slave_status_items', LENGTH('$_show_slave_status_name') + 2))` + --replace_regex /\.[\\\/]master/master/ --let $_show_slave_status_value= query_get_value(SHOW SLAVE STATUS, $_show_slave_status_name, 1) --let $_show_slave_status_value= `SELECT REPLACE("$_show_slave_status_value", '$MYSQL_TEST_DIR', 'MYSQL_TEST_DIR')` --echo $_show_slave_status_name = '$_show_slave_status_value' diff --git a/mysql-test/suite/perfschema/r/binlog_mix.result b/mysql-test/suite/perfschema/r/binlog_mix.result index 3b2ab2bb435..97f76619619 100644 --- a/mysql-test/suite/perfschema/r/binlog_mix.result +++ b/mysql-test/suite/perfschema/r/binlog_mix.result @@ -26,10 +26,6 @@ update performance_schema.setup_instruments set enabled='YES' and name not in ("wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock"); show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (performance_schema.setup_instruments) -master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by server */ master-bin.000001 # Query # # use `test`; create table test.t1 (thread_id integer) @@ -44,7 +40,3 @@ master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ master-bin.000001 # Query # # use `test`; DROP TABLE `t2` /* generated by server */ -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (performance_schema.setup_instruments) -master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # COMMIT diff --git a/mysql-test/suite/perfschema/r/binlog_row.result b/mysql-test/suite/perfschema/r/binlog_row.result index 644e5d58e23..1bcdb4a6c58 100644 --- a/mysql-test/suite/perfschema/r/binlog_row.result +++ b/mysql-test/suite/perfschema/r/binlog_row.result @@ -26,10 +26,6 @@ update performance_schema.setup_instruments set enabled='YES' and name not in ("wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock"); show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (performance_schema.setup_instruments) -master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by server */ master-bin.000001 # Query # # use `test`; create table test.t1 (thread_id integer) @@ -44,7 +40,3 @@ master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ master-bin.000001 # Query # # use `test`; DROP TABLE `t2` /* generated by server */ -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (performance_schema.setup_instruments) -master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # COMMIT diff --git a/mysql-test/suite/perfschema/r/binlog_stmt.result b/mysql-test/suite/perfschema/r/binlog_stmt.result index 3fcecfdd1ca..1d18bd984b8 100644 --- a/mysql-test/suite/perfschema/r/binlog_stmt.result +++ b/mysql-test/suite/perfschema/r/binlog_stmt.result @@ -20,12 +20,14 @@ insert into test.t1 select thread_id from performance_schema.events_waits_current; Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses the general log, slow query log, or performance_schema table(s). This is unsafe because system tables may differ on slaves. +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Mixing self-logging and non-self-logging engines in a statement is unsafe. insert into test.t2 select name from performance_schema.setup_instruments where name like "wait/synch/rwlock/sql/%" and name not in ("wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock"); Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses the general log, slow query log, or performance_schema table(s). This is unsafe because system tables may differ on slaves. +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Mixing self-logging and non-self-logging engines in a statement is unsafe. drop table test.t1; drop table test.t2; update performance_schema.setup_instruments set enabled='YES' diff --git a/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result b/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result index c1b2c6e3195..1bee6f2ec1a 100644 --- a/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result +++ b/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result @@ -11,7 +11,7 @@ reset slave; start slave; include/wait_for_slave_param.inc [Last_IO_Errno] Last_IO_Errno = '1236' -Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'binlog truncated in the middle of event; consider out of disk space on master; the last event was read from './master-bin.000001' at 316, the last byte read was read from './master-bin.000001' at 335.'' +Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'binlog truncated in the middle of event; consider out of disk space on master; the last event was read from 'master-bin.000001' at 316, the last byte read was read from 'master-bin.000001' at 335.'' reset master; stop slave; reset slave; diff --git a/mysql-test/suite/rpl/r/rpl_performance_schema.result b/mysql-test/suite/rpl/r/rpl_performance_schema.result new file mode 100644 index 00000000000..ffda66c5bb9 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_performance_schema.result @@ -0,0 +1,4 @@ +include/master-slave.inc +[connection master] +UPDATE performance_schema.setup_instruments SET ENABLED="NO"; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_performance_schema.test b/mysql-test/suite/rpl/t/rpl_performance_schema.test new file mode 100644 index 00000000000..0562b0ea658 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_performance_schema.test @@ -0,0 +1,10 @@ +--source include/master-slave.inc +--source include/have_perfschema.inc +--source include/have_binlog_format_mixed.inc + +UPDATE performance_schema.setup_instruments SET ENABLED="NO"; + +--sync_slave_with_master +--source include/rpl_end.inc + +# End of test case diff --git a/sql/log_event.cc b/sql/log_event.cc index 816e4f4f38a..bd5f6306c47 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -10127,7 +10127,11 @@ void issue_long_find_row_warning(Log_event_type type, @note If the engine allows random access of the records, a combination of @c position() and @c rnd_pos() will be used. - */ + + Note that one MUST call ha_index_or_rnd_end() after this function if + it returns 0 as we must leave the row position in the handler intact + for any following update/delete command. +*/ int Rows_log_event::find_row(const Relay_log_info *rli) { @@ -10216,7 +10220,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli) { DBUG_PRINT("info",("ha_index_init returns error %d",error)); table->file->print_error(error, MYF(0)); - goto err; + goto end; } /* Fill key data for the row */ @@ -10251,7 +10255,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli) error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); table->file->ha_index_end(); - goto err; + goto end; } /* @@ -10281,15 +10285,15 @@ int Rows_log_event::find_row(const Relay_log_info *rli) /* Unique does not have non nullable part */ if (!(table->key_info->flags & (HA_NULL_PART_KEY))) { - table->file->ha_index_end(); - goto ok; + error= 0; + goto end; } else { KEY *keyinfo= table->key_info; /* - Unique has nullable part. We need to check if there is any field in the - BI image that is null and part of UNNI. + Unique has nullable part. We need to check if there is any + field in the BI image that is null and part of UNNI. */ bool null_found= FALSE; for (uint i=0; i < keyinfo->key_parts && !null_found; i++) @@ -10301,8 +10305,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli) if (!null_found) { - table->file->ha_index_end(); - goto ok; + error= 0; + goto end; } /* else fall through to index scan */ @@ -10345,14 +10349,9 @@ int Rows_log_event::find_row(const Relay_log_info *rli) DBUG_PRINT("info",("no record matching the given row found")); table->file->print_error(error, MYF(0)); table->file->ha_index_end(); - goto err; + goto end; } } - - /* - Have to restart the scan to be able to fetch the next row. - */ - table->file->ha_index_end(); } else { @@ -10360,14 +10359,12 @@ int Rows_log_event::find_row(const Relay_log_info *rli) /* We use this to test that the correct key is used in test cases. */ DBUG_EXECUTE_IF("slave_crash_if_table_scan", abort();); - int restart_count= 0; // Number of times scanning has restarted from top - /* We don't have a key: search the table using rnd_next() */ if ((error= table->file->ha_rnd_init_with_error(1))) { DBUG_PRINT("info",("error initializing table scan" " (ha_rnd_init returns %d)",error)); - goto err; + goto end; } is_table_scan= true; @@ -10383,8 +10380,14 @@ int Rows_log_event::find_row(const Relay_log_info *rli) switch (error) { case 0: + DBUG_DUMP("record found", table->record[0], table->s->reclength); break; + case HA_ERR_END_OF_FILE: + DBUG_PRINT("info", ("Record not found")); + table->file->ha_rnd_end(); + goto end; + /* If the record was deleted, we pick the next one without doing any comparisons. @@ -10392,58 +10395,28 @@ int Rows_log_event::find_row(const Relay_log_info *rli) case HA_ERR_RECORD_DELETED: goto restart_rnd_next; - case HA_ERR_END_OF_FILE: - if (++restart_count < 2) - { - int error2; - if ((error2= table->file->ha_rnd_init_with_error(1))) - { - error= error2; - goto err; - } - } - break; - default: DBUG_PRINT("info", ("Failed to get next record" " (rnd_next returns %d)",error)); table->file->print_error(error, MYF(0)); table->file->ha_rnd_end(); - goto err; + goto end; } } - while (restart_count < 2 && record_compare(table)); + while (record_compare(table)); /* Note: above record_compare will take into accout all record fields which might be incorrect in case a partial row was given in the event */ - /* - Have to restart the scan to be able to fetch the next row. - */ - if (restart_count == 2) - DBUG_PRINT("info", ("Record not found")); - else - DBUG_DUMP("record found", table->record[0], table->s->reclength); - table->file->ha_rnd_end(); - DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0); - goto err; } -ok: + +end: if (is_table_scan || is_index_scan) issue_long_find_row_warning(get_type_code(), m_table->alias.c_ptr(), is_index_scan, rli); - - table->default_column_bitmaps(); - DBUG_RETURN(0); - -err: - if (is_table_scan || is_index_scan) - issue_long_find_row_warning(get_type_code(), m_table->alias.c_ptr(), - is_index_scan, rli); - table->default_column_bitmaps(); DBUG_RETURN(error); } @@ -10516,6 +10489,7 @@ int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli) Delete the record found, located in record[0] */ error= m_table->file->ha_delete_row(m_table->record[0]); + m_table->file->ha_index_or_rnd_end(); } return error; } @@ -10658,7 +10632,7 @@ Update_rows_log_event::do_exec_row(const Relay_log_info *const rli) m_curr_row= m_curr_row_end; /* this also updates m_curr_row_end */ if ((error= unpack_current_row(rli))) - return error; + goto err; /* Now we have the right row to update. The old row (the one we're @@ -10678,6 +10652,8 @@ Update_rows_log_event::do_exec_row(const Relay_log_info *const rli) if (error == HA_ERR_RECORD_IS_THE_SAME) error= 0; +err: + m_table->file->ha_index_or_rnd_end(); return error; } diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 49d35197d60..09a58e29c18 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -2218,7 +2218,11 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, @note If the engine allows random access of the records, a combination of @c position() and @c rnd_pos() will be used. - */ + + Note that one MUST call ha_index_or_rnd_end() after this function if + it returns 0 as we must leave the row position in the handler intact + for any following update/delete command. +*/ int Old_rows_log_event::find_row(const Relay_log_info *rli) { @@ -2361,15 +2365,14 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) /* Unique does not have non nullable part */ if (!(table->key_info->flags & (HA_NULL_PART_KEY))) { - table->file->ha_index_end(); DBUG_RETURN(0); } else { KEY *keyinfo= table->key_info; /* - Unique has nullable part. We need to check if there is any field in the - BI image that is null and part of UNNI. + Unique has nullable part. We need to check if there is any + field in the BI image that is null and part of UNNI. */ bool null_found= FALSE; for (uint i=0; i < keyinfo->key_parts && !null_found; i++) @@ -2381,7 +2384,6 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) if (!null_found) { - table->file->ha_index_end(); DBUG_RETURN(0); } @@ -2424,11 +2426,6 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) DBUG_RETURN(error); } } - - /* - Have to restart the scan to be able to fetch the next row. - */ - table->file->ha_index_end(); } else { @@ -2462,8 +2459,10 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) if (++restart_count < 2) { int error2; + table->file->ha_rnd_end(); if ((error2= table->file->ha_rnd_init_with_error(1))) DBUG_RETURN(error2); + goto restart_rnd_next; } break; @@ -2489,7 +2488,8 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) DBUG_PRINT("info", ("Record not found")); else DBUG_DUMP("record found", table->record[0], table->s->reclength); - table->file->ha_rnd_end(); + if (error) + table->file->ha_rnd_end(); DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0); DBUG_RETURN(error); @@ -2738,6 +2738,7 @@ int Delete_rows_log_event_old::do_exec_row(const Relay_log_info *const rli) Delete the record found, located in record[0] */ error= m_table->file->ha_delete_row(m_table->record[0]); + m_table->file->ha_index_or_rnd_end(); } return error; } @@ -2874,6 +2875,8 @@ Update_rows_log_event_old::do_exec_row(const Relay_log_info *const rli) #endif error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]); + m_table->file->ha_index_or_rnd_end(); + if (error == HA_ERR_RECORD_IS_THE_SAME) error= 0; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 86d80b14ce5..9e92e9c6262 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1672,18 +1672,26 @@ int ha_myisam::index_init(uint idx, bool sorted) int ha_myisam::index_end() { + DBUG_ENTER("ha_myisam::index_end"); active_index=MAX_KEY; //pushed_idx_cond_keyno= MAX_KEY; mi_set_index_cond_func(file, NULL, 0); in_range_check_pushed_down= FALSE; ds_mrr.dsmrr_close(); - return 0; +#if !defined(DBUG_OFF) && defined(SQL_SELECT_FIXED_FOR_UPDATE) + file->update&= ~HA_STATE_AKTIV; // Forget active row +#endif + DBUG_RETURN(0); } int ha_myisam::rnd_end() { + DBUG_ENTER("ha_myisam::rnd_end"); ds_mrr.dsmrr_close(); - return 0; +#if !defined(DBUG_OFF) && defined(SQL_SELECT_FIXED_FOR_UPDATE) + file->update&= ~HA_STATE_AKTIV; // Forget active row +#endif + DBUG_RETURN(0); } int ha_myisam::index_read_map(uchar *buf, const uchar *key, @@ -1785,6 +1793,7 @@ void ha_myisam::position(const uchar *record) { my_off_t row_position= mi_position(file); my_store_ptr(ref, ref_length, row_position); + file->update|= HA_STATE_AKTIV; // Row can be updated } int ha_myisam::info(uint flag) diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h index 9557bc25b6e..17ab601e60f 100644 --- a/storage/perfschema/ha_perfschema.h +++ b/storage/perfschema/ha_perfschema.h @@ -70,9 +70,13 @@ public: Without HA_FAST_KEY_READ, the optimizer reads all columns and never calls ::rnd_pos(), so it is guaranteed to return only thread records. + We use HA_HAS_OWN_BINLOGGING to stop changes to this table to + be logged to slaves (as enabled performance tracking on all slaves + is probably not what anyone wants) */ - return HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT | - HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_NO_BLOBS; + return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT | + HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | + HA_HAS_OWN_BINLOGGING | HA_NO_BLOBS); } /**