diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index a3e88765554..3961c7e8c27 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -711,9 +711,9 @@ user CREATE TABLE `user` ( `is_role` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `default_role` char(80) COLLATE utf8_bin NOT NULL DEFAULT '', `max_statement_time` decimal(12,6) NOT NULL DEFAULT 0.000000, - `password_last_changed` timestamp NULL DEFAULT NULL, + `password_last_changed` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), `password_lifetime` smallint(5) unsigned DEFAULT NULL, - `account_locked` enum('N','Y') COLLATE utf8_bin NOT NULL DEFAULT 'N', + `account_locked` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', PRIMARY KEY (`Host`,`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges' CREATE ROLE `aRole`; @@ -726,6 +726,132 @@ mysql.session N root N mysql.sys N aRole Y +DROP ROLE aRole; +# +# MDEV-24122: Fix previously MySQL-5.7 data directories that upgraded prior to MDEV-23201 +# +# +DROP TABLE IF EXISTS mysql.user; +FLUSH TABLES mysql.user; +ALTER TABLE mysql.user ADD is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE mysql.user ADD default_role char(80) binary DEFAULT '' NOT NULL; +ALTER TABLE mysql.user ADD max_statement_time decimal(12,6) DEFAULT 0 NOT NULL; +FLUSH PRIVILEGES; +Phase 1/7: Checking and upgrading mysql database +Processing databases +mysql +mysql.column_stats OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.gtid_slave_pos OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.host OK +mysql.index_stats OK +mysql.innodb_index_stats OK +mysql.innodb_table_stats OK +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.proxies_priv OK +mysql.roles_mapping OK +mysql.servers OK +mysql.table_stats OK +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.user OK +Phase 2/7: Installing used storage engines... Skipped +Phase 3/7: Fixing views +Phase 4/7: Running 'mysql_fix_privilege_tables' +Phase 5/7: Fixing table and database names +Phase 6/7: Checking and upgrading tables +Processing databases +information_schema +mtr +mtr.global_suppressions OK +mtr.test_suppressions OK +performance_schema +test +Phase 7/7: Running 'FLUSH PRIVILEGES' +OK +SHOW CREATE TABLE mysql.user; +Table Create Table +user CREATE TABLE `user` ( + `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '', + `User` char(80) COLLATE utf8_bin NOT NULL DEFAULT '', + `Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', + `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '', + `ssl_cipher` blob NOT NULL, + `x509_issuer` blob NOT NULL, + `x509_subject` blob NOT NULL, + `max_questions` int(11) unsigned NOT NULL DEFAULT 0, + `max_updates` int(11) unsigned NOT NULL DEFAULT 0, + `max_connections` int(11) unsigned NOT NULL DEFAULT 0, + `max_user_connections` int(11) NOT NULL DEFAULT 0, + `plugin` char(64) CHARACTER SET latin1 NOT NULL DEFAULT '', + `authentication_string` text COLLATE utf8_bin NOT NULL, + `password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `is_role` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `default_role` char(80) COLLATE utf8_bin NOT NULL DEFAULT '', + `max_statement_time` decimal(12,6) NOT NULL DEFAULT 0.000000, + `password_last_changed` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `password_lifetime` smallint(5) unsigned DEFAULT NULL, + `account_locked` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + PRIMARY KEY (`Host`,`User`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges' +CREATE ROLE `aRole`; +SET DEFAULT ROLE aRole; +SHOW GRANTS; +Grants for root@localhost +GRANT aRole TO 'root'@'localhost' WITH ADMIN OPTION +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +GRANT USAGE ON *.* TO 'aRole' +SET DEFAULT ROLE aRole FOR 'root'@'localhost' +SET DEFAULT ROLE NONE; +SHOW GRANTS; +Grants for root@localhost +GRANT aRole TO 'root'@'localhost' WITH ADMIN OPTION +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION +GRANT USAGE ON *.* TO 'aRole' DROP ROLE `aRole`; FLUSH PRIVILEGES; End of 10.2 tests diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test index a6702f91aa6..c116af860a6 100644 --- a/mysql-test/t/mysql_upgrade.test +++ b/mysql-test/t/mysql_upgrade.test @@ -246,6 +246,36 @@ FLUSH PRIVILEGES; SET ROLE `aRole`; SELECT `User`, `is_role` FROM `mysql`.`user`; +DROP ROLE aRole; + +--echo # +--echo # MDEV-24122: Fix previously MySQL-5.7 data directories that upgraded prior to MDEV-23201 +--echo # +--echo # + +# For 10.4 merge - dropping the view. +# DROP VIEW IF EXISTS mysql.user; +DROP TABLE IF EXISTS mysql.user; +--copy_file std_data/mysql57user.frm $MYSQLD_DATADIR/mysql/user.frm +--copy_file std_data/mysql57user.MYI $MYSQLD_DATADIR/mysql/user.MYI +--copy_file std_data/mysql57user.MYD $MYSQLD_DATADIR/mysql/user.MYD +FLUSH TABLES mysql.user; + +# What prior to MDEV-23201 would of done: +ALTER TABLE mysql.user ADD is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE mysql.user ADD default_role char(80) binary DEFAULT '' NOT NULL; +ALTER TABLE mysql.user ADD max_statement_time decimal(12,6) DEFAULT 0 NOT NULL; +FLUSH PRIVILEGES; + +--exec $MYSQL_UPGRADE --force 2>&1 +SHOW CREATE TABLE mysql.user; + +CREATE ROLE `aRole`; +SET DEFAULT ROLE aRole; +SHOW GRANTS; +SET DEFAULT ROLE NONE; +SHOW GRANTS; + DROP ROLE `aRole`; --exec $MYSQL mysql < $MYSQLTEST_VARDIR/tmp/user.sql FLUSH PRIVILEGES; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 9a8ebaa119e..8baee4fef17 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -647,16 +647,30 @@ UPDATE user SET Create_tablespace_priv = Super_priv WHERE @hadCreateTablespacePr ALTER TABLE user ADD plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL AFTER max_user_connections, ADD authentication_string TEXT NOT NULL AFTER plugin; ALTER TABLE user CHANGE auth_string authentication_string TEXT NOT NULL; -ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, - MODIFY authentication_string TEXT NOT NULL; + ALTER TABLE user ADD password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER authentication_string; ALTER TABLE user ADD is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER password_expired; ALTER TABLE user ADD default_role char(80) binary DEFAULT '' NOT NULL AFTER is_role; ALTER TABLE user ADD max_statement_time decimal(12,6) DEFAULT 0 NOT NULL AFTER default_role; + -- Somewhere above, we ran ALTER TABLE user .... CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin. --- we want password_expired column to have collation utf8_general_ci. -ALTER TABLE user MODIFY password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; -ALTER TABLE user MODIFY is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +-- we want password_expired column to have collation utf8_general_ci. +-- Order columns correctly that were not ordered until MDEV-23201 (ff8ffef3e1915d7a9caa07d9461cd8d47c4baf98) + +ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL AFTER max_user_connections, + MODIFY authentication_string TEXT NOT NULL AFTER plugin, + MODIFY password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER authentication_string, + MODIFY is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER password_expired, + MODIFY default_role char(80) binary DEFAULT '' NOT NULL AFTER is_role, + MODIFY max_statement_time decimal(12,6) DEFAULT 0 NOT NULL AFTER default_role, +-- MDEV-24122 formerly mysql5.7 users may have the following columns password_last_changed, +-- password_lifetime and account_locked. Ensure they are beyond the end of the user columns +-- used by MariaDB. MariaDB-10.4 will use these in the creation of mysql.global_priv. +-- password_last_changed has a DEFAULT/ON UPDATE of CURRENT_TIMESTAMP to keep track of +-- time until 10.4 added. + MODIFY IF EXISTS password_last_changed timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER max_statement_time, + MODIFY IF EXISTS password_lifetime smallint unsigned DEFAULT NULL AFTER password_last_changed, + MODIFY IF EXISTS account_locked enum('N', 'Y') CHARACTER SET utf8 DEFAULT 'N' NOT NULL after password_lifetime; -- Need to pre-fill mysql.proxies_priv with access for root even when upgrading from -- older versions