Merge lp:~stewart/drizzle/7.1-innodb-1.1.5 into lp:drizzle/7.1
- 7.1-innodb-1.1.5
- Merge into 7.1
Status: | Merged |
---|---|
Merged at revision: | 2550 |
Proposed branch: | lp:~stewart/drizzle/7.1-innodb-1.1.5 |
Merge into: | lp:drizzle/7.1 |
Diff against target: |
3520 lines (+1778/-498) 46 files modified
plugin/innobase/btr/btr0btr.cc (+1/-1) plugin/innobase/btr/btr0cur.cc (+28/-132) plugin/innobase/buf/buf0buf.cc (+272/-83) plugin/innobase/buf/buf0flu.cc (+30/-2) plugin/innobase/buf/buf0lru.cc (+12/-4) plugin/innobase/dict/dict0dict.cc (+45/-30) plugin/innobase/dict/dict0load.cc (+17/-3) plugin/innobase/dict/dict0mem.cc (+56/-0) plugin/innobase/fil/fil0fil.cc (+32/-4) plugin/innobase/fsp/fsp0fsp.cc (+1/-1) plugin/innobase/handler/ha_innodb.cc (+1/-1) plugin/innobase/ibuf/ibuf0ibuf.cc (+96/-17) plugin/innobase/include/btr0cur.h (+14/-28) plugin/innobase/include/buf0buf.h (+70/-0) plugin/innobase/include/data0data.h (+8/-3) plugin/innobase/include/data0data.ic (+18/-8) plugin/innobase/include/dict0mem.h (+24/-0) plugin/innobase/include/ibuf0ibuf.h (+38/-9) plugin/innobase/include/mem0mem.ic (+6/-6) plugin/innobase/include/mtr0mtr.ic (+1/-1) plugin/innobase/include/os0file.h (+2/-0) plugin/innobase/include/row0upd.h (+11/-3) plugin/innobase/include/srv0srv.h (+10/-2) plugin/innobase/include/sync0rw.h (+1/-0) plugin/innobase/include/univ.i (+25/-10) plugin/innobase/include/ut0bh.h (+152/-0) plugin/innobase/include/ut0bh.ic (+125/-0) plugin/innobase/include/ut0ut.h (+13/-13) plugin/innobase/include/ut0vec.h (+19/-0) plugin/innobase/include/ut0vec.ic (+29/-0) plugin/innobase/lock/lock0lock.cc (+75/-4) plugin/innobase/log/log0recv.cc (+1/-1) plugin/innobase/os/os0file.cc (+34/-9) plugin/innobase/plugin.am (+3/-0) plugin/innobase/row/row0ins.cc (+1/-1) plugin/innobase/row/row0merge.cc (+2/-2) plugin/innobase/row/row0mysql.cc (+2/-2) plugin/innobase/row/row0purge.cc (+1/-1) plugin/innobase/row/row0umod.cc (+6/-7) plugin/innobase/row/row0upd.cc (+254/-91) plugin/innobase/srv/srv0srv.cc (+39/-5) plugin/innobase/srv/srv0start.cc (+19/-1) plugin/innobase/sync/sync0arr.cc (+18/-10) plugin/innobase/trx/trx0i_s.cc (+1/-2) plugin/innobase/ut/ut0bh.cc (+164/-0) plugin/innobase/ut/ut0dbg.cc (+1/-1) |
To merge this branch: | bzr merge lp:~stewart/drizzle/7.1-innodb-1.1.5 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Drizzle Trunk | Pending | ||
Review via email: mp+106800@code.launchpad.net |
Commit message
Description of the change
Update InnoDB to 1.1.5 from MySQL 5.5.9
No Jenkins run as it's giving me 404 instead of, well, Jenkins.
Stewart Smith (stewart) wrote : | # |
Vijay Samuel (vjsamuel) wrote : | # |
We should probably add those files to POTFILES.in
Cheers,
-Vijay
On Tue, May 22, 2012 at 7:04 PM, Stewart Smith <email address hidden>wrote:
> https:/
> --
> https:/
> Your team Drizzle Trunk is requested to review the proposed merge of
> lp:~stewart/drizzle/7.1-innodb-1.1.5 into lp:drizzle/7.1.
>
Brian Aker (brianaker) wrote : | # |
Stewart Smith (stewart) wrote : | # |
On Tue, 22 May 2012 22:10:42 -0000, Brian Aker <email address hidden> wrote:
> https:/
>
> Build failures.
Should be fixed now. Funny that it didn't show up on param build.
Do we have the blinken lights disabled for our jenkins now? Personally I
find them kind of useful to check status....
--
Stewart Smith
Preview Diff
1 | === modified file 'plugin/innobase/btr/btr0btr.cc' |
2 | --- plugin/innobase/btr/btr0btr.cc 2011-03-20 06:58:32 +0000 |
3 | +++ plugin/innobase/btr/btr0btr.cc 2012-05-22 12:41:18 +0000 |
4 | @@ -663,7 +663,7 @@ |
5 | " to fix the\n" |
6 | "InnoDB: corruption. If the crash happens at " |
7 | "the database startup, see\n" |
8 | - "InnoDB: " REFMAN "forcing-recovery.html about\n" |
9 | + "InnoDB: " REFMAN "forcing-innodb-recovery.html about\n" |
10 | "InnoDB: forcing recovery. " |
11 | "Then dump + drop + reimport.\n", stderr); |
12 | |
13 | |
14 | === modified file 'plugin/innobase/btr/btr0cur.cc' |
15 | --- plugin/innobase/btr/btr0cur.cc 2010-12-27 18:39:11 +0000 |
16 | +++ plugin/innobase/btr/btr0cur.cc 2012-05-22 12:41:18 +0000 |
17 | @@ -1874,7 +1874,8 @@ |
18 | NOT call it if index is secondary */ |
19 | |
20 | if (!dict_index_is_clust(index) |
21 | - || row_upd_changes_ord_field_binary(NULL, index, update)) { |
22 | + || row_upd_changes_ord_field_binary(NULL, NULL, |
23 | + index, update)) { |
24 | |
25 | /* Remove possible hash index pointer to this record */ |
26 | btr_search_update_hash_on_delete(cursor); |
27 | @@ -2626,27 +2627,24 @@ |
28 | btr_cur_del_mark_set_clust_rec( |
29 | /*===========================*/ |
30 | ulint flags, /*!< in: undo logging and locking flags */ |
31 | - btr_cur_t* cursor, /*!< in: cursor */ |
32 | + buf_block_t* block, /*!< in/out: buffer block of the record */ |
33 | + rec_t* rec, /*!< in/out: record */ |
34 | + dict_index_t* index, /*!< in: clustered index of the record */ |
35 | + const ulint* offsets,/*!< in: rec_get_offsets(rec) */ |
36 | ibool val, /*!< in: value to set */ |
37 | que_thr_t* thr, /*!< in: query thread */ |
38 | mtr_t* mtr) /*!< in: mtr */ |
39 | { |
40 | - dict_index_t* index; |
41 | - buf_block_t* block; |
42 | roll_ptr_t roll_ptr; |
43 | ulint err; |
44 | - rec_t* rec; |
45 | page_zip_des_t* page_zip; |
46 | trx_t* trx; |
47 | - mem_heap_t* heap = NULL; |
48 | - ulint offsets_[REC_OFFS_NORMAL_SIZE]; |
49 | - ulint* offsets = offsets_; |
50 | - rec_offs_init(offsets_); |
51 | |
52 | - rec = btr_cur_get_rec(cursor); |
53 | - index = cursor->index; |
54 | + ut_ad(dict_index_is_clust(index)); |
55 | + ut_ad(rec_offs_validate(rec, index, offsets)); |
56 | ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); |
57 | - offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); |
58 | + ut_ad(buf_block_get_frame(block) == page_align(rec)); |
59 | + ut_ad(page_is_leaf(page_align(rec))); |
60 | |
61 | #ifdef UNIV_DEBUG |
62 | if (btr_cur_print_record_ops && thr) { |
63 | @@ -2658,13 +2656,12 @@ |
64 | ut_ad(dict_index_is_clust(index)); |
65 | ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); |
66 | |
67 | - err = lock_clust_rec_modify_check_and_lock(flags, |
68 | - btr_cur_get_block(cursor), |
69 | + err = lock_clust_rec_modify_check_and_lock(flags, block, |
70 | rec, index, offsets, thr); |
71 | |
72 | if (err != DB_SUCCESS) { |
73 | |
74 | - goto func_exit; |
75 | + return(err); |
76 | } |
77 | |
78 | err = trx_undo_report_row_operation(flags, TRX_UNDO_MODIFY_OP, thr, |
79 | @@ -2672,11 +2669,9 @@ |
80 | &roll_ptr); |
81 | if (err != DB_SUCCESS) { |
82 | |
83 | - goto func_exit; |
84 | + return(err); |
85 | } |
86 | |
87 | - block = btr_cur_get_block(cursor); |
88 | - |
89 | if (block->is_hashed) { |
90 | rw_lock_x_lock(&btr_search_latch); |
91 | } |
92 | @@ -2699,10 +2694,6 @@ |
93 | btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx, |
94 | roll_ptr, mtr); |
95 | |
96 | -func_exit: |
97 | - if (UNIV_LIKELY_NULL(heap)) { |
98 | - mem_heap_free(heap); |
99 | - } |
100 | return(err); |
101 | } |
102 | |
103 | @@ -3754,107 +3745,35 @@ |
104 | } |
105 | |
106 | /*******************************************************************//** |
107 | -Marks not updated extern fields as not-owned by this record. The ownership |
108 | -is transferred to the updated record which is inserted elsewhere in the |
109 | +Marks non-updated off-page fields as disowned by this record. The ownership |
110 | +must be transferred to the updated record which is inserted elsewhere in the |
111 | index tree. In purge only the owner of externally stored field is allowed |
112 | -to free the field. |
113 | -@return TRUE if BLOB ownership was transferred */ |
114 | +to free the field. */ |
115 | UNIV_INTERN |
116 | -ibool |
117 | -btr_cur_mark_extern_inherited_fields( |
118 | -/*=================================*/ |
119 | +void |
120 | +btr_cur_disown_inherited_fields( |
121 | +/*============================*/ |
122 | page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed |
123 | part will be updated, or NULL */ |
124 | rec_t* rec, /*!< in/out: record in a clustered index */ |
125 | dict_index_t* index, /*!< in: index of the page */ |
126 | const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ |
127 | const upd_t* update, /*!< in: update vector */ |
128 | - mtr_t* mtr) /*!< in: mtr, or NULL if not logged */ |
129 | + mtr_t* mtr) /*!< in/out: mini-transaction */ |
130 | { |
131 | - ulint n; |
132 | - ulint j; |
133 | ulint i; |
134 | - ibool change_ownership = FALSE; |
135 | |
136 | - ut_ad(rec_offs_validate(rec, NULL, offsets)); |
137 | + ut_ad(rec_offs_validate(rec, index, offsets)); |
138 | ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)); |
139 | - |
140 | - if (!rec_offs_any_extern(offsets)) { |
141 | - |
142 | - return(FALSE); |
143 | - } |
144 | - |
145 | - n = rec_offs_n_fields(offsets); |
146 | - |
147 | - for (i = 0; i < n; i++) { |
148 | - if (rec_offs_nth_extern(offsets, i)) { |
149 | - |
150 | - /* Check it is not in updated fields */ |
151 | - |
152 | - if (update) { |
153 | - for (j = 0; j < upd_get_n_fields(update); |
154 | - j++) { |
155 | - if (upd_get_nth_field(update, j) |
156 | - ->field_no == i) { |
157 | - |
158 | - goto updated; |
159 | - } |
160 | - } |
161 | - } |
162 | - |
163 | + ut_ad(rec_offs_any_extern(offsets)); |
164 | + ut_ad(mtr); |
165 | + |
166 | + for (i = 0; i < rec_offs_n_fields(offsets); i++) { |
167 | + if (rec_offs_nth_extern(offsets, i) |
168 | + && !upd_get_field_by_field_no(update, i)) { |
169 | btr_cur_set_ownership_of_extern_field( |
170 | page_zip, rec, index, offsets, i, FALSE, mtr); |
171 | - |
172 | - change_ownership = TRUE; |
173 | -updated: |
174 | - ; |
175 | - } |
176 | - } |
177 | - |
178 | - return(change_ownership); |
179 | -} |
180 | - |
181 | -/*******************************************************************//** |
182 | -The complement of the previous function: in an update entry may inherit |
183 | -some externally stored fields from a record. We must mark them as inherited |
184 | -in entry, so that they are not freed in a rollback. */ |
185 | -UNIV_INTERN |
186 | -void |
187 | -btr_cur_mark_dtuple_inherited_extern( |
188 | -/*=================================*/ |
189 | - dtuple_t* entry, /*!< in/out: updated entry to be |
190 | - inserted to clustered index */ |
191 | - const upd_t* update) /*!< in: update vector */ |
192 | -{ |
193 | - ulint i; |
194 | - |
195 | - for (i = 0; i < dtuple_get_n_fields(entry); i++) { |
196 | - |
197 | - dfield_t* dfield = dtuple_get_nth_field(entry, i); |
198 | - byte* data; |
199 | - ulint len; |
200 | - ulint j; |
201 | - |
202 | - if (!dfield_is_ext(dfield)) { |
203 | - continue; |
204 | - } |
205 | - |
206 | - /* Check if it is in updated fields */ |
207 | - |
208 | - for (j = 0; j < upd_get_n_fields(update); j++) { |
209 | - if (upd_get_nth_field(update, j)->field_no == i) { |
210 | - |
211 | - goto is_updated; |
212 | - } |
213 | - } |
214 | - |
215 | - data = (unsigned char *)dfield_get_data(dfield); |
216 | - len = dfield_get_len(dfield); |
217 | - data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN] |
218 | - |= BTR_EXTERN_INHERITED_FLAG; |
219 | - |
220 | -is_updated: |
221 | - ; |
222 | + } |
223 | } |
224 | } |
225 | |
226 | @@ -3894,29 +3813,6 @@ |
227 | } |
228 | |
229 | /*******************************************************************//** |
230 | -Marks all extern fields in a dtuple as owned by the record. */ |
231 | -UNIV_INTERN |
232 | -void |
233 | -btr_cur_unmark_dtuple_extern_fields( |
234 | -/*================================*/ |
235 | - dtuple_t* entry) /*!< in/out: clustered index entry */ |
236 | -{ |
237 | - ulint i; |
238 | - |
239 | - for (i = 0; i < dtuple_get_n_fields(entry); i++) { |
240 | - dfield_t* dfield = dtuple_get_nth_field(entry, i); |
241 | - |
242 | - if (dfield_is_ext(dfield)) { |
243 | - byte* data = (unsigned char *)dfield_get_data(dfield); |
244 | - ulint len = dfield_get_len(dfield); |
245 | - |
246 | - data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN] |
247 | - &= ~BTR_EXTERN_OWNER_FLAG; |
248 | - } |
249 | - } |
250 | -} |
251 | - |
252 | -/*******************************************************************//** |
253 | Flags the data tuple fields that are marked as extern storage in the |
254 | update vector. We use this function to remember which fields we must |
255 | mark as extern storage in a record inserted for an update. |
256 | |
257 | === modified file 'plugin/innobase/buf/buf0buf.cc' |
258 | --- plugin/innobase/buf/buf0buf.cc 2011-04-07 05:47:57 +0000 |
259 | +++ plugin/innobase/buf/buf0buf.cc 2012-05-22 12:41:18 +0000 |
260 | @@ -534,7 +534,7 @@ |
261 | "InnoDB: Error: page %lu log sequence number %"PRIu64". " |
262 | "InnoDB: is in the future! Current system log sequence number %"PRIu64". " |
263 | "Your database may be corrupt or you may have copied the InnoDB tablespace but not the InnoDB log files. See " |
264 | - " " REFMAN "forcing-recovery.html for more information. ", |
265 | + " " REFMAN "forcing-innodb-recovery.html for more information. ", |
266 | (ulong) mach_read_from_4(read_buf |
267 | + FIL_PAGE_OFFSET), |
268 | mach_read_from_8(read_buf + FIL_PAGE_LSN), |
269 | @@ -2744,7 +2744,8 @@ |
270 | ut_ad(zip_size == fil_space_get_zip_size(space)); |
271 | ut_ad(ut_is_2pow(zip_size)); |
272 | #ifndef UNIV_LOG_DEBUG |
273 | - ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL)); |
274 | + ut_ad(!ibuf_inside() || ibuf_page_low(space, zip_size, offset, |
275 | + FALSE, file, line, NULL)); |
276 | #endif |
277 | buf_pool->stat.n_page_gets++; |
278 | fold = buf_page_address_fold(space, offset); |
279 | @@ -4037,7 +4038,7 @@ |
280 | "InnoDB: TABLE to scan your" |
281 | " table for corruption.\n" |
282 | "InnoDB: See also " |
283 | - REFMAN "forcing-recovery.html\n" |
284 | + REFMAN "forcing-innodb-recovery.html\n" |
285 | "InnoDB: about forcing recovery.\n", stderr); |
286 | |
287 | if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { |
288 | @@ -4792,23 +4793,203 @@ |
289 | return(ratio); |
290 | } |
291 | |
292 | +/*******************************************************************//** |
293 | +Aggregates a pool stats information with the total buffer pool stats */ |
294 | +static |
295 | +void |
296 | +buf_stats_aggregate_pool_info( |
297 | +/*==========================*/ |
298 | + buf_pool_info_t* total_info, /*!< in/out: the buffer pool |
299 | + info to store aggregated |
300 | + result */ |
301 | + const buf_pool_info_t* pool_info) /*!< in: individual buffer pool |
302 | + stats info */ |
303 | +{ |
304 | + ut_a(total_info && pool_info); |
305 | + |
306 | + /* Nothing to copy if total_info is the same as pool_info */ |
307 | + if (total_info == pool_info) { |
308 | + return; |
309 | + } |
310 | + |
311 | + total_info->pool_size += pool_info->pool_size; |
312 | + total_info->lru_len += pool_info->lru_len; |
313 | + total_info->old_lru_len += pool_info->old_lru_len; |
314 | + total_info->free_list_len += pool_info->free_list_len; |
315 | + total_info->flush_list_len += pool_info->flush_list_len; |
316 | + total_info->n_pend_unzip += pool_info->n_pend_unzip; |
317 | + total_info->n_pend_reads += pool_info->n_pend_reads; |
318 | + total_info->n_pending_flush_lru += pool_info->n_pending_flush_lru; |
319 | + total_info->n_pending_flush_list += pool_info->n_pending_flush_list; |
320 | + total_info->n_pending_flush_single_page += |
321 | + pool_info->n_pending_flush_single_page; |
322 | + total_info->n_pages_made_young += pool_info->n_pages_made_young; |
323 | + total_info->n_pages_not_made_young += pool_info->n_pages_not_made_young; |
324 | + total_info->n_pages_read += pool_info->n_pages_read; |
325 | + total_info->n_pages_created += pool_info->n_pages_created; |
326 | + total_info->n_pages_written += pool_info->n_pages_written; |
327 | + total_info->n_page_gets += pool_info->n_page_gets; |
328 | + total_info->n_ra_pages_read += pool_info->n_ra_pages_read; |
329 | + total_info->n_ra_pages_evicted += pool_info->n_ra_pages_evicted; |
330 | + total_info->page_made_young_rate += pool_info->page_made_young_rate; |
331 | + total_info->page_not_made_young_rate += |
332 | + pool_info->page_not_made_young_rate; |
333 | + total_info->pages_read_rate += pool_info->pages_read_rate; |
334 | + total_info->pages_created_rate += pool_info->pages_created_rate; |
335 | + total_info->pages_written_rate += pool_info->pages_written_rate; |
336 | + total_info->n_page_get_delta += pool_info->n_page_get_delta; |
337 | + total_info->page_read_delta += pool_info->page_read_delta; |
338 | + total_info->young_making_delta += pool_info->young_making_delta; |
339 | + total_info->not_young_making_delta += pool_info->not_young_making_delta; |
340 | + total_info->pages_readahead_rate += pool_info->pages_readahead_rate; |
341 | + total_info->pages_evicted_rate += pool_info->pages_evicted_rate; |
342 | + total_info->unzip_lru_len += pool_info->unzip_lru_len; |
343 | + total_info->io_sum += pool_info->io_sum; |
344 | + total_info->io_cur += pool_info->io_cur; |
345 | + total_info->unzip_sum += pool_info->unzip_sum; |
346 | + total_info->unzip_cur += pool_info->unzip_cur; |
347 | +} |
348 | +/*******************************************************************//** |
349 | +Collect buffer pool stats information for a buffer pool. Also |
350 | +record aggregated stats if there are more than one buffer pool |
351 | +in the server */ |
352 | +static |
353 | +void |
354 | +buf_stats_get_pool_info( |
355 | +/*====================*/ |
356 | + buf_pool_t* buf_pool, /*!< in: buffer pool */ |
357 | + ulint pool_id, /*!< in: buffer pool ID */ |
358 | + buf_pool_info_t* all_pool_info) /*!< in/out: buffer pool info |
359 | + to fill */ |
360 | +{ |
361 | + buf_pool_info_t* pool_info; |
362 | + time_t current_time; |
363 | + double time_elapsed; |
364 | + |
365 | + /* Find appropriate pool_info to store stats for this buffer pool */ |
366 | + pool_info = &all_pool_info[pool_id]; |
367 | + |
368 | + buf_pool_mutex_enter(buf_pool); |
369 | + buf_flush_list_mutex_enter(buf_pool); |
370 | + |
371 | + pool_info->pool_unique_id = pool_id; |
372 | + |
373 | + pool_info->pool_size = buf_pool->curr_size; |
374 | + |
375 | + pool_info->lru_len = UT_LIST_GET_LEN(buf_pool->LRU); |
376 | + |
377 | + pool_info->old_lru_len = buf_pool->LRU_old_len; |
378 | + |
379 | + pool_info->free_list_len = UT_LIST_GET_LEN(buf_pool->free); |
380 | + |
381 | + pool_info->flush_list_len = UT_LIST_GET_LEN(buf_pool->flush_list); |
382 | + |
383 | + pool_info->n_pend_unzip = UT_LIST_GET_LEN(buf_pool->unzip_LRU); |
384 | + |
385 | + pool_info->n_pend_reads = buf_pool->n_pend_reads; |
386 | + |
387 | + pool_info->n_pending_flush_lru = |
388 | + (buf_pool->n_flush[BUF_FLUSH_LRU] |
389 | + + buf_pool->init_flush[BUF_FLUSH_LRU]); |
390 | + |
391 | + pool_info->n_pending_flush_list = |
392 | + (buf_pool->n_flush[BUF_FLUSH_LIST] |
393 | + + buf_pool->init_flush[BUF_FLUSH_LIST]); |
394 | + |
395 | + pool_info->n_pending_flush_single_page = |
396 | + buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]; |
397 | + |
398 | + buf_flush_list_mutex_exit(buf_pool); |
399 | + |
400 | + current_time = time(NULL); |
401 | + time_elapsed = 0.001 + difftime(current_time, |
402 | + buf_pool->last_printout_time); |
403 | + |
404 | + pool_info->n_pages_made_young = buf_pool->stat.n_pages_made_young; |
405 | + |
406 | + pool_info->n_pages_not_made_young = |
407 | + buf_pool->stat.n_pages_not_made_young; |
408 | + |
409 | + pool_info->n_pages_read = buf_pool->stat.n_pages_read; |
410 | + |
411 | + pool_info->n_pages_created = buf_pool->stat.n_pages_created; |
412 | + |
413 | + pool_info->n_pages_written = buf_pool->stat.n_pages_written; |
414 | + |
415 | + pool_info->n_page_gets = buf_pool->stat.n_page_gets; |
416 | + |
417 | + pool_info->n_ra_pages_read = buf_pool->stat.n_ra_pages_read; |
418 | + |
419 | + pool_info->n_ra_pages_evicted = buf_pool->stat.n_ra_pages_evicted; |
420 | + |
421 | + pool_info->page_made_young_rate = |
422 | + (buf_pool->stat.n_pages_made_young |
423 | + - buf_pool->old_stat.n_pages_made_young) / time_elapsed; |
424 | + |
425 | + pool_info->page_not_made_young_rate = |
426 | + (buf_pool->stat.n_pages_not_made_young |
427 | + - buf_pool->old_stat.n_pages_not_made_young) / time_elapsed; |
428 | + |
429 | + pool_info->pages_read_rate = |
430 | + (buf_pool->stat.n_pages_read |
431 | + - buf_pool->old_stat.n_pages_read) / time_elapsed; |
432 | + |
433 | + pool_info->pages_created_rate = |
434 | + (buf_pool->stat.n_pages_created |
435 | + - buf_pool->old_stat.n_pages_created) / time_elapsed; |
436 | + |
437 | + pool_info->pages_written_rate = |
438 | + (buf_pool->stat.n_pages_written |
439 | + - buf_pool->old_stat.n_pages_written) / time_elapsed; |
440 | + |
441 | + pool_info->n_page_get_delta = buf_pool->stat.n_page_gets |
442 | + - buf_pool->old_stat.n_page_gets; |
443 | + |
444 | + if (pool_info->n_page_get_delta) { |
445 | + pool_info->page_read_delta = buf_pool->stat.n_pages_read |
446 | + - buf_pool->old_stat.n_pages_read; |
447 | + |
448 | + pool_info->young_making_delta = |
449 | + buf_pool->stat.n_pages_made_young |
450 | + - buf_pool->old_stat.n_pages_made_young; |
451 | + |
452 | + pool_info->not_young_making_delta = |
453 | + buf_pool->stat.n_pages_not_made_young |
454 | + - buf_pool->old_stat.n_pages_not_made_young; |
455 | + } |
456 | + |
457 | + pool_info->pages_readahead_rate = |
458 | + (buf_pool->stat.n_ra_pages_read |
459 | + - buf_pool->old_stat.n_ra_pages_read) / time_elapsed; |
460 | + |
461 | + pool_info->pages_evicted_rate = |
462 | + (buf_pool->stat.n_ra_pages_evicted |
463 | + - buf_pool->old_stat.n_ra_pages_evicted) / time_elapsed; |
464 | + |
465 | + pool_info->unzip_lru_len = UT_LIST_GET_LEN(buf_pool->unzip_LRU); |
466 | + |
467 | + pool_info->io_sum = buf_LRU_stat_sum.io; |
468 | + |
469 | + pool_info->io_cur = buf_LRU_stat_cur.io; |
470 | + |
471 | + pool_info->unzip_sum = buf_LRU_stat_sum.unzip; |
472 | + |
473 | + pool_info->unzip_cur = buf_LRU_stat_cur.unzip; |
474 | + |
475 | + buf_refresh_io_stats(buf_pool); |
476 | + buf_pool_mutex_exit(buf_pool); |
477 | +} |
478 | + |
479 | /*********************************************************************//** |
480 | Prints info of the buffer i/o. */ |
481 | static |
482 | void |
483 | buf_print_io_instance( |
484 | /*==================*/ |
485 | - buf_pool_t* buf_pool, /*!< in: buffer pool instance */ |
486 | + buf_pool_info_t*pool_info, /*!< in: buffer pool info */ |
487 | FILE* file) /*!< in/out: buffer where to print */ |
488 | { |
489 | - time_t current_time; |
490 | - double time_elapsed; |
491 | - ulint n_gets_diff; |
492 | - |
493 | - ut_ad(buf_pool); |
494 | - |
495 | - buf_pool_mutex_enter(buf_pool); |
496 | - buf_flush_list_mutex_enter(buf_pool); |
497 | + ut_ad(pool_info); |
498 | |
499 | fprintf(file, |
500 | "Buffer pool size %lu\n" |
501 | @@ -4818,70 +4999,42 @@ |
502 | "Modified db pages %lu\n" |
503 | "Pending reads %lu\n" |
504 | "Pending writes: LRU %lu, flush list %lu, single page %lu\n", |
505 | - (ulong) buf_pool->curr_size, |
506 | - (ulong) UT_LIST_GET_LEN(buf_pool->free), |
507 | - (ulong) UT_LIST_GET_LEN(buf_pool->LRU), |
508 | - (ulong) buf_pool->LRU_old_len, |
509 | - (ulong) UT_LIST_GET_LEN(buf_pool->flush_list), |
510 | - (ulong) buf_pool->n_pend_reads, |
511 | - (ulong) buf_pool->n_flush[BUF_FLUSH_LRU] |
512 | - + buf_pool->init_flush[BUF_FLUSH_LRU], |
513 | - (ulong) buf_pool->n_flush[BUF_FLUSH_LIST] |
514 | - + buf_pool->init_flush[BUF_FLUSH_LIST], |
515 | - (ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]); |
516 | - |
517 | - buf_flush_list_mutex_exit(buf_pool); |
518 | - |
519 | - current_time = time(NULL); |
520 | - time_elapsed = 0.001 + difftime(current_time, |
521 | - buf_pool->last_printout_time); |
522 | + pool_info->pool_size, |
523 | + pool_info->free_list_len, |
524 | + pool_info->lru_len, |
525 | + pool_info->old_lru_len, |
526 | + pool_info->flush_list_len, |
527 | + pool_info->n_pend_reads, |
528 | + pool_info->n_pending_flush_lru, |
529 | + pool_info->n_pending_flush_list, |
530 | + pool_info->n_pending_flush_single_page); |
531 | |
532 | fprintf(file, |
533 | "Pages made young %lu, not young %lu\n" |
534 | "%.2f youngs/s, %.2f non-youngs/s\n" |
535 | "Pages read %lu, created %lu, written %lu\n" |
536 | "%.2f reads/s, %.2f creates/s, %.2f writes/s\n", |
537 | - (ulong) buf_pool->stat.n_pages_made_young, |
538 | - (ulong) buf_pool->stat.n_pages_not_made_young, |
539 | - (buf_pool->stat.n_pages_made_young |
540 | - - buf_pool->old_stat.n_pages_made_young) |
541 | - / time_elapsed, |
542 | - (buf_pool->stat.n_pages_not_made_young |
543 | - - buf_pool->old_stat.n_pages_not_made_young) |
544 | - / time_elapsed, |
545 | - (ulong) buf_pool->stat.n_pages_read, |
546 | - (ulong) buf_pool->stat.n_pages_created, |
547 | - (ulong) buf_pool->stat.n_pages_written, |
548 | - (buf_pool->stat.n_pages_read |
549 | - - buf_pool->old_stat.n_pages_read) |
550 | - / time_elapsed, |
551 | - (buf_pool->stat.n_pages_created |
552 | - - buf_pool->old_stat.n_pages_created) |
553 | - / time_elapsed, |
554 | - (buf_pool->stat.n_pages_written |
555 | - - buf_pool->old_stat.n_pages_written) |
556 | - / time_elapsed); |
557 | - |
558 | - n_gets_diff = buf_pool->stat.n_page_gets |
559 | - - buf_pool->old_stat.n_page_gets; |
560 | - |
561 | - if (n_gets_diff) { |
562 | + pool_info->n_pages_made_young, |
563 | + pool_info->n_pages_not_made_young, |
564 | + pool_info->page_made_young_rate, |
565 | + pool_info->page_not_made_young_rate, |
566 | + pool_info->n_pages_read, |
567 | + pool_info->n_pages_created, |
568 | + pool_info->n_pages_written, |
569 | + pool_info->pages_read_rate, |
570 | + pool_info->pages_created_rate, |
571 | + pool_info->pages_written_rate); |
572 | + |
573 | + if (pool_info->n_page_get_delta) { |
574 | fprintf(file, |
575 | "Buffer pool hit rate %lu / 1000," |
576 | " young-making rate %lu / 1000 not %lu / 1000\n", |
577 | - (ulong) |
578 | - (1000 - ((1000 * (buf_pool->stat.n_pages_read |
579 | - - buf_pool->old_stat.n_pages_read)) |
580 | - / (buf_pool->stat.n_page_gets |
581 | - - buf_pool->old_stat.n_page_gets))), |
582 | - (ulong) |
583 | - (1000 * (buf_pool->stat.n_pages_made_young |
584 | - - buf_pool->old_stat.n_pages_made_young) |
585 | - / n_gets_diff), |
586 | - (ulong) |
587 | - (1000 * (buf_pool->stat.n_pages_not_made_young |
588 | - - buf_pool->old_stat.n_pages_not_made_young) |
589 | - / n_gets_diff)); |
590 | + (ulong) (1000 - (1000 * pool_info->page_read_delta |
591 | + / pool_info->n_page_get_delta)), |
592 | + (ulong) (1000 * pool_info->young_making_delta |
593 | + / pool_info->n_page_get_delta), |
594 | + (ulong) (1000 * pool_info->not_young_making_delta |
595 | + / pool_info->n_page_get_delta)); |
596 | } else { |
597 | fputs("No buffer pool page gets since the last printout\n", |
598 | file); |
599 | @@ -4890,25 +5043,17 @@ |
600 | /* Statistics about read ahead algorithm */ |
601 | fprintf(file, "Pages read ahead %.2f/s," |
602 | " evicted without access %.2f/s\n", |
603 | - (buf_pool->stat.n_ra_pages_read |
604 | - - buf_pool->old_stat.n_ra_pages_read) |
605 | - / time_elapsed, |
606 | - (buf_pool->stat.n_ra_pages_evicted |
607 | - - buf_pool->old_stat.n_ra_pages_evicted) |
608 | - / time_elapsed); |
609 | + pool_info->pages_readahead_rate, |
610 | + pool_info->pages_evicted_rate); |
611 | |
612 | /* Print some values to help us with visualizing what is |
613 | happening with LRU eviction. */ |
614 | fprintf(file, |
615 | "LRU len: %lu, unzip_LRU len: %lu\n" |
616 | "I/O sum[%lu]:cur[%lu], unzip sum[%lu]:cur[%lu]\n", |
617 | - static_cast<ulint>(UT_LIST_GET_LEN(buf_pool->LRU)), |
618 | - static_cast<ulint>(UT_LIST_GET_LEN(buf_pool->unzip_LRU)), |
619 | - buf_LRU_stat_sum.io, buf_LRU_stat_cur.io, |
620 | - buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip); |
621 | - |
622 | - buf_refresh_io_stats(buf_pool); |
623 | - buf_pool_mutex_exit(buf_pool); |
624 | + pool_info->lru_len, pool_info->unzip_lru_len, |
625 | + pool_info->io_sum, pool_info->io_cur, |
626 | + pool_info->unzip_sum, pool_info->unzip_cur); |
627 | } |
628 | |
629 | /*********************************************************************//** |
630 | @@ -4919,14 +5064,58 @@ |
631 | /*=========*/ |
632 | FILE* file) /*!< in/out: buffer where to print */ |
633 | { |
634 | - ulint i; |
635 | + ulint i; |
636 | + buf_pool_info_t* pool_info; |
637 | + buf_pool_info_t* pool_info_total; |
638 | + |
639 | + /* If srv_buf_pool_instances is greater than 1, allocate |
640 | + one extra buf_pool_info_t, the last one stores |
641 | + aggregated/total values from all pools */ |
642 | + if (srv_buf_pool_instances > 1) { |
643 | + pool_info = (buf_pool_info_t*) mem_zalloc(( |
644 | + srv_buf_pool_instances + 1) * sizeof *pool_info); |
645 | + |
646 | + pool_info_total = &pool_info[srv_buf_pool_instances]; |
647 | + } else { |
648 | + ut_a(srv_buf_pool_instances == 1); |
649 | + pool_info_total = pool_info = (buf_pool_info_t*) mem_zalloc( |
650 | + sizeof *pool_info) |
651 | + } |
652 | |
653 | for (i = 0; i < srv_buf_pool_instances; i++) { |
654 | buf_pool_t* buf_pool; |
655 | |
656 | buf_pool = buf_pool_from_array(i); |
657 | - buf_print_io_instance(buf_pool, file); |
658 | - } |
659 | + |
660 | + /* Fetch individual buffer pool info and calculate |
661 | + aggregated stats along the way */ |
662 | + buf_stats_get_pool_info(buf_pool, i, pool_info); |
663 | + |
664 | + /* If we have more than one buffer pool, store |
665 | + the aggregated stats */ |
666 | + if (srv_buf_pool_instances > 1) { |
667 | + buf_stats_aggregate_pool_info(pool_info_total, |
668 | + &pool_info[i]); |
669 | + } |
670 | + } |
671 | + |
672 | + /* Print the aggreate buffer pool info */ |
673 | + buf_print_io_instance(pool_info_total, file); |
674 | + |
675 | + /* If there are more than one buffer pool, print each individual pool |
676 | + info */ |
677 | + if (srv_buf_pool_instances > 1) { |
678 | + fputs("----------------------\n" |
679 | + "INDIVIDUAL BUFFER POOL INFO\n" |
680 | + "----------------------\n", file); |
681 | + |
682 | + for (i = 0; i < srv_buf_pool_instances; i++) { |
683 | + fprintf(file, "---BUFFER POOL %lu\n", i); |
684 | + buf_print_io_instance(&pool_info[i], file); |
685 | + } |
686 | + } |
687 | + |
688 | + mem_free(pool_info); |
689 | } |
690 | |
691 | /**********************************************************************//** |
692 | |
693 | === modified file 'plugin/innobase/buf/buf0flu.cc' |
694 | --- plugin/innobase/buf/buf0flu.cc 2011-04-07 05:47:57 +0000 |
695 | +++ plugin/innobase/buf/buf0flu.cc 2012-05-22 12:41:18 +0000 |
696 | @@ -86,6 +86,34 @@ |
697 | buf_flush_validate_low( |
698 | /*===================*/ |
699 | buf_pool_t* buf_pool); /*!< in: Buffer pool instance */ |
700 | + |
701 | +/******************************************************************//** |
702 | +Validates the flush list some of the time. |
703 | +@return TRUE if ok or the check was skipped */ |
704 | +static |
705 | +ibool |
706 | +buf_flush_validate_skip( |
707 | +/*====================*/ |
708 | + buf_pool_t* buf_pool) /*!< in: Buffer pool instance */ |
709 | +{ |
710 | +/** Try buf_flush_validate_low() every this many times */ |
711 | +# define BUF_FLUSH_VALIDATE_SKIP 23 |
712 | + |
713 | + /** The buf_flush_validate_low() call skip counter. |
714 | + Use a signed type because of the race condition below. */ |
715 | + static int buf_flush_validate_count = BUF_FLUSH_VALIDATE_SKIP; |
716 | + |
717 | + /* There is a race condition below, but it does not matter, |
718 | + because this call is only for heuristic purposes. We want to |
719 | + reduce the call frequency of the costly buf_flush_validate_low() |
720 | + check in debug builds. */ |
721 | + if (--buf_flush_validate_count > 0) { |
722 | + return(TRUE); |
723 | + } |
724 | + |
725 | + buf_flush_validate_count = BUF_FLUSH_VALIDATE_SKIP; |
726 | + return(buf_flush_validate_low(buf_pool)); |
727 | +} |
728 | #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ |
729 | |
730 | /******************************************************************//** |
731 | @@ -301,7 +329,7 @@ |
732 | } |
733 | #endif /* UNIV_DEBUG_VALGRIND */ |
734 | #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG |
735 | - ut_a(buf_flush_validate_low(buf_pool)); |
736 | + ut_a(buf_flush_validate_skip(buf_pool)); |
737 | #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ |
738 | |
739 | buf_flush_list_mutex_exit(buf_pool); |
740 | @@ -535,7 +563,7 @@ |
741 | bpage->oldest_modification = 0; |
742 | |
743 | #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG |
744 | - ut_a(buf_flush_validate_low(buf_pool)); |
745 | + ut_a(buf_flush_validate_skip(buf_pool)); |
746 | #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ |
747 | |
748 | buf_flush_list_mutex_exit(buf_pool); |
749 | |
750 | === modified file 'plugin/innobase/buf/buf0lru.cc' |
751 | --- plugin/innobase/buf/buf0lru.cc 2011-04-07 12:10:16 +0000 |
752 | +++ plugin/innobase/buf/buf0lru.cc 2012-05-22 12:41:18 +0000 |
753 | @@ -2077,6 +2077,7 @@ |
754 | buf_LRU_stat_t* item; |
755 | buf_pool_t* buf_pool; |
756 | ibool evict_started = FALSE; |
757 | + buf_LRU_stat_t cur_stat; |
758 | |
759 | /* If we haven't started eviction yet then don't update stats. */ |
760 | for (i = 0; i < srv_buf_pool_instances; i++) { |
761 | @@ -2098,12 +2099,19 @@ |
762 | buf_LRU_stat_arr_ind++; |
763 | buf_LRU_stat_arr_ind %= BUF_LRU_STAT_N_INTERVAL; |
764 | |
765 | - /* Add the current value and subtract the obsolete entry. */ |
766 | - buf_LRU_stat_sum.io += buf_LRU_stat_cur.io - item->io; |
767 | - buf_LRU_stat_sum.unzip += buf_LRU_stat_cur.unzip - item->unzip; |
768 | + /* Add the current value and subtract the obsolete entry. |
769 | + Since buf_LRU_stat_cur is not protected by any mutex, |
770 | + it can be changing between adding to buf_LRU_stat_sum |
771 | + and copying to item. Assign it to local variables to make |
772 | + sure the same value assign to the buf_LRU_stat_sum |
773 | + and item */ |
774 | + cur_stat = buf_LRU_stat_cur; |
775 | + |
776 | + buf_LRU_stat_sum.io += cur_stat.io - item->io; |
777 | + buf_LRU_stat_sum.unzip += cur_stat.unzip - item->unzip; |
778 | |
779 | /* Put current entry in the array. */ |
780 | - memcpy(item, &buf_LRU_stat_cur, sizeof *item); |
781 | + memcpy(item, &cur_stat, sizeof *item); |
782 | |
783 | func_exit: |
784 | /* Clear the current entry. */ |
785 | |
786 | === modified file 'plugin/innobase/dict/dict0dict.cc' |
787 | --- plugin/innobase/dict/dict0dict.cc 2011-02-04 22:30:00 +0000 |
788 | +++ plugin/innobase/dict/dict0dict.cc 2012-05-22 12:41:18 +0000 |
789 | @@ -52,7 +52,8 @@ |
790 | #include "que0que.h" |
791 | #include "rem0cmp.h" |
792 | #include "row0merge.h" |
793 | -#include "ha_prototypes.h" /* innobase_strcasecmp() */ |
794 | +#include "srv0srv.h" /* srv_lower_case_table_names */ |
795 | +#include "ha_prototypes.h" /* innobase_strcasecmp(), innobase_casedn_str()*/ |
796 | |
797 | #include <ctype.h> |
798 | |
799 | @@ -75,6 +76,7 @@ |
800 | #ifdef UNIV_PFS_RWLOCK |
801 | UNIV_INTERN mysql_pfs_key_t dict_operation_lock_key; |
802 | UNIV_INTERN mysql_pfs_key_t index_tree_rw_lock_key; |
803 | +UNIV_INTERN mysql_pfs_key_t dict_table_stats_latch_key; |
804 | #endif /* UNIV_PFS_RWLOCK */ |
805 | |
806 | #ifdef UNIV_PFS_MUTEX |
807 | @@ -714,7 +716,7 @@ |
808 | &dict_foreign_err_mutex, SYNC_ANY_LATCH); |
809 | |
810 | for (i = 0; i < DICT_TABLE_STATS_LATCHES_SIZE; i++) { |
811 | - rw_lock_create(PFS_NOT_INSTRUMENTED, |
812 | + rw_lock_create(dict_table_stats_latch_key, |
813 | &dict_table_stats_latches[i], SYNC_INDEX_TREE); |
814 | } |
815 | } |
816 | @@ -947,7 +949,7 @@ |
817 | dict_foreign_t* foreign; |
818 | dict_index_t* index; |
819 | ulint fold; |
820 | - char old_name[MAX_TABLE_NAME_LEN + 1]; |
821 | + char old_name[MAX_FULL_NAME_LEN + 1]; |
822 | |
823 | ut_ad(table); |
824 | ut_ad(mutex_own(&(dict_sys->mutex))); |
825 | @@ -959,7 +961,7 @@ |
826 | ut_print_timestamp(stderr); |
827 | fprintf(stderr, "InnoDB: too long table name: '%s', " |
828 | "max length is %d\n", table->name, |
829 | - MAX_TABLE_NAME_LEN); |
830 | + MAX_FULL_NAME_LEN); |
831 | ut_error; |
832 | } |
833 | |
834 | @@ -1080,13 +1082,14 @@ |
835 | /* Allocate a longer name buffer; |
836 | TODO: store buf len to save memory */ |
837 | |
838 | - foreign->foreign_table_name |
839 | - = static_cast<char *>(mem_heap_alloc(foreign->heap, |
840 | - ut_strlen(table->name) + 1)); |
841 | + foreign->foreign_table_name = mem_heap_strdup( |
842 | + foreign->heap, table->name); |
843 | + dict_mem_foreign_table_name_lookup_set(foreign, TRUE); |
844 | + } else { |
845 | + strcpy(foreign->foreign_table_name, table->name); |
846 | + dict_mem_foreign_table_name_lookup_set(foreign, FALSE); |
847 | } |
848 | |
849 | - strcpy(foreign->foreign_table_name, table->name); |
850 | - |
851 | if (strchr(foreign->id, '/')) { |
852 | ulint db_len; |
853 | char* old_id; |
854 | @@ -1152,12 +1155,15 @@ |
855 | /* Allocate a longer name buffer; |
856 | TODO: store buf len to save memory */ |
857 | |
858 | - foreign->referenced_table_name = static_cast<char *>(mem_heap_alloc( |
859 | - foreign->heap, strlen(table->name) + 1)); |
860 | + foreign->referenced_table_name = mem_heap_strdup( |
861 | + foreign->heap, table->name); |
862 | + dict_mem_referenced_table_name_lookup_set(foreign, TRUE); |
863 | + } else { |
864 | + /* Use the same buffer */ |
865 | + strcpy(foreign->referenced_table_name, table->name); |
866 | + dict_mem_referenced_table_name_lookup_set(foreign, FALSE); |
867 | } |
868 | |
869 | - strcpy(foreign->referenced_table_name, table->name); |
870 | - |
871 | foreign = UT_LIST_GET_NEXT(referenced_list, foreign); |
872 | } |
873 | |
874 | @@ -2585,10 +2591,10 @@ |
875 | ut_ad(mutex_own(&(dict_sys->mutex))); |
876 | |
877 | for_table = dict_table_check_if_in_cache_low( |
878 | - foreign->foreign_table_name); |
879 | + foreign->foreign_table_name_lookup); |
880 | |
881 | ref_table = dict_table_check_if_in_cache_low( |
882 | - foreign->referenced_table_name); |
883 | + foreign->referenced_table_name_lookup); |
884 | ut_a(for_table || ref_table); |
885 | |
886 | if (for_table) { |
887 | @@ -2705,7 +2711,7 @@ |
888 | quote = '\0'; |
889 | } else if (quote) { |
890 | /* Within quotes: do nothing. */ |
891 | - } else if (*ptr == '`' || *ptr == '"') { |
892 | + } else if (*ptr == '`' || *ptr == '"' || *ptr == '\'') { |
893 | /* Starting quote: remember the quote character. */ |
894 | quote = *ptr; |
895 | } else { |
896 | @@ -3017,19 +3023,25 @@ |
897 | memcpy(ref, database_name, database_name_len); |
898 | ref[database_name_len] = '/'; |
899 | memcpy(ref + database_name_len + 1, table_name, table_name_len + 1); |
900 | -#ifndef __WIN__ |
901 | - if (srv_lower_case_table_names) { |
902 | -#endif /* !__WIN__ */ |
903 | - /* The table name is always put to lower case on Windows. */ |
904 | + |
905 | + /* Values; 0 = Store and compare as given; case sensitive |
906 | + 1 = Store and compare in lower; case insensitive |
907 | + 2 = Store as given, compare in lower; case semi-sensitive */ |
908 | + if (srv_lower_case_table_names == 2) { |
909 | innobase_casedn_str(ref); |
910 | -#ifndef __WIN__ |
911 | + *table = dict_table_get_low(ref); |
912 | + memcpy(ref, database_name, database_name_len); |
913 | + ref[database_name_len] = '/'; |
914 | + memcpy(ref + database_name_len + 1, table_name, table_name_len + 1); |
915 | + } else { |
916 | + if (srv_lower_case_table_names == 1) { |
917 | + innobase_casedn_str(ref); |
918 | + } |
919 | + *table = dict_table_get_low(ref); |
920 | } |
921 | -#endif /* !__WIN__ */ |
922 | |
923 | *success = TRUE; |
924 | *ref_name = ref; |
925 | - *table = dict_table_get_low(ref); |
926 | - |
927 | return(ptr); |
928 | } |
929 | |
930 | @@ -3518,8 +3530,10 @@ |
931 | } |
932 | |
933 | foreign->foreign_table = table; |
934 | - foreign->foreign_table_name = mem_heap_strdup(foreign->heap, |
935 | - table->name); |
936 | + foreign->foreign_table_name = mem_heap_strdup( |
937 | + foreign->heap, table->name); |
938 | + dict_mem_foreign_table_name_lookup_set(foreign, TRUE); |
939 | + |
940 | foreign->foreign_index = index; |
941 | foreign->n_fields = (unsigned int) i; |
942 | foreign->foreign_col_names = static_cast<const char **>(mem_heap_alloc(foreign->heap, |
943 | @@ -3776,8 +3790,9 @@ |
944 | foreign->referenced_index = index; |
945 | foreign->referenced_table = referenced_table; |
946 | |
947 | - foreign->referenced_table_name |
948 | - = mem_heap_strdup(foreign->heap, referenced_table_name); |
949 | + foreign->referenced_table_name = mem_heap_strdup( |
950 | + foreign->heap, referenced_table_name); |
951 | + dict_mem_referenced_table_name_lookup_set(foreign, TRUE); |
952 | |
953 | foreign->referenced_col_names = static_cast<const char **>(mem_heap_alloc(foreign->heap, |
954 | i * sizeof(void*))); |
955 | @@ -4588,8 +4603,8 @@ |
956 | |
957 | fputs(") REFERENCES ", file); |
958 | |
959 | - if (dict_tables_have_same_db(foreign->foreign_table_name, |
960 | - foreign->referenced_table_name)) { |
961 | + if (dict_tables_have_same_db(foreign->foreign_table_name_lookup, |
962 | + foreign->referenced_table_name_lookup)) { |
963 | /* Do not print the database name of the referenced table */ |
964 | ut_print_name(file, trx, TRUE, |
965 | dict_remove_db_name( |
966 | |
967 | === modified file 'plugin/innobase/dict/dict0load.cc' |
968 | --- plugin/innobase/dict/dict0load.cc 2010-12-28 03:48:30 +0000 |
969 | +++ plugin/innobase/dict/dict0load.cc 2012-05-22 12:41:18 +0000 |
970 | @@ -44,6 +44,7 @@ |
971 | #include "rem0cmp.h" |
972 | #include "srv0start.h" |
973 | #include "srv0srv.h" |
974 | +#include "ha_prototypes.h" /* innobase_casedn_str() */ |
975 | |
976 | |
977 | /** Following are six InnoDB system tables */ |
978 | @@ -442,10 +443,11 @@ |
979 | return(err_msg); |
980 | |
981 | } |
982 | + |
983 | /********************************************************************//** |
984 | This function parses a SYS_FOREIGN record and populate a dict_foreign_t |
985 | structure with the information from the record. For detail information |
986 | -about SYS_FOREIGN fields, please refer to dict_load_foreign() function |
987 | +about SYS_FOREIGN fields, please refer to dict_load_foreign() function. |
988 | @return error message, or NULL on success */ |
989 | UNIV_INTERN |
990 | const char* |
991 | @@ -473,6 +475,11 @@ |
992 | err_len: |
993 | return("incorrect column length in SYS_FOREIGN"); |
994 | } |
995 | + |
996 | + /* This recieves a dict_foreign_t* that points to a stack variable. |
997 | + So mem_heap_free(foreign->heap) is not used as elsewhere. |
998 | + Since the heap used here is freed elsewhere, foreign->heap |
999 | + is not assigned. */ |
1000 | foreign->id = mem_heap_strdupl(heap, (const char*) field, len); |
1001 | |
1002 | rec_get_nth_field_offs_old(rec, 1/*DB_TRX_ID*/, &len); |
1003 | @@ -484,6 +491,9 @@ |
1004 | goto err_len; |
1005 | } |
1006 | |
1007 | + /* The _lookup versions of the referenced and foreign table names |
1008 | + are not assigned since they are not used in this dict_foreign_t */ |
1009 | + |
1010 | field = rec_get_nth_field_old(rec, 3/*FOR_NAME*/, &len); |
1011 | if (UNIV_UNLIKELY(len < 1 || len == UNIV_SQL_NULL)) { |
1012 | goto err_len; |
1013 | @@ -509,6 +519,7 @@ |
1014 | |
1015 | return(NULL); |
1016 | } |
1017 | + |
1018 | /********************************************************************//** |
1019 | This function parses a SYS_FOREIGN_COLS record and extract necessary |
1020 | information from the record and return to caller. |
1021 | @@ -2139,12 +2150,15 @@ |
1022 | foreign->id = mem_heap_strdup(foreign->heap, id); |
1023 | |
1024 | field = rec_get_nth_field_old(rec, 3, &len); |
1025 | + |
1026 | foreign->foreign_table_name = mem_heap_strdupl( |
1027 | foreign->heap, (char*) field, len); |
1028 | + dict_mem_foreign_table_name_lookup_set(foreign, TRUE); |
1029 | |
1030 | field = rec_get_nth_field_old(rec, 4, &len); |
1031 | foreign->referenced_table_name = mem_heap_strdupl( |
1032 | foreign->heap, (char*) field, len); |
1033 | + dict_mem_referenced_table_name_lookup_set(foreign, TRUE); |
1034 | |
1035 | btr_pcur_close(&pcur); |
1036 | mtr_commit(&mtr); |
1037 | @@ -2152,7 +2166,7 @@ |
1038 | dict_load_foreign_cols(id, foreign); |
1039 | |
1040 | ref_table = dict_table_check_if_in_cache_low( |
1041 | - foreign->referenced_table_name); |
1042 | + foreign->referenced_table_name_lookup); |
1043 | |
1044 | /* We could possibly wind up in a deep recursive calls if |
1045 | we call dict_table_get_low() again here if there |
1046 | @@ -2185,7 +2199,7 @@ |
1047 | have to load it so that we are able to make type comparisons |
1048 | in the next function call. */ |
1049 | |
1050 | - for_table = dict_table_get_low(foreign->foreign_table_name); |
1051 | + for_table = dict_table_get_low(foreign->foreign_table_name_lookup); |
1052 | |
1053 | if (for_table && ref_table && check_recursive) { |
1054 | /* This is to record the longest chain of ancesters |
1055 | |
1056 | === modified file 'plugin/innobase/dict/dict0mem.cc' |
1057 | --- plugin/innobase/dict/dict0mem.cc 2010-12-28 03:48:30 +0000 |
1058 | +++ plugin/innobase/dict/dict0mem.cc 2012-05-22 12:41:18 +0000 |
1059 | @@ -33,6 +33,8 @@ |
1060 | #include "data0type.h" |
1061 | #include "mach0data.h" |
1062 | #include "dict0dict.h" |
1063 | +#include "srv0srv.h" /* srv_lower_case_table_names */ |
1064 | +#include "ha_prototypes.h" /* innobase_casedn_str()*/ |
1065 | #ifndef UNIV_HOTBACKUP |
1066 | # include "lock0lock.h" |
1067 | #endif /* !UNIV_HOTBACKUP */ |
1068 | @@ -288,6 +290,60 @@ |
1069 | } |
1070 | |
1071 | /**********************************************************************//** |
1072 | +Sets the foreign_table_name_lookup pointer based on the value of |
1073 | +srv_lower_case_table_names. If that is 0 or 1, foreign_table_name_lookup |
1074 | +will point to foreign_table_name. If 2, then another string is allocated |
1075 | +of the heap and set to lower case. */ |
1076 | +UNIV_INTERN |
1077 | +void |
1078 | +dict_mem_foreign_table_name_lookup_set( |
1079 | +/*===================================*/ |
1080 | + dict_foreign_t* foreign, /*!< in/out: foreign struct */ |
1081 | + ibool do_alloc) /*!< in: is an alloc needed */ |
1082 | +{ |
1083 | + if (srv_lower_case_table_names == 2) { |
1084 | + if (do_alloc) { |
1085 | + foreign->foreign_table_name_lookup = static_cast<char *>(mem_heap_alloc( |
1086 | + foreign->heap, |
1087 | + strlen(foreign->foreign_table_name) + 1)); |
1088 | + } |
1089 | + strcpy(foreign->foreign_table_name_lookup, |
1090 | + foreign->foreign_table_name); |
1091 | + innobase_casedn_str(foreign->foreign_table_name_lookup); |
1092 | + } else { |
1093 | + foreign->foreign_table_name_lookup |
1094 | + = foreign->foreign_table_name; |
1095 | + } |
1096 | +} |
1097 | + |
1098 | +/**********************************************************************//** |
1099 | +Sets the referenced_table_name_lookup pointer based on the value of |
1100 | +srv_lower_case_table_names. If that is 0 or 1, |
1101 | +referenced_table_name_lookup will point to referenced_table_name. If 2, |
1102 | +then another string is allocated of the heap and set to lower case. */ |
1103 | +UNIV_INTERN |
1104 | +void |
1105 | +dict_mem_referenced_table_name_lookup_set( |
1106 | +/*======================================*/ |
1107 | + dict_foreign_t* foreign, /*!< in/out: foreign struct */ |
1108 | + ibool do_alloc) /*!< in: is an alloc needed */ |
1109 | +{ |
1110 | + if (srv_lower_case_table_names == 2) { |
1111 | + if (do_alloc) { |
1112 | + foreign->referenced_table_name_lookup = static_cast<char *>(mem_heap_alloc( |
1113 | + foreign->heap, |
1114 | + strlen(foreign->referenced_table_name) + 1)); |
1115 | + } |
1116 | + strcpy(foreign->referenced_table_name_lookup, |
1117 | + foreign->referenced_table_name); |
1118 | + innobase_casedn_str(foreign->referenced_table_name_lookup); |
1119 | + } else { |
1120 | + foreign->referenced_table_name_lookup |
1121 | + = foreign->referenced_table_name; |
1122 | + } |
1123 | +} |
1124 | + |
1125 | +/**********************************************************************//** |
1126 | Adds a field definition to an index. NOTE: does not take a copy |
1127 | of the column name if the field is a column. The memory occupied |
1128 | by the column name may be released only after publishing the index. */ |
1129 | |
1130 | === modified file 'plugin/innobase/fil/fil0fil.cc' |
1131 | --- plugin/innobase/fil/fil0fil.cc 2011-07-30 09:20:56 +0000 |
1132 | +++ plugin/innobase/fil/fil0fil.cc 2012-05-22 12:41:18 +0000 |
1133 | @@ -300,6 +300,34 @@ |
1134 | initialized. */ |
1135 | fil_system_t* fil_system = NULL; |
1136 | |
1137 | +#ifdef UNIV_DEBUG |
1138 | +/** Try fil_validate() every this many times */ |
1139 | +# define FIL_VALIDATE_SKIP 17 |
1140 | + |
1141 | +/******************************************************************//** |
1142 | +Checks the consistency of the tablespace cache some of the time. |
1143 | +@return TRUE if ok or the check was skipped */ |
1144 | +static |
1145 | +ibool |
1146 | +fil_validate_skip(void) |
1147 | +/*===================*/ |
1148 | +{ |
1149 | + /** The fil_validate() call skip counter. Use a signed type |
1150 | + because of the race condition below. */ |
1151 | + static int fil_validate_count = FIL_VALIDATE_SKIP; |
1152 | + |
1153 | + /* There is a race condition below, but it does not matter, |
1154 | + because this call is only for heuristic purposes. We want to |
1155 | + reduce the call frequency of the costly fil_validate() check |
1156 | + in debug builds. */ |
1157 | + if (--fil_validate_count > 0) { |
1158 | + return(TRUE); |
1159 | + } |
1160 | + |
1161 | + fil_validate_count = FIL_VALIDATE_SKIP; |
1162 | + return(fil_validate()); |
1163 | +} |
1164 | +#endif /* UNIV_DEBUG */ |
1165 | |
1166 | /********************************************************************//** |
1167 | NOTE: you must call fil_mutex_enter_and_prepare_for_io() first! |
1168 | @@ -4304,7 +4332,7 @@ |
1169 | ut_ad(ut_is_2pow(zip_size)); |
1170 | ut_ad(buf); |
1171 | ut_ad(len > 0); |
1172 | - ut_ad(fil_validate()); |
1173 | + ut_ad(fil_validate_skip()); |
1174 | #ifndef UNIV_HOTBACKUP |
1175 | # ifndef UNIV_LOG_DEBUG |
1176 | /* ibuf bitmap pages must be read in the sync aio mode: */ |
1177 | @@ -4463,7 +4491,7 @@ |
1178 | |
1179 | mutex_exit(&fil_system->mutex); |
1180 | |
1181 | - ut_ad(fil_validate()); |
1182 | + ut_ad(fil_validate_skip()); |
1183 | } |
1184 | |
1185 | return(DB_SUCCESS); |
1186 | @@ -4551,7 +4579,7 @@ |
1187 | void* message; |
1188 | ulint type; |
1189 | |
1190 | - ut_ad(fil_validate()); |
1191 | + ut_ad(fil_validate_skip()); |
1192 | |
1193 | if (srv_use_native_aio) { |
1194 | srv_set_io_thread_op_info(segment, "native aio handle"); |
1195 | @@ -4582,7 +4610,7 @@ |
1196 | |
1197 | mutex_exit(&fil_system->mutex); |
1198 | |
1199 | - ut_ad(fil_validate()); |
1200 | + ut_ad(fil_validate_skip()); |
1201 | |
1202 | /* Do the i/o handling */ |
1203 | /* IMPORTANT: since i/o handling for reads will read also the insert |
1204 | |
1205 | === modified file 'plugin/innobase/fsp/fsp0fsp.cc' |
1206 | --- plugin/innobase/fsp/fsp0fsp.cc 2011-04-05 10:32:12 +0000 |
1207 | +++ plugin/innobase/fsp/fsp0fsp.cc 2012-05-22 12:41:18 +0000 |
1208 | @@ -3310,7 +3310,7 @@ |
1209 | "InnoDB: database!\n", (ulong) page); |
1210 | crash: |
1211 | fputs("InnoDB: Please refer to\n" |
1212 | - "InnoDB: " REFMAN "forcing-recovery.html\n" |
1213 | + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" |
1214 | "InnoDB: about forcing recovery.\n", stderr); |
1215 | ut_error; |
1216 | } |
1217 | |
1218 | === modified file 'plugin/innobase/handler/ha_innodb.cc' |
1219 | --- plugin/innobase/handler/ha_innodb.cc 2012-03-03 20:57:17 +0000 |
1220 | +++ plugin/innobase/handler/ha_innodb.cc 2012-05-22 12:41:18 +0000 |
1221 | @@ -7370,7 +7370,7 @@ |
1222 | /* We do not update delete_length if no |
1223 | locking is requested so the "old" value can |
1224 | remain. delete_length is initialized to 0 in |
1225 | - the ha_statistics' constructor. */ |
1226 | + the ha_statistics' constructor.*/ |
1227 | } else if (UNIV_UNLIKELY |
1228 | (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) { |
1229 | /* Avoid accessing the tablespace if |
1230 | |
1231 | === modified file 'plugin/innobase/ibuf/ibuf0ibuf.cc' |
1232 | --- plugin/innobase/ibuf/ibuf0ibuf.cc 2011-04-07 05:47:57 +0000 |
1233 | +++ plugin/innobase/ibuf/ibuf0ibuf.cc 2012-05-22 12:41:18 +0000 |
1234 | @@ -658,22 +658,50 @@ |
1235 | return(ptr); |
1236 | } |
1237 | #ifndef UNIV_HOTBACKUP |
1238 | +# ifdef UNIV_DEBUG |
1239 | +/** Gets the desired bits for a given page from a bitmap page. |
1240 | +@param page in: bitmap page |
1241 | +@param offset in: page whose bits to get |
1242 | +@param zs in: compressed page size in bytes; 0 for uncompressed pages |
1243 | +@param bit in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... |
1244 | +@param mtr in: mini-transaction holding an x-latch on the bitmap page |
1245 | +@return value of bits */ |
1246 | +# define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr) \ |
1247 | + ibuf_bitmap_page_get_bits_low(page, offset, zs, \ |
1248 | + MTR_MEMO_PAGE_X_FIX, mtr, bit) |
1249 | +# else /* UNIV_DEBUG */ |
1250 | +/** Gets the desired bits for a given page from a bitmap page. |
1251 | +@param page in: bitmap page |
1252 | +@param offset in: page whose bits to get |
1253 | +@param zs in: compressed page size in bytes; 0 for uncompressed pages |
1254 | +@param bit in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... |
1255 | +@param mtr in: mini-transaction holding an x-latch on the bitmap page |
1256 | +@return value of bits */ |
1257 | +# define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr) \ |
1258 | + ibuf_bitmap_page_get_bits_low(page, offset, zs, bit) |
1259 | +# endif /* UNIV_DEBUG */ |
1260 | + |
1261 | /********************************************************************//** |
1262 | Gets the desired bits for a given page from a bitmap page. |
1263 | @return value of bits */ |
1264 | UNIV_INLINE |
1265 | ulint |
1266 | -ibuf_bitmap_page_get_bits( |
1267 | -/*======================*/ |
1268 | +ibuf_bitmap_page_get_bits_low( |
1269 | +/*==========================*/ |
1270 | const page_t* page, /*!< in: bitmap page */ |
1271 | ulint page_no,/*!< in: page whose bits to get */ |
1272 | ulint zip_size,/*!< in: compressed page size in bytes; |
1273 | 0 for uncompressed pages */ |
1274 | - ulint bit, /*!< in: IBUF_BITMAP_FREE, |
1275 | +#ifdef UNIV_DEBUG |
1276 | + ulint latch_type, |
1277 | + /*!< in: MTR_MEMO_PAGE_X_FIX, |
1278 | + MTR_MEMO_BUF_FIX, ... */ |
1279 | + mtr_t* mtr, /*!< in: mini-transaction holding latch_type |
1280 | + on the bitmap page */ |
1281 | +#endif /* UNIV_DEBUG */ |
1282 | + ulint bit) /*!< in: IBUF_BITMAP_FREE, |
1283 | + |
1284 | IBUF_BITMAP_BUFFERED, ... */ |
1285 | - mtr_t* /*mtr __attribute__((unused))*/) |
1286 | - /*!< in: mtr containing an |
1287 | - x-latch to the bitmap page */ |
1288 | { |
1289 | ulint byte_offset; |
1290 | ulint bit_offset; |
1291 | @@ -685,7 +713,7 @@ |
1292 | # error "IBUF_BITS_PER_PAGE % 2 != 0" |
1293 | #endif |
1294 | ut_ad(ut_is_2pow(zip_size)); |
1295 | - ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)); |
1296 | + ut_ad(mtr_memo_contains_page(mtr, page, latch_type)); |
1297 | |
1298 | if (!zip_size) { |
1299 | bit_offset = (page_no % UNIV_PAGE_SIZE) * IBUF_BITS_PER_PAGE |
1300 | @@ -1111,21 +1139,29 @@ |
1301 | @return TRUE if level 2 or level 3 page */ |
1302 | UNIV_INTERN |
1303 | ibool |
1304 | -ibuf_page( |
1305 | -/*======*/ |
1306 | - ulint space, /*!< in: space id */ |
1307 | - ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ |
1308 | - ulint page_no,/*!< in: page number */ |
1309 | - mtr_t* mtr) /*!< in: mtr which will contain an x-latch to the |
1310 | - bitmap page if the page is not one of the fixed |
1311 | - address ibuf pages, or NULL, in which case a new |
1312 | - transaction is created. */ |
1313 | +ibuf_page_low( |
1314 | +/*==========*/ |
1315 | + ulint space, /*!< in: space id */ |
1316 | + ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ |
1317 | + ulint page_no,/*!< in: page number */ |
1318 | +#ifdef UNIV_DEBUG |
1319 | + ibool x_latch,/*!< in: FALSE if relaxed check |
1320 | + (avoid latching the bitmap page) */ |
1321 | +#endif /* UNIV_DEBUG */ |
1322 | + const char* file, /*!< in: file name */ |
1323 | + ulint line, /*!< in: line where called */ |
1324 | + mtr_t* mtr) /*!< in: mtr which will contain an |
1325 | + x-latch to the bitmap page if the page |
1326 | + is not one of the fixed address ibuf |
1327 | + pages, or NULL, in which case a new |
1328 | + transaction is created. */ |
1329 | { |
1330 | ibool ret; |
1331 | mtr_t local_mtr; |
1332 | page_t* bitmap_page; |
1333 | |
1334 | ut_ad(!recv_no_ibuf_operations); |
1335 | + ut_ad(x_latch || mtr == NULL); |
1336 | |
1337 | if (srv_fake_write) |
1338 | return(FALSE); |
1339 | @@ -1140,12 +1176,55 @@ |
1340 | |
1341 | ut_ad(fil_space_get_type(IBUF_SPACE_ID) == FIL_TABLESPACE); |
1342 | |
1343 | +#ifdef UNIV_DEBUG |
1344 | + if (!x_latch) { |
1345 | + mtr_start(&local_mtr); |
1346 | + |
1347 | + /* Get the bitmap page without a page latch, so that |
1348 | + we will not be violating the latching order when |
1349 | + another bitmap page has already been latched by this |
1350 | + thread. The page will be buffer-fixed, and thus it |
1351 | + cannot be removed or relocated while we are looking at |
1352 | + it. The contents of the page could change, but the |
1353 | + IBUF_BITMAP_IBUF bit that we are interested in should |
1354 | + not be modified by any other thread. Nobody should be |
1355 | + calling ibuf_add_free_page() or ibuf_remove_free_page() |
1356 | + while the page is linked to the insert buffer b-tree. */ |
1357 | + |
1358 | + bitmap_page = buf_block_get_frame( |
1359 | + buf_page_get_gen( |
1360 | + space, zip_size, |
1361 | + ibuf_bitmap_page_no_calc(zip_size, page_no), |
1362 | + RW_NO_LATCH, NULL, BUF_GET_NO_LATCH, |
1363 | + file, line, &local_mtr)); |
1364 | +# ifdef UNIV_SYNC_DEBUG |
1365 | + /* This is for tracking Bug #58212. This check and message can |
1366 | + be removed once it has been established that our assumptions |
1367 | + about this condition are correct. The bug was only a one-time |
1368 | + occurrence, unable to repeat since then. */ |
1369 | + void* latch = sync_thread_levels_contains(SYNC_IBUF_BITMAP); |
1370 | + if (latch) { |
1371 | + fprintf(stderr, "Bug#58212 UNIV_SYNC_DEBUG" |
1372 | + " levels %p (%u,%u)\n", |
1373 | + latch, (unsigned) space, (unsigned) page_no); |
1374 | + } |
1375 | +# endif /* UNIV_SYNC_DEBUG */ |
1376 | + ret = ibuf_bitmap_page_get_bits_low( |
1377 | + bitmap_page, page_no, zip_size, |
1378 | + MTR_MEMO_BUF_FIX, &local_mtr, IBUF_BITMAP_IBUF); |
1379 | + |
1380 | + mtr_commit(&local_mtr); |
1381 | + return(ret); |
1382 | + } |
1383 | +#endif /* UNIV_DEBUG */ |
1384 | + |
1385 | if (mtr == NULL) { |
1386 | mtr = &local_mtr; |
1387 | mtr_start(mtr); |
1388 | } |
1389 | |
1390 | - bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr); |
1391 | + bitmap_page = ibuf_bitmap_get_map_page_func(space, page_no, zip_size, |
1392 | + file, line, mtr); |
1393 | |
1394 | ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size, |
1395 | IBUF_BITMAP_IBUF, mtr); |
1396 | |
1397 | === modified file 'plugin/innobase/include/btr0cur.h' |
1398 | --- plugin/innobase/include/btr0cur.h 2011-03-14 05:40:28 +0000 |
1399 | +++ plugin/innobase/include/btr0cur.h 2012-05-22 12:41:18 +0000 |
1400 | @@ -334,10 +334,14 @@ |
1401 | btr_cur_del_mark_set_clust_rec( |
1402 | /*===========================*/ |
1403 | ulint flags, /*!< in: undo logging and locking flags */ |
1404 | - btr_cur_t* cursor, /*!< in: cursor */ |
1405 | + buf_block_t* block, /*!< in/out: buffer block of the record */ |
1406 | + rec_t* rec, /*!< in/out: record */ |
1407 | + dict_index_t* index, /*!< in: clustered index of the record */ |
1408 | + const ulint* offsets,/*!< in: rec_get_offsets(rec) */ |
1409 | ibool val, /*!< in: value to set */ |
1410 | que_thr_t* thr, /*!< in: query thread */ |
1411 | - mtr_t* mtr); /*!< in: mtr */ |
1412 | + mtr_t* mtr) /*!< in: mtr */ |
1413 | + __attribute__((nonnull)); |
1414 | /***********************************************************//** |
1415 | Sets a secondary index record delete mark to TRUE or FALSE. |
1416 | @return DB_SUCCESS, DB_LOCK_WAIT, or error number */ |
1417 | @@ -470,40 +474,22 @@ |
1418 | /*======================================*/ |
1419 | dict_index_t* index); /*!< in: index */ |
1420 | /*******************************************************************//** |
1421 | -Marks not updated extern fields as not-owned by this record. The ownership |
1422 | -is transferred to the updated record which is inserted elsewhere in the |
1423 | +Marks non-updated off-page fields as disowned by this record. The ownership |
1424 | +must be transferred to the updated record which is inserted elsewhere in the |
1425 | index tree. In purge only the owner of externally stored field is allowed |
1426 | -to free the field. |
1427 | -@return TRUE if BLOB ownership was transferred */ |
1428 | +to free the field. */ |
1429 | UNIV_INTERN |
1430 | -ibool |
1431 | -btr_cur_mark_extern_inherited_fields( |
1432 | -/*=================================*/ |
1433 | +void |
1434 | +btr_cur_disown_inherited_fields( |
1435 | +/*============================*/ |
1436 | page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed |
1437 | part will be updated, or NULL */ |
1438 | rec_t* rec, /*!< in/out: record in a clustered index */ |
1439 | dict_index_t* index, /*!< in: index of the page */ |
1440 | const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ |
1441 | const upd_t* update, /*!< in: update vector */ |
1442 | - mtr_t* mtr); /*!< in: mtr, or NULL if not logged */ |
1443 | -/*******************************************************************//** |
1444 | -The complement of the previous function: in an update entry may inherit |
1445 | -some externally stored fields from a record. We must mark them as inherited |
1446 | -in entry, so that they are not freed in a rollback. */ |
1447 | -UNIV_INTERN |
1448 | -void |
1449 | -btr_cur_mark_dtuple_inherited_extern( |
1450 | -/*=================================*/ |
1451 | - dtuple_t* entry, /*!< in/out: updated entry to be |
1452 | - inserted to clustered index */ |
1453 | - const upd_t* update); /*!< in: update vector */ |
1454 | -/*******************************************************************//** |
1455 | -Marks all extern fields in a dtuple as owned by the record. */ |
1456 | -UNIV_INTERN |
1457 | -void |
1458 | -btr_cur_unmark_dtuple_extern_fields( |
1459 | -/*================================*/ |
1460 | - dtuple_t* entry); /*!< in/out: clustered index entry */ |
1461 | + mtr_t* mtr) /*!< in/out: mini-transaction */ |
1462 | + __attribute__((nonnull(2,3,4,5,6))); |
1463 | /*******************************************************************//** |
1464 | Stores the fields in big_rec_vec to the tablespace and puts pointers to |
1465 | them in rec. The extern flags in rec will have to be set beforehand. |
1466 | |
1467 | === modified file 'plugin/innobase/include/buf0buf.h' |
1468 | --- plugin/innobase/include/buf0buf.h 2011-04-05 10:32:12 +0000 |
1469 | +++ plugin/innobase/include/buf0buf.h 2012-05-22 12:41:18 +0000 |
1470 | @@ -113,6 +113,76 @@ |
1471 | before putting to the free list */ |
1472 | }; |
1473 | |
1474 | + |
1475 | +/** This structure defines information we will fetch from each buffer pool. It |
1476 | +will be used to print table IO stats */ |
1477 | +struct buf_pool_info_struct{ |
1478 | + /* General buffer pool info */ |
1479 | + ulint pool_unique_id; /*!< Buffer Pool ID */ |
1480 | + ulint pool_size; /*!< Buffer Pool size in pages */ |
1481 | + ulint lru_len; /*!< Length of buf_pool->LRU */ |
1482 | + ulint old_lru_len; /*!< buf_pool->LRU_old_len */ |
1483 | + ulint free_list_len; /*!< Length of buf_pool->free list */ |
1484 | + ulint flush_list_len; /*!< Length of buf_pool->flush_list */ |
1485 | + ulint n_pend_unzip; /*!< buf_pool->n_pend_unzip, pages |
1486 | + pending decompress */ |
1487 | + ulint n_pend_reads; /*!< buf_pool->n_pend_reads, pages |
1488 | + pending read */ |
1489 | + ulint n_pending_flush_lru; /*!< Pages pending flush in LRU */ |
1490 | + ulint n_pending_flush_list; /*!< Pages pending flush in FLUSH |
1491 | + LIST */ |
1492 | + ulint n_pending_flush_single_page;/*!< Pages pending flush in |
1493 | + BUF_FLUSH_SINGLE_PAGE list */ |
1494 | + ulint n_pages_made_young; /*!< number of pages made young */ |
1495 | + ulint n_pages_not_made_young; /*!< number of pages not made young */ |
1496 | + ulint n_pages_read; /*!< buf_pool->n_pages_read */ |
1497 | + ulint n_pages_created; /*!< buf_pool->n_pages_created */ |
1498 | + ulint n_pages_written; /*!< buf_pool->n_pages_written */ |
1499 | + ulint n_page_gets; /*!< buf_pool->n_page_gets */ |
1500 | + ulint n_ra_pages_read; /*!< buf_pool->n_ra_pages_read, number |
1501 | + of pages readahead */ |
1502 | + ulint n_ra_pages_evicted; /*!< buf_pool->n_ra_pages_evicted, |
1503 | + number of readahead pages evicted |
1504 | + without access */ |
1505 | + ulint n_page_get_delta; /*!< num of buffer pool page gets since |
1506 | + last printout */ |
1507 | + |
1508 | + /* Buffer pool access stats */ |
1509 | + double page_made_young_rate; /*!< page made young rate in pages |
1510 | + per second */ |
1511 | + double page_not_made_young_rate;/*!< page not made young rate |
1512 | + in pages per second */ |
1513 | + double pages_read_rate; /*!< num of pages read per second */ |
1514 | + double pages_created_rate; /*!< num of pages create per second */ |
1515 | + double pages_written_rate; /*!< num of pages written per second */ |
1516 | + ulint page_read_delta; /*!< num of pages read since last |
1517 | + printout */ |
1518 | + ulint young_making_delta; /*!< num of pages made young since |
1519 | + last printout */ |
1520 | + ulint not_young_making_delta; /*!< num of pages not make young since |
1521 | + last printout */ |
1522 | + |
1523 | + /* Statistics about read ahead algorithm. */ |
1524 | + double pages_readahead_rate; /*!< readahead rate in pages per |
1525 | + second */ |
1526 | + double pages_evicted_rate; /*!< rate of readahead page evicted |
1527 | + without access, in pages per second */ |
1528 | + |
1529 | + /* Stats about LRU eviction */ |
1530 | + ulint unzip_lru_len; /*!< length of buf_pool->unzip_LRU |
1531 | + list */ |
1532 | + /* Counters for LRU policy */ |
1533 | + ulint io_sum; /*!< buf_LRU_stat_sum.io */ |
1534 | + ulint io_cur; /*!< buf_LRU_stat_cur.io, num of IO |
1535 | + for current interval */ |
1536 | + ulint unzip_sum; /*!< buf_LRU_stat_sum.unzip */ |
1537 | + ulint unzip_cur; /*!< buf_LRU_stat_cur.unzip, num |
1538 | + pages decompressed in current |
1539 | + interval */ |
1540 | +}; |
1541 | + |
1542 | +typedef struct buf_pool_info_struct buf_pool_info_t; |
1543 | + |
1544 | #ifndef UNIV_HOTBACKUP |
1545 | /********************************************************************//** |
1546 | Acquire mutex on all buffer pool instances */ |
1547 | |
1548 | === modified file 'plugin/innobase/include/data0data.h' |
1549 | --- plugin/innobase/include/data0data.h 2011-03-14 05:40:28 +0000 |
1550 | +++ plugin/innobase/include/data0data.h 2012-05-22 12:41:18 +0000 |
1551 | @@ -155,14 +155,19 @@ |
1552 | dfield_t* field, /*!< in/out: data field */ |
1553 | mem_heap_t* heap); /*!< in: memory heap where allocated */ |
1554 | /*********************************************************************//** |
1555 | -Tests if data length and content is equal for two dfields. |
1556 | -@return TRUE if equal */ |
1557 | +Tests if two data fields are equal. |
1558 | +If len==0, tests the data length and content for equality. |
1559 | +If len>0, tests the first len bytes of the content for equality. |
1560 | +@return TRUE if both fields are NULL or if they are equal */ |
1561 | UNIV_INLINE |
1562 | ibool |
1563 | dfield_datas_are_binary_equal( |
1564 | /*==========================*/ |
1565 | const dfield_t* field1, /*!< in: field */ |
1566 | - const dfield_t* field2);/*!< in: field */ |
1567 | + const dfield_t* field2, /*!< in: field */ |
1568 | + ulint len) /*!< in: maximum prefix to compare, |
1569 | + or 0 to compare the whole field length */ |
1570 | + __attribute__((nonnull, warn_unused_result)); |
1571 | /*********************************************************************//** |
1572 | Tests if dfield data length and content is equal to the given. |
1573 | @return TRUE if equal */ |
1574 | |
1575 | === modified file 'plugin/innobase/include/data0data.ic' |
1576 | --- plugin/innobase/include/data0data.ic 2010-12-18 04:43:40 +0000 |
1577 | +++ plugin/innobase/include/data0data.ic 2012-05-22 12:41:18 +0000 |
1578 | @@ -229,20 +229,30 @@ |
1579 | } |
1580 | |
1581 | /*********************************************************************//** |
1582 | -Tests if data length and content is equal for two dfields. |
1583 | -@return TRUE if equal */ |
1584 | +Tests if two data fields are equal. |
1585 | +If len==0, tests the data length and content for equality. |
1586 | +If len>0, tests the first len bytes of the content for equality. |
1587 | +@return TRUE if both fields are NULL or if they are equal */ |
1588 | UNIV_INLINE |
1589 | ibool |
1590 | dfield_datas_are_binary_equal( |
1591 | /*==========================*/ |
1592 | const dfield_t* field1, /*!< in: field */ |
1593 | - const dfield_t* field2) /*!< in: field */ |
1594 | + const dfield_t* field2, /*!< in: field */ |
1595 | + ulint len) /*!< in: maximum prefix to compare, |
1596 | + or 0 to compare the whole field length */ |
1597 | { |
1598 | - ulint len; |
1599 | - |
1600 | - len = field1->len; |
1601 | - |
1602 | - return(len == field2->len |
1603 | + ulint len2 = len; |
1604 | + |
1605 | + if (field1->len == UNIV_SQL_NULL || len == 0 || field1->len < len) { |
1606 | + len = field1->len; |
1607 | + } |
1608 | + |
1609 | + if (field2->len == UNIV_SQL_NULL || len2 == 0 || field2->len < len2) { |
1610 | + len2 = field2->len; |
1611 | + } |
1612 | + |
1613 | + return(len == len2 |
1614 | && (len == UNIV_SQL_NULL |
1615 | || !memcmp(field1->data, field2->data, len))); |
1616 | } |
1617 | |
1618 | === modified file 'plugin/innobase/include/dict0mem.h' |
1619 | --- plugin/innobase/include/dict0mem.h 2011-03-14 05:40:28 +0000 |
1620 | +++ plugin/innobase/include/dict0mem.h 2012-05-22 12:41:18 +0000 |
1621 | @@ -239,6 +239,26 @@ |
1622 | dict_mem_foreign_create(void); |
1623 | /*=========================*/ |
1624 | |
1625 | +/**********************************************************************//** |
1626 | +Sets the foreign_table_name_lookup pointer based on the value of |
1627 | +srv_lower_case_table_names. */ |
1628 | +UNIV_INTERN |
1629 | +void |
1630 | +dict_mem_foreign_table_name_lookup_set( |
1631 | +/*===================================*/ |
1632 | + dict_foreign_t* foreign, /*!< in/out: foreign struct */ |
1633 | + ibool do_alloc); /*!< in: is an alloc needed */ |
1634 | + |
1635 | +/**********************************************************************//** |
1636 | +Sets the reference_table_name_lookup pointer based on the value of |
1637 | +srv_lower_case_table_names. */ |
1638 | +UNIV_INTERN |
1639 | +void |
1640 | +dict_mem_referenced_table_name_lookup_set( |
1641 | +/*======================================*/ |
1642 | + dict_foreign_t* foreign, /*!< in/out: foreign struct */ |
1643 | + ibool do_alloc); /*!< in: is an alloc needed */ |
1644 | + |
1645 | /** Data structure for a column in a table */ |
1646 | struct dict_col_struct{ |
1647 | /*----------------------*/ |
1648 | @@ -394,10 +414,14 @@ |
1649 | unsigned type:6; /*!< 0 or DICT_FOREIGN_ON_DELETE_CASCADE |
1650 | or DICT_FOREIGN_ON_DELETE_SET_NULL */ |
1651 | char* foreign_table_name;/*!< foreign table name */ |
1652 | + char* foreign_table_name_lookup; |
1653 | + /*!< foreign table name used for dict lookup */ |
1654 | dict_table_t* foreign_table; /*!< table where the foreign key is */ |
1655 | const char** foreign_col_names;/*!< names of the columns in the |
1656 | foreign key */ |
1657 | char* referenced_table_name;/*!< referenced table name */ |
1658 | + char* referenced_table_name_lookup; |
1659 | + /*!< referenced table name for dict lookup*/ |
1660 | dict_table_t* referenced_table;/*!< table where the referenced key |
1661 | is */ |
1662 | const char** referenced_col_names;/*!< names of the referenced |
1663 | |
1664 | === modified file 'plugin/innobase/include/ibuf0ibuf.h' |
1665 | --- plugin/innobase/include/ibuf0ibuf.h 2011-03-14 05:40:28 +0000 |
1666 | +++ plugin/innobase/include/ibuf0ibuf.h 2012-05-22 12:41:18 +0000 |
1667 | @@ -245,15 +245,44 @@ |
1668 | @return TRUE if level 2 or level 3 page */ |
1669 | UNIV_INTERN |
1670 | ibool |
1671 | -ibuf_page( |
1672 | -/*======*/ |
1673 | - ulint space, /*!< in: space id */ |
1674 | - ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ |
1675 | - ulint page_no,/*!< in: page number */ |
1676 | - mtr_t* mtr); /*!< in: mtr which will contain an x-latch to the |
1677 | - bitmap page if the page is not one of the fixed |
1678 | - address ibuf pages, or NULL, in which case a new |
1679 | - transaction is created. */ |
1680 | +ibuf_page_low( |
1681 | +/*==========*/ |
1682 | + ulint space, /*!< in: space id */ |
1683 | + ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ |
1684 | + ulint page_no,/*!< in: page number */ |
1685 | +#ifdef UNIV_DEBUG |
1686 | + ibool x_latch,/*!< in: FALSE if relaxed check |
1687 | + (avoid latching the bitmap page) */ |
1688 | +#endif /* UNIV_DEBUG */ |
1689 | + const char* file, /*!< in: file name */ |
1690 | + ulint line, /*!< in: line where called */ |
1691 | + mtr_t* mtr) /*!< in: mtr which will contain an |
1692 | + x-latch to the bitmap page if the page |
1693 | + is not one of the fixed address ibuf |
1694 | + pages, or NULL, in which case a new |
1695 | + transaction is created. */ |
1696 | + __attribute__((warn_unused_result)); |
1697 | +#ifdef UNIV_DEBUG |
1698 | +/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of |
1699 | +pages. Must not be called when recv_no_ibuf_operations==TRUE. |
1700 | +@param space tablespace identifier |
1701 | +@param zip_size compressed page size in bytes, or 0 |
1702 | +@param page_no page number |
1703 | +@param mtr mini-transaction or NULL |
1704 | +@return TRUE if level 2 or level 3 page */ |
1705 | +# define ibuf_page(space, zip_size, page_no, mtr) \ |
1706 | + ibuf_page_low(space, zip_size, page_no, TRUE, __FILE__, __LINE__, mtr) |
1707 | +#else /* UVIV_DEBUG */ |
1708 | +/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of |
1709 | +pages. Must not be called when recv_no_ibuf_operations==TRUE. |
1710 | +@param space tablespace identifier |
1711 | +@param zip_size compressed page size in bytes, or 0 |
1712 | +@param page_no page number |
1713 | +@param mtr mini-transaction or NULL |
1714 | +@return TRUE if level 2 or level 3 page */ |
1715 | +# define ibuf_page(space, zip_size, page_no, mtr) \ |
1716 | + ibuf_page_low(space, zip_size, page_no, __FILE__, __LINE__, mtr) |
1717 | +#endif /* UVIV_DEBUG */ |
1718 | /***********************************************************************//** |
1719 | Frees excess pages from the ibuf free list. This function is called when an OS |
1720 | thread calls fsp services to allocate a new file segment, or a new page to a |
1721 | |
1722 | === modified file 'plugin/innobase/include/mem0mem.ic' |
1723 | --- plugin/innobase/include/mem0mem.ic 2010-12-18 04:43:40 +0000 |
1724 | +++ plugin/innobase/include/mem0mem.ic 2012-05-22 12:41:18 +0000 |
1725 | @@ -350,27 +350,27 @@ |
1726 | ulint n) /*!< in: size of the topmost element */ |
1727 | { |
1728 | mem_block_t* block; |
1729 | - void* buf; |
1730 | + byte* buf; |
1731 | |
1732 | ut_ad(mem_heap_check(heap)); |
1733 | |
1734 | block = UT_LIST_GET_LAST(heap->base); |
1735 | |
1736 | - buf = (byte*)block + mem_block_get_free(block) - MEM_SPACE_NEEDED(n); |
1737 | + buf = (byte*) block + mem_block_get_free(block) - MEM_SPACE_NEEDED(n); |
1738 | |
1739 | #ifdef UNIV_MEM_DEBUG |
1740 | - ut_ad(mem_block_get_start(block) <=(ulint)((byte*)buf - (byte*)block)); |
1741 | + ut_ad(mem_block_get_start(block) <= (ulint) (buf - (byte*) block)); |
1742 | |
1743 | /* In the debug version, advance buf to point at the storage which |
1744 | was given to the caller in the allocation*/ |
1745 | |
1746 | - buf = (byte*)buf + MEM_FIELD_HEADER_SIZE; |
1747 | + buf += MEM_FIELD_HEADER_SIZE; |
1748 | |
1749 | /* Check that the field lengths agree */ |
1750 | - ut_ad(n == (ulint)mem_field_header_get_len(buf)); |
1751 | + ut_ad(n == mem_field_header_get_len(buf)); |
1752 | #endif |
1753 | |
1754 | - return(buf); |
1755 | + return((void*) buf); |
1756 | } |
1757 | |
1758 | /*****************************************************************//** |
1759 | |
1760 | === modified file 'plugin/innobase/include/mtr0mtr.ic' |
1761 | --- plugin/innobase/include/mtr0mtr.ic 2010-12-18 04:43:40 +0000 |
1762 | +++ plugin/innobase/include/mtr0mtr.ic 2012-05-22 12:41:18 +0000 |
1763 | @@ -160,7 +160,7 @@ |
1764 | while (offset > 0) { |
1765 | offset -= sizeof(mtr_memo_slot_t); |
1766 | |
1767 | - slot = dyn_array_get_element(memo, offset); |
1768 | + slot = (mtr_memo_slot_t*) dyn_array_get_element(memo, offset); |
1769 | |
1770 | if ((object == slot->object) && (type == slot->type)) { |
1771 | |
1772 | |
1773 | === modified file 'plugin/innobase/include/os0file.h' |
1774 | --- plugin/innobase/include/os0file.h 2011-04-05 10:32:12 +0000 |
1775 | +++ plugin/innobase/include/os0file.h 2012-05-22 12:41:18 +0000 |
1776 | @@ -376,6 +376,7 @@ |
1777 | typedef DIR* os_file_dir_t; /*!< directory stream */ |
1778 | #endif |
1779 | |
1780 | +#ifdef __WIN__ |
1781 | /***********************************************************************//** |
1782 | Gets the operating system version. Currently works only on Windows. |
1783 | @return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA, |
1784 | @@ -384,6 +385,7 @@ |
1785 | ulint |
1786 | os_get_os_version(void); |
1787 | /*===================*/ |
1788 | +#endif /* __WIN__ */ |
1789 | #ifndef UNIV_HOTBACKUP |
1790 | /****************************************************************//** |
1791 | Creates the seek mutexes used in positioned reads and writes. */ |
1792 | |
1793 | === modified file 'plugin/innobase/include/row0upd.h' |
1794 | --- plugin/innobase/include/row0upd.h 2011-03-14 05:40:28 +0000 |
1795 | +++ plugin/innobase/include/row0upd.h 2012-05-22 12:41:18 +0000 |
1796 | @@ -287,10 +287,13 @@ |
1797 | row and the data values in update are not |
1798 | known when this function is called, e.g., at |
1799 | compile time */ |
1800 | + const row_ext_t*ext, /*!< NULL, or prefixes of the externally |
1801 | + stored columns in the old row */ |
1802 | dict_index_t* index, /*!< in: index of the record */ |
1803 | - const upd_t* update);/*!< in: update vector for the row; NOTE: the |
1804 | + const upd_t* update) /*!< in: update vector for the row; NOTE: the |
1805 | field numbers in this MUST be clustered index |
1806 | positions! */ |
1807 | + __attribute__((nonnull(3,4), warn_unused_result)); |
1808 | /***********************************************************//** |
1809 | Checks if an update vector changes an ordering field of an index record. |
1810 | This function is fast if the update vector is short or the number of ordering |
1811 | @@ -463,11 +466,16 @@ |
1812 | #define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be |
1813 | inserted, old record is already delete |
1814 | marked */ |
1815 | -#define UPD_NODE_UPDATE_ALL_SEC 4 /* an ordering field of the clustered |
1816 | +#define UPD_NODE_INSERT_BLOB 4 /* clustered index record should be |
1817 | + inserted, old record is already |
1818 | + delete-marked; non-updated BLOBs |
1819 | + should be inherited by the new record |
1820 | + and disowned by the old record */ |
1821 | +#define UPD_NODE_UPDATE_ALL_SEC 5 /* an ordering field of the clustered |
1822 | index record was changed, or this is |
1823 | a delete operation: should update |
1824 | all the secondary index records */ |
1825 | -#define UPD_NODE_UPDATE_SOME_SEC 5 /* secondary index entries should be |
1826 | +#define UPD_NODE_UPDATE_SOME_SEC 6 /* secondary index entries should be |
1827 | looked at and updated if an ordering |
1828 | field changed */ |
1829 | |
1830 | |
1831 | === modified file 'plugin/innobase/include/srv0srv.h' |
1832 | --- plugin/innobase/include/srv0srv.h 2011-04-11 21:43:24 +0000 |
1833 | +++ plugin/innobase/include/srv0srv.h 2012-05-22 12:41:18 +0000 |
1834 | @@ -77,8 +77,8 @@ |
1835 | #define SRV_AUTO_EXTEND_INCREMENT \ |
1836 | (srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE)) |
1837 | |
1838 | -/* This is set to TRUE if the MySQL user has set it in MySQL */ |
1839 | -extern ibool srv_lower_case_table_names; |
1840 | +/* This is set to the MySQL server value for this variable. */ |
1841 | +extern uint srv_lower_case_table_names; |
1842 | |
1843 | /* Mutex for locking srv_monitor_file */ |
1844 | extern mutex_t srv_monitor_file_mutex; |
1845 | @@ -503,6 +503,14 @@ |
1846 | srv_get_thread_type(void); |
1847 | /*=====================*/ |
1848 | /*********************************************************************//** |
1849 | +Check whether thread type has reserved a slot. |
1850 | +@return slot number or UNDEFINED if not found*/ |
1851 | +UNIV_INTERN |
1852 | +ulint |
1853 | +srv_thread_has_reserved_slot( |
1854 | +/*=========================*/ |
1855 | + enum srv_thread_type type); /*!< in: thread type to check */ |
1856 | +/*********************************************************************//** |
1857 | Sets the info describing an i/o thread current state. */ |
1858 | UNIV_INTERN |
1859 | void |
1860 | |
1861 | === modified file 'plugin/innobase/include/sync0rw.h' |
1862 | --- plugin/innobase/include/sync0rw.h 2011-03-14 05:40:28 +0000 |
1863 | +++ plugin/innobase/include/sync0rw.h 2012-05-22 12:41:18 +0000 |
1864 | @@ -123,6 +123,7 @@ |
1865 | extern mysql_pfs_key_t trx_i_s_cache_lock_key; |
1866 | extern mysql_pfs_key_t trx_purge_latch_key; |
1867 | extern mysql_pfs_key_t index_tree_rw_lock_key; |
1868 | +extern mysql_pfs_key_t dict_table_stats_latch_key; |
1869 | #endif /* UNIV_PFS_RWLOCK */ |
1870 | |
1871 | |
1872 | |
1873 | === modified file 'plugin/innobase/include/univ.i' |
1874 | --- plugin/innobase/include/univ.i 2011-04-05 10:32:12 +0000 |
1875 | +++ plugin/innobase/include/univ.i 2012-05-22 12:41:18 +0000 |
1876 | @@ -50,9 +50,14 @@ |
1877 | #include "hb_univ.i" |
1878 | #endif /* UNIV_HOTBACKUP */ |
1879 | |
1880 | +/* aux macros to convert M into "123" (string) if M is defined like |
1881 | +#define M 123 */ |
1882 | +#define _IB_TO_STR(s) #s |
1883 | +#define IB_TO_STR(s) _IB_TO_STR(s) |
1884 | + |
1885 | #define INNODB_VERSION_MAJOR 1 |
1886 | #define INNODB_VERSION_MINOR 1 |
1887 | -#define INNODB_VERSION_BUGFIX 4 |
1888 | +#define INNODB_VERSION_BUGFIX 5 |
1889 | |
1890 | /* The following is the InnoDB version as shown in |
1891 | SELECT plugin_version FROM information_schema.plugins; |
1892 | @@ -63,16 +68,14 @@ |
1893 | #define INNODB_VERSION_SHORT \ |
1894 | (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) |
1895 | |
1896 | -/* auxiliary macros to help creating the version as string */ |
1897 | -#define __INNODB_VERSION(a, b, c) (#a "." #b "." #c) |
1898 | -#define _INNODB_VERSION(a, b, c) __INNODB_VERSION(a, b, c) |
1899 | - |
1900 | #define INNODB_VERSION_STR \ |
1901 | - _INNODB_VERSION(INNODB_VERSION_MAJOR, \ |
1902 | - INNODB_VERSION_MINOR, \ |
1903 | - INNODB_VERSION_BUGFIX) |
1904 | + IB_TO_STR(INNODB_VERSION_MAJOR) "." \ |
1905 | + IB_TO_STR(INNODB_VERSION_MINOR) "." \ |
1906 | + IB_TO_STR(INNODB_VERSION_BUGFIX) |
1907 | |
1908 | -#define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/" |
1909 | +#define REFMAN "http://dev.mysql.com/doc/refman/" \ |
1910 | + IB_TO_STR(MYSQL_MAJOR_VERSION) "." \ |
1911 | + IB_TO_STR(MYSQL_MINOR_VERSION) "/en/" |
1912 | |
1913 | #ifdef MYSQL_DYNAMIC_PLUGIN |
1914 | /* In the dynamic plugin, redefine some externally visible symbols |
1915 | @@ -268,7 +271,7 @@ |
1916 | # define UNIV_INTERN |
1917 | #endif |
1918 | |
1919 | -#if (!defined(UNIV_DEBUG) && !defined(UNIV_MUST_NOT_INLINE)) |
1920 | +#ifndef UNIV_MUST_NOT_INLINE |
1921 | /* Definition for inline version */ |
1922 | |
1923 | #ifdef __WIN__ |
1924 | @@ -331,6 +334,18 @@ |
1925 | longer names internally */ |
1926 | #define MAX_TABLE_NAME_LEN 192 |
1927 | |
1928 | +/* The maximum length of a database name. Like MAX_TABLE_NAME_LEN this is |
1929 | +the MySQL's NAME_LEN, see check_and_convert_db_name(). */ |
1930 | +#define MAX_DATABASE_NAME_LEN MAX_TABLE_NAME_LEN |
1931 | + |
1932 | +/* MAX_FULL_NAME_LEN defines the full name path including the |
1933 | +database name and table name. In addition, 14 bytes is added for: |
1934 | + 2 for surrounding quotes around table name |
1935 | + 1 for the separating dot (.) |
1936 | + 9 for the #mysql50# prefix */ |
1937 | +#define MAX_FULL_NAME_LEN \ |
1938 | + (MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN + 14) |
1939 | + |
1940 | /* |
1941 | UNIVERSAL TYPE DEFINITIONS |
1942 | ========================== |
1943 | |
1944 | === added file 'plugin/innobase/include/ut0bh.h' |
1945 | --- plugin/innobase/include/ut0bh.h 1970-01-01 00:00:00 +0000 |
1946 | +++ plugin/innobase/include/ut0bh.h 2012-05-22 12:41:18 +0000 |
1947 | @@ -0,0 +1,152 @@ |
1948 | +/***************************************************************************//** |
1949 | + |
1950 | +Copyright (c) 2011, Oracle Corpn. All Rights Reserved. |
1951 | + |
1952 | +This program is free software; you can redistribute it and/or modify it under |
1953 | +the terms of the GNU General Public License as published by the Free Software |
1954 | +Foundation; version 2 of the License. |
1955 | + |
1956 | +This program is distributed in the hope that it will be useful, but WITHOUT |
1957 | +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1958 | +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
1959 | + |
1960 | +You should have received a copy of the GNU General Public License along with |
1961 | +this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
1962 | +Place, Suite 330, Boston, MA 02111-1307 USA |
1963 | + |
1964 | +*****************************************************************************/ |
1965 | + |
1966 | +/******************************************************************//** |
1967 | +@file include/ut0bh.h |
1968 | +Binary min-heap interface. |
1969 | + |
1970 | +Created 2010-05-28 by Sunny Bains |
1971 | +*******************************************************/ |
1972 | + |
1973 | +#ifndef INNOBASE_UT0BH_H |
1974 | +#define INNOBASE_UT0BH_H |
1975 | + |
1976 | +#include "univ.i" |
1977 | + |
1978 | +/** Comparison function for objects in the binary heap. */ |
1979 | +typedef int (*ib_bh_cmp_t)(const void* p1, const void* p2); |
1980 | + |
1981 | +typedef struct ib_bh_struct ib_bh_t; |
1982 | + |
1983 | +/**********************************************************************//** |
1984 | +Get the number of elements in the binary heap. |
1985 | +@return number of elements */ |
1986 | +UNIV_INLINE |
1987 | +ulint |
1988 | +ib_bh_size( |
1989 | +/*=======*/ |
1990 | + const ib_bh_t* ib_bh); /*!< in: instance */ |
1991 | + |
1992 | +/**********************************************************************//** |
1993 | +Test if binary heap is empty. |
1994 | +@return TRUE if empty. */ |
1995 | +UNIV_INLINE |
1996 | +ibool |
1997 | +ib_bh_is_empty( |
1998 | +/*===========*/ |
1999 | + const ib_bh_t* ib_bh); /*!< in: instance */ |
2000 | + |
2001 | +/**********************************************************************//** |
2002 | +Test if binary heap is full. |
2003 | +@return TRUE if full. */ |
2004 | +UNIV_INLINE |
2005 | +ibool |
2006 | +ib_bh_is_full( |
2007 | +/*===========*/ |
2008 | + const ib_bh_t* ib_bh); /*!< in: instance */ |
2009 | + |
2010 | +/**********************************************************************//** |
2011 | +Get a pointer to the element. |
2012 | +@return pointer to element */ |
2013 | +UNIV_INLINE |
2014 | +void* |
2015 | +ib_bh_get( |
2016 | +/*=======*/ |
2017 | + ib_bh_t* ib_bh, /*!< in: instance */ |
2018 | + ulint i); /*!< in: index */ |
2019 | + |
2020 | +/**********************************************************************//** |
2021 | +Copy an element to the binary heap. |
2022 | +@return pointer to copied element */ |
2023 | +UNIV_INLINE |
2024 | +void* |
2025 | +ib_bh_set( |
2026 | +/*======*/ |
2027 | + ib_bh_t* ib_bh, /*!< in/out: instance */ |
2028 | + ulint i, /*!< in: index */ |
2029 | + const void* elem); /*!< in: element to add */ |
2030 | + |
2031 | +/**********************************************************************//** |
2032 | +Return the first element from the binary heap. |
2033 | +@return pointer to first element or NULL if empty. */ |
2034 | +UNIV_INLINE |
2035 | +void* |
2036 | +ib_bh_first( |
2037 | +/*========*/ |
2038 | + ib_bh_t* ib_bh); /*!< in: instance */ |
2039 | + |
2040 | +/**********************************************************************//** |
2041 | +Return the last element from the binary heap. |
2042 | +@return pointer to last element or NULL if empty. */ |
2043 | +UNIV_INLINE |
2044 | +void* |
2045 | +ib_bh_last( |
2046 | +/*========*/ |
2047 | + ib_bh_t* ib_bh); /*!< in/out: instance */ |
2048 | + |
2049 | +/**********************************************************************//** |
2050 | +Create a binary heap. |
2051 | +@return a new binary heap */ |
2052 | +UNIV_INTERN |
2053 | +ib_bh_t* |
2054 | +ib_bh_create( |
2055 | +/*=========*/ |
2056 | + ib_bh_cmp_t compare, /*!< in: comparator */ |
2057 | + ulint sizeof_elem, /*!< in: size of one element */ |
2058 | + ulint max_elems); /*!< in: max elements allowed */ |
2059 | + |
2060 | +/**********************************************************************//** |
2061 | +Free a binary heap. |
2062 | +@return a new binary heap */ |
2063 | +UNIV_INTERN |
2064 | +void |
2065 | +ib_bh_free( |
2066 | +/*=======*/ |
2067 | + ib_bh_t* ib_bh); /*!< in,own: instance */ |
2068 | + |
2069 | +/**********************************************************************//** |
2070 | +Add an element to the binary heap. Note: The element is copied. |
2071 | +@return pointer to added element or NULL if full. */ |
2072 | +UNIV_INTERN |
2073 | +void* |
2074 | +ib_bh_push( |
2075 | +/*=======*/ |
2076 | + ib_bh_t* ib_bh, /*!< in/out: instance */ |
2077 | + const void* elem); /*!< in: element to add */ |
2078 | + |
2079 | +/**********************************************************************//** |
2080 | +Remove the first element from the binary heap. */ |
2081 | +UNIV_INTERN |
2082 | +void |
2083 | +ib_bh_pop( |
2084 | +/*======*/ |
2085 | + ib_bh_t* ib_bh); /*!< in/out: instance */ |
2086 | + |
2087 | +/** Binary heap data structure */ |
2088 | +struct ib_bh_struct { |
2089 | + ulint max_elems; /*!< max elements allowed */ |
2090 | + ulint n_elems; /*!< current size */ |
2091 | + ulint sizeof_elem; /*!< sizeof element */ |
2092 | + ib_bh_cmp_t compare; /*!< comparator */ |
2093 | +}; |
2094 | + |
2095 | +#ifndef UNIV_NONINL |
2096 | +#include "ut0bh.ic" |
2097 | +#endif |
2098 | + |
2099 | +#endif /* INNOBASE_UT0BH_H */ |
2100 | |
2101 | === added file 'plugin/innobase/include/ut0bh.ic' |
2102 | --- plugin/innobase/include/ut0bh.ic 1970-01-01 00:00:00 +0000 |
2103 | +++ plugin/innobase/include/ut0bh.ic 2012-05-22 12:41:18 +0000 |
2104 | @@ -0,0 +1,125 @@ |
2105 | +/***************************************************************************//** |
2106 | +Copyright (c) 2011, Oracle Corpn. All Rights Reserved. |
2107 | + |
2108 | +This program is free software; you can redistribute it and/or modify it under |
2109 | +the terms of the GNU General Public License as published by the Free Software |
2110 | +Foundation; version 2 of the License. |
2111 | + |
2112 | +This program is distributed in the hope that it will be useful, but WITHOUT |
2113 | +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
2114 | +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
2115 | + |
2116 | +You should have received a copy of the GNU General Public License along with |
2117 | +this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
2118 | +Place, Suite 330, Boston, MA 02111-1307 USA |
2119 | + |
2120 | +*****************************************************************************/ |
2121 | + |
2122 | +/******************************************************************//** |
2123 | +@file include/ut0bh.ic |
2124 | +Binary min-heap implementation. |
2125 | + |
2126 | +Created 2011-01-15 by Sunny Bains |
2127 | +*******************************************************/ |
2128 | + |
2129 | +#include "ut0bh.h" |
2130 | +#include "ut0mem.h" /* For ut_memcpy() */ |
2131 | + |
2132 | +/**********************************************************************//** |
2133 | +Get the number of elements in the binary heap. |
2134 | +@return number of elements */ |
2135 | +UNIV_INLINE |
2136 | +ulint |
2137 | +ib_bh_size( |
2138 | +/*=======*/ |
2139 | + const ib_bh_t* ib_bh) /*!< in: instance */ |
2140 | +{ |
2141 | + return(ib_bh->n_elems); |
2142 | +} |
2143 | + |
2144 | +/**********************************************************************//** |
2145 | +Test if binary heap is empty. |
2146 | +@return TRUE if empty. */ |
2147 | +UNIV_INLINE |
2148 | +ibool |
2149 | +ib_bh_is_empty( |
2150 | +/*===========*/ |
2151 | + const ib_bh_t* ib_bh) /*!< in: instance */ |
2152 | +{ |
2153 | + return(ib_bh_size(ib_bh) == 0); |
2154 | +} |
2155 | + |
2156 | +/**********************************************************************//** |
2157 | +Test if binary heap is full. |
2158 | +@return TRUE if full. */ |
2159 | +UNIV_INLINE |
2160 | +ibool |
2161 | +ib_bh_is_full( |
2162 | +/*===========*/ |
2163 | + const ib_bh_t* ib_bh) /*!< in: instance */ |
2164 | +{ |
2165 | + return(ib_bh_size(ib_bh) >= ib_bh->max_elems); |
2166 | +} |
2167 | + |
2168 | +/**********************************************************************//** |
2169 | +Get a pointer to the element. |
2170 | +@return pointer to element */ |
2171 | +UNIV_INLINE |
2172 | +void* |
2173 | +ib_bh_get( |
2174 | +/*=======*/ |
2175 | + ib_bh_t* ib_bh, /*!< in: instance */ |
2176 | + ulint i) /*!< in: index */ |
2177 | +{ |
2178 | + byte* ptr = (byte*) (ib_bh + 1); |
2179 | + |
2180 | + ut_a(i < ib_bh_size(ib_bh)); |
2181 | + |
2182 | + return(ptr + (ib_bh->sizeof_elem * i)); |
2183 | +} |
2184 | + |
2185 | +/**********************************************************************//** |
2186 | +Copy an element to the binary heap. |
2187 | +@return pointer to copied element */ |
2188 | +UNIV_INLINE |
2189 | +void* |
2190 | +ib_bh_set( |
2191 | +/*======*/ |
2192 | + ib_bh_t* ib_bh, /*!< in/out: instance */ |
2193 | + ulint i, /*!< in: index */ |
2194 | + const void* elem) /*!< in: element to add */ |
2195 | +{ |
2196 | + void* ptr = ib_bh_get(ib_bh, i); |
2197 | + |
2198 | + ut_memcpy(ptr, elem, ib_bh->sizeof_elem); |
2199 | + |
2200 | + return(ptr); |
2201 | +} |
2202 | + |
2203 | +/**********************************************************************//** |
2204 | +Return the first element from the binary heap. |
2205 | +@return pointer to first element or NULL if empty. */ |
2206 | +UNIV_INLINE |
2207 | +void* |
2208 | +ib_bh_first( |
2209 | +/*========*/ |
2210 | + ib_bh_t* ib_bh) /*!< in: instance */ |
2211 | +{ |
2212 | + return(ib_bh_is_empty(ib_bh) ? NULL : ib_bh_get(ib_bh, 0)); |
2213 | +} |
2214 | + |
2215 | +/**********************************************************************//** |
2216 | +Return the last element from the binary heap. |
2217 | +@return pointer to last element or NULL if empty. */ |
2218 | +UNIV_INLINE |
2219 | +void* |
2220 | +ib_bh_last( |
2221 | +/*========*/ |
2222 | + ib_bh_t* ib_bh) /*!< in/out: instance */ |
2223 | +{ |
2224 | + return(ib_bh_is_empty(ib_bh) |
2225 | + ? NULL |
2226 | + : ib_bh_get(ib_bh, ib_bh_size(ib_bh) - 1)); |
2227 | +} |
2228 | + |
2229 | + |
2230 | |
2231 | === modified file 'plugin/innobase/include/ut0ut.h' |
2232 | --- plugin/innobase/include/ut0ut.h 2011-07-30 12:19:38 +0000 |
2233 | +++ plugin/innobase/include/ut0ut.h 2012-05-22 12:41:18 +0000 |
2234 | @@ -56,24 +56,24 @@ |
2235 | typedef time_t ib_time_t; |
2236 | |
2237 | #ifndef UNIV_HOTBACKUP |
2238 | -#if defined(HAVE_IB_PAUSE_INSTRUCTION) |
2239 | -# ifdef WIN32 |
2240 | - /* In the Win32 API, the x86 PAUSE instruction is executed by calling |
2241 | - the YieldProcessor macro defined in WinNT.h. It is a CPU architecture- |
2242 | - independent way by using YieldProcessor.*/ |
2243 | -# define UT_RELAX_CPU() YieldProcessor() |
2244 | -# else |
2245 | - /* According to the gcc info page, asm volatile means that the |
2246 | - instruction has important side-effects and must not be removed. |
2247 | - Also asm volatile may trigger a memory barrier (spilling all registers |
2248 | - to memory). */ |
2249 | -# define UT_RELAX_CPU() __asm__ __volatile__ ("pause") |
2250 | -# endif |
2251 | +#if defined(HAVE_PAUSE_INSTRUCTION) |
2252 | + /* According to the gcc info page, asm volatile means that the |
2253 | + instruction has important side-effects and must not be removed. |
2254 | + Also asm volatile may trigger a memory barrier (spilling all registers |
2255 | + to memory). */ |
2256 | +# define UT_RELAX_CPU() __asm__ __volatile__ ("pause") |
2257 | +#elif defined(HAVE_FAKE_PAUSE_INSTRUCTION) |
2258 | +# define UT_RELAX_CPU() __asm__ __volatile__ ("rep; nop") |
2259 | #elif defined(HAVE_ATOMIC_BUILTINS) |
2260 | # define UT_RELAX_CPU() do { \ |
2261 | volatile lint volatile_var; \ |
2262 | if (os_compare_and_swap_lint(&volatile_var, 0, 1)) ((void)0); \ |
2263 | } while (0) |
2264 | +#elif defined(HAVE_WINDOWS_ATOMICS) |
2265 | + /* In the Win32 API, the x86 PAUSE instruction is executed by calling |
2266 | + the YieldProcessor macro defined in WinNT.h. It is a CPU architecture- |
2267 | + independent way by using YieldProcessor. */ |
2268 | +# define UT_RELAX_CPU() YieldProcessor() |
2269 | #else |
2270 | # define UT_RELAX_CPU() ((void)0) /* avoid warning for an empty statement */ |
2271 | #endif |
2272 | |
2273 | === modified file 'plugin/innobase/include/ut0vec.h' |
2274 | --- plugin/innobase/include/ut0vec.h 2011-03-14 05:40:28 +0000 |
2275 | +++ plugin/innobase/include/ut0vec.h 2012-05-22 12:41:18 +0000 |
2276 | @@ -95,6 +95,25 @@ |
2277 | ulint n); /*!< in: element index to get */ |
2278 | |
2279 | /****************************************************************//** |
2280 | +Get last element. The vector must not be empty. |
2281 | +@return last element */ |
2282 | +UNIV_INLINE |
2283 | +void* |
2284 | +ib_vector_get_last( |
2285 | +/*===============*/ |
2286 | + ib_vector_t* vec); /*!< in: vector */ |
2287 | + |
2288 | +/****************************************************************//** |
2289 | +Set the n'th element. */ |
2290 | +UNIV_INLINE |
2291 | +void |
2292 | +ib_vector_set( |
2293 | +/*==========*/ |
2294 | + ib_vector_t* vec, /*!< in/out: vector */ |
2295 | + ulint n, /*!< in: element index to set */ |
2296 | + void* elem); /*!< in: data element */ |
2297 | + |
2298 | +/****************************************************************//** |
2299 | Remove the last element from the vector. */ |
2300 | UNIV_INLINE |
2301 | void* |
2302 | |
2303 | === modified file 'plugin/innobase/include/ut0vec.ic' |
2304 | --- plugin/innobase/include/ut0vec.ic 2010-12-18 04:43:40 +0000 |
2305 | +++ plugin/innobase/include/ut0vec.ic 2012-05-22 12:41:18 +0000 |
2306 | @@ -51,6 +51,35 @@ |
2307 | } |
2308 | |
2309 | /****************************************************************//** |
2310 | +Get last element. The vector must not be empty. |
2311 | +@return last element */ |
2312 | +UNIV_INLINE |
2313 | +void* |
2314 | +ib_vector_get_last( |
2315 | +/*===============*/ |
2316 | + ib_vector_t* vec) /*!< in: vector */ |
2317 | +{ |
2318 | + ut_a(vec->used > 0); |
2319 | + |
2320 | + return(vec->data[vec->used - 1]); |
2321 | +} |
2322 | + |
2323 | +/****************************************************************//** |
2324 | +Set the n'th element. */ |
2325 | +UNIV_INLINE |
2326 | +void |
2327 | +ib_vector_set( |
2328 | +/*==========*/ |
2329 | + ib_vector_t* vec, /*!< in/out: vector */ |
2330 | + ulint n, /*!< in: element index to set */ |
2331 | + void* elem) /*!< in: data element */ |
2332 | +{ |
2333 | + ut_a(n < vec->used); |
2334 | + |
2335 | + vec->data[n] = elem; |
2336 | +} |
2337 | + |
2338 | +/****************************************************************//** |
2339 | Remove the last element from the vector. |
2340 | @return last vector element */ |
2341 | UNIV_INLINE |
2342 | |
2343 | === modified file 'plugin/innobase/lock/lock0lock.cc' |
2344 | --- plugin/innobase/lock/lock0lock.cc 2010-12-26 03:44:24 +0000 |
2345 | +++ plugin/innobase/lock/lock0lock.cc 2012-05-22 12:41:18 +0000 |
2346 | @@ -3616,6 +3616,80 @@ |
2347 | } |
2348 | |
2349 | /*************************************************************//** |
2350 | +Pops autoinc lock requests from the transaction's autoinc_locks. We |
2351 | +handle the case where there are gaps in the array and they need to |
2352 | +be popped off the stack. */ |
2353 | +UNIV_INLINE |
2354 | +void |
2355 | +lock_table_pop_autoinc_locks( |
2356 | +/*=========================*/ |
2357 | + trx_t* trx) /*!< in/out: transaction that owns the AUTOINC locks */ |
2358 | +{ |
2359 | + ut_ad(mutex_own(&kernel_mutex)); |
2360 | + ut_ad(!ib_vector_is_empty(trx->autoinc_locks)); |
2361 | + |
2362 | + /* Skip any gaps, gaps are NULL lock entries in the |
2363 | + trx->autoinc_locks vector. */ |
2364 | + |
2365 | + do { |
2366 | + ib_vector_pop(trx->autoinc_locks); |
2367 | + |
2368 | + if (ib_vector_is_empty(trx->autoinc_locks)) { |
2369 | + return; |
2370 | + } |
2371 | + |
2372 | + } while (ib_vector_get_last(trx->autoinc_locks) == NULL); |
2373 | +} |
2374 | + |
2375 | +/*************************************************************//** |
2376 | +Removes an autoinc lock request from the transaction's autoinc_locks. */ |
2377 | +UNIV_INLINE |
2378 | +void |
2379 | +lock_table_remove_autoinc_lock( |
2380 | +/*===========================*/ |
2381 | + lock_t* lock, /*!< in: table lock */ |
2382 | + trx_t* trx) /*!< in/out: transaction that owns the lock */ |
2383 | +{ |
2384 | + lock_t* autoinc_lock; |
2385 | + lint i = ib_vector_size(trx->autoinc_locks) - 1; |
2386 | + |
2387 | + ut_ad(mutex_own(&kernel_mutex)); |
2388 | + ut_ad(lock_get_mode(lock) == LOCK_AUTO_INC); |
2389 | + ut_ad(lock_get_type_low(lock) & LOCK_TABLE); |
2390 | + ut_ad(!ib_vector_is_empty(trx->autoinc_locks)); |
2391 | + |
2392 | + /* With stored functions and procedures the user may drop |
2393 | + a table within the same "statement". This special case has |
2394 | + to be handled by deleting only those AUTOINC locks that were |
2395 | + held by the table being dropped. */ |
2396 | + |
2397 | + autoinc_lock = static_cast<ib_lock_t *>(ib_vector_get(trx->autoinc_locks, i)); |
2398 | + |
2399 | + /* This is the default fast case. */ |
2400 | + |
2401 | + if (autoinc_lock == lock) { |
2402 | + lock_table_pop_autoinc_locks(trx); |
2403 | + } else { |
2404 | + /* The last element should never be NULL */ |
2405 | + ut_a(autoinc_lock != NULL); |
2406 | + |
2407 | + /* Handle freeing the locks from within the stack. */ |
2408 | + |
2409 | + while (--i >= 0) { |
2410 | + autoinc_lock = static_cast<ib_lock_t *>(ib_vector_get(trx->autoinc_locks, i)); |
2411 | + |
2412 | + if (UNIV_LIKELY(autoinc_lock == lock)) { |
2413 | + ib_vector_set(trx->autoinc_locks, i, NULL); |
2414 | + return; |
2415 | + } |
2416 | + } |
2417 | + |
2418 | + /* Must find the autoinc lock. */ |
2419 | + ut_error; |
2420 | + } |
2421 | +} |
2422 | + |
2423 | +/*************************************************************//** |
2424 | Removes a table lock request from the queue and the trx list of locks; |
2425 | this is a low-level function which does NOT check if waiting requests |
2426 | can now be granted. */ |
2427 | @@ -3654,10 +3728,7 @@ |
2428 | |
2429 | if (!lock_get_wait(lock) |
2430 | && !ib_vector_is_empty(trx->autoinc_locks)) { |
2431 | - lock_t* autoinc_lock; |
2432 | - |
2433 | - autoinc_lock = static_cast<lock_t *>(ib_vector_pop(trx->autoinc_locks)); |
2434 | - ut_a(autoinc_lock == lock); |
2435 | + lock_table_remove_autoinc_lock(lock, trx); |
2436 | } |
2437 | |
2438 | ut_a(table->n_waiting_or_granted_auto_inc_locks > 0); |
2439 | |
2440 | === modified file 'plugin/innobase/log/log0recv.cc' |
2441 | --- plugin/innobase/log/log0recv.cc 2011-04-07 02:36:30 +0000 |
2442 | +++ plugin/innobase/log/log0recv.cc 2012-05-22 12:41:18 +0000 |
2443 | @@ -2207,7 +2207,7 @@ |
2444 | "InnoDB: far enough in recovery! Please run CHECK TABLE\n" |
2445 | "InnoDB: on your InnoDB tables to check that they are ok!\n" |
2446 | "InnoDB: If mysqld crashes after this recovery, look at\n" |
2447 | - "InnoDB: " REFMAN "forcing-recovery.html\n" |
2448 | + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" |
2449 | "InnoDB: about forcing recovery.\n", stderr); |
2450 | |
2451 | fflush(stderr); |
2452 | |
2453 | === modified file 'plugin/innobase/os/os0file.cc' |
2454 | --- plugin/innobase/os/os0file.cc 2011-04-07 05:47:57 +0000 |
2455 | +++ plugin/innobase/os/os0file.cc 2012-05-22 12:41:18 +0000 |
2456 | @@ -304,6 +304,36 @@ |
2457 | /** Number of pending read operations */ |
2458 | UNIV_INTERN ulint os_n_pending_reads = 0; |
2459 | |
2460 | +#ifdef UNIV_DEBUG |
2461 | +/**********************************************************************//** |
2462 | +Validates the consistency the aio system some of the time. |
2463 | +@return TRUE if ok or the check was skipped */ |
2464 | +UNIV_INTERN |
2465 | +ibool |
2466 | +os_aio_validate_skip(void) |
2467 | +/*======================*/ |
2468 | +{ |
2469 | +/** Try os_aio_validate() every this many times */ |
2470 | +# define OS_AIO_VALIDATE_SKIP 13 |
2471 | + |
2472 | + /** The os_aio_validate() call skip counter. |
2473 | + Use a signed type because of the race condition below. */ |
2474 | + static int os_aio_validate_count = OS_AIO_VALIDATE_SKIP; |
2475 | + |
2476 | + /* There is a race condition below, but it does not matter, |
2477 | + because this call is only for heuristic purposes. We want to |
2478 | + reduce the call frequency of the costly os_aio_validate() |
2479 | + check in debug builds. */ |
2480 | + if (--os_aio_validate_count > 0) { |
2481 | + return(TRUE); |
2482 | + } |
2483 | + |
2484 | + os_aio_validate_count = OS_AIO_VALIDATE_SKIP; |
2485 | + return(os_aio_validate()); |
2486 | +} |
2487 | +#endif /* UNIV_DEBUG */ |
2488 | + |
2489 | +#ifdef __WIN__ |
2490 | /***********************************************************************//** |
2491 | Gets the operating system version. Currently works only on Windows. |
2492 | @return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA, |
2493 | @@ -313,7 +343,6 @@ |
2494 | os_get_os_version(void) |
2495 | /*===================*/ |
2496 | { |
2497 | -#ifdef __WIN__ |
2498 | OSVERSIONINFO os_info; |
2499 | |
2500 | os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
2501 | @@ -342,12 +371,8 @@ |
2502 | ut_error; |
2503 | return(0); |
2504 | } |
2505 | -#else |
2506 | - ut_error; |
2507 | - |
2508 | - return(0); |
2509 | -#endif |
2510 | } |
2511 | +#endif /* __WIN__ */ |
2512 | |
2513 | /***********************************************************************//** |
2514 | Retrieves the last error number if an error occurs in a file io function. |
2515 | @@ -4032,7 +4057,7 @@ |
2516 | ut_ad(n > 0); |
2517 | ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0); |
2518 | ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); |
2519 | - ut_ad(os_aio_validate()); |
2520 | + ut_ad(os_aio_validate_skip()); |
2521 | #ifdef WIN_ASYNC_IO |
2522 | ut_ad((n & 0xFFFFFFFFUL) == n); |
2523 | #endif |
2524 | @@ -4236,7 +4261,7 @@ |
2525 | /* NOTE! We only access constant fields in os_aio_array. Therefore |
2526 | we do not have to acquire the protecting mutex yet */ |
2527 | |
2528 | - ut_ad(os_aio_validate()); |
2529 | + ut_ad(os_aio_validate_skip()); |
2530 | ut_ad(segment < array->n_segments); |
2531 | |
2532 | n = array->n_slots / array->n_segments; |
2533 | @@ -4657,7 +4682,7 @@ |
2534 | |
2535 | srv_set_io_thread_op_info(global_segment, |
2536 | "looking for i/o requests (a)"); |
2537 | - ut_ad(os_aio_validate()); |
2538 | + ut_ad(os_aio_validate_skip()); |
2539 | ut_ad(segment < array->n_segments); |
2540 | |
2541 | n = array->n_slots / array->n_segments; |
2542 | |
2543 | === modified file 'plugin/innobase/plugin.am' |
2544 | --- plugin/innobase/plugin.am 2011-04-06 16:21:39 +0000 |
2545 | +++ plugin/innobase/plugin.am 2012-05-22 12:41:18 +0000 |
2546 | @@ -193,6 +193,8 @@ |
2547 | plugin/innobase/include/ut0byte.h \ |
2548 | plugin/innobase/include/ut0byte.ic \ |
2549 | plugin/innobase/include/ut0dbg.h \ |
2550 | + plugin/innobase/include/ut0bh.h \ |
2551 | + plugin/innobase/include/ut0bh.ic \ |
2552 | plugin/innobase/include/ut0lst.h \ |
2553 | plugin/innobase/include/ut0mem.h \ |
2554 | plugin/innobase/include/ut0mem.ic \ |
2555 | @@ -319,6 +321,7 @@ |
2556 | plugin/innobase/trx/trx0undo.cc \ |
2557 | plugin/innobase/usr/usr0sess.cc \ |
2558 | plugin/innobase/ut/ut0byte.cc \ |
2559 | + plugin/innobase/ut/ut0bh.cc \ |
2560 | plugin/innobase/ut/ut0dbg.cc \ |
2561 | plugin/innobase/ut/ut0list.cc \ |
2562 | plugin/innobase/ut/ut0mem.cc \ |
2563 | |
2564 | === modified file 'plugin/innobase/row/row0ins.cc' |
2565 | --- plugin/innobase/row/row0ins.cc 2010-12-26 23:42:28 +0000 |
2566 | +++ plugin/innobase/row/row0ins.cc 2012-05-22 12:41:18 +0000 |
2567 | @@ -1526,7 +1526,7 @@ |
2568 | if (foreign->foreign_index == index) { |
2569 | |
2570 | if (foreign->referenced_table == NULL) { |
2571 | - dict_table_get(foreign->referenced_table_name, |
2572 | + dict_table_get(foreign->referenced_table_name_lookup, |
2573 | FALSE); |
2574 | } |
2575 | |
2576 | |
2577 | === modified file 'plugin/innobase/row/row0merge.cc' |
2578 | --- plugin/innobase/row/row0merge.cc 2011-04-05 10:32:12 +0000 |
2579 | +++ plugin/innobase/row/row0merge.cc 2012-05-22 12:41:18 +0000 |
2580 | @@ -2399,7 +2399,7 @@ |
2581 | { |
2582 | ulint err = DB_ERROR; |
2583 | pars_info_t* info; |
2584 | - char old_name[MAX_TABLE_NAME_LEN + 1]; |
2585 | + char old_name[MAX_FULL_NAME_LEN + 1]; |
2586 | |
2587 | ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); |
2588 | ut_ad(old_table != new_table); |
2589 | @@ -2414,7 +2414,7 @@ |
2590 | ut_print_timestamp(stderr); |
2591 | fprintf(stderr, "InnoDB: too long table name: '%s', " |
2592 | "max length is %d\n", old_table->name, |
2593 | - MAX_TABLE_NAME_LEN); |
2594 | + MAX_FULL_NAME_LEN); |
2595 | ut_error; |
2596 | } |
2597 | |
2598 | |
2599 | === modified file 'plugin/innobase/row/row0mysql.cc' |
2600 | --- plugin/innobase/row/row0mysql.cc 2010-12-26 23:42:28 +0000 |
2601 | +++ plugin/innobase/row/row0mysql.cc 2012-05-22 12:41:18 +0000 |
2602 | @@ -615,7 +615,7 @@ |
2603 | "InnoDB: If the mysqld server crashes" |
2604 | " after the startup or when\n" |
2605 | "InnoDB: you dump the tables, look at\n" |
2606 | - "InnoDB: " REFMAN "forcing-recovery.html" |
2607 | + "InnoDB: " REFMAN "forcing-innodb-recovery.html" |
2608 | " for help.\n", stderr); |
2609 | break; |
2610 | case DB_FOREIGN_EXCEED_MAX_CASCADE: |
2611 | @@ -3150,7 +3150,7 @@ |
2612 | |
2613 | if (foreign && trx->check_foreigns |
2614 | && !(drop_db && dict_tables_have_same_db( |
2615 | - name, foreign->foreign_table_name))) { |
2616 | + name, foreign->foreign_table_name_lookup))) { |
2617 | FILE* ef = dict_foreign_err_file; |
2618 | |
2619 | /* We only allow dropping a referenced table if |
2620 | |
2621 | === modified file 'plugin/innobase/row/row0purge.cc' |
2622 | --- plugin/innobase/row/row0purge.cc 2010-12-26 15:48:26 +0000 |
2623 | +++ plugin/innobase/row/row0purge.cc 2012-05-22 12:41:18 +0000 |
2624 | @@ -525,7 +525,7 @@ |
2625 | while (node->index != NULL) { |
2626 | index = node->index; |
2627 | |
2628 | - if (row_upd_changes_ord_field_binary(NULL, node->index, |
2629 | + if (row_upd_changes_ord_field_binary(NULL, NULL, node->index, |
2630 | node->update)) { |
2631 | /* Build the older version of the index entry */ |
2632 | entry = row_build_index_entry(node->row, NULL, |
2633 | |
2634 | === modified file 'plugin/innobase/row/row0umod.cc' |
2635 | --- plugin/innobase/row/row0umod.cc 2010-12-24 00:04:05 +0000 |
2636 | +++ plugin/innobase/row/row0umod.cc 2012-05-22 12:41:18 +0000 |
2637 | @@ -693,19 +693,18 @@ |
2638 | while (node->index != NULL) { |
2639 | index = node->index; |
2640 | |
2641 | - if (row_upd_changes_ord_field_binary(node->row, node->index, |
2642 | - node->update)) { |
2643 | + if (row_upd_changes_ord_field_binary( |
2644 | + node->row, node->ext, node->index, node->update)) { |
2645 | |
2646 | /* Build the newest version of the index entry */ |
2647 | entry = row_build_index_entry(node->row, node->ext, |
2648 | index, heap); |
2649 | if (UNIV_UNLIKELY(!entry)) { |
2650 | /* The server must have crashed in |
2651 | - row_upd_clust_rec_by_insert(), in |
2652 | - row_ins_index_entry_low() before |
2653 | - btr_store_big_rec_extern_fields() |
2654 | - has written the externally stored columns |
2655 | - (BLOBs) of the new clustered index entry. */ |
2656 | + row_upd_clust_rec_by_insert() before |
2657 | + the updated externally stored columns (BLOBs) |
2658 | + of the new clustered index entry were |
2659 | + written. */ |
2660 | |
2661 | /* The table must be in DYNAMIC or COMPRESSED |
2662 | format. REDUNDANT and COMPACT formats |
2663 | |
2664 | === modified file 'plugin/innobase/row/row0upd.cc' |
2665 | --- plugin/innobase/row/row0upd.cc 2010-12-27 18:39:11 +0000 |
2666 | +++ plugin/innobase/row/row0upd.cc 2012-05-22 12:41:18 +0000 |
2667 | @@ -248,7 +248,7 @@ |
2668 | foreign->n_fields))) { |
2669 | |
2670 | if (foreign->foreign_table == NULL) { |
2671 | - dict_table_get(foreign->foreign_table_name, |
2672 | + dict_table_get(foreign->foreign_table_name_lookup, |
2673 | FALSE); |
2674 | } |
2675 | |
2676 | @@ -1208,20 +1208,21 @@ |
2677 | row and the data values in update are not |
2678 | known when this function is called, e.g., at |
2679 | compile time */ |
2680 | + const row_ext_t*ext, /*!< NULL, or prefixes of the externally |
2681 | + stored columns in the old row */ |
2682 | dict_index_t* index, /*!< in: index of the record */ |
2683 | const upd_t* update) /*!< in: update vector for the row; NOTE: the |
2684 | field numbers in this MUST be clustered index |
2685 | positions! */ |
2686 | { |
2687 | - ulint n_unique; |
2688 | - ulint n_upd_fields; |
2689 | - ulint i, j; |
2690 | - dict_index_t* clust_index; |
2691 | + ulint n_unique; |
2692 | + ulint i; |
2693 | + const dict_index_t* clust_index; |
2694 | |
2695 | - ut_ad(update && index); |
2696 | + ut_ad(update); |
2697 | + ut_ad(index); |
2698 | |
2699 | n_unique = dict_index_get_n_unique(index); |
2700 | - n_upd_fields = upd_get_n_fields(update); |
2701 | |
2702 | clust_index = dict_table_get_first_index(index->table); |
2703 | |
2704 | @@ -1229,33 +1230,72 @@ |
2705 | |
2706 | const dict_field_t* ind_field; |
2707 | const dict_col_t* col; |
2708 | - ulint col_pos; |
2709 | ulint col_no; |
2710 | + const upd_field_t* upd_field; |
2711 | + const dfield_t* dfield; |
2712 | + dfield_t dfield_ext; |
2713 | + ulint dfield_len; |
2714 | + const byte* buf; |
2715 | |
2716 | ind_field = dict_index_get_nth_field(index, i); |
2717 | col = dict_field_get_col(ind_field); |
2718 | - col_pos = dict_col_get_clust_pos(col, clust_index); |
2719 | col_no = dict_col_get_no(col); |
2720 | |
2721 | - for (j = 0; j < n_upd_fields; j++) { |
2722 | - |
2723 | - const upd_field_t* upd_field |
2724 | - = upd_get_nth_field(update, j); |
2725 | - |
2726 | - /* Note that if the index field is a column prefix |
2727 | - then it may be that row does not contain an externally |
2728 | - stored part of the column value, and we cannot compare |
2729 | - the datas */ |
2730 | - |
2731 | - if (col_pos == upd_field->field_no |
2732 | - && (row == NULL |
2733 | - || ind_field->prefix_len > 0 |
2734 | - || !dfield_datas_are_binary_equal( |
2735 | - dtuple_get_nth_field(row, col_no), |
2736 | - &(upd_field->new_val)))) { |
2737 | - |
2738 | - return(TRUE); |
2739 | + upd_field = upd_get_field_by_field_no( |
2740 | + update, dict_col_get_clust_pos(col, clust_index)); |
2741 | + |
2742 | + if (upd_field == NULL) { |
2743 | + continue; |
2744 | + } |
2745 | + |
2746 | + if (row == NULL) { |
2747 | + ut_ad(ext == NULL); |
2748 | + return(TRUE); |
2749 | + } |
2750 | + |
2751 | + dfield = dtuple_get_nth_field(row, col_no); |
2752 | + |
2753 | + /* This treatment of column prefix indexes is loosely |
2754 | + based on row_build_index_entry(). */ |
2755 | + |
2756 | + if (UNIV_LIKELY(ind_field->prefix_len == 0) |
2757 | + || dfield_is_null(dfield)) { |
2758 | + /* do nothing special */ |
2759 | + } else if (UNIV_LIKELY_NULL(ext)) { |
2760 | + /* See if the column is stored externally. */ |
2761 | + buf = row_ext_lookup(ext, col_no, &dfield_len); |
2762 | + |
2763 | + ut_ad(col->ord_part); |
2764 | + |
2765 | + if (UNIV_LIKELY_NULL(buf)) { |
2766 | + if (UNIV_UNLIKELY(buf == field_ref_zero)) { |
2767 | + /* This should never happen, but |
2768 | + we try to fail safe here. */ |
2769 | + ut_ad(0); |
2770 | + return(TRUE); |
2771 | + } |
2772 | + |
2773 | + goto copy_dfield; |
2774 | } |
2775 | + } else if (dfield_is_ext(dfield)) { |
2776 | + dfield_len = dfield_get_len(dfield); |
2777 | + ut_a(dfield_len > BTR_EXTERN_FIELD_REF_SIZE); |
2778 | + dfield_len -= BTR_EXTERN_FIELD_REF_SIZE; |
2779 | + ut_a(dict_index_is_clust(index) |
2780 | + || ind_field->prefix_len <= dfield_len); |
2781 | + buf = static_cast<const unsigned char*>(dfield_get_data(dfield)); |
2782 | +copy_dfield: |
2783 | + ut_a(dfield_len > 0); |
2784 | + dfield_copy(&dfield_ext, dfield); |
2785 | + dfield_set_data(&dfield_ext, buf, dfield_len); |
2786 | + dfield = &dfield_ext; |
2787 | + } |
2788 | + |
2789 | + if (!dfield_datas_are_binary_equal( |
2790 | + dfield, &upd_field->new_val, |
2791 | + ind_field->prefix_len)) { |
2792 | + |
2793 | + return(TRUE); |
2794 | } |
2795 | } |
2796 | |
2797 | @@ -1339,7 +1379,7 @@ |
2798 | if (col_pos == upd_field->field_no |
2799 | && !dfield_datas_are_binary_equal( |
2800 | dtuple_get_nth_field(entry, i), |
2801 | - &(upd_field->new_val))) { |
2802 | + &upd_field->new_val, 0)) { |
2803 | |
2804 | return(TRUE); |
2805 | } |
2806 | @@ -1606,14 +1646,99 @@ |
2807 | ut_ad(!dict_index_is_clust(node->index)); |
2808 | |
2809 | if (node->state == UPD_NODE_UPDATE_ALL_SEC |
2810 | - || row_upd_changes_ord_field_binary(node->row, node->index, |
2811 | - node->update)) { |
2812 | + || row_upd_changes_ord_field_binary(node->row, node->ext, |
2813 | + node->index, node->update)) { |
2814 | return(row_upd_sec_index_entry(node, thr)); |
2815 | } |
2816 | |
2817 | return(DB_SUCCESS); |
2818 | } |
2819 | |
2820 | +#ifdef UNIV_DEBUG |
2821 | +# define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \ |
2822 | + row_upd_clust_rec_by_insert_inherit_func(rec,offsets,entry,update) |
2823 | +#else /* UNIV_DEBUG */ |
2824 | +# define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \ |
2825 | + row_upd_clust_rec_by_insert_inherit_func(entry,update) |
2826 | +#endif /* UNIV_DEBUG */ |
2827 | +/*******************************************************************//** |
2828 | +Mark non-updated off-page columns inherited when the primary key is |
2829 | +updated. We must mark them as inherited in entry, so that they are not |
2830 | +freed in a rollback. A limited version of this function used to be |
2831 | +called btr_cur_mark_dtuple_inherited_extern(). |
2832 | +@return TRUE if any columns were inherited */ |
2833 | +static __attribute__((warn_unused_result)) |
2834 | +ibool |
2835 | +row_upd_clust_rec_by_insert_inherit_func( |
2836 | +/*=====================================*/ |
2837 | +#ifdef UNIV_DEBUG |
2838 | + const rec_t* rec, /*!< in: old record, or NULL */ |
2839 | + const ulint* offsets,/*!< in: rec_get_offsets(rec), or NULL */ |
2840 | +#endif /* UNIV_DEBUG */ |
2841 | + dtuple_t* entry, /*!< in/out: updated entry to be |
2842 | + inserted into the clustered index */ |
2843 | + const upd_t* update) /*!< in: update vector */ |
2844 | +{ |
2845 | + ibool inherit = FALSE; |
2846 | + ulint i; |
2847 | + |
2848 | + ut_ad(!rec == !offsets); |
2849 | + ut_ad(!rec || rec_offs_any_extern(offsets)); |
2850 | + |
2851 | + for (i = 0; i < dtuple_get_n_fields(entry); i++) { |
2852 | + dfield_t* dfield = dtuple_get_nth_field(entry, i); |
2853 | + byte* data; |
2854 | + ulint len; |
2855 | + |
2856 | + ut_ad(!offsets |
2857 | + || !rec_offs_nth_extern(offsets, i) |
2858 | + == !dfield_is_ext(dfield) |
2859 | + || upd_get_field_by_field_no(update, i)); |
2860 | + if (!dfield_is_ext(dfield) |
2861 | + || upd_get_field_by_field_no(update, i)) { |
2862 | + continue; |
2863 | + } |
2864 | + |
2865 | +#ifdef UNIV_DEBUG |
2866 | + if (UNIV_LIKELY(rec != NULL)) { |
2867 | + const byte* rec_data |
2868 | + = rec_get_nth_field(rec, offsets, i, &len); |
2869 | + ut_ad(len == dfield_get_len(dfield)); |
2870 | + ut_ad(len != UNIV_SQL_NULL); |
2871 | + ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE); |
2872 | + |
2873 | + rec_data += len - BTR_EXTERN_FIELD_REF_SIZE; |
2874 | + |
2875 | + /* The pointer must not be zero. */ |
2876 | + ut_ad(memcmp(rec_data, field_ref_zero, |
2877 | + BTR_EXTERN_FIELD_REF_SIZE)); |
2878 | + /* The BLOB must be owned. */ |
2879 | + ut_ad(!(rec_data[BTR_EXTERN_LEN] |
2880 | + & BTR_EXTERN_OWNER_FLAG)); |
2881 | + } |
2882 | +#endif /* UNIV_DEBUG */ |
2883 | + |
2884 | + len = dfield_get_len(dfield); |
2885 | + ut_a(len != UNIV_SQL_NULL); |
2886 | + ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE); |
2887 | + data = static_cast<unsigned char*>(dfield_get_data(dfield)); |
2888 | + data += len - BTR_EXTERN_FIELD_REF_SIZE; |
2889 | + /* The pointer must not be zero. */ |
2890 | + ut_a(memcmp(data, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE)); |
2891 | + /* The BLOB must be owned. */ |
2892 | + ut_a(!(data[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG)); |
2893 | + |
2894 | + data[BTR_EXTERN_LEN] |= BTR_EXTERN_INHERITED_FLAG; |
2895 | + /* The BTR_EXTERN_INHERITED_FLAG only matters in |
2896 | + rollback. Purge will always free the extern fields of |
2897 | + a delete-marked row. */ |
2898 | + |
2899 | + inherit = TRUE; |
2900 | + } |
2901 | + |
2902 | + return(inherit); |
2903 | +} |
2904 | + |
2905 | /***********************************************************//** |
2906 | Marks the clustered index record deleted and inserts the updated version |
2907 | of the record to the index. This function should be used when the ordering |
2908 | @@ -1632,14 +1757,16 @@ |
2909 | a foreign key constraint */ |
2910 | mtr_t* mtr) /*!< in/out: mtr; gets committed here */ |
2911 | { |
2912 | - mem_heap_t* heap = NULL; |
2913 | + mem_heap_t* heap; |
2914 | btr_pcur_t* pcur; |
2915 | btr_cur_t* btr_cur; |
2916 | trx_t* trx; |
2917 | dict_table_t* table; |
2918 | dtuple_t* entry; |
2919 | ulint err; |
2920 | - ibool change_ownership = FALSE; |
2921 | + ibool change_ownership = FALSE; |
2922 | + rec_t* rec; |
2923 | + ulint* offsets = NULL; |
2924 | |
2925 | ut_ad(node); |
2926 | ut_ad(dict_index_is_clust(index)); |
2927 | @@ -1649,82 +1776,115 @@ |
2928 | pcur = node->pcur; |
2929 | btr_cur = btr_pcur_get_btr_cur(pcur); |
2930 | |
2931 | - if (node->state != UPD_NODE_INSERT_CLUSTERED) { |
2932 | - rec_t* rec; |
2933 | - dict_index_t* node_index; |
2934 | - ulint offsets_[REC_OFFS_NORMAL_SIZE]; |
2935 | - ulint* offsets; |
2936 | - rec_offs_init(offsets_); |
2937 | - |
2938 | - err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, |
2939 | - btr_cur, TRUE, thr, mtr); |
2940 | + heap = mem_heap_create(1000); |
2941 | + |
2942 | + |
2943 | + entry = row_build_index_entry(node->upd_row, node->upd_ext, |
2944 | + index, heap); |
2945 | + ut_a(entry); |
2946 | + |
2947 | + row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id); |
2948 | + |
2949 | + switch (node->state) { |
2950 | + default: |
2951 | + ut_error; |
2952 | + case UPD_NODE_INSERT_BLOB: |
2953 | + /* A lock wait occurred in row_ins_index_entry() in |
2954 | + the previous invocation of this function. Mark the |
2955 | + off-page columns in the entry inherited. */ |
2956 | + |
2957 | + change_ownership = row_upd_clust_rec_by_insert_inherit( |
2958 | + NULL, NULL, entry, node->update); |
2959 | + ut_a(change_ownership); |
2960 | + /* fall through */ |
2961 | + case UPD_NODE_INSERT_CLUSTERED: |
2962 | + /* A lock wait occurred in row_ins_index_entry() in |
2963 | + the previous invocation of this function. */ |
2964 | + break; |
2965 | + case UPD_NODE_UPDATE_CLUSTERED: |
2966 | + /* This is the first invocation of the function where |
2967 | + we update the primary key. Delete-mark the old record |
2968 | + in the clustered index and prepare to insert a new entry. */ |
2969 | + rec = btr_cur_get_rec(btr_cur); |
2970 | + offsets = rec_get_offsets(rec, index, NULL, |
2971 | + ULINT_UNDEFINED, &heap); |
2972 | + ut_ad(page_rec_is_user_rec(rec)); |
2973 | + |
2974 | + err = btr_cur_del_mark_set_clust_rec( |
2975 | + BTR_NO_LOCKING_FLAG, btr_cur_get_block(btr_cur), |
2976 | + rec, index, offsets, TRUE, thr, mtr); |
2977 | if (err != DB_SUCCESS) { |
2978 | + err_exit: |
2979 | mtr_commit(mtr); |
2980 | + mem_heap_free(heap); |
2981 | return(err); |
2982 | } |
2983 | |
2984 | - /* Mark as not-owned the externally stored fields which the new |
2985 | - row inherits from the delete marked record: purge should not |
2986 | - free those externally stored fields even if the delete marked |
2987 | - record is removed from the index tree, or updated. */ |
2988 | - |
2989 | - rec = btr_cur_get_rec(btr_cur); |
2990 | - node_index = dict_table_get_first_index(table); |
2991 | - offsets = rec_get_offsets(rec, node_index, offsets_, |
2992 | - ULINT_UNDEFINED, &heap); |
2993 | - change_ownership = btr_cur_mark_extern_inherited_fields( |
2994 | - btr_cur_get_page_zip(btr_cur), rec, node_index, offsets, |
2995 | - node->update, mtr); |
2996 | + /* If the the new row inherits externally stored |
2997 | + fields (off-page columns a.k.a. BLOBs) from the |
2998 | + delete-marked old record, mark them disowned by the |
2999 | + old record and owned by the new entry. */ |
3000 | + |
3001 | + if (rec_offs_any_extern(offsets)) { |
3002 | + change_ownership = row_upd_clust_rec_by_insert_inherit( |
3003 | + rec, offsets, entry, node->update); |
3004 | + |
3005 | + if (change_ownership) { |
3006 | + btr_pcur_store_position(pcur, mtr); |
3007 | + } |
3008 | + } |
3009 | + |
3010 | if (referenced) { |
3011 | /* NOTE that the following call loses |
3012 | the position of pcur ! */ |
3013 | |
3014 | err = row_upd_check_references_constraints( |
3015 | - node, pcur, table, node_index, offsets, thr, mtr); |
3016 | + node, pcur, table, index, offsets, thr, mtr); |
3017 | |
3018 | if (err != DB_SUCCESS) { |
3019 | - |
3020 | - mtr_commit(mtr); |
3021 | - |
3022 | - if (UNIV_LIKELY_NULL(heap)) { |
3023 | - mem_heap_free(heap); |
3024 | - } |
3025 | - |
3026 | - return(err); |
3027 | + goto err_exit; |
3028 | } |
3029 | } |
3030 | } |
3031 | |
3032 | mtr_commit(mtr); |
3033 | |
3034 | - if (!heap) { |
3035 | - heap = mem_heap_create(500); |
3036 | - } |
3037 | - node->state = UPD_NODE_INSERT_CLUSTERED; |
3038 | - |
3039 | - entry = row_build_index_entry(node->upd_row, node->upd_ext, |
3040 | - index, heap); |
3041 | - ut_a(entry); |
3042 | - |
3043 | - row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id); |
3044 | - |
3045 | - if (change_ownership) { |
3046 | - /* If we return from a lock wait, for example, we may have |
3047 | - extern fields marked as not-owned in entry (marked in the |
3048 | - if-branch above). We must unmark them, take the ownership |
3049 | - back. */ |
3050 | - |
3051 | - btr_cur_unmark_dtuple_extern_fields(entry); |
3052 | - |
3053 | - /* We must mark non-updated extern fields in entry as |
3054 | - inherited, so that a possible rollback will not free them. */ |
3055 | - |
3056 | - btr_cur_mark_dtuple_inherited_extern(entry, node->update); |
3057 | - } |
3058 | - |
3059 | err = row_ins_index_entry(index, entry, |
3060 | node->upd_ext ? node->upd_ext->n_ext : 0, |
3061 | TRUE, thr); |
3062 | + node->state = change_ownership |
3063 | + ? UPD_NODE_INSERT_BLOB |
3064 | + : UPD_NODE_INSERT_CLUSTERED; |
3065 | + |
3066 | + if (err == DB_SUCCESS && change_ownership) { |
3067 | + /* Mark the non-updated fields disowned by the old record. */ |
3068 | + |
3069 | + /* NOTE: this transaction has an x-lock on the record |
3070 | + and therefore other transactions cannot modify the |
3071 | + record when we have no latch on the page. In addition, |
3072 | + we assume that other query threads of the same |
3073 | + transaction do not modify the record in the meantime. |
3074 | + Therefore we can assert that the restoration of the |
3075 | + cursor succeeds. */ |
3076 | + |
3077 | + mtr_start(mtr); |
3078 | + |
3079 | + if (!btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr)) { |
3080 | + ut_error; |
3081 | + } |
3082 | + |
3083 | + rec = btr_cur_get_rec(btr_cur); |
3084 | + offsets = rec_get_offsets(rec, index, offsets, |
3085 | + ULINT_UNDEFINED, &heap); |
3086 | + ut_ad(page_rec_is_user_rec(rec)); |
3087 | + |
3088 | + btr_cur_disown_inherited_fields( |
3089 | + btr_cur_get_page_zip(btr_cur), |
3090 | + rec, index, offsets, node->update, mtr); |
3091 | + |
3092 | + mtr_commit(mtr); |
3093 | + } |
3094 | + |
3095 | mem_heap_free(heap); |
3096 | |
3097 | return(err); |
3098 | @@ -1869,8 +2029,9 @@ |
3099 | /* Mark the clustered index record deleted; we do not have to check |
3100 | locks, because we assume that we have an x-lock on the record */ |
3101 | |
3102 | - err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, |
3103 | - btr_cur, TRUE, thr, mtr); |
3104 | + err = btr_cur_del_mark_set_clust_rec( |
3105 | + BTR_NO_LOCKING_FLAG, btr_cur_get_block(btr_cur), |
3106 | + btr_cur_get_rec(btr_cur), index, offsets, TRUE, thr, mtr); |
3107 | if (err == DB_SUCCESS && referenced) { |
3108 | /* NOTE that the following call loses the position of pcur ! */ |
3109 | |
3110 | @@ -2015,7 +2176,8 @@ |
3111 | |
3112 | row_upd_store_row(node); |
3113 | |
3114 | - if (row_upd_changes_ord_field_binary(node->row, index, node->update)) { |
3115 | + if (row_upd_changes_ord_field_binary(node->row, node->ext, index, |
3116 | + node->update)) { |
3117 | |
3118 | /* Update causes an ordering field (ordering fields within |
3119 | the B-tree) of the clustered index record to change: perform |
3120 | @@ -2085,7 +2247,8 @@ |
3121 | } |
3122 | |
3123 | if (node->state == UPD_NODE_UPDATE_CLUSTERED |
3124 | - || node->state == UPD_NODE_INSERT_CLUSTERED) { |
3125 | + || node->state == UPD_NODE_INSERT_CLUSTERED |
3126 | + || node->state == UPD_NODE_INSERT_BLOB) { |
3127 | |
3128 | log_free_check(); |
3129 | err = row_upd_clust_step(node, thr); |
3130 | |
3131 | === modified file 'plugin/innobase/srv/srv0srv.cc' |
3132 | --- plugin/innobase/srv/srv0srv.cc 2011-07-30 09:20:56 +0000 |
3133 | +++ plugin/innobase/srv/srv0srv.cc 2012-05-22 12:41:18 +0000 |
3134 | @@ -88,9 +88,11 @@ |
3135 | #include "trx0i_s.h" |
3136 | #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */ |
3137 | |
3138 | -/* This is set to TRUE if the MySQL user has set it in MySQL; currently |
3139 | -affects only FOREIGN KEY definition parsing */ |
3140 | -UNIV_INTERN ibool srv_lower_case_table_names = FALSE; |
3141 | +/* This is set to the MySQL server value for this variable. It is only |
3142 | +needed for FOREIGN KEY definition parsing since FOREIGN KEY names are not |
3143 | +stored in the server metadata. The server stores and enforces it for |
3144 | +regular database and table names.*/ |
3145 | +UNIV_INTERN uint srv_lower_case_table_names = 0; |
3146 | |
3147 | /* The following counter is incremented whenever there is some user activity |
3148 | in the server */ |
3149 | @@ -894,6 +896,7 @@ |
3150 | |
3151 | ut_a(type > 0); |
3152 | ut_a(type <= SRV_MASTER); |
3153 | + ut_ad(mutex_own(&kernel_mutex)); |
3154 | |
3155 | i = 0; |
3156 | slot = srv_table_get_nth_slot(i); |
3157 | @@ -1045,6 +1048,37 @@ |
3158 | } |
3159 | |
3160 | /*********************************************************************//** |
3161 | +Check whether thread type has reserved a slot. Return the first slot that |
3162 | +is found. This works because we currently have only 1 thread of each type. |
3163 | +@return slot number or ULINT_UNDEFINED if not found*/ |
3164 | +UNIV_INTERN |
3165 | +ulint |
3166 | +srv_thread_has_reserved_slot( |
3167 | +/*=========================*/ |
3168 | + enum srv_thread_type type) /*!< in: thread type to check */ |
3169 | +{ |
3170 | + ulint i; |
3171 | + ulint slot_no = ULINT_UNDEFINED; |
3172 | + |
3173 | + mutex_enter(&kernel_mutex); |
3174 | + |
3175 | + for (i = 0; i < OS_THREAD_MAX_N; i++) { |
3176 | + srv_slot_t* slot; |
3177 | + |
3178 | + slot = srv_table_get_nth_slot(i); |
3179 | + |
3180 | + if (slot->in_use && slot->type == type) { |
3181 | + slot_no = i; |
3182 | + break; |
3183 | + } |
3184 | + } |
3185 | + |
3186 | + mutex_exit(&kernel_mutex); |
3187 | + |
3188 | + return(slot_no); |
3189 | +} |
3190 | + |
3191 | +/*********************************************************************//** |
3192 | Initializes the server. */ |
3193 | UNIV_INTERN |
3194 | void |
3195 | @@ -2753,10 +2787,10 @@ |
3196 | srv_main_thread_process_no = os_proc_get_number(); |
3197 | srv_main_thread_id = os_thread_pf(os_thread_get_curr_id()); |
3198 | |
3199 | + mutex_enter(&kernel_mutex); |
3200 | + |
3201 | srv_table_reserve_slot(SRV_MASTER); |
3202 | |
3203 | - mutex_enter(&kernel_mutex); |
3204 | - |
3205 | srv_n_threads_active[SRV_MASTER]++; |
3206 | |
3207 | mutex_exit(&kernel_mutex); |
3208 | |
3209 | === modified file 'plugin/innobase/srv/srv0start.cc' |
3210 | --- plugin/innobase/srv/srv0start.cc 2011-07-30 09:20:56 +0000 |
3211 | +++ plugin/innobase/srv/srv0start.cc 2012-05-22 12:41:18 +0000 |
3212 | @@ -1292,7 +1292,7 @@ |
3213 | drizzled::errmsg_printf(drizzled::error::INFO, "InnoDB: Completed initialization of buffer pool"); |
3214 | |
3215 | if (err != DB_SUCCESS) { |
3216 | - drizzled::errmsg_printf(drizzled::error::ERROR, "InnoDB: Fatal error: cannot allocate the memory for the buffer pool"); |
3217 | + drizzled::errmsg_printf(drizzled::error::ERROR, "InnoDB: Fatal error: cannot allocate memory for the buffer pool"); |
3218 | |
3219 | return(DB_ERROR); |
3220 | } |
3221 | @@ -1697,6 +1697,24 @@ |
3222 | os_thread_create(&srv_purge_thread, NULL, NULL); |
3223 | } |
3224 | |
3225 | + /* Wait for the purge and master thread to startup. */ |
3226 | + |
3227 | + while (srv_shutdown_state == SRV_SHUTDOWN_NONE) { |
3228 | + if (srv_thread_has_reserved_slot(SRV_MASTER) == ULINT_UNDEFINED |
3229 | + || (srv_n_purge_threads == 1 |
3230 | + && srv_thread_has_reserved_slot(SRV_WORKER) |
3231 | + == ULINT_UNDEFINED)) { |
3232 | + |
3233 | + ut_print_timestamp(stderr); |
3234 | + fprintf(stderr, " InnoDB: " |
3235 | + "Waiting for the background threads to " |
3236 | + "start\n"); |
3237 | + os_thread_sleep(1000000); |
3238 | + } else { |
3239 | + break; |
3240 | + } |
3241 | + } |
3242 | + |
3243 | #ifdef UNIV_DEBUG |
3244 | /* buf_debug_prints = TRUE; */ |
3245 | #endif /* UNIV_DEBUG */ |
3246 | |
3247 | === modified file 'plugin/innobase/sync/sync0arr.cc' |
3248 | --- plugin/innobase/sync/sync0arr.cc 2010-12-26 00:22:34 +0000 |
3249 | +++ plugin/innobase/sync/sync0arr.cc 2012-05-22 12:41:18 +0000 |
3250 | @@ -590,9 +590,6 @@ |
3251 | ulint depth) /*!< in: recursion depth */ |
3252 | { |
3253 | sync_cell_t* new; |
3254 | - ibool ret; |
3255 | - |
3256 | - depth++; |
3257 | |
3258 | if (pass != 0) { |
3259 | /* If pass != 0, then we do not know which threads are |
3260 | @@ -604,7 +601,7 @@ |
3261 | |
3262 | new = sync_array_find_thread(arr, thread); |
3263 | |
3264 | - if (new == start) { |
3265 | + if (UNIV_UNLIKELY(new == start)) { |
3266 | /* Stop running of other threads */ |
3267 | |
3268 | ut_dbg_stop_threads = TRUE; |
3269 | @@ -616,11 +613,7 @@ |
3270 | return(TRUE); |
3271 | |
3272 | } else if (new) { |
3273 | - ret = sync_array_detect_deadlock(arr, start, new, depth); |
3274 | - |
3275 | - if (ret) { |
3276 | - return(TRUE); |
3277 | - } |
3278 | + return(sync_array_detect_deadlock(arr, start, new, depth + 1)); |
3279 | } |
3280 | return(FALSE); |
3281 | } |
3282 | @@ -930,12 +923,25 @@ |
3283 | ulint fatal_timeout = srv_fatal_semaphore_wait_threshold; |
3284 | ibool fatal = FALSE; |
3285 | |
3286 | +#ifdef UNIV_DEBUG_VALGRIND |
3287 | + /* Increase the timeouts if running under valgrind because it executes |
3288 | + extremely slowly. UNIV_DEBUG_VALGRIND does not necessary mean that |
3289 | + we are running under valgrind but we have no better way to tell. |
3290 | + See Bug#58432 innodb.innodb_bug56143 fails under valgrind |
3291 | + for an example */ |
3292 | +# define SYNC_ARRAY_TIMEOUT 2400 |
3293 | + fatal_timeout *= 10; |
3294 | +#else |
3295 | +# define SYNC_ARRAY_TIMEOUT 240 |
3296 | +#endif |
3297 | + |
3298 | for (i = 0; i < sync_primary_wait_array->n_cells; i++) { |
3299 | |
3300 | cell = sync_array_get_nth_cell(sync_primary_wait_array, i); |
3301 | |
3302 | if (cell->wait_object != NULL && cell->waiting |
3303 | - && difftime(time(NULL), cell->reservation_time) > 240) { |
3304 | + && difftime(time(NULL), cell->reservation_time) |
3305 | + > SYNC_ARRAY_TIMEOUT) { |
3306 | fputs("InnoDB: Warning: a long semaphore wait:\n", |
3307 | stderr); |
3308 | sync_array_cell_print(stderr, cell); |
3309 | @@ -977,6 +983,8 @@ |
3310 | " to the standard error stream\n"); |
3311 | } |
3312 | |
3313 | +#undef SYNC_ARRAY_TIMEOUT |
3314 | + |
3315 | return(fatal); |
3316 | } |
3317 | |
3318 | |
3319 | === modified file 'plugin/innobase/trx/trx0i_s.cc' |
3320 | --- plugin/innobase/trx/trx0i_s.cc 2011-02-17 00:14:13 +0000 |
3321 | +++ plugin/innobase/trx/trx0i_s.cc 2012-05-22 12:41:18 +0000 |
3322 | @@ -447,7 +447,7 @@ |
3323 | /* record lock */ |
3324 | ut_ad(!strcmp("RECORD", row->lock_type)); |
3325 | ut_ad(row->lock_index != NULL); |
3326 | - ut_ad(row->lock_data != NULL); |
3327 | + /* row->lock_data == NULL if buf_page_try_get() == NULL */ |
3328 | ut_ad(row->lock_page != ULINT_UNDEFINED); |
3329 | ut_ad(row->lock_rec != ULINT_UNDEFINED); |
3330 | } |
3331 | @@ -513,7 +513,6 @@ |
3332 | stmt= trx->mysql_thd->getQueryStringCopy(stmt_len); |
3333 | |
3334 | if (stmt != NULL) { |
3335 | - |
3336 | char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1]; |
3337 | |
3338 | if (stmt_len > TRX_I_S_TRX_QUERY_MAX_LEN) { |
3339 | |
3340 | === added file 'plugin/innobase/ut/ut0bh.cc' |
3341 | --- plugin/innobase/ut/ut0bh.cc 1970-01-01 00:00:00 +0000 |
3342 | +++ plugin/innobase/ut/ut0bh.cc 2012-05-22 12:41:18 +0000 |
3343 | @@ -0,0 +1,164 @@ |
3344 | +/***************************************************************************//** |
3345 | +Copyright (c) 2010, 2011, Oracle Corpn. All Rights Reserved. |
3346 | + |
3347 | +Portions of this file contain modifications contributed and copyrighted by |
3348 | +Sun Microsystems, Inc. Those modifications are gratefully acknowledged and |
3349 | +are described briefly in the InnoDB documentation. The contributions by |
3350 | +Sun Microsystems are incorporated with their permission, and subject to the |
3351 | +conditions contained in the file COPYING.Sun_Microsystems. |
3352 | + |
3353 | +This program is free software; you can redistribute it and/or modify it under |
3354 | +the terms of the GNU General Public License as published by the Free Software |
3355 | +Foundation; version 2 of the License. |
3356 | + |
3357 | +This program is distributed in the hope that it will be useful, but WITHOUT |
3358 | +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
3359 | +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
3360 | + |
3361 | +You should have received a copy of the GNU General Public License along with |
3362 | +this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
3363 | +Place, Suite 330, Boston, MA 02111-1307 USA |
3364 | + |
3365 | +*****************************************************************************/ |
3366 | + |
3367 | +/******************************************************************//** |
3368 | +@file ut/ut0bh.c |
3369 | +Binary min-heap implementation. |
3370 | + |
3371 | +Created 2010-05-28 by Sunny Bains |
3372 | +*******************************************************/ |
3373 | + |
3374 | +#include "ut0bh.h" |
3375 | +#include "ut0mem.h" |
3376 | + |
3377 | +#ifdef UNIV_NONINL |
3378 | +#include "ut0bh.ic" |
3379 | +#endif |
3380 | + |
3381 | +#include <string.h> |
3382 | + |
3383 | +/**********************************************************************//** |
3384 | +Create a binary heap. |
3385 | +@return a new binary heap */ |
3386 | +UNIV_INTERN |
3387 | +ib_bh_t* |
3388 | +ib_bh_create( |
3389 | +/*=========*/ |
3390 | + ib_bh_cmp_t compare, /*!< in: comparator */ |
3391 | + ulint sizeof_elem, /*!< in: size of one element */ |
3392 | + ulint max_elems) /*!< in: max elements allowed */ |
3393 | +{ |
3394 | + ulint sz; |
3395 | + ib_bh_t* ib_bh; |
3396 | + |
3397 | + sz = sizeof(*ib_bh) + (sizeof_elem * max_elems); |
3398 | + |
3399 | + ib_bh = (ib_bh_t*) ut_malloc(sz); |
3400 | + memset(ib_bh, 0x0, sz); |
3401 | + |
3402 | + ib_bh->compare = compare; |
3403 | + ib_bh->max_elems = max_elems; |
3404 | + ib_bh->sizeof_elem = sizeof_elem; |
3405 | + |
3406 | + return(ib_bh); |
3407 | +} |
3408 | + |
3409 | +/**********************************************************************//** |
3410 | +Free a binary heap. |
3411 | +@return a new binary heap */ |
3412 | +UNIV_INTERN |
3413 | +void |
3414 | +ib_bh_free( |
3415 | +/*=======*/ |
3416 | + ib_bh_t* ib_bh) /*!< in/own: instance */ |
3417 | +{ |
3418 | + ut_free(ib_bh); |
3419 | +} |
3420 | + |
3421 | +/**********************************************************************//** |
3422 | +Add an element to the binary heap. Note: The element is copied. |
3423 | +@return pointer to added element or NULL if full. */ |
3424 | +UNIV_INTERN |
3425 | +void* |
3426 | +ib_bh_push( |
3427 | +/*=======*/ |
3428 | + ib_bh_t* ib_bh, /*!< in/out: instance */ |
3429 | + const void* elem) /*!< in: element to add */ |
3430 | +{ |
3431 | + void* ptr; |
3432 | + |
3433 | + if (ib_bh_is_full(ib_bh)) { |
3434 | + return(NULL); |
3435 | + } else if (ib_bh_is_empty(ib_bh)) { |
3436 | + ++ib_bh->n_elems; |
3437 | + return(ib_bh_set(ib_bh, 0, elem)); |
3438 | + } else { |
3439 | + ulint i; |
3440 | + |
3441 | + i = ib_bh->n_elems; |
3442 | + |
3443 | + ++ib_bh->n_elems; |
3444 | + |
3445 | + for (ptr = ib_bh_get(ib_bh, i >> 1); |
3446 | + i > 0 && ib_bh->compare(ptr, elem) > 0; |
3447 | + i >>= 1, ptr = ib_bh_get(ib_bh, i >> 1)) { |
3448 | + |
3449 | + ib_bh_set(ib_bh, i, ptr); |
3450 | + } |
3451 | + |
3452 | + ptr = ib_bh_set(ib_bh, i, elem); |
3453 | + } |
3454 | + |
3455 | + return(ptr); |
3456 | +} |
3457 | + |
3458 | +/**********************************************************************//** |
3459 | +Remove the first element from the binary heap. */ |
3460 | +UNIV_INTERN |
3461 | +void |
3462 | +ib_bh_pop( |
3463 | +/*======*/ |
3464 | + ib_bh_t* ib_bh) /*!< in/out: instance */ |
3465 | +{ |
3466 | + byte* ptr; |
3467 | + byte* last; |
3468 | + ulint parent = 0; |
3469 | + |
3470 | + if (ib_bh_is_empty(ib_bh)) { |
3471 | + return; |
3472 | + } else if (ib_bh_size(ib_bh) == 1) { |
3473 | + --ib_bh->n_elems; |
3474 | + return; |
3475 | + } |
3476 | + |
3477 | + last = (byte*) ib_bh_last(ib_bh); |
3478 | + |
3479 | + /* Start from the child node */ |
3480 | + ptr = (byte*) ib_bh_get(ib_bh, 1); |
3481 | + |
3482 | + while (ptr < last) { |
3483 | + /* If the "right" child node is < "left" child node */ |
3484 | + if (ib_bh->compare(ptr + ib_bh->sizeof_elem, ptr) < 0) { |
3485 | + ptr += ib_bh->sizeof_elem; |
3486 | + } |
3487 | + |
3488 | + if (ib_bh->compare(last, ptr) <= 0) { |
3489 | + break; |
3490 | + } |
3491 | + |
3492 | + ib_bh_set(ib_bh, parent, ptr); |
3493 | + |
3494 | + parent = (ptr - (byte*) ib_bh_first(ib_bh)) |
3495 | + / ib_bh->sizeof_elem; |
3496 | + |
3497 | + if ((parent << 1) >= ib_bh_size(ib_bh)) { |
3498 | + break; |
3499 | + } |
3500 | + |
3501 | + ptr = (byte*) ib_bh_get(ib_bh, parent << 1); |
3502 | + } |
3503 | + |
3504 | + --ib_bh->n_elems; |
3505 | + |
3506 | + ib_bh_set(ib_bh, parent, last); |
3507 | +} |
3508 | |
3509 | === modified file 'plugin/innobase/ut/ut0dbg.cc' |
3510 | --- plugin/innobase/ut/ut0dbg.cc 2010-12-24 02:12:29 +0000 |
3511 | +++ plugin/innobase/ut/ut0dbg.cc 2012-05-22 12:41:18 +0000 |
3512 | @@ -77,7 +77,7 @@ |
3513 | " or crashes, even\n" |
3514 | "InnoDB: immediately after the mysqld startup, there may be\n" |
3515 | "InnoDB: corruption in the InnoDB tablespace. Please refer to\n" |
3516 | - "InnoDB: " REFMAN "forcing-recovery.html\n" |
3517 | + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" |
3518 | "InnoDB: about forcing recovery.\n", stderr); |
3519 | #if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT) |
3520 | ut_dbg_stop_threads = TRUE; |
https:/ /jenkins. drizzle. org/view/ All/job/ drizzle- param/923/