-
-
Notifications
You must be signed in to change notification settings - Fork 2k
MDEV-38412 System tablespace fails to shrink due to legacy tables #4884
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 11.4
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5690,6 +5690,84 @@ dberr_t IndexDefragmenter::defragment(SpaceDefragmenter *space_defrag) noexcept | |
| return err; | ||
| } | ||
|
|
||
| /** Determine if a table should be dropped during system tablespace | ||
| autoshrinking. This function identifies legacy tables in the | ||
| system tablespace that should be removed. A table is considered a | ||
| legacy/unknown table if the table name does not contain '/' | ||
| (indicating it's not a proper database/table name) | ||
| @return error code or DB_SUCCESS */ | ||
| static dberr_t fsp_drop_legacy_tables(bool &drop_unknown) noexcept | ||
Thirunarayanan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| mtr_t mtr{nullptr}; | ||
| btr_pcur_t pcur; | ||
| dberr_t err= DB_SUCCESS; | ||
| std::vector<table_id_t> unknown_tables; | ||
| mtr.start(); | ||
| for (const rec_t *rec= dict_startscan_system(&pcur, &mtr, | ||
| dict_sys.sys_tables); | ||
| rec; rec= dict_getnext_system(&pcur, &mtr)) | ||
| { | ||
| const byte *field= nullptr; | ||
| ulint len= 0; | ||
| if (rec_get_deleted_flag(rec, 0)) | ||
| continue; | ||
Thirunarayanan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| field= rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__SPACE, &len); | ||
| if (len != 4) | ||
| { | ||
| err= DB_CORRUPTION; | ||
| break; | ||
| } | ||
| if (mach_read_from_4(field) != 0) | ||
| continue; | ||
| field= rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__ID, &len); | ||
| if (len != 8) | ||
| { | ||
| err= DB_CORRUPTION; | ||
| break; | ||
| } | ||
|
|
||
| table_id_t table_id= mach_read_from_8(field); | ||
| if (dict_sys.is_sys_table(table_id)) | ||
| continue; | ||
| field = rec_get_nth_field_old( | ||
| rec, DICT_FLD__SYS_TABLES__NAME, &len); | ||
|
|
||
| if (len == UNIV_SQL_NULL || len == 0) | ||
| { | ||
| err= DB_CORRUPTION; | ||
| break; | ||
| } | ||
| if (memchr(rec, '/', len)) | ||
| continue; | ||
| sql_print_information("InnoDB: Found the unknown table %.*s", | ||
| (int) len, rec); | ||
Thirunarayanan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| unknown_tables.emplace_back(table_id); | ||
| } | ||
| mtr.commit(); | ||
| if (err || unknown_tables.size() == 0) | ||
| return err; | ||
|
Comment on lines
+5746
to
+5748
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do not need |
||
|
|
||
| drop_unknown= true; | ||
| sql_print_information("InnoDB: Dropping the unknown tables"); | ||
| trx_t *trx= trx_create(); | ||
| trx_start_for_ddl(trx); | ||
| dict_sys.lock(SRW_LOCK_CALL); | ||
|
|
||
| for (table_id_t table_id : unknown_tables) | ||
| { | ||
| err= delete_from_sys_table_entries(table_id, trx); | ||
|
Comment on lines
+5751
to
+5758
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that we only need to lock |
||
| if (err) | ||
| break; | ||
| } | ||
|
|
||
| if (err == DB_SUCCESS) | ||
| trx->commit(); | ||
Thirunarayanan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| else | ||
| trx->rollback(); | ||
| dict_sys.unlock(); | ||
| trx->clear_and_free(); | ||
| return err; | ||
| } | ||
| /** check whether any user table exist in system tablespace | ||
| @retval DB_SUCCESS_LOCKED_REC if user table exist | ||
| @retval DB_SUCCESS if no user table exist | ||
|
|
@@ -5781,7 +5859,10 @@ void fsp_system_tablespace_truncate(bool shutdown) | |
|
|
||
| if (!shutdown) | ||
| { | ||
| err= space->defragment(); | ||
| bool drop_unknown= false; | ||
| err= fsp_drop_legacy_tables(drop_unknown); | ||
| if (err == DB_SUCCESS || drop_unknown == false) | ||
| err= space->defragment(); | ||
Thirunarayanan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (err) | ||
| { | ||
| srv_sys_space.set_shrink_fail(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we also look for the specific names of the garbage tables here? We could be outputting some garbage, and the test would not catch that.
Can we also check the contents of
INFORMATION_SCHEMA.INNODB_SYS_TABLESand friends to show that the dummy tables appear and disappear as intended?