Commit 9cb9e9bc authored by unknown's avatar unknown

Bug#25513

  "Federared Transactions Failure"
  Bug occurs when the user performs an operation which inserts more than 
  one row into the federated table and the federated table references a 
  remote table stored within a transactional storage engine. When the
  insert operation for any one row in the statement fails due to 
  constraint violation, the federated engine is unable to perform 
  statement rollback and so the remote table contains a partial commit. 
  The user would expect a statement to perform the same so a statement 
  rollback is expected.
  This bug was fixed by implementing  bulk-insert handling into the
  federated storage engine. This will relieve the bug for most common
  situations by enabling the generation of a multi-row insert into the
  remote table and thus permitting the remote table to perform 
  statement rollback when neccessary.
  The multi-row insert is limited to the maximum packet size between 
  servers and should the size overflow, more than one insert statement 
  will be sent and this bug will reappear. Multi-row insert is disabled
  when an "INSERT...ON DUPLICATE KEY UPDATE" is being performed.
  The bulk-insert handling will offer a significant performance boost 
  when inserting a large number of small rows.
This patch builds on Bug29019 and Bug25511


sql/ha_federated.cc:
  bug25513
    new member methods:
      start_bulk_insert() - initializes memory for bulk insert
      end_bulk_insert() - sends any remaining bulk insert and frees memory
      append_stmt_insert() - create the INSERT statement
sql/ha_federated.h:
  bug25513
    new member value:
      bulk_insert
    new member methods:
      start_bulk_insert(), end_bulk_insert(), append_stmt_insert()
    make member methods private:
      read_next(), index_read_idx_with_result_set()
mysql-test/r/federated_innodb.result:
  New BitKeeper file ``mysql-test/r/federated_innodb.result''
mysql-test/t/federated_innodb-slave.opt:
  New BitKeeper file ``mysql-test/t/federated_innodb-slave.opt''
mysql-test/t/federated_innodb.test:
  New BitKeeper file ``mysql-test/t/federated_innodb.test''
parent 01f714fd
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;
stop slave;
DROP DATABASE IF EXISTS federated;
CREATE DATABASE federated;
DROP DATABASE IF EXISTS federated;
CREATE DATABASE federated;
create table federated.t1 (a int primary key, b varchar(64))
engine=myisam;
create table federated.t1 (a int primary key, b varchar(64))
engine=federated
connection='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
insert into federated.t1 values (1,"Larry"), (2,"Curly"), (1,"Moe");
ERROR 23000: Can't write; duplicate key in table 't1'
select * from federated.t1;
a b
1 Larry
2 Curly
truncate federated.t1;
alter table federated.t1 engine=innodb;
insert into federated.t1 values (1,"Larry"), (2,"Curly"), (1,"Moe");
ERROR 23000: Can't write; duplicate key in table 't1'
select * from federated.t1;
a b
drop table federated.t1;
drop table federated.t1;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
source include/federated.inc;
source include/have_innodb.inc;
#
# Bug#25513 Federated transaction failures
#
connection slave;
create table federated.t1 (a int primary key, b varchar(64))
engine=myisam;
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval create table federated.t1 (a int primary key, b varchar(64))
engine=federated
connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
--error ER_DUP_KEY
insert into federated.t1 values (1,"Larry"), (2,"Curly"), (1,"Moe");
select * from federated.t1;
connection slave;
truncate federated.t1;
alter table federated.t1 engine=innodb;
connection master;
--error ER_DUP_KEY
insert into federated.t1 values (1,"Larry"), (2,"Curly"), (1,"Moe");
select * from federated.t1;
drop table federated.t1;
connection slave;
drop table federated.t1;
source include/federated_cleanup.inc;
This diff is collapsed.
...@@ -159,6 +159,7 @@ class ha_federated: public handler ...@@ -159,6 +159,7 @@ class ha_federated: public handler
char remote_error_buf[FEDERATED_QUERY_BUFFER_SIZE]; char remote_error_buf[FEDERATED_QUERY_BUFFER_SIZE];
bool ignore_duplicates, replace_duplicates; bool ignore_duplicates, replace_duplicates;
bool insert_dup_update; bool insert_dup_update;
DYNAMIC_STRING bulk_insert;
private: private:
/* /*
...@@ -173,6 +174,14 @@ class ha_federated: public handler ...@@ -173,6 +174,14 @@ class ha_federated: public handler
bool records_in_range); bool records_in_range);
int stash_remote_error(); int stash_remote_error();
bool append_stmt_insert(String *query);
int read_next(byte *buf, MYSQL_RES *result);
int index_read_idx_with_result_set(byte *buf, uint index,
const byte *key,
uint key_len,
ha_rkey_function find_flag,
MYSQL_RES **result);
public: public:
ha_federated(TABLE *table_arg); ha_federated(TABLE *table_arg);
~ha_federated() ~ha_federated()
...@@ -258,6 +267,8 @@ class ha_federated: public handler ...@@ -258,6 +267,8 @@ class ha_federated: public handler
int open(const char *name, int mode, uint test_if_locked); // required int open(const char *name, int mode, uint test_if_locked); // required
int close(void); // required int close(void); // required
void start_bulk_insert(ha_rows rows);
int end_bulk_insert();
int write_row(byte *buf); int write_row(byte *buf);
int update_row(const byte *old_data, byte *new_data); int update_row(const byte *old_data, byte *new_data);
int delete_row(const byte *buf); int delete_row(const byte *buf);
...@@ -301,14 +312,7 @@ class ha_federated: public handler ...@@ -301,14 +312,7 @@ class ha_federated: public handler
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); //required enum thr_lock_type lock_type); //required
virtual bool get_error_message(int error, String *buf); bool get_error_message(int error, String *buf);
int read_next(byte *buf, MYSQL_RES *result);
int index_read_idx_with_result_set(byte *buf, uint index,
const byte *key,
uint key_len,
ha_rkey_function find_flag,
MYSQL_RES **result);
}; };
bool federated_db_init(void); bool federated_db_init(void);
......
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