diff --git a/sql/handler.cc b/sql/handler.cc
index 51c888e4872..d311e912852 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -7344,15 +7344,23 @@ int handler::binlog_log_row(const uchar *before_record,
 {
   DBUG_ENTER("handler::binlog_log_row");
 
-  int error = 0;
-  if (row_logging)
-    error= binlog_log_row_to_binlog(table, before_record, after_record,
-                                    log_func, row_logging_has_trans);
+  int error= 0;
+  if (row_logging &&
+      ((error= binlog_log_row_to_binlog(table, before_record, after_record,
+                                        log_func, row_logging_has_trans))))
+    DBUG_RETURN(error);
 
 #ifdef HAVE_REPLICATION
-  if (unlikely(!error && table->s->online_alter_binlog && is_root_handler()))
+  if (unlikely(table->s->online_alter_binlog))
+  {
+    /*
+      This is ensured by prepare_for_alter_table_logging() and
+      as row_logging is never enable for alter table
+    */
+    DBUG_ASSERT(is_root_handler());
     error= online_alter_log_row(table, before_record, after_record,
                                 log_func);
+  }
 #endif // HAVE_REPLICATION
 
   DBUG_RETURN(error);
@@ -7458,7 +7466,7 @@ int handler::ha_reset()
   /*
     Disable row logging.
   */
-  row_logging= row_logging_init= 0;
+  binlog_log_row_needed= row_logging= row_logging_init= 0;
   clear_cached_table_binlog_row_based_flag();
   /* Reset information about pushed engine conditions */
   cancel_pushed_idx_cond();
@@ -7830,11 +7838,8 @@ bool handler::prepare_for_row_logging()
   if (wsrep_check_if_binlog_row(table) &&
       check_table_binlog_row_based())
   {
-    /*
-      Row logging enabled. Intialize all variables and write
-      annotated and table maps
-    */
-    row_logging= row_logging_init= 1;
+    /* Row logging enabled. Intialize all needed variables */
+    binlog_log_row_needed= row_logging= row_logging_init= 1;
 
     /*
       We need to have a transactional behavior for SQLCOM_CREATE_TABLE
@@ -7852,11 +7857,19 @@ bool handler::prepare_for_row_logging()
   else
   {
     /* Check row_logging has not been properly cleared from previous command */
-    DBUG_ASSERT(row_logging == 0);
+    DBUG_ASSERT(binlog_log_row_needed == 0 && row_logging == 0);
   }
+  prepare_for_alter_table_logging();
   DBUG_RETURN(row_logging);
 }
 
+void handler::prepare_for_alter_table_logging()
+{
+#ifdef HAVE_REPLICATION
+  if (table->s->online_alter_binlog)
+    binlog_log_row_needed= is_root_handler();
+#endif
+}
 
 /*
   Do all initialization needed for insert
@@ -7909,19 +7922,21 @@ int handler::ha_write_row(const uchar *buf)
   if (likely(!error))
   {
     rows_stats.inserted++;
-    Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
-    error= binlog_log_row(0, buf, log_func);
+    if (binlog_log_row_needed)
+    {
+      Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
+      if ((error= binlog_log_row(0, buf, log_func)))
+        goto err;
+    }
 
 #ifdef WITH_WSREP
     if (WSREP_NNULL(ha_thd()) && table_share->tmp_table == NO_TMP_TABLE &&
-        ht->flags & HTON_WSREP_REPLICATION &&
-        !error && (error= wsrep_after_row(ha_thd())))
-    {
-      DBUG_RETURN(error);
-    }
+        ht->flags & HTON_WSREP_REPLICATION)
+      error= wsrep_after_row(ha_thd());
 #endif /* WITH_WSREP */
   }
 
+err:
   DEBUG_SYNC_C("ha_write_row_end");
   DBUG_RETURN(error);
 }
@@ -7960,8 +7975,13 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data)
   if (likely(!error))
   {
     rows_stats.updated++;
-    Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;
-    error= binlog_log_row(old_data, new_data, log_func);
+
+    if (binlog_log_row_needed)
+    {
+      Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;
+      if ((error= binlog_log_row(old_data, new_data, log_func)))
+        return error;
+    }
 
 #ifdef WITH_WSREP
     THD *thd= ha_thd();
@@ -7978,7 +7998,7 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data)
                       " can not mark as PA unsafe");
       }
 
-      if (!error && table_share->tmp_table == NO_TMP_TABLE &&
+      if (table_share->tmp_table == NO_TMP_TABLE &&
           ht->flags & HTON_WSREP_REPLICATION)
         error= wsrep_after_row(thd);
     }
