Merge lp:~akopytov/percona-server/bug851674-5.1 into lp:percona-server/5.1
- bug851674-5.1
- Merge into 5.1
Proposed by
Alexey Kopytov
Status: | Merged |
---|---|
Merged at revision: | 286 |
Proposed branch: | lp:~akopytov/percona-server/bug851674-5.1 |
Merge into: | lp:percona-server/5.1 |
Diff against target: |
372 lines (+269/-8) 1 file modified
patches/innodb_expand_fast_index_creation.patch (+269/-8) |
To merge this branch: | bzr merge lp:~akopytov/percona-server/bug851674-5.1 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Approve | ||
Review via email: mp+75912@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote : | # |
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
LGTM with:
1) Please use "||" in (pk_processed | !has_pk)
2) (Optional) Please assert that the my_snprintf buffer does not overflow.
review:
Approve
Revision history for this message
Alexey Kopytov (akopytov) wrote : | # |
On 22.09.11 15:26, Laurynas Biveinis wrote:
> Review: Approve
>
> LGTM with:
> 1) Please use "||" in (pk_processed | !has_pk)
Fixed, thanks!
> 2) (Optional) Please assert that the my_snprintf buffer does not overflow.
>
It turns out it's not even possible to check for overflows in
my_snprintf(), because unlike regular snprintf(), my_vsnprintf() (which
does the actual work) never returns values equal or greater than 'n'. It
returns the length of the resulting string (without terminating '\0')
which is (n-1) at most.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'patches/innodb_expand_fast_index_creation.patch' |
2 | --- patches/innodb_expand_fast_index_creation.patch 2011-09-06 11:50:30 +0000 |
3 | +++ patches/innodb_expand_fast_index_creation.patch 2011-09-22 11:51:23 +0000 |
4 | @@ -54,7 +54,7 @@ |
5 | {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.", |
6 | &opt_ignore, &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, |
7 | 0, 0}, |
8 | -@@ -2246,6 +2256,128 @@ |
9 | +@@ -2246,6 +2256,182 @@ |
10 | } |
11 | |
12 | /* |
13 | @@ -83,6 +83,8 @@ |
14 | + SYNOPSIS |
15 | + skip_secondary_keys() |
16 | + create_str SHOW CREATE TABLE output |
17 | ++ has_pk TRUE, if the table has PRIMARY KEY |
18 | ++ (or UNIQUE key on non-nullable columns) |
19 | + |
20 | + |
21 | + DESCRIPTION |
22 | @@ -93,11 +95,12 @@ |
23 | + mysqldump sets foreign_key_checks to 0 anyway. |
24 | +*/ |
25 | + |
26 | -+static void skip_secondary_keys(char *create_str) |
27 | ++static void skip_secondary_keys(char *create_str, my_bool has_pk) |
28 | +{ |
29 | + char *ptr, *strend; |
30 | + char *last_comma = NULL; |
31 | + HASH ignored_columns; |
32 | ++ my_bool pk_processed= FALSE; |
33 | + |
34 | + if (hash_init(&ignored_columns, charset_info, 16, 0, 0, |
35 | + (hash_get_key) get_table_key, |
36 | @@ -110,6 +113,7 @@ |
37 | + while (*ptr) |
38 | + { |
39 | + char *tmp, *orig_ptr, c; |
40 | ++ my_bool is_unique; |
41 | + |
42 | + orig_ptr= ptr; |
43 | + /* Skip leading whitespace */ |
44 | @@ -124,7 +128,8 @@ |
45 | + |
46 | + /* Is it a secondary index definition? */ |
47 | + if (c == '\n' && |
48 | -+ (!strncmp(ptr, "UNIQUE KEY ", sizeof("UNIQUE KEY ") - 1) || |
49 | ++ (((is_unique= !strncmp(ptr, "UNIQUE KEY ", sizeof("UNIQUE KEY ")-1)) && |
50 | ++ (pk_processed || !has_pk)) || |
51 | + !strncmp(ptr, "KEY ", sizeof("KEY ") - 1) || |
52 | + !strncmp(ptr, "CONSTRAINT ", sizeof("CONSTRAINT ") - 1)) && |
53 | + !contains_ignored_column(&ignored_columns, ptr)) |
54 | @@ -152,6 +157,10 @@ |
55 | + { |
56 | + char *end; |
57 | + |
58 | ++ if ((has_pk && is_unique && !pk_processed) || |
59 | ++ !strncmp(ptr, "PRIMARY KEY ", sizeof("PRIMARY KEY ") - 1)) |
60 | ++ pk_processed= TRUE; |
61 | ++ |
62 | + if (strstr(ptr, "AUTO_INCREMENT") && *ptr == '`') |
63 | + { |
64 | + /* |
65 | @@ -180,20 +189,83 @@ |
66 | +} |
67 | + |
68 | +/* |
69 | ++ Check if the table has a primary key defined either explicitly or |
70 | ++ implicitly (i.e. a unique key on non-nullable columns). |
71 | ++ |
72 | ++ SYNOPSIS |
73 | ++ my_bool has_primary_key(const char *table_name) |
74 | ++ |
75 | ++ table_name quoted table name |
76 | ++ |
77 | ++ RETURNS TRUE if the table has a primary key |
78 | ++ |
79 | ++ DESCRIPTION |
80 | ++*/ |
81 | ++ |
82 | ++static my_bool has_primary_key(const char *table_name) |
83 | ++{ |
84 | ++ MYSQL_RES *res= NULL; |
85 | ++ MYSQL_ROW row; |
86 | ++ char query_buff[QUERY_LENGTH]; |
87 | ++ my_bool has_pk= TRUE; |
88 | ++ |
89 | ++ my_snprintf(query_buff, sizeof(query_buff), |
90 | ++ "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE " |
91 | ++ "TABLE_SCHEMA=DATABASE() AND TABLE_NAME='%s' AND " |
92 | ++ "COLUMN_KEY='PRI'", table_name); |
93 | ++ if (mysql_query(mysql, query_buff) || !(res= mysql_store_result(mysql)) || |
94 | ++ !(row= mysql_fetch_row(res))) |
95 | ++ { |
96 | ++ fprintf(stderr, "Warning: Couldn't determine if table %s has a " |
97 | ++ "primary key (%s). " |
98 | ++ "--innodb-optimize-keys may work inefficiently.\n", |
99 | ++ table_name, mysql_error(mysql)); |
100 | ++ goto cleanup; |
101 | ++ } |
102 | ++ |
103 | ++ has_pk= atoi(row[0]) > 0; |
104 | ++ |
105 | ++cleanup: |
106 | ++ if (res) |
107 | ++ mysql_free_result(res); |
108 | ++ |
109 | ++ return has_pk; |
110 | ++} |
111 | ++ |
112 | ++ |
113 | ++/* |
114 | get_table_structure -- retrievs database structure, prints out corresponding |
115 | CREATE statement and fills out insert_pat if the table is the type we will |
116 | be dumping. |
117 | -@@ -2486,6 +2618,9 @@ |
118 | +@@ -2282,6 +2468,7 @@ |
119 | + int len; |
120 | + MYSQL_RES *result; |
121 | + MYSQL_ROW row; |
122 | ++ my_bool has_pk; |
123 | + DBUG_ENTER("get_table_structure"); |
124 | + DBUG_PRINT("enter", ("db: %s table: %s", db, table)); |
125 | + |
126 | +@@ -2323,6 +2510,9 @@ |
127 | + result_table= quote_name(table, table_buff, 1); |
128 | + opt_quoted_table= quote_name(table, table_buff2, 0); |
129 | + |
130 | ++ if (opt_innodb_optimize_keys && !strcmp(table_type, "InnoDB")) |
131 | ++ has_pk= has_primary_key(table); |
132 | ++ |
133 | + if (opt_order_by_primary) |
134 | + order_by= primary_key_fields(result_table); |
135 | + |
136 | +@@ -2486,6 +2676,9 @@ |
137 | |
138 | row= mysql_fetch_row(result); |
139 | |
140 | + if (opt_innodb_optimize_keys && !strcmp(table_type, "InnoDB")) |
141 | -+ skip_secondary_keys(row[1]); |
142 | ++ skip_secondary_keys(row[1], has_pk); |
143 | + |
144 | fprintf(sql_file, (opt_compatible_mode & 3) ? "%s;\n" : |
145 | "/*!40101 SET @saved_cs_client = @@character_set_client */;\n" |
146 | "/*!40101 SET character_set_client = utf8 */;\n" |
147 | -@@ -3578,6 +3713,27 @@ |
148 | +@@ -3578,6 +3771,27 @@ |
149 | goto err; |
150 | } |
151 | |
152 | @@ -223,7 +295,7 @@ |
153 | { |
154 | --- /dev/null |
155 | +++ b/mysql-test/r/percona_mysqldump_innodb_optimize_keys.result |
156 | -@@ -0,0 +1,171 @@ |
157 | +@@ -0,0 +1,299 @@ |
158 | +# |
159 | +# Test the --innodb-optimize-keys option. |
160 | +# |
161 | @@ -395,6 +467,134 @@ |
162 | + |
163 | +###################################### |
164 | +DROP TABLE t1, t2; |
165 | ++CREATE TABLE t1 ( |
166 | ++a INT NOT NULL, |
167 | ++UNIQUE KEY (a)) ENGINE=InnoDB; |
168 | ++CREATE TABLE t2 ( |
169 | ++a INT NOT NULL, |
170 | ++b INT NOT NULL, |
171 | ++UNIQUE KEY (a,b)) ENGINE=InnoDB; |
172 | ++CREATE TABLE t3 ( |
173 | ++a INT, |
174 | ++b INT, |
175 | ++UNIQUE KEY (a,b)) ENGINE=InnoDB; |
176 | ++CREATE TABLE t4 ( |
177 | ++a INT NOT NULL, |
178 | ++b INT NOT NULL, |
179 | ++PRIMARY KEY (a,b), |
180 | ++UNIQUE KEY(b)) ENGINE=InnoDB; |
181 | ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE |
182 | ++TABLE_SCHEMA=DATABASE() AND |
183 | ++TABLE_NAME='t1' AND |
184 | ++COLUMN_KEY='PRI'; |
185 | ++COUNT(*) |
186 | ++1 |
187 | ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE |
188 | ++TABLE_SCHEMA=DATABASE() AND |
189 | ++TABLE_NAME='t2' AND |
190 | ++COLUMN_KEY='PRI'; |
191 | ++COUNT(*) |
192 | ++2 |
193 | ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE |
194 | ++TABLE_SCHEMA=DATABASE() AND |
195 | ++TABLE_NAME='t3' AND |
196 | ++COLUMN_KEY='PRI'; |
197 | ++COUNT(*) |
198 | ++0 |
199 | ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE |
200 | ++TABLE_SCHEMA=DATABASE() AND |
201 | ++TABLE_NAME='t4' AND |
202 | ++COLUMN_KEY='PRI'; |
203 | ++COUNT(*) |
204 | ++2 |
205 | ++INSERT INTO t1 VALUES (1), (2), (3); |
206 | ++INSERT INTO t2 VALUES (1,1), (2,2), (3,3); |
207 | ++INSERT INTO t3 SELECT * FROM t2; |
208 | ++INSERT INTO t4 SELECT * FROM t2; |
209 | ++###################################### |
210 | ++ |
211 | ++/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; |
212 | ++/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; |
213 | ++/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; |
214 | ++/*!40101 SET NAMES utf8 */; |
215 | ++/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; |
216 | ++/*!40103 SET TIME_ZONE='+00:00' */; |
217 | ++/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; |
218 | ++/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; |
219 | ++/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; |
220 | ++/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; |
221 | ++DROP TABLE IF EXISTS `t1`; |
222 | ++/*!40101 SET @saved_cs_client = @@character_set_client */; |
223 | ++/*!40101 SET character_set_client = utf8 */; |
224 | ++CREATE TABLE `t1` ( |
225 | ++ `a` int(11) NOT NULL, |
226 | ++ UNIQUE KEY `a` (`a`) |
227 | ++) ENGINE=InnoDB DEFAULT CHARSET=latin1; |
228 | ++/*!40101 SET character_set_client = @saved_cs_client */; |
229 | ++ |
230 | ++LOCK TABLES `t1` WRITE; |
231 | ++/*!40000 ALTER TABLE `t1` DISABLE KEYS */; |
232 | ++INSERT INTO `t1` VALUES (1),(2),(3); |
233 | ++/*!40000 ALTER TABLE `t1` ENABLE KEYS */; |
234 | ++UNLOCK TABLES; |
235 | ++DROP TABLE IF EXISTS `t2`; |
236 | ++/*!40101 SET @saved_cs_client = @@character_set_client */; |
237 | ++/*!40101 SET character_set_client = utf8 */; |
238 | ++CREATE TABLE `t2` ( |
239 | ++ `a` int(11) NOT NULL, |
240 | ++ `b` int(11) NOT NULL, |
241 | ++ UNIQUE KEY `a` (`a`,`b`) |
242 | ++) ENGINE=InnoDB DEFAULT CHARSET=latin1; |
243 | ++/*!40101 SET character_set_client = @saved_cs_client */; |
244 | ++ |
245 | ++LOCK TABLES `t2` WRITE; |
246 | ++/*!40000 ALTER TABLE `t2` DISABLE KEYS */; |
247 | ++INSERT INTO `t2` VALUES (1,1),(2,2),(3,3); |
248 | ++/*!40000 ALTER TABLE `t2` ENABLE KEYS */; |
249 | ++UNLOCK TABLES; |
250 | ++DROP TABLE IF EXISTS `t3`; |
251 | ++/*!40101 SET @saved_cs_client = @@character_set_client */; |
252 | ++/*!40101 SET character_set_client = utf8 */; |
253 | ++CREATE TABLE `t3` ( |
254 | ++ `a` int(11) DEFAULT NULL, |
255 | ++ `b` int(11) DEFAULT NULL |
256 | ++) ENGINE=InnoDB DEFAULT CHARSET=latin1; |
257 | ++/*!40101 SET character_set_client = @saved_cs_client */; |
258 | ++ |
259 | ++LOCK TABLES `t3` WRITE; |
260 | ++/*!40000 ALTER TABLE `t3` DISABLE KEYS */; |
261 | ++INSERT INTO `t3` VALUES (1,1),(2,2),(3,3); |
262 | ++ALTER TABLE `t3` ADD UNIQUE KEY `a` (`a`,`b`); |
263 | ++/*!40000 ALTER TABLE `t3` ENABLE KEYS */; |
264 | ++UNLOCK TABLES; |
265 | ++DROP TABLE IF EXISTS `t4`; |
266 | ++/*!40101 SET @saved_cs_client = @@character_set_client */; |
267 | ++/*!40101 SET character_set_client = utf8 */; |
268 | ++CREATE TABLE `t4` ( |
269 | ++ `a` int(11) NOT NULL, |
270 | ++ `b` int(11) NOT NULL, |
271 | ++ PRIMARY KEY (`a`,`b`) |
272 | ++) ENGINE=InnoDB DEFAULT CHARSET=latin1; |
273 | ++/*!40101 SET character_set_client = @saved_cs_client */; |
274 | ++ |
275 | ++LOCK TABLES `t4` WRITE; |
276 | ++/*!40000 ALTER TABLE `t4` DISABLE KEYS */; |
277 | ++INSERT INTO `t4` VALUES (1,1),(2,2),(3,3); |
278 | ++ALTER TABLE `t4` ADD UNIQUE KEY `b` (`b`); |
279 | ++/*!40000 ALTER TABLE `t4` ENABLE KEYS */; |
280 | ++UNLOCK TABLES; |
281 | ++/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; |
282 | ++ |
283 | ++/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; |
284 | ++/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; |
285 | ++/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; |
286 | ++/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; |
287 | ++/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; |
288 | ++/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; |
289 | ++/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; |
290 | ++ |
291 | ++###################################### |
292 | ++DROP TABLE t1, t2, t3, t4; |
293 | --- a/mysql-test/suite/innodb_plugin/r/innodb.result |
294 | +++ b/mysql-test/suite/innodb_plugin/r/innodb.result |
295 | @@ -1679,7 +1679,7 @@ |
296 | @@ -437,7 +637,7 @@ |
297 | # Save the original values of some variables in order to be able to |
298 | --- /dev/null |
299 | +++ b/mysql-test/t/percona_mysqldump_innodb_optimize_keys.test |
300 | -@@ -0,0 +1,94 @@ |
301 | +@@ -0,0 +1,155 @@ |
302 | +# Embedded server doesn't support external clients |
303 | +--source include/not_embedded.inc |
304 | + |
305 | @@ -530,6 +730,67 @@ |
306 | + |
307 | +DROP TABLE t1, t2; |
308 | + |
309 | ++######################################################################## |
310 | ++# Bug #851674: --innodb-optimize-keys does not work correctly with table |
311 | ++# without PRIMARY KEY |
312 | ++######################################################################## |
313 | ++ |
314 | ++CREATE TABLE t1 ( |
315 | ++ a INT NOT NULL, |
316 | ++ UNIQUE KEY (a)) ENGINE=InnoDB; |
317 | ++ |
318 | ++CREATE TABLE t2 ( |
319 | ++ a INT NOT NULL, |
320 | ++ b INT NOT NULL, |
321 | ++ UNIQUE KEY (a,b)) ENGINE=InnoDB; |
322 | ++ |
323 | ++CREATE TABLE t3 ( |
324 | ++ a INT, |
325 | ++ b INT, |
326 | ++ UNIQUE KEY (a,b)) ENGINE=InnoDB; |
327 | ++ |
328 | ++CREATE TABLE t4 ( |
329 | ++ a INT NOT NULL, |
330 | ++ b INT NOT NULL, |
331 | ++ PRIMARY KEY (a,b), |
332 | ++ UNIQUE KEY(b)) ENGINE=InnoDB; |
333 | ++ |
334 | ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE |
335 | ++ TABLE_SCHEMA=DATABASE() AND |
336 | ++ TABLE_NAME='t1' AND |
337 | ++ COLUMN_KEY='PRI'; |
338 | ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE |
339 | ++ TABLE_SCHEMA=DATABASE() AND |
340 | ++ TABLE_NAME='t2' AND |
341 | ++ COLUMN_KEY='PRI'; |
342 | ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE |
343 | ++ TABLE_SCHEMA=DATABASE() AND |
344 | ++ TABLE_NAME='t3' AND |
345 | ++ COLUMN_KEY='PRI'; |
346 | ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE |
347 | ++ TABLE_SCHEMA=DATABASE() AND |
348 | ++ TABLE_NAME='t4' AND |
349 | ++ COLUMN_KEY='PRI'; |
350 | ++ |
351 | ++INSERT INTO t1 VALUES (1), (2), (3); |
352 | ++INSERT INTO t2 VALUES (1,1), (2,2), (3,3); |
353 | ++INSERT INTO t3 SELECT * FROM t2; |
354 | ++INSERT INTO t4 SELECT * FROM t2; |
355 | ++ |
356 | ++--exec $MYSQL_DUMP --skip-comments --innodb-optimize-keys test t1 t2 t3 t4 >$file |
357 | ++ |
358 | ++--echo ###################################### |
359 | ++--cat_file $file |
360 | ++--echo ###################################### |
361 | ++ |
362 | ++# Check that the resulting dump can be imported back |
363 | ++ |
364 | ++--exec $MYSQL test < $file |
365 | ++ |
366 | ++--remove_file $file |
367 | ++ |
368 | ++DROP TABLE t1, t2, t3, t4; |
369 | ++ |
370 | +# Wait till we reached the initial number of concurrent sessions |
371 | +--source include/wait_until_count_sessions.inc |
372 | --- a/sql/sql_lex.cc |
http:// jenkins. percona. com/view/ Percona% 20Server% 205.1/job/ percona- server- 5.1-param/ 140/ is unavailable because build #139 has been stuck for 3 days.