From 79d2e6c82f5dfa2b5fd9f74d2129815b22ca819c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 4 Nov 2013 13:37:39 +0100 Subject: [PATCH 1/4] MDEV-5232 SET ROLE checks privileges differently from check_access() use the same inconsistent priv_user@host pair for SET ROLE privilege checks, just as check_access() does --- mysql-test/suite/roles/set_role-5232.result | 15 +++++++++++++++ mysql-test/suite/roles/set_role-5232.test | 20 ++++++++++++++++++++ sql/sql_acl.cc | 4 +++- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/roles/set_role-5232.result create mode 100644 mysql-test/suite/roles/set_role-5232.test diff --git a/mysql-test/suite/roles/set_role-5232.result b/mysql-test/suite/roles/set_role-5232.result new file mode 100644 index 00000000000..888a5f10c3d --- /dev/null +++ b/mysql-test/suite/roles/set_role-5232.result @@ -0,0 +1,15 @@ +create user ''@localhost; +create user c; +grant select on mysql.* to c; +create role r1; +grant r1 to c; +select user(), current_user(); +user() current_user() +c@localhost @localhost +select user from mysql.user group by user; +ERROR 42000: SELECT command denied to user ''@'localhost' for table 'user' +set role r1; +ERROR OP000: Invalid role specification `r1`. +drop role r1; +drop user c; +drop user ''@localhost; diff --git a/mysql-test/suite/roles/set_role-5232.test b/mysql-test/suite/roles/set_role-5232.test new file mode 100644 index 00000000000..c6cb3d925a4 --- /dev/null +++ b/mysql-test/suite/roles/set_role-5232.test @@ -0,0 +1,20 @@ +# +# MDEV-5232 SET ROLE checks privileges differently from check_access() +# +--source include/not_embedded.inc +create user ''@localhost; +create user c; +grant select on mysql.* to c; +create role r1; +grant r1 to c; +connect (c,localhost,c,,,,,); +select user(), current_user(); +--error ER_TABLEACCESS_DENIED_ERROR +select user from mysql.user group by user; +--error ER_INVALID_ROLE +set role r1; +disconnect c; +connection default; +drop role r1; +drop user c; +drop user ''@localhost; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index adc073f7117..879316f1da3 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1871,7 +1871,9 @@ int acl_check_setrole(THD *thd, char *rolename, ulonglong *access) continue; acl_user= (ACL_USER *)acl_user_base; - if (acl_user->wild_eq(thd->security_ctx->user, thd->security_ctx->host)) + /* Yes! priv_user@host. Don't ask why - that's what check_access() does. */ + if (acl_user->wild_eq(thd->security_ctx->priv_user, + thd->security_ctx->host)) { is_granted= TRUE; break; From 032a61fc0ac748af272db4f3931d22d48c9e9785 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 4 Nov 2013 13:40:20 +0100 Subject: [PATCH 2/4] restore the condition in filename_to_tablename() (broken in the revid:sergii@pisem.net-20130615170931-bn2h8j30vu5bfp0t) --- sql/sql_table.cc | 9 +++------ sql/sql_table.h | 7 ++----- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2b1dbbd394f..602e4faa979 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -365,11 +365,8 @@ uint explain_filename(THD* thd, Table name length. */ -uint filename_to_tablename(const char *from, char *to, uint to_length -#ifndef DBUG_OFF - , bool stay_quiet -#endif /* DBUG_OFF */ - ) +uint filename_to_tablename(const char *from, char *to, uint to_length, + bool stay_quiet) { uint errors; size_t res; @@ -382,7 +379,7 @@ uint filename_to_tablename(const char *from, char *to, uint to_length { res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) - to); - if (IF_DBUG(!stay_quiet,0)) + if (!stay_quiet) sql_print_error("Invalid (old?) table or database name '%s'", from); } diff --git a/sql/sql_table.h b/sql/sql_table.h index 58280b45861..02e72fc564c 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -123,11 +123,8 @@ enum enum_explain_filename_mode /** Don't check foreign key constraints while renaming table */ #define NO_FK_CHECKS (1 << 4) -uint filename_to_tablename(const char *from, char *to, uint to_length -#ifndef DBUG_OFF - , bool stay_quiet = false -#endif /* DBUG_OFF */ - ); +uint filename_to_tablename(const char *from, char *to, uint to_length, + bool stay_quiet = false); uint tablename_to_filename(const char *from, char *to, uint to_length); uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length); bool check_mysql50_prefix(const char *name); From 1ef87c5578a3a5d2a6481b7b0dfbca9b0f3d0e48 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 4 Nov 2013 21:37:29 +0100 Subject: [PATCH 3/4] MDEV-5080 Assertion `strcmp(share->unique_file_name,filename) || share->last_version' fails at /storage/myisam/mi_open.c:67 extend table names discovery (ha_discover_table_names() and Discovered_table_list) to return or optionally filter out temporary tables ("#sql..."). SHOW commands and I_S tables typically want temp table filtered out, while DROP DATABASE wants to see them too. additonally, remove the supression for the warning "Invalid (old?) table or database name" from mtr, and add it to .test files as needed (we need to test that this warning does *not* happen in drop.test) --- mysql-test/include/mtr_warnings.sql | 2 +- mysql-test/mysql-test-run.pl | 2 +- mysql-test/r/create.result | 1 + mysql-test/r/drop.result | 1 + mysql-test/r/mysqlcheck.result | 1 + mysql-test/r/upgrade.result | 1 + .../suite/rpl/r/rpl_mysql_upgrade.result | 1 + mysql-test/suite/rpl/t/rpl_mysql_upgrade.test | 1 + .../sys_vars/r/ignore_db_dirs_basic.result | 1 + .../sys_vars/t/ignore_db_dirs_basic.test | 2 ++ mysql-test/t/create.test | 1 + mysql-test/t/drop.test | 2 ++ mysql-test/t/mysqlcheck.test | 1 + mysql-test/t/upgrade.test | 1 + sql/handler.cc | 34 ++++++++++++++++--- sql/handler.h | 3 ++ sql/sql_db.cc | 2 +- 17 files changed, 50 insertions(+), 7 deletions(-) diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index 0a6077c21d2..0ad1079cd92 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -108,7 +108,7 @@ INSERT INTO global_suppressions VALUES ("Incorrect definition of table"), ("Incorrect information in file"), ("InnoDB: Warning: we did not need to do crash recovery"), - ("Invalid \\(old\\?\\) table or database name"), + /*("Invalid \\(old\\?\\) table or database name"),*/ ("Lock wait timeout exceeded"), ("Log entry on master is longer than max_allowed_packet"), ("unknown option '--loose-"), diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 9c4b1142ecc..2672d130a5f 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -4775,7 +4775,7 @@ sub extract_warning_lines ($$) { qr/slave SQL thread aborted/, qr/unknown option '--loose[-_]/, qr/unknown variable 'loose[-_]/, - qr/Invalid .*old.* table or database name/, + #qr/Invalid .*old.* table or database name/, qr/Now setting lower_case_table_names to [02]/, qr/Setting lower_case_table_names=2/, qr/You have forced lower_case_table_names to 0/, diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 2dd9bc8cfec..173a3887f4a 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("table or database name 't-1'"); drop table if exists t1,t2,t3,t4,t5; drop database if exists mysqltest; drop view if exists v1; diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 55309e54fb3..e1adfe95d8b 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("table or database name 'abc`def'"); drop table if exists t1; drop database if exists mysqltest; drop database if exists client_test_db; diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 3f5c08d7294..46469556215 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("Invalid .old.. table or database name"); DROP TABLE IF EXISTS t1, `t``1`, `t 1`; drop view if exists v1; drop database if exists client_test_db; diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result index d565bb2dbd6..48f0cd4ffb5 100644 --- a/mysql-test/r/upgrade.result +++ b/mysql-test/r/upgrade.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("Invalid .old.. table or database name"); drop database if exists `mysqltest1`; drop database if exists `mysqltest-1`; drop database if exists `#mysql50#mysqltest-1`; diff --git a/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result index 632529ce2b9..9e360beba2c 100644 --- a/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result +++ b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result @@ -1,6 +1,7 @@ include/master-slave.inc [connection master] call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +call mtr.add_suppression("table or database name 'mysqltest-1'"); DROP DATABASE IF EXISTS `#mysql50#mysqltest-1`; CREATE DATABASE `#mysql50#mysqltest-1`; Master position is not changed diff --git a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test index fedad86ea91..ec40d23f9eb 100644 --- a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test +++ b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test @@ -11,6 +11,7 @@ --source include/have_mysql_upgrade.inc call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +call mtr.add_suppression("table or database name 'mysqltest-1'"); connection master; --disable_warnings diff --git a/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result b/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result index 5802c71d280..6ae3fd70188 100644 --- a/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result +++ b/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("table or database name '.otherdir'"); select @@ignore_db_dirs; @@ignore_db_dirs e,lost+found,.mysqlgui,ignored_db diff --git a/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic.test b/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic.test index 9544fc540f9..78f6479dea6 100644 --- a/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic.test +++ b/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic.test @@ -1,3 +1,5 @@ +call mtr.add_suppression("table or database name '.otherdir'"); + select @@ignore_db_dirs; let $MYSQLD_DATADIR= `select @@datadir`; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index f82d859243a..a1152045dd9 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1,3 +1,4 @@ +call mtr.add_suppression("table or database name 't-1'"); # # Check some special create statements. # diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test index 079b10cf708..2cd87b1d980 100644 --- a/mysql-test/t/drop.test +++ b/mysql-test/t/drop.test @@ -1,3 +1,5 @@ +call mtr.add_suppression("table or database name 'abc`def'"); + # Initialise --disable_warnings drop table if exists t1; diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 06d702495c2..d7dab675dc6 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -1,3 +1,4 @@ +call mtr.add_suppression("Invalid .old.. table or database name"); # Embedded server doesn't support external clients --source include/not_embedded.inc diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index c6d01a16f49..18375856a79 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -1,3 +1,4 @@ +call mtr.add_suppression("Invalid .old.. table or database name"); -- source include/not_embedded.inc --disable_warnings diff --git a/sql/handler.cc b/sql/handler.cc index d7adf85fa55..5ef40768798 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4571,10 +4571,9 @@ static int cmp_table_names(LEX_STRING * const *a, LEX_STRING * const *b) Discovered_table_list::Discovered_table_list(THD *thd_arg, Dynamic_array *tables_arg, - const LEX_STRING *wild_arg) + const LEX_STRING *wild_arg) : + thd(thd_arg), with_temps(false), tables(tables_arg) { - thd= thd_arg; - tables= tables_arg; if (wild_arg->str && wild_arg->str[0]) { wild= wild_arg->str; @@ -4586,6 +4585,12 @@ Discovered_table_list::Discovered_table_list(THD *thd_arg, bool Discovered_table_list::add_table(const char *tname, size_t tlen) { + /* + TODO Check with_temps and filter out temp tables. + Implement the check, when we'll have at least one affected engine (with + custom discover_table_names() method, that calls add_table() directly). + Note: avoid comparing the same name twice (here and in add_file). + */ if (wild && my_wildcmp(files_charset_info, tname, tname + tlen, wild, wend, wild_prefix, wild_one, wild_many)) return 0; @@ -4598,8 +4603,13 @@ bool Discovered_table_list::add_table(const char *tname, size_t tlen) bool Discovered_table_list::add_file(const char *fname) { + bool is_temp= strncmp(fname, STRING_WITH_LEN(tmp_file_prefix)) == 0; + + if (is_temp && !with_temps) + return 0; + char tname[SAFE_NAME_LEN + 1]; - size_t tlen= filename_to_tablename(fname, tname, sizeof(tname)); + size_t tlen= filename_to_tablename(fname, tname, sizeof(tname), is_temp); return add_table(tname, tlen); } @@ -4658,6 +4668,22 @@ static my_bool discover_names(THD *thd, plugin_ref plugin, return 0; } +/** + Return the list of tables + + @param thd + @param db database to look into + @param dirp list of files in this database (as returned by my_dir()) + @param result the object to return the list of files in + @param reusable if true, on return, 'dirp' will be a valid list of all + non-table files. If false, discovery will work much faster, + but it will leave 'dirp' corrupted and completely unusable, + only good for my_dirend(). + + Normally, reusable=false for SHOW and INFORMATION_SCHEMA, and reusable=true + for DROP DATABASE (as it needs to know and delete non-table files). +*/ + int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, Discovered_table_list *result, bool reusable) { diff --git a/sql/handler.h b/sql/handler.h index e77d80e7668..a3537add781 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3193,11 +3193,14 @@ class Discovered_table_list: public handlerton::discovered_list { THD *thd; const char *wild, *wend; + bool with_temps; // whether to include temp tables in the result public: Dynamic_array *tables; Discovered_table_list(THD *thd_arg, Dynamic_array *tables_arg, const LEX_STRING *wild_arg); + Discovered_table_list(THD *thd_arg, Dynamic_array *tables_arg) + : thd(thd_arg), wild(NULL), with_temps(true), tables(tables_arg) {} ~Discovered_table_list() {} bool add_table(const char *tname, size_t tlen); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 7cc2caaa881..ec7561594c9 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -991,7 +991,7 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, /* first, get the list of tables */ Dynamic_array files(dirp->number_of_files); - Discovered_table_list tl(thd, &files, &null_lex_str); + Discovered_table_list tl(thd, &files); if (ha_discover_table_names(thd, &db, dirp, &tl, true)) DBUG_RETURN(1); From bf603250b02c936a271d628c93078cba3d081823 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 4 Nov 2013 21:46:16 +0100 Subject: [PATCH 4/4] increase the initial ibdata1 size, as explained in MySQL-5.6 revid:kevin.lewis@oracle.com-20120802192452-kmikiz990xzje18b " A maximum size of 10 Mb works in 5.1 because the initial required size of ibdata1 was less than 10M. But in 5.5, a change was made to allocate all 128 rollback segments at bootstrap. Since then, the initial size has been 10M + the default autoextend size of 8M. In 5.6, worklog 6216 changes the autoextend size from 8M to 64M. This changes the initial size of ibdata1 from 18M in 5.5 and earlier releases of 5.6 to 74M in the current mysql-5.6 and mysql-trunk. So this change is especially needed in 5.6. " 12M is enough to avoid autoextending during bootstrap --- mysql-test/include/default_mysqld.cnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf index 96848c39f11..12add65b387 100644 --- a/mysql-test/include/default_mysqld.cnf +++ b/mysql-test/include/default_mysqld.cnf @@ -39,7 +39,7 @@ loose-aria-pagecache-buffer-size=8M loose-feedback-user-info= mysql-test -loose-innodb_data_file_path= ibdata1:10M:autoextend +loose-innodb_data_file_path= ibdata1:12M:autoextend loose-innodb_buffer_pool_size= 8M loose-innodb_write_io_threads= 2 loose-innodb_read_io_threads= 2