| Bug #72584 | storage/inobase/dict/dict0dict.cc | ||
|---|---|---|---|
| Submitted: | 8 May 2014 19:53 | Modified: | 12 May 2014 17:11 |
| Reporter: | 徹 赤松 | Email Updates: | |
| Status: | Not a Bug | Impact on me: | |
| Category: | MySQL Server: InnoDB storage engine | Severity: | S3 (Non-critical) |
| Version: | 5.7.4 | OS: | Linux |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | dict_table_remove_from_cache_low, dict0dict.cc, innodb | ||
[9 May 2014 13:28]
MySQL Verification Team
Mr. Akamatsu, Thank you very much for your interest and for the analyzing our code. Please, do that in future too, as bugs can creep in quite easily. However, in this case, there is not bug. Linked lists of both foreign indices and indigenous indices are removed in both cases from last to the first and not from the first to the last one. Let us take the example of the indices. A macro UT_LIST_GET_LAST gets the last index in the linked list. That is the macro that initializes the counter. Then the function dict_index_remove_from_cache_low(table, index, lru_evict) is called. In that function, the last index in the linked list is removed, with a macro UT_LIST_REMOVE. Hence, in the next iteration, the macro UT_LIST_GET_LAST gets a NEW index that is the next one in the list, which is last, so the removal progresses from the last index to the first one. Same process is done for foreign indices.
[12 May 2014 17:11]
徹 赤松
Dir Sinisa Milivojevic, Thank you for the polite reply.

Description: i am reading source code of InnDB storage engine version 5.7.4 now. When i read dict_table_remove_from_cache_low function in storage/innobase/dict/dict0dict.cc, i found a bug. storage/innobase/dict/dict0dict.cc 1760 dict_table_remove_from_cache_low( 1761 /*=============================*/ 1762 dict_table_t* table, /*!< in, own: table */ 1763 ibool lru_evict) /*!< in: TRUE if table being evicted 1764 to make room in the table LRU list */ 1765 { ... 1783 /* Remove the foreign constraints from the cache */ 1784 x 1785 for (foreign = UT_LIST_GET_LAST(table->foreign_list); 1786 foreign != NULL; x 1787 foreign = UT_LIST_GET_LAST(table->foreign_list)) { 1788 1789 dict_foreign_remove_from_cache(foreign); 1790 } oooooo o 1785 for (foreign = UT_LIST_GET_FIRST(table->foreign_list); o 1787 foreign = UT_LIST_GET_NEXT(foreign_list, foreign); ... 1802 /* Remove the indexes from the cache */ 1803 x 1804 for (index = UT_LIST_GET_LAST(table->indexes); 1805 index != NULL; x 1806 index = UT_LIST_GET_LAST(table->indexes)) { 1807 1808 dict_index_remove_from_cache_low(table, index, lru_evict); 1809 } oooooo o 1804 for (index = UT_LIST_GET_FIRST(table->indexes); o 1806 index = UT_LIST_GET_NEXT(indexes, index); Please check and i am pleased if you can reply. How to repeat: i can not repeat it, but remove only key on the LAST LIST. So many foreign_keys and indexes remain on the cache, it is no good. Suggested fix: i think change under 4 lines. Line number is in mysql version-5.7.4. o 1785 for (foreign = UT_LIST_GET_FIRST(table->foreign_list); o 1787 foreign = UT_LIST_GET_NEXT(foreign_list, foreign); o 1804 for (index = UT_LIST_GET_FIRST(table->indexes); o 1806 index = UT_LIST_GET_NEXT(indexes, index);