Description:
create a partition table, and using XA trx, after xa prepare and restart, it will reports ' Invalid (old?) table or database name' in error log
How to repeat:
a simple test case, check the error log after running it
call mtr.add_suppression("Found .* prepared XA transactions");
create table t1(a int primary key, b int) PARTITION BY HASH(a) PARTITIONS 4;
connect (con1,localhost,root);
--connection con1
xa begin '123';
insert into t1 values(1,2);
xa end '123';
xa prepare '123';
--connection default
#restart
--source include/restart_mysqld.inc
disconnect con1;
--connection default
xa recover;
xa commit '123';
drop table t1;
and the error log:
[ERROR] [MY-010520] [Server] Invalid (old?) table or database name 't1#p#p1'
Suggested fix:
get_table_name_info() doesn't handle partition table, should format dbname and tablename.
a simple fix like this:
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index eb7bf18..f50a5ca 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -2793,15 +2793,14 @@ dberr_t trx_prepare_for_mysql(trx_t *trx) {
static bool get_table_name_info(st_handler_tablename *table,
const dict_table_t *dd_table,
MEM_ROOT *mem_root) {
- const char *ptr;
+ std::string db_str;
+ std::string tbl_str;
+ dict_name::get_table(dd_table->name.m_name, db_str, tbl_str);
- size_t len = dict_get_db_name_len(dd_table->name.m_name);
- table->db = strmake_root(mem_root, dd_table->name.m_name, len);
+ table->db = strmake_root(mem_root, db_str.c_str(), db_str.size());
if (table->db == nullptr) return true;
-
- ptr = dict_remove_db_name(dd_table->name.m_name);
- len = ut_strlen(ptr);
- table->tablename = strmake_root(mem_root, ptr, len);
+
+ table->tablename = strmake_root(mem_root, tbl_str.c_str(), tbl_str.size());
if (table->tablename == nullptr) return true;
return false;