Skip to content

Commit

Permalink
MDEV-15373 engine gtid_slave_pos table name disobeys lower-case-table…
Browse files Browse the repository at this point in the history
…-names

Replicated transaction extra gtid statement on slave failed to specify
an engine gtid_slave_pos name correctly. In case  lower-case-table-names > 0
the InnoDB table name was generated to reproduce the lower-case-table-names=0 version
which is of mixed cases.
In rpl.rpl_mdev12179 test run this triggered a failure to DROP table which
was due to the innodb table handle was not closed:
 InnoDB: Waited XYZ seconds for ref-count on table: `mysql`.`gtid_slave_pos_innodb`
on windows.
The closing issue was caused by having the table registered twice in the table cache,
for its lower- and mixed- case name versions. The DROP-table handler closed only
only one of the cache item to leave the 2nd one active.
(On Linux a failure occurs earlier at attempt to open an expected lower-cased table:

  Last_Error: Error during XID COMMIT: failed to update GTID state in mysql.gtid_slave_pos: 1146: Table 'mysql.gtid_slave_pos_InnoDB' doesn't exist

but the table's name as the message shows is not in the right case).

Fixed with consulting lower-case-table-names when the engine gtid-slave-pos table
is created.
Note the lower-case-table-names=a-value created table will not recognized when next
the lower case option changes to a different value.
In 10.4 a follow-up patch is going to lowercase gtid-slave-pos autocreated table
at once at their origination, and a warning is issued in the 10.3 current patch.
  • Loading branch information
andrelkin committed May 18, 2018
1 parent 2a33d24 commit 9df656d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 8 deletions.
22 changes: 16 additions & 6 deletions mysql-test/suite/rpl/r/rpl_mdev12179.result
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include/rpl_init.inc [topology=1->2]
connection server_2;
call mtr.add_suppression("The automatically created table.*name may not be entirely in lowercase");
SET GLOBAL gtid_pos_auto_engines="innodb";
ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first
include/stop_slave.inc
Expand Down Expand Up @@ -152,12 +153,12 @@ a
1
2
*** Verify that mysql.gtid_slave_pos_InnoDB is auto-created ***
SELECT table_name, engine FROM information_schema.tables
SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
table_name engine
lower(table_name) engine
gtid_slave_pos MyISAM
gtid_slave_pos_InnoDB InnoDB
gtid_slave_pos_innodb InnoDB
include/stop_slave.inc
SET sql_log_bin=0;
INSERT INTO mysql.gtid_slave_pos SELECT * FROM mysql.gtid_slave_pos_InnoDB;
Expand Down Expand Up @@ -245,15 +246,24 @@ a
3
4
*** Verify that mysql.gtid_slave_pos_InnoDB is auto-created ***
SELECT table_name, engine FROM information_schema.tables
SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
table_name engine
lower(table_name) engine
gtid_slave_pos MyISAM
gtid_slave_pos_InnoDB InnoDB
gtid_slave_pos_innodb InnoDB
SELECT domain_id, max(seq_no) FROM mysql.gtid_slave_pos GROUP BY domain_id;
domain_id max(seq_no)
0 13
connection server_2;
*** Restart the slave server to prove 'gtid_slave_pos_innodb' autodiscovery ***
connection server_2;
SELECT max(seq_no) FROM mysql.gtid_slave_pos_InnoDB into @seq_no;
connection server_1;
INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2;
include/save_master_gtid.inc
connection server_2;
include/sync_with_master_gtid.inc
include/stop_slave.inc
SET GLOBAL gtid_pos_auto_engines="";
SET sql_log_bin=0;
Expand Down
40 changes: 38 additions & 2 deletions mysql-test/suite/rpl/t/rpl_mdev12179.test
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
--source include/rpl_init.inc

--connection server_2
call mtr.add_suppression("The automatically created table.*name may not be entirely in lowercase");

--error ER_SLAVE_MUST_STOP
SET GLOBAL gtid_pos_auto_engines="innodb";
--source include/stop_slave.inc
Expand Down Expand Up @@ -161,7 +163,8 @@ let $wait_condition=
SELECT EXISTS (SELECT * FROM information_schema.tables
WHERE table_schema='mysql' AND table_name='gtid_slave_pos_InnoDB');
--source include/wait_condition.inc
SELECT table_name, engine FROM information_schema.tables
# MDEV-15373 lowercases 'table_name' to satisfy --lower-case-table-names options
SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;

Expand Down Expand Up @@ -225,7 +228,7 @@ let $wait_condition=
SELECT EXISTS (SELECT * FROM information_schema.tables
WHERE table_schema='mysql' AND table_name='gtid_slave_pos_InnoDB');
--source include/wait_condition.inc
SELECT table_name, engine FROM information_schema.tables
SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
SELECT domain_id, max(seq_no) FROM mysql.gtid_slave_pos GROUP BY domain_id;
Expand Down Expand Up @@ -265,6 +268,39 @@ while (!$done)
# Note that at this point, the contents of table t2, as well as the GTID
# position, is non-deterministic.

# MDEV-15373 engine gtid_slave_pos table name disobeys lower-case-table-names
# This snippet verifies that engine gtid_slave_pos table is found,
# its data are up-to-date.
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
--connection server_2
--shutdown_server 30
--source include/wait_until_disconnected.inc

--echo *** Restart the slave server to prove 'gtid_slave_pos_innodb' autodiscovery ***
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
restart: --skip-slave-start=0
EOF

--connection server_2
--enable_reconnect
--source include/wait_until_connected_again.inc
SELECT max(seq_no) FROM mysql.gtid_slave_pos_InnoDB into @seq_no;

--connection server_1
INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2;
--source include/save_master_gtid.inc

--connection server_2
--source include/sync_with_master_gtid.inc
if (`SELECT max(seq_no) <> @seq_no + 1 FROM mysql.gtid_slave_pos_InnoDB`)
{
SELECT * FROM mysql.gtid_slave_pos_InnoDB;
--die Inconsistent table
}
#
# end of MDEV-15373

#--connection server_2
--source include/stop_slave.inc
Expand Down
1 change: 1 addition & 0 deletions sql/rpl_rli.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1780,6 +1780,7 @@ gtid_pos_auto_create_tables(rpl_slave_state::gtid_pos_table **list_ptr)
p= strmake(p, plugin_name(*auto_engines)->str, FN_REFLEN - (p - buf));
table_name.str= buf;
table_name.length= p - buf;
table_case_convert(const_cast<char*>(table_name.str), table_name.length);
entry= rpl_global_gtid_slave_state->alloc_gtid_pos_table
(&table_name, hton, rpl_slave_state::GTID_POS_AUTO_CREATE);
if (!entry)
Expand Down
7 changes: 7 additions & 0 deletions sql/slave.cc
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,13 @@ gtid_pos_table_creation(THD *thd, plugin_ref engine, LEX_CSTRING *table_name)
FALSE, FALSE);
if (unlikely(thd->is_error()))
err= 1;
/* The warning is relevant to 10.3 and earlier. */
sql_print_warning("The automatically created table '%s' name may not be "
"entirely in lowercase. The table name will be converted "
"to lowercase to any future upgrade to 10.4.0 and later "
"version where it will be auto-created at once "
"in lowercase.",
table_name->str);
end:
thd->variables.option_bits= thd_saved_option;
thd->reset_query();
Expand Down

0 comments on commit 9df656d

Please sign in to comment.