]>
Commit | Line | Data |
---|---|---|
5b9e9ff4 ER |
1 | diff -ruN a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c |
2 | --- a/innobase/btr/btr0sea.c 2009-08-27 18:42:17.000000000 +0900 | |
3 | +++ b/innobase/btr/btr0sea.c 2009-08-27 18:43:11.000000000 +0900 | |
4 | @@ -1077,6 +1077,124 @@ | |
5 | } | |
6 | ||
7 | /************************************************************************ | |
8 | +Drops a page hash index based on index */ | |
9 | + | |
10 | +void | |
11 | +btr_search_drop_page_hash_index_on_index( | |
12 | +/*=====================================*/ | |
13 | + dict_index_t* index) /* in: record descriptor */ | |
14 | +{ | |
15 | + page_t* page; | |
16 | + hash_table_t* table; | |
17 | + buf_block_t* block; | |
18 | + ulint n_fields; | |
19 | + ulint n_bytes; | |
20 | + rec_t* rec; | |
21 | + ulint fold; | |
22 | + ulint prev_fold; | |
23 | + dulint tree_id; | |
24 | + ulint n_cached; | |
25 | + ulint n_recs; | |
26 | + ulint* folds; | |
27 | + ulint i; | |
28 | + mem_heap_t* heap = NULL; | |
29 | + ulint* offsets; | |
30 | + | |
31 | + rw_lock_x_lock(&btr_search_latch); | |
32 | + mutex_enter(&buf_pool->mutex); | |
33 | + | |
34 | + table = btr_search_sys->hash_index; | |
35 | + | |
36 | + block = UT_LIST_GET_LAST(buf_pool->LRU); | |
37 | + | |
38 | + while (block != NULL) { | |
39 | + if (block->index == index && block->is_hashed) { | |
40 | + page = block->frame; | |
41 | + | |
42 | + /* from btr_search_drop_page_hash_index() */ | |
43 | + n_fields = block->curr_n_fields; | |
44 | + n_bytes = block->curr_n_bytes; | |
45 | + | |
46 | + ut_a(n_fields + n_bytes > 0); | |
47 | + | |
48 | + n_recs = page_get_n_recs(page); | |
49 | + | |
50 | + /* Calculate and cache fold values into an array for fast deletion | |
51 | + from the hash index */ | |
52 | + | |
53 | + folds = mem_alloc(n_recs * sizeof(ulint)); | |
54 | + | |
55 | + n_cached = 0; | |
56 | + | |
57 | + rec = page_get_infimum_rec(page); | |
58 | + rec = page_rec_get_next(rec); | |
59 | + | |
60 | + tree_id = btr_page_get_index_id(page); | |
61 | + | |
62 | + ut_a(0 == ut_dulint_cmp(tree_id, index->id)); | |
63 | + | |
64 | + prev_fold = 0; | |
65 | + | |
66 | + offsets = NULL; | |
67 | + | |
68 | + while (!page_rec_is_supremum(rec)) { | |
69 | + /* FIXME: in a mixed tree, not all records may have enough | |
70 | + ordering fields: */ | |
71 | + offsets = rec_get_offsets(rec, index, offsets, | |
72 | + n_fields + (n_bytes > 0), &heap); | |
73 | + ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0)); | |
74 | + fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id); | |
75 | + | |
76 | + if (fold == prev_fold && prev_fold != 0) { | |
77 | + | |
78 | + goto next_rec; | |
79 | + } | |
80 | + | |
81 | + /* Remove all hash nodes pointing to this page from the | |
82 | + hash chain */ | |
83 | + | |
84 | + folds[n_cached] = fold; | |
85 | + n_cached++; | |
86 | +next_rec: | |
87 | + rec = page_rec_get_next(rec); | |
88 | + prev_fold = fold; | |
89 | + } | |
90 | + | |
91 | + for (i = 0; i < n_cached; i++) { | |
92 | + | |
93 | + ha_remove_all_nodes_to_page(table, folds[i], page); | |
94 | + } | |
95 | + | |
96 | + ut_a(index->search_info->ref_count > 0); | |
97 | + index->search_info->ref_count--; | |
98 | + | |
99 | + block->is_hashed = FALSE; | |
100 | + block->index = NULL; | |
101 | + | |
102 | + if (UNIV_UNLIKELY(block->n_pointers)) { | |
103 | + /* Corruption */ | |
104 | + ut_print_timestamp(stderr); | |
105 | + fprintf(stderr, | |
106 | +" InnoDB: Corruption of adaptive hash index. After dropping\n" | |
107 | +"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n", | |
108 | + index->name, (ulong) block->n_pointers); | |
109 | + } | |
110 | + | |
111 | + mem_free(folds); | |
112 | + } | |
113 | + | |
114 | + block = UT_LIST_GET_PREV(LRU, block); | |
115 | + } | |
116 | + | |
117 | + mutex_exit(&buf_pool->mutex); | |
118 | + rw_lock_x_unlock(&btr_search_latch); | |
119 | + | |
120 | + if (UNIV_LIKELY_NULL(heap)) { | |
121 | + mem_heap_free(heap); | |
122 | + } | |
123 | +} | |
124 | + | |
125 | +/************************************************************************ | |
126 | Drops a page hash index when a page is freed from a fseg to the file system. | |
127 | Drops possible hash index if the page happens to be in the buffer pool. */ | |
128 | ||
129 | diff -ruN a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c | |
130 | --- a/innobase/dict/dict0boot.c 2009-07-07 21:53:58.000000000 +0900 | |
131 | +++ b/innobase/dict/dict0boot.c 2009-08-27 18:42:59.000000000 +0900 | |
389e9b46 | 132 | @@ -247,6 +247,7 @@ |
133 | system tables */ | |
134 | /*-------------------------*/ | |
135 | table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, FALSE); | |
136 | + table->n_mysql_handles_opened = 1; /* for pin */ | |
137 | ||
138 | dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0); | |
139 | dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0); | |
140 | @@ -283,6 +284,7 @@ | |
141 | ut_a(success); | |
142 | /*-------------------------*/ | |
143 | table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, FALSE); | |
144 | + table->n_mysql_handles_opened = 1; /* for pin */ | |
145 | ||
146 | dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0); | |
147 | dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0); | |
148 | @@ -309,6 +311,7 @@ | |
149 | ut_a(success); | |
150 | /*-------------------------*/ | |
151 | table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, FALSE); | |
152 | + table->n_mysql_handles_opened = 1; /* for pin */ | |
153 | ||
154 | dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0); | |
155 | dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0); | |
156 | @@ -345,6 +348,7 @@ | |
157 | ut_a(success); | |
158 | /*-------------------------*/ | |
159 | table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, FALSE); | |
160 | + table->n_mysql_handles_opened = 1; /* for pin */ | |
161 | ||
162 | dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0); | |
163 | dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0); | |
5b9e9ff4 ER |
164 | diff -ruN a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c |
165 | --- a/innobase/dict/dict0crea.c 2009-07-07 21:53:58.000000000 +0900 | |
166 | +++ b/innobase/dict/dict0crea.c 2009-08-27 18:42:59.000000000 +0900 | |
389e9b46 | 167 | @@ -1178,6 +1178,9 @@ |
168 | /* Foreign constraint system tables have already been | |
169 | created, and they are ok */ | |
170 | ||
171 | + table1->n_mysql_handles_opened = 1; /* for pin */ | |
172 | + table2->n_mysql_handles_opened = 1; /* for pin */ | |
173 | + | |
174 | mutex_exit(&(dict_sys->mutex)); | |
175 | ||
176 | return(DB_SUCCESS); | |
5b9e9ff4 | 177 | @@ -1267,6 +1270,11 @@ |
389e9b46 | 178 | |
179 | trx->op_info = ""; | |
5b9e9ff4 | 180 | |
389e9b46 | 181 | + table1 = dict_table_get_low("SYS_FOREIGN"); |
182 | + table2 = dict_table_get_low("SYS_FOREIGN_COLS"); | |
183 | + table1->n_mysql_handles_opened = 1; /* for pin */ | |
184 | + table2->n_mysql_handles_opened = 1; /* for pin */ | |
5b9e9ff4 | 185 | + |
389e9b46 | 186 | row_mysql_unlock_data_dictionary(trx); |
187 | ||
5b9e9ff4 ER |
188 | trx_free_for_mysql(trx); |
189 | diff -ruN a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c | |
190 | --- a/innobase/dict/dict0dict.c 2009-07-07 21:53:58.000000000 +0900 | |
191 | +++ b/innobase/dict/dict0dict.c 2009-08-27 18:43:11.000000000 +0900 | |
389e9b46 | 192 | @@ -638,6 +638,8 @@ |
193 | mutex_enter(&(dict_sys->mutex)); | |
194 | ||
195 | table = dict_table_get_on_id_low(table_id, trx); | |
196 | + | |
197 | + dict_table_LRU_trim(table); | |
198 | ||
199 | mutex_exit(&(dict_sys->mutex)); | |
200 | ||
201 | @@ -752,6 +754,8 @@ | |
202 | ||
203 | table = dict_table_get_low(table_name); | |
204 | ||
205 | + dict_table_LRU_trim(table); | |
206 | + | |
207 | mutex_exit(&(dict_sys->mutex)); | |
208 | ||
209 | if (table != NULL) { | |
5b9e9ff4 | 210 | @@ -787,6 +791,8 @@ |
389e9b46 | 211 | table->n_mysql_handles_opened++; |
212 | } | |
89b96684 | 213 | |
5b9e9ff4 ER |
214 | + dict_table_LRU_trim(table); |
215 | + | |
389e9b46 | 216 | mutex_exit(&(dict_sys->mutex)); |
217 | ||
5b9e9ff4 | 218 | if (table != NULL) { |
389e9b46 | 219 | @@ -1267,20 +1273,64 @@ |
220 | too much space. Currently not used! */ | |
221 | ||
222 | void | |
223 | -dict_table_LRU_trim(void) | |
224 | -/*=====================*/ | |
225 | +dict_table_LRU_trim( | |
226 | +/*================*/ | |
227 | + dict_table_t* self) | |
228 | { | |
229 | dict_table_t* table; | |
230 | dict_table_t* prev_table; | |
231 | + dict_foreign_t* foreign; | |
232 | + ulint n_removed; | |
233 | + ulint n_have_parent; | |
234 | + ulint cached_foreign_tables; | |
5b9e9ff4 ER |
235 | |
236 | - ut_error; | |
389e9b46 | 237 | + //ut_error; |
5b9e9ff4 ER |
238 | |
239 | #ifdef UNIV_SYNC_DEBUG | |
240 | ut_ad(mutex_own(&(dict_sys->mutex))); | |
241 | #endif /* UNIV_SYNC_DEBUG */ | |
242 | ||
389e9b46 | 243 | +retry: |
244 | + n_removed = n_have_parent = 0; | |
245 | table = UT_LIST_GET_LAST(dict_sys->table_LRU); | |
246 | ||
247 | + while ( srv_dict_size_limit && table | |
248 | + && ((dict_sys->table_hash->n_cells | |
249 | + + dict_sys->table_id_hash->n_cells | |
250 | + + dict_sys->col_hash->n_cells) * sizeof(hash_cell_t) | |
251 | + + dict_sys->size) > srv_dict_size_limit ) { | |
252 | + prev_table = UT_LIST_GET_PREV(table_LRU, table); | |
253 | + | |
254 | + if (table == self || table->n_mysql_handles_opened) | |
255 | + goto next_loop; | |
256 | + | |
257 | + cached_foreign_tables = 0; | |
258 | + foreign = UT_LIST_GET_FIRST(table->foreign_list); | |
259 | + while (foreign != NULL) { | |
260 | + if (foreign->referenced_table) | |
261 | + cached_foreign_tables++; | |
262 | + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); | |
263 | + } | |
264 | + | |
265 | + /* TODO: use table->mem_fix also, if it becomes exact. */ | |
266 | + | |
267 | + if (cached_foreign_tables == 0) { | |
268 | + dict_table_remove_from_cache(table); | |
269 | + n_removed++; | |
270 | + } else { | |
271 | + n_have_parent++; | |
272 | + } | |
273 | +next_loop: | |
274 | + table = prev_table; | |
275 | + } | |
276 | + | |
277 | + if ( srv_dict_size_limit && n_have_parent && n_removed | |
278 | + && ((dict_sys->table_hash->n_cells | |
279 | + + dict_sys->table_id_hash->n_cells | |
280 | + + dict_sys->col_hash->n_cells) * sizeof(hash_cell_t) | |
281 | + + dict_sys->size) > srv_dict_size_limit ) | |
282 | + goto retry; | |
283 | +/* | |
284 | while (table && (dict_sys->size > | |
285 | buf_pool_get_max_size() / DICT_POOL_PER_VARYING)) { | |
286 | ||
89b96684 | 287 | @@ -1292,6 +1342,7 @@ |
389e9b46 | 288 | |
289 | table = prev_table; | |
290 | } | |
291 | +*/ | |
292 | } | |
293 | ||
294 | /************************************************************************** | |
5b9e9ff4 ER |
295 | @@ -1565,6 +1616,10 @@ |
296 | #ifdef UNIV_SYNC_DEBUG | |
297 | ut_ad(mutex_own(&(dict_sys->mutex))); | |
298 | #endif /* UNIV_SYNC_DEBUG */ | |
299 | + /* remove all entry of the index from adaptive hash index, | |
300 | + because removing from adaptive hash index needs dict_index */ | |
301 | + if (srv_use_adaptive_hash_indexes && srv_dict_size_limit) | |
302 | + btr_search_drop_page_hash_index_on_index(index); | |
303 | ||
304 | /* We always create search info whether or not adaptive | |
305 | hash index is enabled or not. */ | |
306 | diff -ruN a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c | |
307 | --- a/innobase/ibuf/ibuf0ibuf.c 2009-08-27 18:42:17.000000000 +0900 | |
308 | +++ b/innobase/ibuf/ibuf0ibuf.c 2009-08-27 18:42:59.000000000 +0900 | |
389e9b46 | 309 | @@ -535,6 +535,7 @@ |
310 | sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space); | |
311 | /* use old-style record format for the insert buffer */ | |
312 | table = dict_mem_table_create(buf, space, 2, FALSE); | |
313 | + table->n_mysql_handles_opened = 1; /* for pin */ | |
314 | ||
315 | dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0); | |
316 | dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0); | |
5b9e9ff4 ER |
317 | diff -ruN a/innobase/include/btr0sea.h b/innobase/include/btr0sea.h |
318 | --- a/innobase/include/btr0sea.h 2009-07-07 21:54:00.000000000 +0900 | |
319 | +++ b/innobase/include/btr0sea.h 2009-08-27 18:43:11.000000000 +0900 | |
320 | @@ -97,6 +97,13 @@ | |
321 | /*============================*/ | |
322 | page_t* page); /* in: index page, s- or x-latched */ | |
323 | /************************************************************************ | |
324 | +Drops a page hash index based on index */ | |
325 | + | |
326 | +void | |
327 | +btr_search_drop_page_hash_index_on_index( | |
328 | +/*=====================================*/ | |
329 | + dict_index_t* index); /* in: record descriptor */ | |
330 | +/************************************************************************ | |
331 | Drops a page hash index when a page is freed from a fseg to the file system. | |
332 | Drops possible hash index if the page happens to be in the buffer pool. */ | |
333 | ||
334 | diff -ruN a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h | |
335 | --- a/innobase/include/dict0dict.h 2009-07-07 21:54:01.000000000 +0900 | |
336 | +++ b/innobase/include/dict0dict.h 2009-08-27 18:42:59.000000000 +0900 | |
389e9b46 | 337 | @@ -938,6 +938,11 @@ |
338 | const char* ptr, /* in: scan from */ | |
339 | const char* string);/* in: look for this */ | |
340 | ||
341 | +void | |
342 | +dict_table_LRU_trim( | |
343 | +/*================*/ | |
344 | + dict_table_t* self); | |
345 | + | |
346 | /* Buffers for storing detailed information about the latest foreign key | |
347 | and unique key errors */ | |
348 | extern FILE* dict_foreign_err_file; | |
5b9e9ff4 ER |
349 | diff -ruN a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic |
350 | --- a/innobase/include/dict0dict.ic 2009-07-07 21:54:01.000000000 +0900 | |
351 | +++ b/innobase/include/dict0dict.ic 2009-08-27 18:42:59.000000000 +0900 | |
389e9b46 | 352 | @@ -533,6 +533,13 @@ |
353 | ||
354 | HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold, table, | |
355 | ut_strcmp(table->name, table_name) == 0); | |
356 | + | |
357 | + /* make young in table_LRU */ | |
358 | + if (table) { | |
359 | + UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); | |
360 | + UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table); | |
361 | + } | |
362 | + | |
363 | return(table); | |
364 | } | |
365 | ||
366 | @@ -592,6 +599,10 @@ | |
367 | if (table != NULL) { | |
368 | table->mem_fix++; | |
369 | ||
370 | + /* make young in table_LRU */ | |
371 | + UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); | |
372 | + UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table); | |
373 | + | |
374 | /* lock_push(trx, table, LOCK_DICT_MEM_FIX) */ | |
375 | } | |
376 | ||
5b9e9ff4 ER |
377 | diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h |
378 | --- a/innobase/include/srv0srv.h 2009-08-27 18:42:17.000000000 +0900 | |
379 | +++ b/innobase/include/srv0srv.h 2009-08-27 18:42:59.000000000 +0900 | |
380 | @@ -147,6 +147,8 @@ | |
389e9b46 | 381 | extern uint srv_read_ahead; |
89b96684 | 382 | extern uint srv_adaptive_checkpoint; |
89b96684 | 383 | |
5b9e9ff4 ER |
384 | +extern ulint srv_dict_size_limit; |
385 | + | |
389e9b46 | 386 | extern volatile ibool srv_io_pattern; |
387 | extern ulong srv_io_pattern_trace; | |
5b9e9ff4 | 388 | extern ulong srv_io_pattern_trace_running; |
89b96684 | 389 | @@ -552,6 +554,7 @@ |
389e9b46 | 390 | ulint innodb_data_writes; |
391 | ulint innodb_data_written; | |
392 | ulint innodb_data_reads; | |
393 | + ulint innodb_dict_tables; | |
394 | ulint innodb_buffer_pool_pages_total; | |
395 | ulint innodb_buffer_pool_pages_data; | |
396 | ulint innodb_buffer_pool_pages_dirty; | |
5b9e9ff4 ER |
397 | diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c |
398 | --- a/innobase/srv/srv0srv.c 2009-08-27 18:42:17.000000000 +0900 | |
399 | +++ b/innobase/srv/srv0srv.c 2009-08-27 18:42:59.000000000 +0900 | |
400 | @@ -353,6 +353,8 @@ | |
89b96684 ER |
401 | uint srv_read_ahead = 3; /* 1: random 2: linear 3: Both */ |
402 | uint srv_adaptive_checkpoint = 0; /* 0: none 1: reflex 2: estimate */ | |
89b96684 | 403 | |
5b9e9ff4 ER |
404 | +ulint srv_dict_size_limit = 0; |
405 | + | |
389e9b46 | 406 | volatile ibool srv_io_pattern = FALSE; |
407 | ulint srv_io_pattern_trace = 0; | |
5b9e9ff4 | 408 | ulint srv_io_pattern_trace_running = 0; |
89b96684 | 409 | @@ -1953,6 +1955,7 @@ |
389e9b46 | 410 | export_vars.innodb_data_reads= os_n_file_reads; |
411 | export_vars.innodb_data_writes= os_n_file_writes; | |
412 | export_vars.innodb_data_written= srv_data_written; | |
413 | + export_vars.innodb_dict_tables= (dict_sys ? UT_LIST_GET_LEN(dict_sys->table_LRU) : 0); | |
414 | export_vars.innodb_buffer_pool_read_requests= buf_pool->n_page_gets; | |
415 | export_vars.innodb_buffer_pool_write_requests= srv_buf_pool_write_requests; | |
416 | export_vars.innodb_buffer_pool_wait_free= srv_buf_pool_wait_free; | |
5b9e9ff4 ER |
417 | diff -ruN a/mysql-test/r/innodb_dict_size_limit.result b/mysql-test/r/innodb_dict_size_limit.result |
418 | --- /dev/null 1970-01-01 09:00:00.000000000 +0900 | |
419 | +++ b/mysql-test/r/innodb_dict_size_limit.result 2009-08-27 18:42:59.000000000 +0900 | |
389e9b46 | 420 | @@ -0,0 +1,60 @@ |
421 | +DROP TABLE IF EXISTS `test_5`; | |
422 | +DROP TABLE IF EXISTS `test_4`; | |
423 | +DROP TABLE IF EXISTS `test_3`; | |
424 | +DROP TABLE IF EXISTS `test_2`; | |
425 | +DROP TABLE IF EXISTS `test_1`; | |
426 | +SET storage_engine=InnoDB; | |
427 | +SET GLOBAL innodb_dict_size_limit=1; | |
428 | +FLUSH TABLES; | |
429 | +CREATE TABLE `test_1` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
430 | +CREATE TABLE `test_2` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
431 | +CREATE TABLE `test_3` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
432 | +CREATE TABLE `test_4` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
433 | +CREATE TABLE `test_5` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
434 | +ALTER TABLE `test_5` ADD CONSTRAINT FOREIGN KEY(`b`) REFERENCES `test_4`(`a`); | |
435 | +ALTER TABLE `test_4` ADD CONSTRAINT FOREIGN KEY(`b`) REFERENCES `test_3`(`a`); | |
436 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
437 | +Variable_name Value | |
438 | +Innodb_dict_tables 9 | |
439 | +FLUSH TABLES; | |
440 | +SELECT * FROM `test_1`; | |
441 | +a b | |
442 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
443 | +Variable_name Value | |
444 | +Innodb_dict_tables 8 | |
445 | +SELECT * FROM `test_3`; | |
446 | +a b | |
447 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
448 | +Variable_name Value | |
449 | +Innodb_dict_tables 11 | |
450 | +FLUSH TABLES; | |
451 | +SELECT * FROM `test_2`; | |
452 | +a b | |
453 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
454 | +Variable_name Value | |
455 | +Innodb_dict_tables 8 | |
456 | +SELECT * FROM `test_1`; | |
457 | +a b | |
458 | +FLUSH TABLES; | |
459 | +SELECT * FROM `test_4`; | |
460 | +a b | |
461 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
462 | +Variable_name Value | |
463 | +Innodb_dict_tables 9 | |
464 | +SELECT * FROM `test_3`; | |
465 | +a b | |
466 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
467 | +Variable_name Value | |
468 | +Innodb_dict_tables 10 | |
469 | +SET GLOBAL innodb_dict_size_limit=0; | |
470 | +FLUSH TABLES; | |
471 | +SELECT * FROM `test_2`; | |
472 | +a b | |
473 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
474 | +Variable_name Value | |
475 | +Innodb_dict_tables 11 | |
476 | +DROP TABLE `test_5`; | |
477 | +DROP TABLE `test_4`; | |
478 | +DROP TABLE `test_3`; | |
479 | +DROP TABLE `test_2`; | |
480 | +DROP TABLE `test_1`; | |
5b9e9ff4 ER |
481 | diff -ruN a/mysql-test/t/innodb_dict_size_limit.test b/mysql-test/t/innodb_dict_size_limit.test |
482 | --- /dev/null 1970-01-01 09:00:00.000000000 +0900 | |
483 | +++ b/mysql-test/t/innodb_dict_size_limit.test 2009-08-27 18:42:59.000000000 +0900 | |
389e9b46 | 484 | @@ -0,0 +1,63 @@ |
485 | +# | |
486 | +# Test for new variable innodb_dict_size_limit; | |
487 | +# | |
488 | +-- source include/have_innodb.inc | |
489 | + | |
490 | +--disable_warnings | |
491 | +DROP TABLE IF EXISTS `test_5`; | |
492 | +DROP TABLE IF EXISTS `test_4`; | |
493 | +DROP TABLE IF EXISTS `test_3`; | |
494 | +DROP TABLE IF EXISTS `test_2`; | |
495 | +DROP TABLE IF EXISTS `test_1`; | |
496 | +--enable_warnings | |
497 | + | |
498 | +SET storage_engine=InnoDB; | |
499 | +SET GLOBAL innodb_dict_size_limit=1; | |
500 | + | |
501 | +FLUSH TABLES; | |
502 | + | |
503 | +CREATE TABLE `test_1` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
504 | +CREATE TABLE `test_2` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
505 | +CREATE TABLE `test_3` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
506 | +CREATE TABLE `test_4` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
507 | +CREATE TABLE `test_5` (`a` int, `b` int, PRIMARY KEY (`a`)); | |
508 | + | |
509 | +ALTER TABLE `test_5` ADD CONSTRAINT FOREIGN KEY(`b`) REFERENCES `test_4`(`a`); | |
510 | +ALTER TABLE `test_4` ADD CONSTRAINT FOREIGN KEY(`b`) REFERENCES `test_3`(`a`); | |
511 | + | |
512 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
513 | + | |
514 | +FLUSH TABLES; | |
515 | +SELECT * FROM `test_1`; | |
516 | + | |
517 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
518 | + | |
519 | +SELECT * FROM `test_3`; | |
520 | + | |
521 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
522 | + | |
523 | +FLUSH TABLES; | |
524 | +SELECT * FROM `test_2`; | |
525 | + | |
526 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
527 | + | |
528 | +SELECT * FROM `test_1`; | |
529 | +FLUSH TABLES; | |
530 | +SELECT * FROM `test_4`; | |
531 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
532 | + | |
533 | +SELECT * FROM `test_3`; | |
534 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
535 | + | |
536 | +SET GLOBAL innodb_dict_size_limit=0; | |
537 | +FLUSH TABLES; | |
538 | +SELECT * FROM `test_2`; | |
539 | + | |
540 | +SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables'; | |
541 | + | |
542 | +DROP TABLE `test_5`; | |
543 | +DROP TABLE `test_4`; | |
544 | +DROP TABLE `test_3`; | |
545 | +DROP TABLE `test_2`; | |
546 | +DROP TABLE `test_1`; | |
547 | + | |
5b9e9ff4 ER |
548 | diff -ruN a/patch_info/innodb_dict_size_limit.info b/patch_info/innodb_dict_size_limit.info |
549 | --- /dev/null 1970-01-01 09:00:00.000000000 +0900 | |
550 | +++ b/patch_info/innodb_dict_size_limit.info 2009-08-27 18:42:59.000000000 +0900 | |
389e9b46 | 551 | @@ -0,0 +1,9 @@ |
552 | +File=innodb_dict_size_limit.patch | |
553 | +Name=Limit dictionary cache size | |
554 | +Version=1.0 | |
555 | +Author=Percona | |
556 | +License=GPL | |
557 | +Comment=Variable innodb_dict_size_limit in bytes | |
558 | +ChangeLog= | |
559 | +2009-01-26 | |
560 | +YK: Initial release | |
5b9e9ff4 ER |
561 | diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc |
562 | --- a/sql/ha_innodb.cc 2009-08-27 18:42:17.000000000 +0900 | |
563 | +++ b/sql/ha_innodb.cc 2009-08-27 18:42:59.000000000 +0900 | |
89b96684 ER |
564 | @@ -288,6 +288,8 @@ |
565 | (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG}, | |
566 | {"dblwr_writes", | |
567 | (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG}, | |
568 | + {"dict_tables", | |
569 | + (char*) &export_vars.innodb_dict_tables, SHOW_LONG}, | |
570 | {"log_waits", | |
571 | (char*) &export_vars.innodb_log_waits, SHOW_LONG}, | |
572 | {"log_write_requests", | |
5b9e9ff4 ER |
573 | diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h |
574 | --- a/sql/ha_innodb.h 2009-08-27 18:42:17.000000000 +0900 | |
575 | +++ b/sql/ha_innodb.h 2009-08-27 18:42:59.000000000 +0900 | |
89b96684 ER |
576 | @@ -243,6 +243,7 @@ |
577 | extern ulong srv_enable_unsafe_group_commit; | |
578 | extern uint srv_read_ahead; | |
579 | extern uint srv_adaptive_checkpoint; | |
580 | +extern ulong srv_dict_size_limit; | |
581 | extern ulong srv_show_locks_held; | |
582 | extern ulong srv_show_verbose_locks; | |
583 | extern ulong srv_io_pattern_trace; | |
5b9e9ff4 ER |
584 | diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc |
585 | --- a/sql/mysqld.cc 2009-08-27 18:42:17.000000000 +0900 | |
586 | +++ b/sql/mysqld.cc 2009-08-27 18:42:59.000000000 +0900 | |
89b96684 ER |
587 | @@ -5101,6 +5101,7 @@ |
588 | OPT_INNODB_ADAPTIVE_CHECKPOINT, | |
589 | OPT_INNODB_READ_IO_THREADS, | |
590 | OPT_INNODB_WRITE_IO_THREADS, | |
591 | + OPT_INNODB_DICT_SIZE_LIMIT, | |
592 | OPT_INNODB_ADAPTIVE_HASH_INDEX, | |
593 | OPT_FEDERATED, | |
594 | OPT_INNODB_USE_LEGACY_CARDINALITY_ALGORITHM | |
595 | @@ -5464,6 +5465,10 @@ | |
596 | "Number of background write I/O threads in InnoDB.", | |
597 | (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads, | |
598 | 0, GET_LONG, REQUIRED_ARG, 8, 1, 64, 0, 0, 0}, | |
599 | + {"innodb_dict_size_limit", OPT_INNODB_DICT_SIZE_LIMIT, | |
600 | + "Limit the allocated memory for dictionary cache. (0: unlimited)", | |
601 | + (gptr*) &srv_dict_size_limit, (gptr*) &srv_dict_size_limit, 0, | |
602 | + GET_ULONG, REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 0 ,0}, | |
603 | {"innodb_io_pattern_trace", OPT_INNODB_IO_PATTERN_TRACE, | |
604 | "Create/Drop the internal hash table for IO pattern tracing.", | |
605 | (gptr*) &srv_io_pattern_trace, (gptr*) &srv_io_pattern_trace, | |
5b9e9ff4 ER |
606 | diff -ruN a/sql/set_var.cc b/sql/set_var.cc |
607 | --- a/sql/set_var.cc 2009-08-27 18:42:17.000000000 +0900 | |
608 | +++ b/sql/set_var.cc 2009-08-27 18:42:59.000000000 +0900 | |
89b96684 ER |
609 | @@ -540,6 +540,8 @@ |
610 | sys_var_enum sys_innodb_adaptive_checkpoint("innodb_adaptive_checkpoint", | |
611 | &srv_adaptive_checkpoint, | |
612 | &innodb_adaptive_checkpoint_typelib, fix_innodb_adaptive_checkpoint); | |
613 | +sys_var_long_ptr sys_innodb_dict_size_limit("innodb_dict_size_limit", | |
614 | + &srv_dict_size_limit); | |
615 | sys_var_long_ptr sys_innodb_show_locks_held( | |
616 | "innodb_show_locks_held", | |
617 | &srv_show_locks_held); | |
618 | @@ -930,6 +932,7 @@ | |
619 | &sys_innodb_read_ahead, | |
620 | &sys_innodb_enable_unsafe_group_commit, | |
621 | &sys_innodb_adaptive_checkpoint, | |
622 | + &sys_innodb_dict_size_limit, | |
623 | &sys_innodb_show_locks_held, | |
624 | &sys_innodb_show_verbose_locks, | |
625 | &sys_innodb_io_pattern_trace, | |
626 | @@ -1084,6 +1087,7 @@ | |
627 | {sys_innodb_adaptive_checkpoint.name, (char*) &sys_innodb_adaptive_checkpoint, SHOW_SYS}, | |
628 | {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG}, | |
629 | {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG}, | |
630 | + {sys_innodb_dict_size_limit.name, (char*) &sys_innodb_dict_size_limit, SHOW_SYS}, | |
631 | {sys_innodb_io_pattern_trace.name, (char*) &sys_innodb_io_pattern_trace, SHOW_SYS}, | |
632 | {sys_innodb_io_pattern_trace_running.name, (char*) &sys_innodb_io_pattern_trace_running, SHOW_SYS}, | |
633 | {sys_innodb_io_pattern_size_limit.name, (char*) &sys_innodb_io_pattern_size_limit, SHOW_SYS}, |