Commit bebb3427 authored by Ritheesh Vedire's avatar Ritheesh Vedire

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.
      
parent d13408f8
......@@ -8004,6 +8004,14 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %lu", (ulong) m_table, m_table_id));
/*
A row event comprising of a P_S table
- should not be replicated (i.e executed) by the slave SQL thread.
- should not be executed by the client in the form BINLOG '...' stmts.
*/
if (table && table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
table= NULL;
if (table)
{
bool transactional_table= table->file->has_transactions();
......
/* 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();
......
/* 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 @@ class ha_perfschema : public handler
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. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment