Merge lp:~akopytov/percona-server/bug851674-5.1 into lp:percona-server/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
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+75912@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote :

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.

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

Subscribers

People subscribed via source and target branches