Bug #35807 INSTALL PLUGIN replicates row-based, but not stmt-based
Submitted: 3 Apr 2008 15:53 Modified: 15 Sep 2008 16:09
Reporter: Ingo Strüwing Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Row Based Replication ( RBR ) Severity:S3 (Non-critical)
Version:5.1.24 OS:Any
Assigned to: Ingo Strüwing CPU Architecture:Any

[3 Apr 2008 15:53] Ingo Strüwing
Description:
INSTALL PLUGIN and UNINSTALL PLUGIN work with statement-based and mixed replication, but not with row-based replication. The test shows that there is no  statement-based, but row-based replication of these statements:

rpl.rpl_plugin_load 'row'      [ fail ]

=== SHOW MASTER STATUS ===
---- 1. ----
File    slave-bin.000001
Position        320
Binlog_Do_DB
Binlog_Ignore_DB
==========================

=== SHOW SLAVE STATUS ===
---- 1. ----
Slave_IO_State  Waiting for master to send event
Master_Host     127.0.0.1
Master_User     root
Master_Port     10560
Connect_Retry   1
Master_Log_File master-bin.000001
Read_Master_Log_Pos     210
Relay_Log_File  slave-relay-bin.000003
Relay_Log_Pos   252
Relay_Master_Log_File   master-bin.000001
Slave_IO_Running        Yes
Slave_SQL_Running       No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno      1062
Last_Error      Duplicate entry 'example' for key 'PRIMARY'
Skip_Counter    0
Exec_Master_Log_Pos     106
Relay_Log_Space 511
Until_Condition None
Until_Log_File
Until_Log_Pos   0
Master_SSL_Allowed      No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master
Master_SSL_Verify_Server_Cert   No
Last_IO_Errno   0
Last_IO_Error
Last_SQL_Errno  1062
Last_SQL_Error  Duplicate entry 'example' for key 'PRIMARY'
=========================

mysqltest: At line 37: could not sync with master ('select master_pos_wait('master-bin.000001', 210)' returned NULL)

The result from queries just before the failure was:
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
connection master
INSTALL PLUGIN example SONAME 'ha_example.so';
connection slave
INSTALL PLUGIN example SONAME 'ha_example.so';
connection master

More results from queries before failure can be found in /home2/mydev/mysql-5.1-ateam/mysql-test/var/log/rpl_plugin_load.log

Warnings from just before the error:
Note 1051 Unknown table 't1' 
Note 1051 Unknown table 't2' 
Note 1051 Unknown table 't3' 
Note 1051 Unknown table 't4' 
Note 1051 Unknown table 't5' 
Note 1051 Unknown table 't6' 
Note 1051 Unknown table 't7' 
Note 1051 Unknown table 't8'

Stopping All Servers
Restoring snapshot of databases
Resuming Tests

rpl.rpl_plugin_load 'stmt'     [ pass ]             18
rpl.rpl_plugin_load 'mix'      [ pass ]             19

The slave error log contains:

[ERROR] Slave SQL: Could not execute Write_rows event on table mysql.plugin; Duplicate entry 'example' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log master-bin.000001, end_log_pos 210, Error_code: 0

How to repeat:
Add the following files to the test suite:

mysql-test/suite/rpl/t/rpl_plugin_load-master.opt:

$EXAMPLE_PLUGIN_OPT

mysql-test/suite/rpl/t/rpl_plugin_load-slave.opt:

$EXAMPLE_PLUGIN_OPT

mysql-test/suite/rpl/t/rpl_plugin_load.test:

--source include/not_embedded.inc
--source include/have_log_bin.inc
# Dynamic loading of Example does not work on Windows currently.
--source include/not_windows.inc

#
# Check if server has support for loading udf's
# i.e it will support dlopen
#
--require r/have_dynamic_loading.require
disable_query_log;
show variables like "have_dynamic_loading";
enable_query_log;

--require r/true.require
disable_query_log;
select LENGTH("$EXAMPLE_PLUGIN") > 0 as `TRUE`;
enable_query_log;

source ./include/master-slave.inc;

echo connection master;
connection master;
INSTALL PLUGIN example SONAME 'ha_example.so';
#
    echo connection slave;
    connection slave;
    INSTALL PLUGIN example SONAME 'ha_example.so';
#
echo connection master;
connection master;

# We have to sync with master, to ensure slave had time to start properly
# before we stop it. If not, we get errors about UNIX_TIMESTAMP() in the log.
connection master;
sync_slave_with_master;

--echo End of 5.1 tests

echo connection master;
connection master;
UNINSTALL PLUGIN example;

echo connection slave;
connection slave;
UNINSTALL PLUGIN example;

echo connection default;
connection default;

mysql-test/suite/rpl/r/rpl_plugin_load.result:

stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
connection master
INSTALL PLUGIN example SONAME 'ha_example.so';
connection slave
INSTALL PLUGIN example SONAME 'ha_example.so';
connection master
End of 5.1 tests
connection master
UNINSTALL PLUGIN example;
connection slave
UNINSTALL PLUGIN example;
connection default

Run (cd mysql-test && ./mysql-test-run.pl --force rpl_plugin_load)

