Bug #113416 Contribution by Tencent: replaying rename space ddl log fails
Submitted: 14 Dec 2023 7:34 Modified: 14 Dec 2023 8:37
Reporter: Xiaodong Huang (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: DDL Severity:S2 (Serious)
Version:8.2.0 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution, ddl log, exchange partition, rename table

[14 Dec 2023 7:34] Xiaodong Huang
Description:
When a DDL statement related to Log_Type::RENAME_SPACE_LOG type ddl log crashes unexpectedly and the server is subsequently restarted. In such cases, the table involved in the DDL statement may not be found.

Root Cause:
The format of  Log_Type::RENAME_SPACE_LOG  is similar to 

[DDL record: RENAME SPACE, id=13038, thread_id=13, space_id=2436, old_file_path="old_file_path".ibd, new_file_path="new_file_path".ibd].

Both the “old_file_path“ and “new_file_path“ use "my_charset_filename" charset,  while the tablespace name uses "system_charset_info" charset. During the DDL recovery process,the "new_space_name" is parsed from the "new_file_path" without converting the charset. As a result, after the server restarts, loading the space related to "new_file_path" fails.

Definition:  
The “my_charset_filename”  includes the following characters, any other characters being converted to @xxxx as referenced in   https://dev.mysql.com/doc/refman/8.0/en/identifier-mapping.html

1.   '\0'  NULL
2.    A..Z  capital letters,
3.    a..z  small letters
4.    0..9  digits
5.    _     underscore

The “system_charset_info” is Unicode (UTF-8).

How to repeat:
1. Prepare multiple tables with names containing special characters that are present in "system_charset_info" but not in "my_charset_filename". For example, create 50 tables with name containing the Chinese character "测试". The table names are listed as follows:

   create table `测试001` (a int);

   create table `测试002`(a int);

    ...

   create table `测试050`(a int);

2. Ensure that the `innodb_print_ddl_logs` variable is enabled and execute the RENAME TABLE statement to rename these tables containing special characters. When you see the DDL logs appear in the error log, immediately kill the server. For example, rename tables `测试001`, `测试002`, ..., `测试050` to `测试101`, `测试102`, ..., `测试150`.

   RENAME TABLE `测试001` TO `测试101`, `测试002` TO `测试102`, ..., `测试050` TO `测试150`;

3. Restart the server and then use the SHOW CREATE TABLE statement to display the tables recovered from replaying the DDL log. The result will report "Tablespace is missing for table 测试xxx".

Suggested fix:
The "fil_space_t::name" use "system_charset_info" charset.  During the DDL recovery process, the function fil_rename_tablespace parses the tablespace name from “new_file_path“ . it then transfers tablespace name to "fil_space_t::name”  by invoking fil_rename_tablespace function.
[14 Dec 2023 7:38] Xiaodong Huang
Very simple bugfix

(*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: 0001-bugfix-for-this-problem.patch (application/octet-stream, text), 1.16 KiB.

[14 Dec 2023 8:37] MySQL Verification Team
Hello Xiaodong,

Thank you for the report and contribution.

regards,
Umesh