<?xml version="1.0" encoding="utf-8"?>
<launchpad-bug id="662714">
  <date_last_updated>2010-10-19 07:40:38.949987+00:00</date_last_updated>
  <api_links>
    <bug_api_link>https://api.launchpad.net/1.0/bugs/662714</bug_api_link>
    <bug_owner_link>https://api.launchpad.net/1.0/~pstoev-askmonty</bug_owner_link>
    <milestone_link>https://api.launchpad.net/1.0/maria/+milestone/5.2</milestone_link>
    <linked_branches_collection_link>https://api.launchpad.net/1.0/bugs/662714/linked_branches</linked_branches_collection_link>
    <activity_link>https://api.launchpad.net/1.0/bugs/662714/activity</activity_link>
  </api_links>
  <bug_web_link>https://bugs.launchpad.net/bugs/662714</bug_web_link>
  <owner>Philip Stoev</owner>
  <assignee></assignee>
  <milestone_title>Maria 5.2</milestone_title>
  <duplicate_link></duplicate_link>
  <duplicate_bug_id></duplicate_bug_id>
  <title>PBXT replication failure with simple transactions</title>
  <status>Confirmed</status>
  <importance>Undecided</importance>
  <created>2010-10-18 14:58:28.318706+00:00</created>
  <description>
<![CDATA[The following test causes PBXT replication to fail:
--source include/master-slave.inc
--disable_abort_on_error
--disable_warnings
--disable_query_log
--disable_result_log

CREATE TABLE `table10_pbxt_int_autoinc` ( `col_int_key` int, pk integer auto_increment, `col_int` int, /*Indices*/ key (`col_int_key` ), primary key (pk)) ENGINE=pbxt;
INSERT /*! IGNORE */ INTO table10_pbxt_int_autoinc VALUES  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100);
SET AUTOCOMMIT=OFF;
DELETE FROM `table10_pbxt_int_autoinc` WHERE 1 = 1 LIMIT 6;
UPDATE `table10_pbxt_int_autoinc` SET `pk` = 2 WHERE `col_int_key` > 3 LIMIT 6;
UPDATE `table10_pbxt_int_autoinc` SET `col_int_key` = 2 WHERE `pk` > 0 LIMIT 2;
set autocommit=1;


The error is

Last_SQL_Error  Could not execute Update_rows event on table test.table10_pbxt_int_autoinc; Can't find record in 'table10_pbxt_int_autoinc', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log master-bin.000001, end_log_pos 1083

]]>  </description>
  <activities>
    <activity datechanged="2010-10-18T14:57:33.575503+00:00">
      <oldvalue>
<![CDATA[]]>      </oldvalue>
      <newvalue>
<![CDATA[]]>      </newvalue>
      <whatchanged>bug</whatchanged>
      <person>Philip Stoev</person>
      <message>added bug</message>
    </activity>
    <activity datechanged="2010-10-18T14:58:06.928375+00:00">
      <oldvalue>
