Skip to content

Commit 6b94984

Browse files
author
Slawomir Maludzinski
committed
Bug#35404584 Multi-column indexes with writest will cause HA_ERR_FOUND_DUPP_KEY
Issue description ----------------- Replication uses write-sets to detect dependencies and/or conflicts among transactions. The write-set is extracted from primary, not null unique and not null foreign keys when the binary log format is ROW and the option`transaction_write_set_extraction` is enabled, both options are enabled by default. For string columns, indexes can be created that use only the leading part of column values, using col_name(length) syntax to specify an index prefix length. Analysis -------- It was discovered that multi-column unique key write-sets were not properly generated, more precisely it was considering that unique keys could only refer the leading part of column values, while the whole values of referenced key columns are added to writeset. Proposed solution ----------------- In add_pke(), the values of the columns related to the multi-column key should not be added to the writeset without truncation. Only the specified width should be added. Change-Id: I6d22b2e703096feb315bb85c50e6f2768ff25380
1 parent debfff7 commit 6b94984

19 files changed

+2452
-77
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
include/group_replication.inc
2+
Warnings:
3+
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
4+
Note #### Storing MySQL user name or password information in the connection metadata repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START REPLICA; see the 'START REPLICA Syntax' in the MySQL Manual for more information.
5+
[connection server1]
6+
7+
############################################################
8+
# 1. Create a table on server1.
9+
[connection server1]
10+
CREATE TABLE t1(a VARCHAR(64), b VARCHAR(64), PRIMARY KEY(a(4), b));
11+
include/rpl_sync.inc
12+
13+
############################################################
14+
# 2. Set a debug sync before broadcast message to group on
15+
# connection server_1.
16+
# Commit a transaction that will be block before broadcast.
17+
[connection server_1]
18+
SET @debug_save= @@GLOBAL.DEBUG;
19+
SET @@GLOBAL.DEBUG='d,group_replication_before_message_broadcast';
20+
BEGIN;
21+
INSERT INTO t1 VALUES ('aaaazzzz', 'bbbbxxxx');
22+
COMMIT;
23+
24+
############################################################
25+
# 3. Wait until server_1 connection reaches the
26+
# group_replication_before_message_broadcast debug sync point.
27+
[connection server1]
28+
29+
############################################################
30+
# 4. Execute a transaction on server2, that will reach first
31+
# certification, since server_1 is blocked before broadcast.
32+
[connection server2]
33+
INSERT INTO t1 VALUES ('aaaaxxxx', 'bbbbxxxx');
34+
35+
############################################################
36+
# 5. Signal the waiting thread on server_1 to resume.
37+
[connection server1]
38+
SET DEBUG_SYNC='now SIGNAL waiting';
39+
SET @@GLOBAL.DEBUG= @debug_save;
40+
41+
############################################################
42+
# 6. It will end up in an error stating that it was aborted,
43+
# since transactions are conflicting and server2 was
44+
# ordered first.
45+
[connection server2]
46+
include/sync_slave_sql_with_master.inc
47+
[connection server_1]
48+
ERROR 40000: Plugin instructed the server to rollback the current transaction.
49+
50+
############################################################
51+
# 7. Assert that number of certified transactions are the
52+
# expected ones.
53+
[connection server1]
54+
include/assert.inc [The value of Count_Transactions_Checked should be 3 after starting group replication]
55+
include/assert.inc [The value of Count_Conflicts_Detected should be 1 after starting group replication]
56+
57+
############################################################
58+
# Checking the positive case in which there is no conflict.
59+
############################################################
60+
61+
############################################################
62+
# 1. Set a debug sync before broadcast message to group on
63+
# connection server_1.
64+
# Commit a transaction that will be block before broadcast.
65+
[connection server_1]
66+
SET @@GLOBAL.DEBUG='d,group_replication_before_message_broadcast';
67+
BEGIN;
68+
INSERT INTO t1 VALUES ('ccccxxxx', 'bbbbxxxx');
69+
COMMIT;
70+
71+
############################################################
72+
# 2. Wait until server_1 connection reaches the
73+
# group_replication_before_message_broadcast debug sync point.
74+
[connection server1]
75+
76+
############################################################
77+
# 3. Execute a transaction on server2, that will reach first
78+
# certification, since server_1 is blocked before broadcast.
79+
[connection server2]
80+
INSERT INTO t1 VALUES ('ddddxxxx', 'bbbbxxxx');
81+
include/sync_slave_sql_with_master.inc
82+
83+
############################################################
84+
# 4. Signal the waiting thread on server_1 to resume.
85+
[connection server1]
86+
SET DEBUG_SYNC='now SIGNAL waiting';
87+
SET @@GLOBAL.DEBUG= @debug_save;
88+
89+
########################################################################
90+
# 5. It will execute without error as the conflicting transactions have
91+
# been removed.
92+
[connection server_1]
93+
include/rpl_sync.inc
94+
95+
############################################################
96+
# 6. Assert that number of certified transactions are the
97+
# expected ones.
98+
[connection server1]
99+
include/assert.inc [Table t1 will contain 3 rows after the above execution]
100+
include/assert.inc [Table t1 will contain row after the above execution]
101+
include/assert.inc [Table t1 will contain row after the above execution]
102+
include/assert.inc [Table t1 will contain row after the above execution]
103+
include/assert.inc [The value of Count_Transactions_Checked should be 5 after starting group replication]
104+
include/assert.inc [The value of Count_Conflicts_Detected should be 1 after starting group replication]
105+
106+
############################################################
107+
# Clean up.
108+
DROP TABLE t1;
109+
include/group_replication_end.inc
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
include/group_replication.inc
2+
Warnings:
3+
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
4+
Note #### Storing MySQL user name or password information in the connection metadata repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START REPLICA; see the 'START REPLICA Syntax' in the MySQL Manual for more information.
5+
[connection server1]
6+
7+
############################################################
8+
# 1. Create a table on server1.
9+
[connection server1]
10+
CREATE TABLE t1(a VARCHAR(64), b VARCHAR(64), PRIMARY KEY(a(4), b));
11+
include/rpl_sync.inc
12+
13+
############################################################
14+
# 2. Set a debug sync before broadcast message to group on
15+
# connection server_1.
16+
# Commit a transaction that will be block before broadcast.
17+
[connection server_1]
18+
SET @debug_save= @@GLOBAL.DEBUG;
19+
SET @@GLOBAL.DEBUG='d,group_replication_before_message_broadcast';
20+
BEGIN;
21+
INSERT INTO t1 VALUE('aaaaxxxx', 'bbbbxxxx');
22+
COMMIT;
23+
24+
############################################################
25+
# 3. Wait until server_1 connection reaches the
26+
# group_replication_before_message_broadcast debug sync point.
27+
[connection server1]
28+
29+
############################################################
30+
# 4. Execute a transaction on server2, that will reach first
31+
# certification, since server_1 is blocked before broadcast.
32+
# Set do_not_add_pke_key_part debug so that server adds
33+
# only not truncated PKE. See Bug#35404584.
34+
[connection server2]
35+
SET @debug_save2= @@GLOBAL.DEBUG;
36+
SET @@GLOBAL.DEBUG= 'd,do_not_add_pke_key_part';
37+
INSERT INTO t1 VALUE('aaaaxxxx', 'bbbbxxxx');
38+
39+
############################################################
40+
# 5. Signal the waiting thread on server_1 to resume.
41+
[connection server1]
42+
SET DEBUG_SYNC='now SIGNAL waiting';
43+
SET @@GLOBAL.DEBUG= @debug_save;
44+
45+
############################################################
46+
# 6. It will end up in an error stating that it was aborted,
47+
# since transactions are conflicting and server2 was
48+
# ordered first.
49+
[connection server2]
50+
include/sync_slave_sql_with_master.inc
51+
[connection server_1]
52+
ERROR 40000: Plugin instructed the server to rollback the current transaction.
53+
54+
############################################################
55+
# 7. Assert that number of certified transactions are the
56+
# expected ones.
57+
[connection server1]
58+
include/assert.inc [The value of Count_Transactions_Checked should be 3 after starting group replication]
59+
include/assert.inc [The value of Count_Conflicts_Detected should be 1 after starting group replication]
60+
61+
############################################################
62+
# Checking the positive case in which there is no conflict.
63+
############################################################
64+
65+
############################################################
66+
# 1. Set a debug sync before broadcast message to group on
67+
# connection server_1.
68+
# Commit a transaction that will be block before broadcast.
69+
[connection server_1]
70+
SET @@GLOBAL.DEBUG='d,group_replication_before_message_broadcast';
71+
BEGIN;
72+
INSERT INTO t1 VALUES ('ccccxxxx', 'bbbbxxxx');
73+
COMMIT;
74+
75+
############################################################
76+
# 2. Wait until server_1 connection reaches the
77+
# group_replication_before_message_broadcast debug sync point.
78+
[connection server1]
79+
80+
############################################################
81+
# 3. Execute a transaction on server2, that will reach first
82+
# certification, since server_1 is blocked before broadcast.
83+
# Set do_not_add_pke_key_part debug so that server adds
84+
# only not truncated PKE. See Bug#35404584.
85+
[connection server2]
86+
INSERT INTO t1 VALUES ('ddddxxxx', 'bbbbxxxx');
87+
include/sync_slave_sql_with_master.inc
88+
89+
############################################################
90+
# 4. Signal the waiting thread on server_1 to resume.
91+
[connection server1]
92+
SET DEBUG_SYNC='now SIGNAL waiting';
93+
SET @@GLOBAL.DEBUG= @debug_save;
94+
95+
########################################################################
96+
# 5. It will execute without error as the conflicting transactions have
97+
# been removed.
98+
[connection server_1]
99+
include/rpl_sync.inc
100+
101+
############################################################
102+
# 6. Assert that number of certified transactions are the
103+
# expected ones.
104+
[connection server1]
105+
include/assert.inc [Table t1 will contain 3 rows after the above execution]
106+
include/assert.inc [Table t1 will contain row after the above execution]
107+
include/assert.inc [Table t1 will contain row after the above execution]
108+
include/assert.inc [Table t1 will contain row after the above execution]
109+
include/assert.inc [The value of Count_Transactions_Checked should be 5 after starting group replication]
110+
include/assert.inc [The value of Count_Conflicts_Detected should be 1 after starting group replication]
111+
112+
############################################################
113+
# Clean up.
114+
[connection server2]
115+
SET @@GLOBAL.DEBUG= @debug_save2;
116+
[connection server1]
117+
DROP TABLE t1;
118+
include/group_replication_end.inc
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
include/group_replication.inc
2+
Warnings:
3+
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
4+
Note #### Storing MySQL user name or password information in the connection metadata repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START REPLICA; see the 'START REPLICA Syntax' in the MySQL Manual for more information.
5+
[connection server1]
6+
7+
############################################################
8+
# 1. Create a table on server1.
9+
[connection server1]
10+
CREATE TABLE t1(p INT, a VARCHAR(64), b VARCHAR(64), PRIMARY KEY(p), UNIQUE KEY(a(4), b));
11+
include/rpl_sync.inc
12+
13+
############################################################
14+
# 2. Set a debug sync before broadcast message to group on
15+
# connection server_1.
16+
# Commit a transaction that will be block before broadcast.
17+
[connection server_1]
18+
SET @debug_save= @@GLOBAL.DEBUG;
19+
SET @@GLOBAL.DEBUG='d,group_replication_before_message_broadcast';
20+
BEGIN;
21+
INSERT INTO t1 VALUE(1, 'aaaazzzz', 'bbbbxxxx');
22+
COMMIT;
23+
24+
############################################################
25+
# 3. Wait until server_1 connection reaches the
26+
# group_replication_before_message_broadcast debug sync point.
27+
[connection server1]
28+
29+
############################################################
30+
# 4. Execute a transaction on server2, that will reach first
31+
# certification, since server_1 is blocked before broadcast.
32+
[connection server2]
33+
INSERT INTO t1 VALUE(1, 'aaaaxxxx', 'bbbbxxxx');
34+
35+
############################################################
36+
# 5. Signal the waiting thread on server_1 to resume.
37+
[connection server1]
38+
SET DEBUG_SYNC='now SIGNAL waiting';
39+
SET @@GLOBAL.DEBUG= @debug_save;
40+
41+
############################################################
42+
# 6. It will end up in an error stating that it was aborted,
43+
# since transactions are conflicting and server2 was
44+
# ordered first.
45+
[connection server2]
46+
include/sync_slave_sql_with_master.inc
47+
[connection server_1]
48+
ERROR 40000: Plugin instructed the server to rollback the current transaction.
49+
50+
############################################################
51+
# 7. Assert that number of certified transactions are the
52+
# expected ones.
53+
[connection server1]
54+
include/assert.inc [The value of Count_Transactions_Checked should be 3 after starting group replication]
55+
include/assert.inc [The value of Count_Conflicts_Detected should be 1 after starting group replication]
56+
57+
############################################################
58+
# Checking the positive case in which there is no conflict.
59+
############################################################
60+
61+
############################################################
62+
# 1. Set a debug sync before broadcast message to group on
63+
# connection server_1.
64+
# Commit a transaction that will be block before broadcast.
65+
[connection server_1]
66+
SET @@GLOBAL.DEBUG='d,group_replication_before_message_broadcast';
67+
BEGIN;
68+
INSERT INTO t1 VALUE(2, 'ccccxxxx', 'bbbbxxxx');
69+
COMMIT;
70+
71+
############################################################
72+
# 2. Wait until server_1 connection reaches the
73+
# group_replication_before_message_broadcast debug sync point.
74+
[connection server1]
75+
76+
############################################################
77+
# 3. Execute a transaction on server2, that will reach first
78+
# certification, since server_1 is blocked before broadcast.
79+
[connection server2]
80+
INSERT INTO t1 VALUES (3, 'ddddxxxx', 'bbbbxxxx');
81+
include/sync_slave_sql_with_master.inc
82+
83+
############################################################
84+
# 4. Signal the waiting thread on server_1 to resume.
85+
[connection server1]
86+
SET DEBUG_SYNC='now SIGNAL waiting';
87+
SET @@GLOBAL.DEBUG= @debug_save;
88+
89+
########################################################################
90+
# 5. It will execute without error as the conflicting transactions have
91+
# been removed.
92+
[connection server_1]
93+
include/rpl_sync.inc
94+
95+
############################################################
96+
# 6. Assert that number of certified transactions are the
97+
# expected ones.
98+
[connection server1]
99+
include/assert.inc [Table t1 will contain 3 rows after the above execution]
100+
include/assert.inc [Table t1 will contain row after the above execution]
101+
include/assert.inc [Table t1 will contain row after the above execution]
102+
include/assert.inc [Table t1 will contain row after the above execution]
103+
include/assert.inc [The value of Count_Transactions_Checked should be 5 after starting group replication]
104+
include/assert.inc [The value of Count_Conflicts_Detected should be 1 after starting group replication]
105+
106+
############################################################
107+
# Clean up.
108+
DROP TABLE t1;
109+
include/group_replication_end.inc

0 commit comments

Comments
 (0)