From: Davi Arnaut Date: March 8 2010 6:43pm Subject: bzr commit into mysql-next-mr-bugfixing branch (davi:3119) Bug#33669 List-Archive: http://lists.mysql.com/commits/102611 X-Bug: 33669 Message-Id: <20100308184309.16825444242@skynet> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_epFd3xqtpL6xP7TiGfzpUg)" --Boundary_(ID_epFd3xqtpL6xP7TiGfzpUg) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline # At a local mysql-next-mr-bugfixing repository of davi 3119 Davi Arnaut 2010-03-08 Bug#33669: Transactional temporary tables do not work under --read-only The problem was that in read only mode (read_only enabled), the server would mistakenly deny data modification attempts for temporary tables which belong to a transactional storage engine (eg. InnoDB). The solution is to allow transactional temporary tables to be modified under read only mode. As a whole, the read only mode does not apply to any kind of temporary table. @ mysql-test/r/read_only_innodb.result Add test case result for Bug#33669 @ mysql-test/t/read_only_innodb.test Add test case for Bug#33669 @ sql/lock.cc Rename mysql_lock_tables_check to lock_tables_check and make it static. Move locking related checks from get_lock_data to lock_tables_check. Allow write locks to temporary tables even under read-only. modified: mysql-test/r/read_only_innodb.result mysql-test/t/read_only_innodb.test sql/lock.cc === modified file 'mysql-test/r/read_only_innodb.result' --- a/mysql-test/r/read_only_innodb.result 2009-12-09 15:56:34 +0000 +++ b/mysql-test/r/read_only_innodb.result 2010-03-08 18:43:02 +0000 @@ -46,3 +46,73 @@ UNLOCK TABLES; DROP TABLE t1; DROP USER test@localhost; echo End of 5.1 tests +# +# Bug#33669: Transactional temporary tables do not work under --read-only +# +DROP DATABASE IF EXISTS db1; +# Setup user and tables +CREATE USER bug33669@localhost; +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT) ENGINE=INNODB; +CREATE TABLE db1.t2 (a INT) ENGINE=INNODB; +INSERT INTO db1.t1 VALUES (1); +INSERT INTO db1.t2 VALUES (2); +GRANT CREATE TEMPORARY TABLES, DROP, INSERT, +SELECT, LOCK TABLES ON db1.* TO bug33669@localhost; +SET GLOBAL READ_ONLY = ON; +# Connection con1 (user bug33669): +# Create, insert and drop temporary table: +CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB; +INSERT INTO temp VALUES (1); +DROP TABLE temp; +# Lock base tables and use temporary table: +CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB; +LOCK TABLES t1 READ, t2 READ; +SELECT * FROM t1; +a +1 +INSERT INTO temp values (1); +SELECT * FROM t2; +a +2 +UNLOCK TABLES; +DROP TABLE temp; +# Transaction +BEGIN; +SELECT * FROM t1; +a +1 +CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB; +INSERT INTO t1 VALUES (1); +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +INSERT INTO temp VALUES (1); +SELECT * FROM t2; +a +2 +ROLLBACK; +SELECT * FROM temp; +a +DROP TABLE temp; +# Lock base table as READ and temporary table as WRITE: +CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB; +LOCK TABLES t1 READ, temp WRITE; +SELECT * FROM t1; +a +1 +SELECT * FROM temp; +a +INSERT INTO t1 VALUES (1); +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +INSERT INTO temp VALUES (1); +DROP TABLE temp; +UNLOCK TABLES; +# Lock temporary table that shadows a base table. +CREATE TEMPORARY TABLE t1 (a INT) ENGINE=INNODB; +LOCK TABLES t1 WRITE; +DROP TABLE t1; +SELECT * FROM t1; +ERROR HY000: Table 't1' was not locked with LOCK TABLES +# Disconnect and cleanup +SET GLOBAL READ_ONLY = OFF; +DROP USER bug33669@localhost; +DROP DATABASE db1; === modified file 'mysql-test/t/read_only_innodb.test' --- a/mysql-test/t/read_only_innodb.test 2009-12-09 15:56:34 +0000 +++ b/mysql-test/t/read_only_innodb.test 2010-03-08 18:43:02 +0000 @@ -83,3 +83,75 @@ DROP USER test@localhost; disconnect con1; --echo echo End of 5.1 tests + +--echo # +--echo # Bug#33669: Transactional temporary tables do not work under --read-only +--echo # + +--disable_warnings +DROP DATABASE IF EXISTS db1; +--enable_warnings + +--echo # Setup user and tables +CREATE USER bug33669@localhost; +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT) ENGINE=INNODB; +CREATE TABLE db1.t2 (a INT) ENGINE=INNODB; +INSERT INTO db1.t1 VALUES (1); +INSERT INTO db1.t2 VALUES (2); +GRANT CREATE TEMPORARY TABLES, DROP, INSERT, + SELECT, LOCK TABLES ON db1.* TO bug33669@localhost; +SET GLOBAL READ_ONLY = ON; +connect(con1,localhost,bug33669,,db1); +--echo # Connection con1 (user bug33669): + +--echo # Create, insert and drop temporary table: +CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB; +INSERT INTO temp VALUES (1); +DROP TABLE temp; + +--echo # Lock base tables and use temporary table: +CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB; +LOCK TABLES t1 READ, t2 READ; +SELECT * FROM t1; +INSERT INTO temp values (1); +SELECT * FROM t2; +UNLOCK TABLES; +DROP TABLE temp; + +--echo # Transaction +BEGIN; +SELECT * FROM t1; +CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB; +--error ER_OPTION_PREVENTS_STATEMENT +INSERT INTO t1 VALUES (1); +INSERT INTO temp VALUES (1); +SELECT * FROM t2; +ROLLBACK; +SELECT * FROM temp; +DROP TABLE temp; + +--echo # Lock base table as READ and temporary table as WRITE: +CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB; +LOCK TABLES t1 READ, temp WRITE; +SELECT * FROM t1; +SELECT * FROM temp; +--error ER_OPTION_PREVENTS_STATEMENT +INSERT INTO t1 VALUES (1); +INSERT INTO temp VALUES (1); +DROP TABLE temp; +UNLOCK TABLES; + +--echo # Lock temporary table that shadows a base table. +CREATE TEMPORARY TABLE t1 (a INT) ENGINE=INNODB; +LOCK TABLES t1 WRITE; +DROP TABLE t1; +--error ER_TABLE_NOT_LOCKED +SELECT * FROM t1; + +--echo # Disconnect and cleanup +disconnect con1; +connection default; +SET GLOBAL READ_ONLY = OFF; +DROP USER bug33669@localhost; +DROP DATABASE db1; === modified file 'sql/lock.cc' --- a/sql/lock.cc 2010-02-24 17:04:00 +0000 +++ b/sql/lock.cc 2010-03-08 18:43:02 +0000 @@ -89,8 +89,8 @@ extern HASH open_cache; #define GET_LOCK_UNLOCK 1 #define GET_LOCK_STORE_LOCKS 2 -static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count, - uint flags, TABLE **write_locked); +static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, + uint flags); static int lock_external(THD *thd, TABLE **table,uint count); static int unlock_external(THD *thd, TABLE **table,uint count); static void print_lock_error(int error, const char *); @@ -107,15 +107,20 @@ static int thr_lock_errno_to_mysql[]= @param flags Lock flags @return 0 if all the check passed, non zero if a check failed. */ -int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags) +static int +lock_tables_check(THD *thd, TABLE **tables, uint count, + bool *write_lock_used, uint flags) { + bool superuser; bool log_table_write_query; uint system_count; uint i; - DBUG_ENTER("mysql_lock_tables_check"); + DBUG_ENTER("lock_tables_check"); system_count= 0; + *write_lock_used= FALSE; + superuser= thd->security_ctx->master_access & SUPER_ACL; log_table_write_query= (is_log_table_write_query(thd->lex->sql_command) || ((flags & MYSQL_LOCK_PERF_SCHEMA) != 0)); @@ -148,10 +153,18 @@ int mysql_lock_tables_check(THD *thd, TA } } - if ((t->s->table_category == TABLE_CATEGORY_SYSTEM) && - (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE)) + if (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE) { - system_count++; + *write_lock_used= TRUE; + + if (t->s->table_category == TABLE_CATEGORY_SYSTEM) + system_count++; + + if (t->db_stat & HA_READ_ONLY) + { + my_error(ER_OPEN_AS_READONLY, MYF(0), t->alias); + DBUG_RETURN(1); + } } /* @@ -172,6 +185,20 @@ int mysql_lock_tables_check(THD *thd, TA thd->mdl_context.is_lock_owner(MDL_key::TABLE, t->s->db.str, t->s->table_name.str, MDL_SHARED))); + + /* + Prevent modifications to base tables if READ_ONLY is activated. + In any case, read only does not apply to temporary tables. + */ + if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) && !t->s->tmp_table) + { + if (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE && + !superuser && opt_readonly && !thd->slave_thread) + { + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); + DBUG_RETURN(1); + } + } } /* @@ -267,15 +294,15 @@ static void reset_lock_data_and_free(MYS MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags, bool *need_reopen) { - MYSQL_LOCK *sql_lock; - TABLE *write_lock_used; int rc; + MYSQL_LOCK *sql_lock; + bool write_lock_used; DBUG_ENTER("mysql_lock_tables"); *need_reopen= FALSE; - if (mysql_lock_tables_check(thd, tables, count, flags)) + if (lock_tables_check(thd, tables, count, &write_lock_used, flags)) DBUG_RETURN (NULL); ulong timeout= (flags & MYSQL_LOCK_IGNORE_TIMEOUT) ? @@ -283,8 +310,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, for (;;) { - if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS, - &write_lock_used))) + if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS))) break; if (global_read_lock && write_lock_used && @@ -308,21 +334,6 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, } } - if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) && - write_lock_used && - opt_readonly && - !(thd->security_ctx->master_access & SUPER_ACL) && - !thd->slave_thread) - { - /* - Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock. - We do not wait for READ_ONLY=0, and fail. - */ - reset_lock_data_and_free(&sql_lock); - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); - break; - } - thd_proc_info(thd, "System lock"); DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); if (sql_lock->table_count && lock_external(thd, sql_lock->table, @@ -459,9 +470,7 @@ void mysql_unlock_tables(THD *thd, MYSQL void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count) { MYSQL_LOCK *sql_lock; - TABLE *write_lock_used; - if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK, - &write_lock_used))) + if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK))) mysql_unlock_tables(thd, sql_lock); } @@ -603,9 +612,7 @@ void mysql_lock_downgrade_write(THD *thd thr_lock_type new_lock_type) { MYSQL_LOCK *locked; - TABLE *write_lock_used; - if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK, - &write_lock_used))) + if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK))) { for (uint i=0; i < locked->lock_count; i++) thr_downgrade_write_lock(locked->locks[i], new_lock_type); @@ -619,11 +626,9 @@ void mysql_lock_downgrade_write(THD *thd void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock) { MYSQL_LOCK *locked; - TABLE *write_lock_used; DBUG_ENTER("mysql_lock_abort"); - if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK, - &write_lock_used))) + if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK))) { for (uint i=0; i < locked->lock_count; i++) thr_abort_locks(locked->locks[i]->lock, upgrade_lock); @@ -648,12 +653,10 @@ void mysql_lock_abort(THD *thd, TABLE *t bool mysql_lock_abort_for_thread(THD *thd, TABLE *table) { MYSQL_LOCK *locked; - TABLE *write_lock_used; bool result= FALSE; DBUG_ENTER("mysql_lock_abort_for_thread"); - if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK, - &write_lock_used))) + if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK))) { for (uint i=0; i < locked->lock_count; i++) { @@ -848,11 +851,10 @@ static int unlock_external(THD *thd, TAB @param flags One of: - GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock - GET_LOCK_STORE_LOCKS : Store lock info in TABLE - @param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE */ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, - uint flags, TABLE **write_lock_used) + uint flags) { uint i,tables,lock_count; MYSQL_LOCK *sql_lock; @@ -861,9 +863,8 @@ static MYSQL_LOCK *get_lock_data(THD *th DBUG_ENTER("get_lock_data"); DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS)); - DBUG_PRINT("info", ("count %d", count)); - *write_lock_used=0; + for (i=tables=lock_count=0 ; i < count ; i++) { TABLE *t= table_ptr[i]; @@ -895,24 +896,12 @@ static MYSQL_LOCK *get_lock_data(THD *th { TABLE *table; enum thr_lock_type lock_type; + THR_LOCK_DATA **org_locks = locks; if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) continue; lock_type= table->reginfo.lock_type; DBUG_ASSERT(lock_type != TL_WRITE_DEFAULT && lock_type != TL_READ_DEFAULT); - if (lock_type >= TL_WRITE_ALLOW_WRITE) - { - *write_lock_used=table; - if (table->db_stat & HA_READ_ONLY) - { - my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias); - /* Clear the lock type of the lock data that are stored already. */ - sql_lock->lock_count= (uint) (locks - sql_lock->locks); - reset_lock_data_and_free(&sql_lock); - DBUG_RETURN(0); - } - } - THR_LOCK_DATA **org_locks = locks; locks_start= locks; locks= table->file->store_lock(thd, locks, (flags & GET_LOCK_UNLOCK) ? TL_IGNORE : --Boundary_(ID_epFd3xqtpL6xP7TiGfzpUg) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/davi.arnaut@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/davi.arnaut@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: davi.arnaut@stripped # target_branch: file:///home/davi/bzr/bugs/33669-5.5/ # testament_sha1: be84da4d5d78546cd55489aa52742c7c2c360619 # timestamp: 2010-03-08 15:43:08 -0300 # base_revision_id: vvaintroub@stripped\ # 6o50m3lm74s9kekx # # Begin bundle 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 --Boundary_(ID_epFd3xqtpL6xP7TiGfzpUg)--