<![CDATA[The following test causes PBXT replication to fail:

--source include/master-slave.inc
--disable_abort_on_error
--disable_warnings
--disable_query_log
--disable_result_log

CREATE TABLE `table10_pbxt_int_autoinc` ( `col_int_key` int, pk integer auto_increment, `col_int` int, /*Indices*/ key (`col_int_key` ), primary key (pk)) EN$
INSERT /*! IGNORE */ INTO table10_pbxt_int_autoinc VALUES  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,$
SET AUTOCOMMIT=OFF;
DELETE FROM `table10_pbxt_int_autoinc` WHERE 1 = 1 LIMIT 6;
UPDATE `table10_pbxt_int_autoinc` SET `pk` = 2 WHERE `col_int_key` > 3 LIMIT 6;
UPDATE `table10_pbxt_int_autoinc` SET `col_int_key` = 2 WHERE `pk` > 0 LIMIT 2;
set autocommit=1;


--connection master
--sync_slave_with_master

The error is

Last_SQL_Error  Could not execute Update_rows event on table test.table10_pbxt_int_autoinc; Can't find record in 'table10_pbxt_int_autoinc', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log master-bin.000001, end_log_pos 1083]]>      </oldvalue>
      <newvalue>
<![CDATA[The following test causes PBXT replication to fail:
--source include/master-slave.inc
--disable_abort_on_error
--disable_warnings
--disable_query_log
--disable_result_log

CREATE TABLE `table10_pbxt_int_autoinc` ( `col_int_key` int, pk integer auto_increment, `col_int` int, /*Indices*/ key (`col_int_key` ), primary key (pk)) ENGINE=pbxt;
INSERT /*! IGNORE */ INTO table10_pbxt_int_autoinc VALUES  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100);
SET AUTOCOMMIT=OFF;
DELETE FROM `table10_pbxt_int_autoinc` WHERE 1 = 1 LIMIT 6;
UPDATE `table10_pbxt_int_autoinc` SET `pk` = 2 WHERE `col_int_key` > 3 LIMIT 6;
UPDATE `table10_pbxt_int_autoinc` SET `col_int_key` = 2 WHERE `pk` > 0 LIMIT 2;
set autocommit=1;


The error is

Last_SQL_Error  Could not execute Update_rows event on table test.table10_pbxt_int_autoinc; Can't find record in 'table10_pbxt_int_autoinc', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log master-bin.000001, end_log_pos 1083

]]>      </newvalue>
      <whatchanged>description</whatchanged>
      <person>Philip Stoev</person>
      <message></message>
    </activity>
    <activity datechanged="2010-10-18T14:58:28.318706+00:00">
      <oldvalue>
<![CDATA[]]>      </oldvalue>
      <newvalue>
<![CDATA[maria]]>      </newvalue>
      <whatchanged>bug task added</whatchanged>
      <person>Philip Stoev</person>
      <message></message>
    </activity>
    <activity datechanged="2010-10-18T15:04:26.198774+00:00">
      <oldvalue>
<![CDATA[]]>      </oldvalue>
      <newvalue>
<![CDATA[5.2]]>      </newvalue>
      <whatchanged>maria: milestone</whatchanged>
      <person>Philip Stoev</person>
      <message></message>
    </activity>
    <activity datechanged="2010-10-18T15:22:50.179173+00:00">
      <oldvalue>
<![CDATA[PBXT replication failure with autocommit=ON/OFF]]>      </oldvalue>
      <newvalue>
<![CDATA[PBXT replication failure with simple transactions]]>      </newvalue>
      <whatchanged>summary</whatchanged>
      <person>Philip Stoev</person>
      <message></message>
    </activity>
    <activity datechanged="2010-10-18T20:48:37.790356+00:00">
      <oldvalue>
<![CDATA[New]]>      </oldvalue>
      <newvalue>
<![CDATA[Confirmed]]>      </newvalue>
      <whatchanged>maria: status</whatchanged>
      <person>Kristian Nielsen</person>
      <message></message>
    </activity>
    <activity datechanged="2010-10-19T07:25:22.543166+00:00">
      <oldvalue>
<![CDATA[New]]>      </oldvalue>
      <newvalue>
<![CDATA[Confirmed]]>      </newvalue>
      <whatchanged>pbxt: status</whatchanged>
      <person>Paul McCullagh</person>
      <message></message>
    </activity>
  </activities>
  <comments>
    <comment commentlink="https://api.launchpad.net/1.0/pbxt/+bug/662714/comments/0" datecreated="2010-10-18T14:57:33.575503+00:00">
      <person>Philip Stoev</person>
      <subject>
<![CDATA[PBXT replication failure with autocommit=ON/OFF]]>      </subject>
      <content>
<![CDATA[The following test causes PBXT replication to fail:

--source include/master-slave.inc
--disable_abort_on_error
--disable_warnings
--disable_query_log
--disable_result_log

CREATE TABLE `table10_pbxt_int_autoinc` ( `col_int_key` int, pk integer auto_increment, `col_int` int, /*Indices*/ key (`col_int_key` ), primary key (pk)) EN$
INSERT /*! IGNORE */ INTO table10_pbxt_int_autoinc VALUES  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,  (100, NULL, 100) ,$
SET AUTOCOMMIT=OFF;
DELETE FROM `table10_pbxt_int_autoinc` WHERE 1 = 1 LIMIT 6;
UPDATE `table10_pbxt_int_autoinc` SET `pk` = 2 WHERE `col_int_key` > 3 LIMIT 6;
UPDATE `table10_pbxt_int_autoinc` SET `col_int_key` = 2 WHERE `pk` > 0 LIMIT 2;
set autocommit=1;


--connection master
--sync_slave_with_master

The error is

Last_SQL_Error  Could not execute Update_rows event on table test.table10_pbxt_int_autoinc; Can't find record in 'table10_pbxt_int_autoinc', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log master-bin.000001, end_log_pos 1083]]>      </content>
    </comment>
    <comment commentlink="https://api.launchpad.net/1.0/pbxt/+bug/662714/comments/1" datecreated="2010-10-18T15:06:26.520866+00:00">
      <person>Philip Stoev</person>
      <subject>
<![CDATA[Re: PBXT replication failure with autocommit=ON/OFF]]>      </subject>
      <content>
<![CDATA[Bug is also reproducible without LIMIT in the queries and with COMMIT instead of autocommit=1 . The table has a primary key.]]>      </content>
    </comment>
    <comment commentlink="https://api.launchpad.net/1.0/pbxt/+bug/662714/comments/2" datecreated="2010-10-18T19:00:30.724533+00:00">
      <person>Kristian Nielsen</person>
      <subject>
<![CDATA[Re: PBXT replication failure with simple transactions]]>      </subject>
      <content>
<![CDATA[The problem can be repeated with a simpler test case that does not involve replication:

--source include/have_pbxt.inc
CREATE TABLE t1 (a INT, b INTEGER AUTO_INCREMENT PRIMARY KEY, c INT) ENGINE=pbxt;
INSERT INTO t1 VALUES (100, NULL, 100), (100, NULL, 100);
BEGIN;
--error 1062
UPDATE t1 SET b = 20 WHERE a > 3 LIMIT 6;
SELECT * FROM t1 ORDER BY b;
COMMIT;
SELECT * FROM t1 ORDER BY b;
DROP TABLE t1;
DROP DATABASE pbxt;

The failing update is not rolled back as it should be; it leaves the primary key of the first row changed from 2 to 20.
]]>      </content>
    </comment>
    <comment commentlink="https://api.launchpad.net/1.0/pbxt/+bug/662714/comments/3" datecreated="2010-10-18T19:53:51.172180+00:00">
      <person>Kristian Nielsen</person>
      <subject>
<![CDATA[Re: PBXT replication failure with simple transactions]]>      </subject>
      <content>
<![CDATA[This may be a limitation of PBXT with transactions where some statements fail.

From the PBXT documentation, http://www.primebase.org/documentation/#diffs :

8.2 No Statement Level Sub-transactions

PBXT does not support statement level sub-transactions. This means that if an error occurs, PBXT will rollback the entire transaction, not just the current statement.

The only exception to this is the duplicate key error. PBXT undoes the INSERT or UPDATE statement when an duplicate key error occurs. The user is then free to decide whether to continue, or rollback the transaction.

Note that this can cause problems for replication, and means that INSERT with multiple rows should not be used when replicating PBXT tables. For example:

use test;
drop table if exists t;
create table t ( i int not null, unique index i (i) ) engine = PBXT;
set autocommit = 0;
insert into t values (1),(2),(2);
# error 1062 (duplicate key) occurs
commit;

select * from t;
i
1
2

In the above example, the INSERT statement is not completely rolled back. MySQL replication, however, will not replicate any part of the statement because it assumes that a transactional storage engine supports statement level sub-transactions.

In the original test case, the first UPDATE statement fails, and is therefore not replicated, however it is not completely rolled back despite what the pbxt documentation says.
]]>      </content>
    </comment>
    <comment commentlink="https://api.launchpad.net/1.0/pbxt/+bug/662714/comments/4" datecreated="2010-10-18T20:16:53+00:00">
      <person>Philip Stoev</person>
      <subject>
<![CDATA[Re: [Bug 662714] Re: PBXT replication failure with simple transactions]]>      </subject>
      <content>
<![CDATA[Thanks for the pointer, will try to construct a test case that is error-free 
and does not use multi-row insert.

Philip Stoev 
]]>      </content>
    </comment>
    <comment commentlink="https://api.launchpad.net/1.0/pbxt/+bug/662714/comments/5" datecreated="2010-10-18T20:48:27.800036+00:00">
      <person>Kristian Nielsen</person>
      <subject>
<![CDATA[Re: PBXT replication failure with simple transactions]]>      </subject>
      <content>
<![CDATA[Actually, thinking more, I do believe that this is a bug in PBXT.

I don't know if PBXT should be able to roll back only the statement that fails with duplicate key error, as the documentation states. But if not, it should do like NDB, which also is not able to roll back single statements that fail. In this case, the transaction should be marked as failed, and any further operations in the transaction should cause an error (including commit, but excluding rollback of course).

This will force the transaction to roll back in its entirety, and replication will not fail.

Philip, a possible work-around might be if you can in your tests detect failing statements, and in such cases roll back the entire transactions. This might be useful for any engine that lacks the ability to roll back single statements.]]>      </content>
    </comment>
    <comment commentlink="https://api.launchpad.net/1.0/pbxt/+bug/662714/comments/6" datecreated="2010-10-19T07:40:38.579212+00:00">
      <person>Paul McCullagh</person>
      <subject>
<![CDATA[Re: PBXT replication failure with simple transactions]]>      </subject>
      <content>
<![CDATA[Kristian, your insights into the problem are spot on. 

The documentation is incorrect. The "statement undo", is only done correctly in the special case that the statement only affects one row. At least, this is all that is done in the current implementation.

As you say, PBXT should return an error in all other cases, and then continue to return an error until the end of the transaction.

]]>      </content>
    </comment>
  </comments>
</launchpad-bug>
