Merge lp:~akopytov/percona-server/bug1035225-5.1 into lp:percona-server/5.1

Proposed by Alexey Kopytov
Status: Merged
Approved by: Laurynas Biveinis
Approved revision: no longer in the source branch.
Merged at revision: 463
Proposed branch: lp:~akopytov/percona-server/bug1035225-5.1
Merge into: lp:percona-server/5.1
Diff against target: 237 lines (+131/-2)
6 files modified
Percona-Server/mysql-test/r/percona_bug1035225.result (+32/-0)
Percona-Server/mysql-test/t/percona_bug1035225.test (+47/-0)
Percona-Server/sql/handler.cc (+2/-0)
Percona-Server/sql/sql_insert.cc (+44/-2)
Percona-Server/sql/sql_parse.cc (+1/-0)
Percona-Server/sql/table.h (+5/-0)
To merge this branch: bzr merge lp:~akopytov/percona-server/bug1035225-5.1
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+119348@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote :
Revision history for this message
Alexey Kopytov (akopytov) wrote :

issue #25040

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'Percona-Server/mysql-test/r/percona_bug1035225.result'
2--- Percona-Server/mysql-test/r/percona_bug1035225.result 1970-01-01 00:00:00 +0000
3+++ Percona-Server/mysql-test/r/percona_bug1035225.result 2012-08-13 13:40:26 +0000
4@@ -0,0 +1,32 @@
5+CREATE TABLE t(
6+id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
7+k INT,
8+c CHAR(1),
9+UNIQUE KEY(k)) ENGINE=InnoDB;
10+#
11+# Connection 1
12+#
13+SET DEBUG_SYNC='ha_write_row_end SIGNAL continue2 WAIT_FOR continue1';
14+affected rows: 0
15+INSERT INTO t(k) VALUES (1), (2), (3) ON DUPLICATE KEY UPDATE c='1';
16+#
17+# Connection 2
18+#
19+SET DEBUG_SYNC='start_ha_write_row WAIT_FOR continue2';
20+affected rows: 0
21+SET DEBUG_SYNC='after_mysql_insert SIGNAL continue1';
22+affected rows: 0
23+INSERT INTO t(k) VALUES (2), (4), (5) ON DUPLICATE KEY UPDATE c='2';
24+affected rows: 3
25+info: Records: 3 Duplicates: 0 Warnings: 0
26+affected rows: 4
27+info: Records: 3 Duplicates: 1 Warnings: 0
28+SET DEBUG_SYNC='RESET';
29+SELECT * FROM t ORDER BY k;
30+id k c
31+1 1 NULL
32+4 2 1
33+2 3 NULL
34+5 4 NULL
35+6 5 NULL
36+DROP TABLE t;
37
38=== added file 'Percona-Server/mysql-test/t/percona_bug1035225.test'
39--- Percona-Server/mysql-test/t/percona_bug1035225.test 1970-01-01 00:00:00 +0000
40+++ Percona-Server/mysql-test/t/percona_bug1035225.test 2012-08-13 13:40:26 +0000
41@@ -0,0 +1,47 @@
42+##########################################################################
43+# LP bug #1035225 / MySQL bug #66301: INSERT ... ON DUPLICATE KEY UPDATE +
44+# innodb_autoinc_lock_mode=1 is broken
45+##########################################################################
46+
47+--source include/have_innodb.inc
48+--source include/have_debug_sync.inc
49+
50+CREATE TABLE t(
51+ id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
52+ k INT,
53+ c CHAR(1),
54+ UNIQUE KEY(k)) ENGINE=InnoDB;
55+
56+--enable_info
57+
58+--connect(con1, localhost, root)
59+--connect(con2, localhost, root)
60+
61+--connection con1
62+
63+--echo #
64+--echo # Connection 1
65+--echo #
66+SET DEBUG_SYNC='ha_write_row_end SIGNAL continue2 WAIT_FOR continue1';
67+--send INSERT INTO t(k) VALUES (1), (2), (3) ON DUPLICATE KEY UPDATE c='1'
68+
69+--connection con2
70+--echo #
71+--echo # Connection 2
72+--echo #
73+SET DEBUG_SYNC='start_ha_write_row WAIT_FOR continue2';
74+SET DEBUG_SYNC='after_mysql_insert SIGNAL continue1';
75+INSERT INTO t(k) VALUES (2), (4), (5) ON DUPLICATE KEY UPDATE c='2';
76+
77+--connection con1
78+--reap
79+--disable_info
80+SET DEBUG_SYNC='RESET';
81+SELECT * FROM t ORDER BY k;
82+
83+--disconnect con1
84+--disconnect con2
85+
86+--connection default
87+
88+DROP TABLE t;
89
90=== modified file 'Percona-Server/sql/handler.cc'
91--- Percona-Server/sql/handler.cc 2012-06-07 10:43:53 +0000
92+++ Percona-Server/sql/handler.cc 2012-08-13 13:40:26 +0000
93@@ -4804,6 +4804,8 @@
94 DBUG_RETURN(error);
95 if (unlikely(error= binlog_log_row(table, 0, buf, log_func)))
96 DBUG_RETURN(error); /* purecov: inspected */
97+
98+ DEBUG_SYNC_C("ha_write_row_end");
99 DBUG_RETURN(0);
100 }
101
102
103=== modified file 'Percona-Server/sql/sql_insert.cc'
104--- Percona-Server/sql/sql_insert.cc 2012-02-07 03:25:46 +0000
105+++ Percona-Server/sql/sql_insert.cc 2012-08-13 13:40:26 +0000
106@@ -282,7 +282,7 @@
107
108
109 /*
110- Check update fields for the timestamp field.
111+ Check update fields for the timestamp and auto_increment fields.
112
113 SYNOPSIS
114 check_update_fields()
115@@ -295,6 +295,9 @@
116 If the update fields include the timestamp field,
117 remove TIMESTAMP_AUTO_SET_ON_UPDATE from table->timestamp_field_type.
118
119+ If the update fields include an autoinc field, set the
120+ table->next_number_field_updated flag.
121+
122 RETURN
123 0 OK
124 -1 Error
125@@ -305,6 +308,7 @@
126 {
127 TABLE *table= insert_table_list->table;
128 my_bool timestamp_mark= 0;
129+ my_bool autoinc_mark= FALSE;
130
131 if (table->timestamp_field)
132 {
133@@ -316,6 +320,15 @@
134 table->timestamp_field->field_index);
135 }
136
137+ table->next_number_field_updated= FALSE;
138+
139+ if (table->found_next_number_field)
140+ {
141+ autoinc_mark=
142+ bitmap_test_and_clear(table->write_set,
143+ table->found_next_number_field->field_index);
144+ }
145+
146 /* Check the fields we are going to modify */
147 if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, 0))
148 return -1;
149@@ -335,6 +348,18 @@
150 bitmap_set_bit(table->write_set,
151 table->timestamp_field->field_index);
152 }
153+
154+ if (table->found_next_number_field)
155+ {
156+ if (bitmap_is_set(table->write_set,
157+ table->found_next_number_field->field_index))
158+ table->next_number_field_updated= TRUE;
159+
160+ if (autoinc_mark)
161+ bitmap_set_bit(table->write_set,
162+ table->found_next_number_field->field_index);
163+ }
164+
165 return 0;
166 }
167
168@@ -1371,6 +1396,7 @@
169 MY_BITMAP *save_read_set, *save_write_set;
170 ulonglong prev_insert_id= table->file->next_insert_id;
171 ulonglong insert_id_for_cur_row= 0;
172+ ulonglong prev_insert_id_for_cur_row= 0;
173 DBUG_ENTER("write_record");
174
175 info->records++;
176@@ -1514,6 +1540,7 @@
177 Except if LAST_INSERT_ID(#) was in the INSERT query, which is
178 handled separately by THD::arg_of_last_insert_id_function.
179 */
180+ prev_insert_id_for_cur_row= table->file->insert_id_for_cur_row;
181 insert_id_for_cur_row= table->file->insert_id_for_cur_row= 0;
182 trg_error= (table->triggers &&
183 table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
184@@ -1521,9 +1548,24 @@
185 info->copied++;
186 }
187
188- if (table->next_number_field)
189+ /*
190+ Only update next_insert_id if the AUTO_INCREMENT value was explicitly
191+ updated, so we don't update next_insert_id with the value from the row
192+ being updated. Otherwise reset next_insert_id to what it was before
193+ the duplicate key error, since that value is unused.
194+ */
195+ if (table->next_number_field_updated)
196+ {
197+ DBUG_ASSERT(table->next_number_field != NULL);
198+
199 table->file->adjust_next_insert_id_after_explicit_value(
200 table->next_number_field->val_int());
201+ }
202+ else
203+ {
204+ table->file->restore_auto_increment(prev_insert_id_for_cur_row);
205+ }
206+
207 info->touched++;
208
209 goto ok_or_after_trg_err;
210
211=== modified file 'Percona-Server/sql/sql_parse.cc'
212--- Percona-Server/sql/sql_parse.cc 2012-05-09 04:14:12 +0000
213+++ Percona-Server/sql/sql_parse.cc 2012-08-13 13:40:26 +0000
214@@ -3449,6 +3449,7 @@
215 DBUG_ASSERT(!debug_sync_set_action(current_thd,
216 STRING_WITH_LEN(act)));
217 };);
218+ DEBUG_SYNC(thd, "after_mysql_insert");
219 break;
220 }
221 case SQLCOM_REPLACE_SELECT:
222
223=== modified file 'Percona-Server/sql/table.h'
224--- Percona-Server/sql/table.h 2012-04-02 02:09:15 +0000
225+++ Percona-Server/sql/table.h 2012-08-13 13:40:26 +0000
226@@ -696,6 +696,11 @@
227
228 Field *next_number_field; /* Set if next_number is activated */
229 Field *found_next_number_field; /* Set on open */
230+ /*
231+ Set if next_number_field is in the UPDATE fields of INSERT ... ON DUPLICATE
232+ KEY UPDATE.
233+ */
234+ my_bool next_number_field_updated;
235 Field_timestamp *timestamp_field;
236
237 /* Table's triggers, 0 if there are no of them */

Subscribers

People subscribed via source and target branches