Merge lp:~akopytov/percona-server/bug832528 into lp:percona-server/5.1
- bug832528
- Merge into 5.1
Proposed by
Alexey Kopytov
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 279 | ||||
Proposed branch: | lp:~akopytov/percona-server/bug832528 | ||||
Merge into: | lp:percona-server/5.1 | ||||
Diff against target: |
422 lines (+410/-0) 2 files modified
patches/bug53761.patch (+409/-0) patches/series (+1/-0) |
||||
To merge this branch: | bzr merge lp:~akopytov/percona-server/bug832528 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Yasufumi Kinoshita (community) | Approve | ||
Review via email: mp+72843@code.launchpad.net |
Commit message
Description of the change
Backport of the fix for MySQL bug #53761 to 5.1. There is no test case, because:
1. The bug can only be triggered on a fairly large dataset (verified the fix manually on customer's data dump).
2. The original fix did not contain a test case.
To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote : | # |
Revision history for this message
Yasufumi Kinoshita (yasufumi-kinoshita) wrote : | # |
I think no conflict with other XtraDB patches.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'patches/bug53761.patch' | |||
2 | --- patches/bug53761.patch 1970-01-01 00:00:00 +0000 | |||
3 | +++ patches/bug53761.patch 2011-08-25 09:13:51 +0000 | |||
4 | @@ -0,0 +1,409 @@ | |||
5 | 1 | # name : bug53761.patch | ||
6 | 2 | # maintainer : Alexey | ||
7 | 3 | # | ||
8 | 4 | # Backport of the fix for MySQL bug #53761 to 5.1 | ||
9 | 5 | # | ||
10 | 6 | --- a/storage/innodb_plugin/btr/btr0cur.c | ||
11 | 7 | +++ b/storage/innodb_plugin/btr/btr0cur.c | ||
12 | 8 | @@ -3117,6 +3117,7 @@ | ||
13 | 9 | { | ||
14 | 10 | btr_path_t* slot; | ||
15 | 11 | rec_t* rec; | ||
16 | 12 | + page_t* page; | ||
17 | 13 | |||
18 | 14 | ut_a(cursor->path_arr); | ||
19 | 15 | |||
20 | 16 | @@ -3139,8 +3140,155 @@ | ||
21 | 17 | |||
22 | 18 | slot = cursor->path_arr + (root_height - height); | ||
23 | 19 | |||
24 | 20 | + page = page_align(rec); | ||
25 | 21 | + | ||
26 | 22 | slot->nth_rec = page_rec_get_n_recs_before(rec); | ||
27 | 23 | - slot->n_recs = page_get_n_recs(page_align(rec)); | ||
28 | 24 | + slot->n_recs = page_get_n_recs(page); | ||
29 | 25 | + slot->page_no = page_get_page_no(page); | ||
30 | 26 | + slot->page_level = btr_page_get_level_low(page); | ||
31 | 27 | +} | ||
32 | 28 | + | ||
33 | 29 | +/*******************************************************************//** | ||
34 | 30 | +Estimate the number of rows between slot1 and slot2 for any level on a | ||
35 | 31 | +B-tree. This function starts from slot1->page and reads a few pages to | ||
36 | 32 | +the right, counting their records. If we reach slot2->page quickly then | ||
37 | 33 | +we know exactly how many records there are between slot1 and slot2 and | ||
38 | 34 | +we set is_n_rows_exact to TRUE. If we cannot reach slot2->page quickly | ||
39 | 35 | +then we calculate the average number of records in the pages scanned | ||
40 | 36 | +so far and assume that all pages that we did not scan up to slot2->page | ||
41 | 37 | +contain the same number of records, then we multiply that average to | ||
42 | 38 | +the number of pages between slot1->page and slot2->page (which is | ||
43 | 39 | +n_rows_on_prev_level). In this case we set is_n_rows_exact to FALSE. | ||
44 | 40 | +@return number of rows (exact or estimated) */ | ||
45 | 41 | +static | ||
46 | 42 | +ib_int64_t | ||
47 | 43 | +btr_estimate_n_rows_in_range_on_level( | ||
48 | 44 | +/*==================================*/ | ||
49 | 45 | + dict_index_t* index, /*!< in: index */ | ||
50 | 46 | + btr_path_t* slot1, /*!< in: left border */ | ||
51 | 47 | + btr_path_t* slot2, /*!< in: right border */ | ||
52 | 48 | + ib_int64_t n_rows_on_prev_level, /*!< in: number of rows | ||
53 | 49 | + on the previous level for the | ||
54 | 50 | + same descend paths; used to | ||
55 | 51 | + determine the numbe of pages | ||
56 | 52 | + on this level */ | ||
57 | 53 | + ibool* is_n_rows_exact) /*!< out: TRUE if the returned | ||
58 | 54 | + value is exact i.e. not an | ||
59 | 55 | + estimation */ | ||
60 | 56 | +{ | ||
61 | 57 | + ulint space; | ||
62 | 58 | + ib_int64_t n_rows; | ||
63 | 59 | + ulint n_pages_read; | ||
64 | 60 | + ulint page_no; | ||
65 | 61 | + ulint zip_size; | ||
66 | 62 | + ulint level; | ||
67 | 63 | + | ||
68 | 64 | + space = dict_index_get_space(index); | ||
69 | 65 | + | ||
70 | 66 | + n_rows = 0; | ||
71 | 67 | + n_pages_read = 0; | ||
72 | 68 | + | ||
73 | 69 | + /* Assume by default that we will scan all pages between | ||
74 | 70 | + slot1->page_no and slot2->page_no */ | ||
75 | 71 | + *is_n_rows_exact = TRUE; | ||
76 | 72 | + | ||
77 | 73 | + /* add records from slot1->page_no which are to the right of | ||
78 | 74 | + the record which serves as a left border of the range, if any */ | ||
79 | 75 | + if (slot1->nth_rec < slot1->n_recs) { | ||
80 | 76 | + n_rows += slot1->n_recs - slot1->nth_rec; | ||
81 | 77 | + } | ||
82 | 78 | + | ||
83 | 79 | + /* add records from slot2->page_no which are to the left of | ||
84 | 80 | + the record which servers as a right border of the range, if any */ | ||
85 | 81 | + if (slot2->nth_rec > 1) { | ||
86 | 82 | + n_rows += slot2->nth_rec - 1; | ||
87 | 83 | + } | ||
88 | 84 | + | ||
89 | 85 | + /* count the records in the pages between slot1->page_no and | ||
90 | 86 | + slot2->page_no (non inclusive), if any */ | ||
91 | 87 | + | ||
92 | 88 | + zip_size = fil_space_get_zip_size(space); | ||
93 | 89 | + | ||
94 | 90 | + /* Do not read more than this number of pages in order not to hurt | ||
95 | 91 | + performance with this code which is just an estimation. If we read | ||
96 | 92 | + this many pages before reaching slot2->page_no then we estimate the | ||
97 | 93 | + average from the pages scanned so far */ | ||
98 | 94 | + #define N_PAGES_READ_LIMIT 10 | ||
99 | 95 | + | ||
100 | 96 | + page_no = slot1->page_no; | ||
101 | 97 | + level = slot1->page_level; | ||
102 | 98 | + | ||
103 | 99 | + do { | ||
104 | 100 | + mtr_t mtr; | ||
105 | 101 | + page_t* page; | ||
106 | 102 | + buf_block_t* block; | ||
107 | 103 | + | ||
108 | 104 | + mtr_start(&mtr); | ||
109 | 105 | + | ||
110 | 106 | + /* fetch the page */ | ||
111 | 107 | + block = buf_page_get(space, zip_size, page_no, RW_S_LATCH, | ||
112 | 108 | + &mtr); | ||
113 | 109 | + | ||
114 | 110 | + page = buf_block_get_frame(block); | ||
115 | 111 | + | ||
116 | 112 | + /* It is possible that the tree has been reorganized in the | ||
117 | 113 | + meantime and this is a different page. If this happens the | ||
118 | 114 | + calculated estimate will be bogus, which is not fatal as | ||
119 | 115 | + this is only an estimate. We are sure that a page with | ||
120 | 116 | + page_no exists because InnoDB never frees pages, only | ||
121 | 117 | + reuses them. */ | ||
122 | 118 | + if (fil_page_get_type(page) != FIL_PAGE_INDEX | ||
123 | 119 | + || ut_dulint_cmp(btr_page_get_index_id(page), index->id) | ||
124 | 120 | + || btr_page_get_level_low(page) != level) { | ||
125 | 121 | + | ||
126 | 122 | + /* The page got reused for something else */ | ||
127 | 123 | + goto inexact; | ||
128 | 124 | + } | ||
129 | 125 | + | ||
130 | 126 | + n_pages_read++; | ||
131 | 127 | + | ||
132 | 128 | + if (page_no != slot1->page_no) { | ||
133 | 129 | + /* Do not count the records on slot1->page_no, | ||
134 | 130 | + we already counted them before this loop. */ | ||
135 | 131 | + n_rows += page_get_n_recs(page); | ||
136 | 132 | + } | ||
137 | 133 | + | ||
138 | 134 | + page_no = btr_page_get_next(page, &mtr); | ||
139 | 135 | + | ||
140 | 136 | + mtr_commit(&mtr); | ||
141 | 137 | + | ||
142 | 138 | + if (n_pages_read == N_PAGES_READ_LIMIT | ||
143 | 139 | + || page_no == FIL_NULL) { | ||
144 | 140 | + /* Either we read too many pages or | ||
145 | 141 | + we reached the end of the level without passing | ||
146 | 142 | + through slot2->page_no, the tree must have changed | ||
147 | 143 | + in the meantime */ | ||
148 | 144 | + goto inexact; | ||
149 | 145 | + } | ||
150 | 146 | + | ||
151 | 147 | + } while (page_no != slot2->page_no); | ||
152 | 148 | + | ||
153 | 149 | + return(n_rows); | ||
154 | 150 | + | ||
155 | 151 | +inexact: | ||
156 | 152 | + | ||
157 | 153 | + *is_n_rows_exact = FALSE; | ||
158 | 154 | + | ||
159 | 155 | + /* We did interrupt before reaching slot2->page */ | ||
160 | 156 | + | ||
161 | 157 | + if (n_pages_read > 0) { | ||
162 | 158 | + /* The number of pages on this level is | ||
163 | 159 | + n_rows_on_prev_level, multiply it by the | ||
164 | 160 | + average number of recs per page so far */ | ||
165 | 161 | + n_rows = n_rows_on_prev_level | ||
166 | 162 | + * n_rows / n_pages_read; | ||
167 | 163 | + } else { | ||
168 | 164 | + /* The tree changed before we could even | ||
169 | 165 | + start with slot1->page_no */ | ||
170 | 166 | + n_rows = 10; | ||
171 | 167 | + } | ||
172 | 168 | + | ||
173 | 169 | + return(n_rows); | ||
174 | 170 | } | ||
175 | 171 | |||
176 | 172 | /*******************************************************************//** | ||
177 | 173 | @@ -3165,6 +3313,7 @@ | ||
178 | 174 | ibool diverged_lot; | ||
179 | 175 | ulint divergence_level; | ||
180 | 176 | ib_int64_t n_rows; | ||
181 | 177 | + ibool is_n_rows_exact; | ||
182 | 178 | ulint i; | ||
183 | 179 | mtr_t mtr; | ||
184 | 180 | |||
185 | 181 | @@ -3207,6 +3356,7 @@ | ||
186 | 182 | /* We have the path information for the range in path1 and path2 */ | ||
187 | 183 | |||
188 | 184 | n_rows = 1; | ||
189 | 185 | + is_n_rows_exact = TRUE; | ||
190 | 186 | diverged = FALSE; /* This becomes true when the path is not | ||
191 | 187 | the same any more */ | ||
192 | 188 | diverged_lot = FALSE; /* This becomes true when the paths are | ||
193 | 189 | @@ -3222,7 +3372,7 @@ | ||
194 | 190 | if (slot1->nth_rec == ULINT_UNDEFINED | ||
195 | 191 | || slot2->nth_rec == ULINT_UNDEFINED) { | ||
196 | 192 | |||
197 | 193 | - if (i > divergence_level + 1) { | ||
198 | 194 | + if (i > divergence_level + 1 && !is_n_rows_exact) { | ||
199 | 195 | /* In trees whose height is > 1 our algorithm | ||
200 | 196 | tends to underestimate: multiply the estimate | ||
201 | 197 | by 2: */ | ||
202 | 198 | @@ -3234,7 +3384,9 @@ | ||
203 | 199 | to over 1 / 2 of the estimated rows in the whole | ||
204 | 200 | table */ | ||
205 | 201 | |||
206 | 202 | - if (n_rows > index->table->stat_n_rows / 2) { | ||
207 | 203 | + if (n_rows > index->table->stat_n_rows / 2 | ||
208 | 204 | + && !is_n_rows_exact) { | ||
209 | 205 | + | ||
210 | 206 | n_rows = index->table->stat_n_rows / 2; | ||
211 | 207 | |||
212 | 208 | /* If there are just 0 or 1 rows in the table, | ||
213 | 209 | @@ -3260,10 +3412,15 @@ | ||
214 | 210 | divergence_level = i; | ||
215 | 211 | } | ||
216 | 212 | } else { | ||
217 | 213 | - /* Maybe the tree has changed between | ||
218 | 214 | - searches */ | ||
219 | 215 | - | ||
220 | 216 | - return(10); | ||
221 | 217 | + /* It is possible that | ||
222 | 218 | + slot1->nth_rec >= slot2->nth_rec | ||
223 | 219 | + if, for example, we have a single page | ||
224 | 220 | + tree which contains (inf, 5, 6, supr) | ||
225 | 221 | + and we select where x > 20 and x < 30; | ||
226 | 222 | + in this case slot1->nth_rec will point | ||
227 | 223 | + to the supr record and slot2->nth_rec | ||
228 | 224 | + will point to 6 */ | ||
229 | 225 | + n_rows = 0; | ||
230 | 226 | } | ||
231 | 227 | |||
232 | 228 | } else if (diverged && !diverged_lot) { | ||
233 | 229 | @@ -3287,8 +3444,9 @@ | ||
234 | 230 | } | ||
235 | 231 | } else if (diverged_lot) { | ||
236 | 232 | |||
237 | 233 | - n_rows = (n_rows * (slot1->n_recs + slot2->n_recs)) | ||
238 | 234 | - / 2; | ||
239 | 235 | + n_rows = btr_estimate_n_rows_in_range_on_level( | ||
240 | 236 | + index, slot1, slot2, n_rows, | ||
241 | 237 | + &is_n_rows_exact); | ||
242 | 238 | } | ||
243 | 239 | } | ||
244 | 240 | } | ||
245 | 241 | --- a/storage/innodb_plugin/include/btr0cur.h | ||
246 | 242 | +++ b/storage/innodb_plugin/include/btr0cur.h | ||
247 | 243 | @@ -652,6 +652,11 @@ | ||
248 | 244 | order); value ULINT_UNDEFINED | ||
249 | 245 | denotes array end */ | ||
250 | 246 | ulint n_recs; /*!< number of records on the page */ | ||
251 | 247 | + ulint page_no; /*!< no of the page containing the record */ | ||
252 | 248 | + ulint page_level; /*!< level of the page, if later we fetch | ||
253 | 249 | + the page under page_no and it is no different | ||
254 | 250 | + level then we know that the tree has been | ||
255 | 251 | + reorganized */ | ||
256 | 252 | }; | ||
257 | 253 | |||
258 | 254 | #define BTR_PATH_ARRAY_N_SLOTS 250 /*!< size of path array (in slots) */ | ||
259 | 255 | --- a/mysql-test/suite/innodb_plugin/r/innodb_gis.result | ||
260 | 256 | +++ b/mysql-test/suite/innodb_plugin/r/innodb_gis.result | ||
261 | 257 | @@ -572,7 +572,7 @@ | ||
262 | 258 | EXPLAIN | ||
263 | 259 | SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); | ||
264 | 260 | id select_type table type possible_keys key key_len ref rows Extra | ||
265 | 261 | -1 SIMPLE t2 ref p p 28 const 1 Using where | ||
266 | 262 | +1 SIMPLE t2 ref p p 28 const 2 Using where | ||
267 | 263 | SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); | ||
268 | 264 | COUNT(*) | ||
269 | 265 | 2 | ||
270 | 266 | --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result | ||
271 | 267 | +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result | ||
272 | 268 | @@ -889,13 +889,13 @@ | ||
273 | 269 | id 1 | ||
274 | 270 | select_type SIMPLE | ||
275 | 271 | table t1 | ||
276 | 272 | -type range | ||
277 | 273 | +type index | ||
278 | 274 | possible_keys bkey | ||
279 | 275 | -key bkey | ||
280 | 276 | -key_len 5 | ||
281 | 277 | +key PRIMARY | ||
282 | 278 | +key_len 4 | ||
283 | 279 | ref NULL | ||
284 | 280 | -rows 16 | ||
285 | 281 | -Extra Using where; Using index; Using filesort | ||
286 | 282 | +rows 32 | ||
287 | 283 | +Extra Using where | ||
288 | 284 | SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; | ||
289 | 285 | a b | ||
290 | 286 | 1 2 | ||
291 | 287 | @@ -934,12 +934,12 @@ | ||
292 | 288 | id 1 | ||
293 | 289 | select_type SIMPLE | ||
294 | 290 | table t1 | ||
295 | 291 | -type range | ||
296 | 292 | +type index | ||
297 | 293 | possible_keys bkey | ||
298 | 294 | key bkey | ||
299 | 295 | key_len 5 | ||
300 | 296 | ref NULL | ||
301 | 297 | -rows 16 | ||
302 | 298 | +rows 32 | ||
303 | 299 | Extra Using where; Using index | ||
304 | 300 | SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a; | ||
305 | 301 | a b | ||
306 | 302 | @@ -989,7 +989,7 @@ | ||
307 | 303 | key bkey | ||
308 | 304 | key_len 5 | ||
309 | 305 | ref const | ||
310 | 306 | -rows 8 | ||
311 | 307 | +rows 16 | ||
312 | 308 | Extra Using where; Using index; Using filesort | ||
313 | 309 | SELECT * FROM t2 WHERE b=1 ORDER BY a; | ||
314 | 310 | a b c | ||
315 | 311 | @@ -1018,7 +1018,7 @@ | ||
316 | 312 | key bkey | ||
317 | 313 | key_len 10 | ||
318 | 314 | ref const,const | ||
319 | 315 | -rows 8 | ||
320 | 316 | +rows 16 | ||
321 | 317 | Extra Using where; Using index | ||
322 | 318 | SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a; | ||
323 | 319 | a b c | ||
324 | 320 | @@ -1047,7 +1047,7 @@ | ||
325 | 321 | key bkey | ||
326 | 322 | key_len 10 | ||
327 | 323 | ref const,const | ||
328 | 324 | -rows 8 | ||
329 | 325 | +rows 16 | ||
330 | 326 | Extra Using where; Using index | ||
331 | 327 | SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY b,c,a; | ||
332 | 328 | a b c | ||
333 | 329 | @@ -1076,7 +1076,7 @@ | ||
334 | 330 | key bkey | ||
335 | 331 | key_len 10 | ||
336 | 332 | ref const,const | ||
337 | 333 | -rows 8 | ||
338 | 334 | +rows 16 | ||
339 | 335 | Extra Using where; Using index | ||
340 | 336 | SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY c,a; | ||
341 | 337 | a b c | ||
342 | 338 | @@ -1211,7 +1211,7 @@ | ||
343 | 339 | key b | ||
344 | 340 | key_len 5 | ||
345 | 341 | ref const | ||
346 | 342 | -rows 1 | ||
347 | 343 | +rows 2 | ||
348 | 344 | Extra Using where; Using index | ||
349 | 345 | SELECT * FROM t1 WHERE b=2 ORDER BY a ASC; | ||
350 | 346 | a b | ||
351 | 347 | @@ -1226,7 +1226,7 @@ | ||
352 | 348 | key b | ||
353 | 349 | key_len 5 | ||
354 | 350 | ref const | ||
355 | 351 | -rows 1 | ||
356 | 352 | +rows 2 | ||
357 | 353 | Extra Using where; Using index | ||
358 | 354 | SELECT * FROM t1 WHERE b=2 ORDER BY a DESC; | ||
359 | 355 | a b | ||
360 | 356 | @@ -1370,7 +1370,7 @@ | ||
361 | 357 | INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1; | ||
362 | 358 | EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; | ||
363 | 359 | id select_type table type possible_keys key key_len ref rows Extra | ||
364 | 360 | -1 SIMPLE t1 index t1_b PRIMARY 4 NULL 8 Using where | ||
365 | 361 | +1 SIMPLE t1 range t1_b t1_b 5 NULL 8 Using where | ||
366 | 362 | SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; | ||
367 | 363 | a b c | ||
368 | 364 | 8 1 1 | ||
369 | 365 | @@ -1729,7 +1729,7 @@ | ||
370 | 366 | FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; | ||
371 | 367 | id select_type table type possible_keys key key_len ref rows Extra | ||
372 | 368 | 1 PRIMARY <derived2> system NULL NULL NULL NULL 1 | ||
373 | 369 | -2 DERIVED t1 index c3,c2 c2 10 NULL 5 | ||
374 | 370 | +2 DERIVED t1 ALL c3,c2 c3 5 5 Using filesort | ||
375 | 371 | DROP TABLE t1; | ||
376 | 372 | CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) | ||
377 | 373 | ENGINE=InnoDB; | ||
378 | 374 | @@ -1743,7 +1743,7 @@ | ||
379 | 375 | FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; | ||
380 | 376 | id select_type table type possible_keys key key_len ref rows Extra | ||
381 | 377 | 1 PRIMARY <derived2> system NULL NULL NULL NULL 1 | ||
382 | 378 | -2 DERIVED t1 index c3,c2 c2 18 NULL 5 | ||
383 | 379 | +2 DERIVED t1 ALL c3,c2 c3 9 5 Using filesort | ||
384 | 380 | DROP TABLE t1; | ||
385 | 381 | CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), | ||
386 | 382 | KEY (c3), KEY (c2, c3)) | ||
387 | 383 | @@ -1758,7 +1758,7 @@ | ||
388 | 384 | FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; | ||
389 | 385 | id select_type table type possible_keys key key_len ref rows Extra | ||
390 | 386 | 1 PRIMARY <derived2> system NULL NULL NULL NULL 1 | ||
391 | 387 | -2 DERIVED t1 index c3,c2 c2 14 NULL 5 | ||
392 | 388 | +2 DERIVED t1 ALL c3,c2 c3 7 5 Using filesort | ||
393 | 389 | DROP TABLE t1; | ||
394 | 390 | End of 5.1 tests | ||
395 | 391 | drop table if exists t1, t2, t3; | ||
396 | 392 | @@ -1834,7 +1834,7 @@ | ||
397 | 393 | key b | ||
398 | 394 | key_len 5 | ||
399 | 395 | ref NULL | ||
400 | 396 | -rows 3 | ||
401 | 397 | +rows 5 | ||
402 | 398 | Extra Using where; Using index | ||
403 | 399 | EXPLAIN SELECT c FROM bar WHERE c>2;; | ||
404 | 400 | id 1 | ||
405 | 401 | @@ -2430,7 +2430,7 @@ | ||
406 | 402 | WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; | ||
407 | 403 | id select_type table type possible_keys key key_len ref rows Extra | ||
408 | 404 | 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away | ||
409 | 405 | -2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 3537 Using sort_union(idx,PRIMARY); Using where | ||
410 | 406 | +2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 1536 Using sort_union(idx,PRIMARY); Using where | ||
411 | 407 | SELECT COUNT(*) FROM | ||
412 | 408 | (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY) | ||
413 | 409 | WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; | ||
414 | 0 | 410 | ||
415 | === modified file 'patches/series' | |||
416 | --- patches/series 2011-08-01 21:45:17 +0000 | |||
417 | +++ patches/series 2011-08-25 09:13:51 +0000 | |||
418 | @@ -60,3 +60,4 @@ | |||
419 | 60 | bug813587.patch | 60 | bug813587.patch |
420 | 61 | innodb_bug47167_test_fix.patch | 61 | innodb_bug47167_test_fix.patch |
421 | 62 | disable_query_cache_28249_test_sporadic_failure.patch | 62 | disable_query_cache_28249_test_sporadic_failure.patch |
422 | 63 | bug53761.patch |
http:// jenkins. percona. com/view/ Percona% 20Server% 205.1/job/ percona- server- 5.1-param/ 126/