From bebb3427f2fb46d257a2530b791e8c5d28f933ee Mon Sep 17 00:00:00 2001 From: Ritheesh Vedire Date: Fri, 31 Jan 2014 04:25:39 +0530 Subject: Bug#16814264: FILTER OUT THE PERFORMANCE_SCHEMA RELAY LOG EVENTS FROM RELAY LOG Performance schema tables are local to a server and they should not be allowed to be executed by the slave from the relay log. From 5.6.10, P_S events are not written into the binary log. But prior to that, from mysql 5.5 onwards, P_S events are written to the binary log by master. The following are problematic scenarios: 1. Master 5.5 -> Slave 5.5 ======================== A) RBR: Slave crashes B) SBR: P_S statements are replicated. 2.Master 5.5 -> Slave 5.6 ======================== A) RBR: SQL thd generates error B) SBR : P_S statements are replicated 3. 5.5 binlog executed on a server 5.5 using mysqlbinlog|mysql ================================================================= A) RBR: Server crash (because of BINLOG'... statement) B) SBR: P_S statements are executed 4. 5.5 binlog executed on server 5.6 using mysqlbinlog|mysql ================================================================ A) RBR: SQL error (because of BINLOG'... statement) B) SBR: P_S statements are executed. The generalized behaviour should be: a) Slave SQL thread should certainly ignore P_S events read from the relay log. b) mysqlbinlog|mysql should replay the binlog succesfully. --- storage/perfschema/ha_perfschema.cc | 8 +++++++- storage/perfschema/ha_perfschema.h | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) (limited to 'storage') diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc index 468ec7fd8e8..4f41c8ef334 100644 --- a/storage/perfschema/ha_perfschema.cc +++ b/storage/perfschema/ha_perfschema.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -250,6 +250,9 @@ int ha_perfschema::update_row(const uchar *old_data, uchar *new_data) { DBUG_ENTER("ha_perfschema::update_row"); + if (is_executed_by_slave()) + DBUG_RETURN(0); + DBUG_ASSERT(m_table); int result= m_table->update_row(table, old_data, new_data, table->field); DBUG_RETURN(result); @@ -334,6 +337,9 @@ int ha_perfschema::delete_all_rows(void) DBUG_ENTER("ha_perfschema::delete_all_rows"); + if (is_executed_by_slave()) + DBUG_RETURN(0); + DBUG_ASSERT(m_table_share); if (m_table_share->m_delete_all_rows) result= m_table_share->m_delete_all_rows(); diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h index c0ee0827dbc..28875da6944 100644 --- a/storage/perfschema/ha_perfschema.h +++ b/storage/perfschema/ha_perfschema.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,6 +17,8 @@ #define HA_PERFSCHEMA_H #include "handler.h" /* class handler */ +#include "table.h" +#include "sql_class.h" #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ @@ -149,6 +151,39 @@ public: virtual void print_error(int error, myf errflags); private: + /** + Check if the caller is a replication thread or the caller is called + by a client thread executing base64 encoded BINLOG'... statement. + + In theory, performance schema tables are not supposed to be replicated. + This is true and enforced starting with MySQL 5.6.10. + In practice, in previous versions such as MySQL 5.5 (GA) or earlier 5.6 + (non GA) DML on performance schema tables could end up written in the binlog, + both in STATEMENT and ROW format. + While these records are not supposed to be there, they are found when: + - performing replication from a 5.5 master to a 5.6 slave during + upgrades + - performing replication from 5.5 (performance_schema enabled) + to a 5.6 slave + - performing point in time recovery in 5.6 with old archived logs. + + This API detects when the code calling the performance schema storage + engine is a slave thread or whether the code calling isthe client thread + executing a BINLOG'.. statement. + + This API acts as a late filter for the above mentioned cases. + + For ROW format, @see Rows_log_event::do_apply_event + + */ + bool is_executed_by_slave() const + { + DBUG_ASSERT(table != NULL); + DBUG_ASSERT(table->in_use != NULL); + return table->in_use->slave_thread; + + } + /** MySQL lock */ THR_LOCK_DATA m_thr_lock; /** Performance schema table share for this table handler. */ -- cgit v1.2.1