-
Notifications
You must be signed in to change notification settings - Fork 2
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
MDEV-28452 wsrep_ready: OFF after MDL BF-BF conflict #426
base: 10.6
Are you sure you want to change the base?
Changes from all commits
3aa83f7
d456e13
4e785bd
827d90d
d20fcad
a9adda4
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 |
---|---|---|
@@ -0,0 +1,60 @@ | ||
connection node_2; | ||
connection node_1; | ||
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; | ||
connection node_1; | ||
CREATE TABLE `user` ( | ||
`id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`environment_id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, | ||
`password` char(60) COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`status` enum('sign_up','invited','active','archived') | ||
COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'invited', | ||
`last_login` datetime DEFAULT NULL, | ||
PRIMARY KEY (`id`), | ||
UNIQUE KEY `user_username_unique` (`username`), | ||
KEY `user_environment_id_index` (`environment_id`) | ||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; | ||
CREATE TABLE `log_history_daily` ( | ||
`type` enum('unknown','user','developer','api_key','api_env', | ||
'mail_token','device') COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`status` enum('valid','invalid') COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`origin` enum('unknown','browser','go','android','ios','third_party') | ||
COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'unknown', | ||
`ip` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, | ||
`user_id` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, | ||
`date` date NOT NULL, | ||
PRIMARY KEY (`type`,`status`,`origin`,`ip`,`value`,`date`), | ||
KEY `log_history_daily_user_id_foreign` (`user_id`), | ||
CONSTRAINT `log_history_daily_user_id_foreign` FOREIGN KEY (`user_id`) | ||
REFERENCES `user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE | ||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; | ||
SET SESSION autocommit = 0; | ||
INSERT INTO `user` VALUES ("id_1", "abc", "user 1", "secret", "active", NULL); | ||
INSERT INTO `log_history_daily` VALUES ("user", "valid", "unknown", | ||
"192.168.0.1", "Sample", "id_1", "2024-04-22"); | ||
COMMIT; | ||
connection node_2; | ||
SET GLOBAL wsrep_slave_threads = 2; | ||
SELECT @@wsrep_slave_threads; | ||
@@wsrep_slave_threads | ||
2 | ||
SET GLOBAL debug_dbug = "+d,sync.mdev_28452"; | ||
connection node_1; | ||
OPTIMIZE TABLE `log_history_daily`; | ||
Table Op Msg_type Msg_text | ||
test.log_history_daily optimize note Table does not support optimize, doing recreate + analyze instead | ||
test.log_history_daily optimize status OK | ||
COMMIT; | ||
UPDATE `user` SET `last_login` = '2024-04-23' WHERE `id`="id_1"; | ||
COMMIT; | ||
connection node_2a; | ||
SET DEBUG_SYNC='NOW WAIT_FOR mdev_28452_reached'; | ||
SET GLOBAL debug_dbug = 'RESET'; | ||
SET DEBUG_SYNC = 'now SIGNAL signal.mdev_28452'; | ||
SET DEBUG_SYNC = 'RESET'; | ||
connection node_1; | ||
DROP TABLE `log_history_daily`; | ||
DROP TABLE `user`; | ||
connection node_2; | ||
SET GLOBAL wsrep_slave_threads = DEFAULT; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# | ||
# Test for MDEV-28452: wsrep_ready: OFF after MDL BF-BF conflict | ||
# | ||
|
||
--source include/galera_cluster.inc | ||
--source include/have_debug.inc | ||
--source include/have_debug_sync.inc | ||
|
||
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 | ||
|
||
--connection node_1 | ||
|
||
# create two tables | ||
CREATE TABLE `user` ( | ||
`id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`environment_id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, | ||
`password` char(60) COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`status` enum('sign_up','invited','active','archived') | ||
COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'invited', | ||
`last_login` datetime DEFAULT NULL, | ||
PRIMARY KEY (`id`), | ||
UNIQUE KEY `user_username_unique` (`username`), | ||
KEY `user_environment_id_index` (`environment_id`) | ||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; | ||
|
||
|
||
CREATE TABLE `log_history_daily` ( | ||
`type` enum('unknown','user','developer','api_key','api_env', | ||
'mail_token','device') COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`status` enum('valid','invalid') COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`origin` enum('unknown','browser','go','android','ios','third_party') | ||
COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'unknown', | ||
`ip` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, | ||
`value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, | ||
`user_id` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, | ||
`date` date NOT NULL, | ||
PRIMARY KEY (`type`,`status`,`origin`,`ip`,`value`,`date`), | ||
KEY `log_history_daily_user_id_foreign` (`user_id`), | ||
CONSTRAINT `log_history_daily_user_id_foreign` FOREIGN KEY (`user_id`) | ||
REFERENCES `user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE | ||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; | ||
|
||
|
||
SET SESSION autocommit = 0; | ||
|
||
# insert one row in each table | ||
INSERT INTO `user` VALUES ("id_1", "abc", "user 1", "secret", "active", NULL); | ||
INSERT INTO `log_history_daily` VALUES ("user", "valid", "unknown", | ||
"192.168.0.1", "Sample", "id_1", "2024-04-22"); | ||
COMMIT; | ||
|
||
# Start two slave threads in node 2. | ||
# Set up a synchronizaton point (sync.mdev_28452) for slave thread 1 | ||
# where the thread stops when it holds an exclusive metadata lock | ||
# (MDL_EXCLUSIVE) for the OPTIMIZE TABLE statement (see below). | ||
--connection node_2 | ||
SET GLOBAL wsrep_slave_threads = 2; | ||
SELECT @@wsrep_slave_threads; | ||
SET GLOBAL debug_dbug = "+d,sync.mdev_28452"; | ||
|
||
# Run two transactions sequentially on node 1: | ||
# 1) OPTIMIZE TABLE on the child table of the foreign key constraint, | ||
--connection node_1 | ||
OPTIMIZE TABLE `log_history_daily`; | ||
COMMIT; | ||
|
||
# 2) and UPDATE on the parent table of the foreign key constraint. | ||
# update the row in "user" so that it affects the foreign key in | ||
# "log_history_daily" | ||
UPDATE `user` SET `last_login` = '2024-04-23' WHERE `id`="id_1"; | ||
COMMIT; | ||
|
||
# allow the stopped OPTIMIZE TABLE transaction to proceed | ||
--connection node_2a | ||
|
||
# wait till debug sync point has been set on node 2 | ||
SET DEBUG_SYNC='NOW WAIT_FOR mdev_28452_reached'; | ||
|
||
SET GLOBAL debug_dbug = 'RESET'; | ||
SET DEBUG_SYNC = 'now SIGNAL signal.mdev_28452'; | ||
SET DEBUG_SYNC = 'RESET'; | ||
|
||
# wait till the UPDATE has finished on node 2 | ||
--let $wait_condition = SELECT COUNT(*) > 0 FROM `user` WHERE `last_login` = '2024-04-23' | ||
--source include/wait_condition.inc | ||
|
||
# cleanup | ||
--connection node_1 | ||
DROP TABLE `log_history_daily`; | ||
DROP TABLE `user`; | ||
--connection node_2 | ||
SET GLOBAL wsrep_slave_threads = DEFAULT; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1608,18 +1608,45 @@ bool Sql_cmd_optimize_table::execute(THD *thd) | |
FALSE, UINT_MAX, FALSE)) | ||
goto error; /* purecov: inspected */ | ||
|
||
WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table); | ||
#ifdef WITH_WSREP | ||
if (WSREP(thd) && | ||
(!thd->is_current_stmt_binlog_format_row() || | ||
!thd->find_temporary_table(first_table))) | ||
{ | ||
/* | ||
It makes sense to set auto_increment_* to defaults in TOI operations. | ||
Must be done before wsrep_TOI_begin() since Query_log_event encapsulating | ||
TOI statement and auto inc variables for wsrep replication is constructed | ||
there. Variables are reset back in THD::reset_for_next_command() before | ||
processing of next command. | ||
*/ | ||
if (wsrep_auto_increment_control) | ||
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 don't understand why we need to change auto_increment variables here. 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 tested also without changing 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. Optimize table could do table re-create, but I do not know if that has any effect on autoinc values (could be verified using show create table x; in both nodes). |
||
{ | ||
thd->variables.auto_increment_offset = 1; | ||
thd->variables.auto_increment_increment = 1; | ||
} | ||
|
||
wsrep::key_array keys; | ||
if (wsrep_thd_is_local(thd) && | ||
!wsrep_append_fk_parent_table(thd, first_table, &keys)) | ||
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. If wsrep_append_fk_parent_table fails, then we skip TOI, and but still perform the OPTIMIZE locally. 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. Yes, it is certainly possible to change the code so that |
||
{ | ||
WSREP_TO_ISOLATION_BEGIN_ALTER(first_table->db.str, | ||
first_table->table_name.str, | ||
first_table, NULL, &keys, NULL) | ||
{ | ||
WSREP_WARN("OPTIMIZE TABLE isolation failure"); | ||
DBUG_RETURN(TRUE); | ||
} | ||
} | ||
} | ||
#endif /* WITH_WSREP */ | ||
res= (specialflag & SPECIAL_NO_NEW_FUNC) ? | ||
mysql_recreate_table(thd, first_table, &recreate_info, true) : | ||
mysql_admin_table(thd, first_table, &m_lex->check_opt, | ||
&msg_optimize, TL_WRITE, 1, 0, 0, 0, | ||
&handler::ha_optimize, 0, true); | ||
m_lex->first_select_lex()->table_list.first= first_table; | ||
m_lex->query_tables= first_table; | ||
|
||
#ifdef WITH_WSREP | ||
wsrep_error_label: | ||
#endif /* WITH_WSREP */ | ||
error: | ||
DBUG_RETURN(res); | ||
} | ||
|
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.
Is these table column names directly from customer and do you really need all columns?
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.
These column names are indeed copied exactly from the customer case.
I have now removed all those columns that are not part of the keys and, thus, do not affect the test in any way.
But it would be possible to create a minimal test case with table names
t1
andt2
and with just two columns per table.