transactions that split GPB in transaction log are not handling a rollback correctly
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Drizzle |
Fix Released
|
Medium
|
David Shrewsbury | ||
7.0 |
Fix Released
|
Medium
|
David Shrewsbury |
Bug Description
I changed transaction_
ran the following:
use test;
CREATE TABLE t1 (
id INT NOT NULL
, value INT NOT NULL
, PRIMARY KEY (id)
);
START TRANSACTION;
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (1,1);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (2,2);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (3,3);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (4,4);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (5,5);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (6,6);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (7,7);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (8,8);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (9,9);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (10,10);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (11,11);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (12,12);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (13,13);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (14,14);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (15,15);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (16,16);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (17,17);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (18,18);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (19,19);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (20,20);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (21,21);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (22,22);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (23,23);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (24,24);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (25,25);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (26,26);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (27,27);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (28,28);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (29,29);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (30,30);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (31,31);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (32,32);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (33,33);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (34,34);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (35,35);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (36,36);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (37,37);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (38,38);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (39,39);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (40,40);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (41,41);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (42,42);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (43,43);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (44,44);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (45,45);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (47,47);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (48,48);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (49,49);
INSERT INTO `test`.`t1` (`id`,`value`) VALUES (50,50);
ROLLBACK;
transaction log contents
drizzle> SELECT PRINT_TRANSACTI
| transaction_context {
server_id: 1
transaction_id: 1
start_timestamp: 1283135027866274
end_timestamp: 1283135027866366
}
statement {
type: CREATE_TABLE
start_timestamp: 1283135027866287
end_timestamp: 1283135027866365
create_
table {
name: "t1"
engine {
name: "InnoDB"
}
field {
name: "id"
type: INTEGER
constraints {
}
}
field {
name: "value"
type: INTEGER
constraints {
}
}
indexes {
name: "PRIMARY"
is_primary: true
is_unique: true
type: UNKNOWN_INDEX
key_length: 4
index_part {
fieldnr: 0
}
options {
}
}
type: STANDARD
schema: "test"
options {
collation: "utf8_general_ci"
}
creation_
update_
}
}
}
|
| transaction_context {
server_id: 1
transaction_id: 2
start_timestamp: 1283135027923477
end_timestamp: 1283135027938057
}
statement {
type: INSERT
start_timestamp: 1283135027923481
end_timestamp: 1283135027938055
insert_header {
table_metadata {
schema_name: "test"
table_name: "t1"
}
field_metadata {
type: INTEGER
name: "id"
}
field_metadata {
type: INTEGER
name: "value"
}
}
insert_data {
segment_id: 1
end_segment: false
record {
insert_value: "1"
insert_value: "1"
is_null: false
is_null: false
}
record {
insert_value: "2"
insert_value: "2"
is_null: false
is_null: false
}
record {
insert_value: "3"
insert_value: "3"
is_null: false
is_null: false
}
record {
insert_value: "4"
insert_value: "4"
is_null: false
is_null: false
}
record {
insert_value: "5"
insert_value: "5"
is_null: false
is_null: false
}
record {
insert_value: "6"
insert_value: "6"
is_null: false
is_null: false
}
record {
insert_value: "7"
insert_value: "7"
is_null: false
is_null: false
}
record {
insert_value: "8"
insert_value: "8"
is_null: false
is_null: false
}
record {
insert_value: "9"
insert_value: "9"
is_null: false
is_null: false
}
record {
insert_value: "10"
insert_value: "10"
is_null: false
is_null: false
}
record {
insert_value: "11"
insert_value: "11"
is_null: false
is_null: false
}
record {
insert_value: "12"
insert_value: "12"
is_null: false
is_null: false
}
record {
insert_value: "13"
insert_value: "13"
is_null: false
is_null: false
}
record {
insert_value: "14"
insert_value: "14"
is_null: false
is_null: false
}
record {
insert_value: "15"
insert_value: "15"
is_null: false
is_null: false
}
record {
insert_value: "16"
insert_value: "16"
is_null: false
is_null: false
}
record {
insert_value: "17"
insert_value: "17"
is_null: false
is_null: false
}
record {
insert_value: "18"
insert_value: "18"
is_null: false
is_null: false
}
record {
insert_value: "19"
insert_value: "19"
is_null: false
is_null: false
}
record {
insert_value: "20"
insert_value: "20"
is_null: false
is_null: false
}
record {
insert_value: "21"
insert_value: "21"
is_null: false
is_null: false
}
record {
insert_value: "22"
insert_value: "22"
is_null: false
is_null: false
}
record {
insert_value: "23"
insert_value: "23"
is_null: false
is_null: false
}
record {
insert_value: "24"
insert_value: "24"
is_null: false
is_null: false
}
record {
insert_value: "25"
insert_value: "25"
is_null: false
is_null: false
}
record {
insert_value: "26"
insert_value: "26"
is_null: false
is_null: false
}
insert_value: "27"
insert_value: "27"
is_null: false
is_null: false
}
record {
insert_value: "28"
insert_value: "28"
is_null: false
is_null: false
}
record {
insert_value: "29"
insert_value: "29"
is_null: false
is_null: false
}
record {
insert_value: "30"
insert_value: "30"
is_null: false
is_null: false
}
record {
insert_value: "31"
insert_value: "31"
is_null: false
is_null: false
}
record {
insert_value: "32"
insert_value: "32"
is_null: false
is_null: false
}
record {
insert_value: "33"
insert_value: "33"
is_null: false
is_null: false
}
record {
insert_value: "34"
insert_value: "34"
is_null: false
is_null: false
}
record {
insert_value: "35"
insert_value: "35"
is_null: false
is_null: false
}
2 rows in set (0 sec)
drizzle>
Related branches
- Brian Aker: Needs Information
-
Diff: 104 lines (+29/-4)1 file modifieddrizzled/transaction_services.cc (+29/-4)
I suspect that on a rollback, the current active Transaction is simply deleted. Any previous Transaction messages associated with the same transaction will have already been sent through the replication stream.
I think we are going to have to design a way to buffer bulk load transactions and only send them to the replication stream once the transaction is complete. We could handle rollbacks properly then. And that will also fix the possibility of Transactions being intermingled in the replication stream with multiple concurrent sessions.