Suggested fix:
Remove row-based replication from [UN]INSTALL PLUGIN:

===== sql/sql_plugin.cc 1.84 vs edited =====
--- 1.84/sql/sql_plugin.cc      2008-03-14 18:50:33 +01:00
+++ edited/sql/sql_plugin.cc    2008-04-03 17:27:00 +02:00
@@ -1666,11 +1666,18 @@ bool mysql_install_plugin(THD *thd, cons
     goto deinit;
   }
 
+  /*
+    We do not replicate the INSTALL PLUGIN statement. Disable binlogging
+    of the insert into the plugin table, so that it is not replicated in
+    row based mode.
+  */
+  tmp_disable_binlog(thd);
   table->use_all_columns();
   restore_record(table, s->default_values);
   table->field[0]->store(name->str, name->length, system_charset_info);
   table->field[1]->store(dl->str, dl->length, files_charset_info);
   error= table->file->ha_write_row(table->record[0]);
+  reenable_binlog(thd);
   if (error)
   {
     table->file->print_error(error, MYF(0));
@@ -1727,6 +1734,12 @@ bool mysql_uninstall_plugin(THD *thd, co
   reap_plugins();
   pthread_mutex_unlock(&LOCK_plugin);
 
+  /*
+    We do not replicate the UNINSTALL PLUGIN statement. Disable binlogging
+    of the insert into the plugin table, so that it is not replicated in
+    row based mode.
+  */
+  tmp_disable_binlog(thd);
   table->use_all_columns();
   table->field[0]->store(name->str, name->length, system_charset_info);
   if (! table->file->index_read_idx_map(table->record[0], 0,
@@ -1738,12 +1751,14 @@ bool mysql_uninstall_plugin(THD *thd, co
     if ((error= table->file->ha_delete_row(table->record[0])))
     {
       table->file->print_error(error, MYF(0));
-      DBUG_RETURN(TRUE);
+      goto err1;
     }
   }
+  reenable_binlog(thd);
   DBUG_RETURN(FALSE);
 err:
   pthread_mutex_unlock(&LOCK_plugin);
+err1:
   DBUG_RETURN(TRUE);
 }
[3 Apr 2008 15:58] Ingo Strüwing
A possible workaround could be to stop replication for a moment, install the plugin(s), and restart replication, which I deem inacceptable.
[3 Apr 2008 16:07] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/44879

ChangeSet@1.2576, 2008-04-03 18:07:19+02:00, istruewing@stella.local +5 -0
  Bug#35807 - INSTALL PLUGIN replicates row-based, but not stmt-based
  
  INSTALL PLUGIN and UNINSTALL PLUGIN worked with statement-based and
  mixed-mode replication only, but not with row-based replication.
  
  There is no statement-based replication of these statements.
  But there was row-based replication of the inserts and deletes
  to and from the mysql.plugin table.
  
  The fix is to suppress binlogging during insert and delete to
  and from the mysql.plugin table.
[9 Jul 2008 17:50] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/49336

2624 Ingo Struewing	2008-07-09
      Bug#35807 - INSTALL PLUGIN replicates row-based, but not stmt-based
      
      INSTALL PLUGIN and UNINSTALL PLUGIN worked with statement-based and
      mixed-mode replication only, but not with row-based replication.
      
      There is no statement-based replication of these statements.
      But there was row-based replication of the inserts and deletes
      to and from the mysql.plugin table.
      
      The fix is to suppress binlogging during insert and delete to
      and from the mysql.plugin table.
[11 Jul 2008 14:28] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/49577

2624 Ingo Struewing	2008-07-11
      Bug#35807 - INSTALL PLUGIN replicates row-based, but not stmt-based
      
      INSTALL PLUGIN and UNINSTALL PLUGIN worked with statement-based and
      mixed-mode replication only, but not with row-based replication.
      
      There is no statement-based replication of these statements.
      But there was row-based replication of the inserts and deletes
      to and from the mysql.plugin table.
      
      The fix is to suppress binlogging during insert and delete to
      and from the mysql.plugin table.
[20 Aug 2008 10:56] Sven Sandberg
I pushed this to 5.1-bugteam and 6.0-bugteam
[21 Aug 2008 18:05] Bugs System
Pushed into 5.1.28  (revid:sven@mysql.com-20080819153556-y1kpcq87mbpyreie) (version source revid:sergefp@mysql.com-20080820003849-6ab1op9dxo52n27e) (pib:3)
[22 Aug 2008 8:38] Jon Stephens
Documented in the 5.1.28 changelog as follows:

        INSTALL PLUGIN and UNINSTALL PLUGIN caused row-based replication to
        fail.

          NOTE: These statements are not replicated; however, when using row-based
          logging, the changes they make to mysql system tables are written
          to the binary log.

Set bug status back to Patch Queued pending merge to 6.0 tree.
[14 Sep 2008 4:03] Bugs System
Pushed into 6.0.6-alpha  (revid:sven@mysql.com-20080819153556-y1kpcq87mbpyreie) (version source revid:hakan@mysql.com-20080716175219-8unfm2ikarselqpw) (pib:3)
[15 Sep 2008 16:09] Jon Stephens
Also documented in 6.0.6 changelog.