@@ -8036,8 +8056,12 @@ int handler::ha_delete_row(const uchar *buf)
   if (likely(!error))
   {
     rows_stats.deleted++;
-    Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
-    error= binlog_log_row(buf, 0, log_func);
+    if (binlog_log_row_needed)
+    {
+      Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
+      if ((error= binlog_log_row(buf, 0, log_func)))
+        return error;
+    }
 
 #ifdef WITH_WSREP
     THD *thd= ha_thd();
@@ -8054,7 +8078,7 @@ int handler::ha_delete_row(const uchar *buf)
                       " can not mark as PA unsafe");
       }
 
-      if (!error && table_share->tmp_table == NO_TMP_TABLE &&
+      if (table_share->tmp_table == NO_TMP_TABLE &&
           ht->flags & HTON_WSREP_REPLICATION)
         error= wsrep_after_row(thd);
     }
diff --git a/sql/handler.h b/sql/handler.h
index ed3192a662b..768be5687b9 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -3395,7 +3395,7 @@ class handler :public Sql_alloc
   void end_psi_batch_mode();
 
   /* If we have row logging enabled for this table */
-  bool row_logging, row_logging_init;
+  bool row_logging, row_logging_init, binlog_log_row_needed;
   /* If the row logging should be done in transaction cache */
   bool row_logging_has_trans;
 
@@ -3444,7 +3444,7 @@ class handler :public Sql_alloc
     m_psi_batch_mode(PSI_BATCH_MODE_NONE),
     m_psi_numrows(0),
     m_psi_locker(NULL),
-    row_logging(0), row_logging_init(0),
+    row_logging(0), row_logging_init(0), binlog_log_row_needed(0),
     m_lock_type(F_UNLCK), ha_share(NULL), optimizer_where_cost(0),
     optimizer_scan_setup_cost(0)
   {
@@ -5105,6 +5105,7 @@ class handler :public Sql_alloc
   virtual int delete_table(const char *name);
   bool check_table_binlog_row_based();
   bool prepare_for_row_logging();
+  void prepare_for_alter_table_logging();
   int prepare_for_insert(bool do_create);
   int binlog_log_row(const uchar *before_record,
                      const uchar *after_record,
@@ -5501,6 +5502,7 @@ class handler :public Sql_alloc
 
   bool log_not_redoable_operation(const char *operation);
 
+
 protected:
   Handler_share *get_ha_share_ptr();
   void set_ha_share_ptr(Handler_share *arg_ha_share);
diff --git a/sql/log.cc b/sql/log.cc
index bfc1a2c1625..cba633f72e8 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -6057,6 +6057,15 @@ void THD::binlog_prepare_for_row_logging()
   DBUG_VOID_RETURN;
 }
 
+void THD::binlog_prepare_for_alter_table_logging()
+{
+  for (TABLE *table= open_tables ; table; table= table->next)
+  {
+    if (table->query_id == query_id && table->current_lock == F_WRLCK)
+      table->file->prepare_for_alter_table_logging();
+  }
+}
+
 /**
    Write annnotated row event (the query) if needed
 */
diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
index 20188d6c11d..ae783f714b3 100644
--- a/sql/rpl_gtid.cc
+++ b/sql/rpl_gtid.cc
@@ -721,7 +721,8 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
   if (WSREP_ON_ && wsrep_thd_is_local(thd))
   {
     thd->wsrep_ignore_table= false;
-    table->file->row_logging= 1; // replication requires binary logging
+    // replication requires binary logging
+    table->file->row_logging= table->file->binlog_log_row_needed= 1;
     wsrep_start_trx_if_not_started(thd);
   }
   else
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 4e5f8bf3846..5b3b553dd26 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -6962,8 +6962,13 @@ int THD::decide_logging_format(TABLE_LIST *tables)
       }
     }
 
-    if (is_write && is_current_stmt_binlog_format_row())
-      binlog_prepare_for_row_logging();
+    if (is_write)
+    {
+      if (is_current_stmt_binlog_format_row())
+        binlog_prepare_for_row_logging();
+      else
+        binlog_prepare_for_alter_table_logging();
+    }
   }
   else
   {
@@ -6978,6 +6983,8 @@ int THD::decide_logging_format(TABLE_LIST *tables)
                         binlog_filter->db_ok(db.str)));
     if (WSREP_NNULL(this) && is_current_stmt_binlog_format_row())
       binlog_prepare_for_row_logging();
+    else
+      binlog_prepare_for_alter_table_logging();
   }
   DBUG_RETURN(0);
 }
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 7b30069ddf8..e8cb0aa6751 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3176,6 +3176,7 @@ class THD: public THD_count, /* this must be first */
   bool prepare_handlers_for_update(uint flag);
   bool binlog_write_annotated_row(Log_event_writer *writer);
   void binlog_prepare_for_row_logging();
+  void binlog_prepare_for_alter_table_logging();
   bool binlog_write_table_maps();
 
   void set_server_id(uint32 sid) { variables.server_id = sid; }
