Commit 9c2961ab authored by He Zhenxing's avatar He Zhenxing

Auto merge

parents 7f76b4d3 f147aa35
...@@ -207,3 +207,30 @@ insert into t2 (a) values (3); ...@@ -207,3 +207,30 @@ insert into t2 (a) values (3);
unlock tables; unlock tables;
# --> connection con1 # --> connection con1
drop table t1, t2, t3; drop table t1, t2, t3;
#
# Bug#51710 FLUSH TABLES <view> WITH READ LOCK kills the server
#
drop view if exists v1, v2, v3;
drop table if exists t1, v1;
create table t1 (a int);
create view v1 as select 1;
create view v2 as select * from t1;
create view v3 as select * from v2;
flush table v1, v2, v3 with read lock;
ERROR HY000: 'test.v1' is not BASE TABLE
flush table v1 with read lock;
ERROR HY000: 'test.v1' is not BASE TABLE
flush table v2 with read lock;
ERROR HY000: 'test.v2' is not BASE TABLE
flush table v3 with read lock;
ERROR HY000: 'test.v3' is not BASE TABLE
create temporary table v1 (a int);
flush table v1 with read lock;
ERROR HY000: 'test.v1' is not BASE TABLE
drop view v1;
create table v1 (a int);
flush table v1 with read lock;
drop temporary table v1;
unlock tables;
drop view v2, v3;
drop table t1, v1;
...@@ -46,3 +46,174 @@ UNLOCK TABLES; ...@@ -46,3 +46,174 @@ UNLOCK TABLES;
DROP TABLE t1; DROP TABLE t1;
DROP USER test@localhost; DROP USER test@localhost;
echo End of 5.1 tests 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, DELETE, UPDATE,
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
# INSERT SELECT from base table into temporary table:
CREATE TEMPORARY TABLE temp1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE temp2 LIKE temp1;
BEGIN;
INSERT INTO temp1 VALUES (10);
INSERT INTO temp2 VALUES (10);
INSERT INTO temp1 SELECT * FROM t1;
INSERT INTO temp2 SELECT * FROM t2;
SELECT * FROM temp1 ORDER BY a;
a
1
10
SELECT * FROM temp2 ORDER BY a;
a
2
10
ROLLBACK;
SELECT * FROM temp1,temp2;
a a
LOCK TABLES t1 READ, t2 READ;
INSERT INTO temp1 VALUES (10);
INSERT INTO temp2 VALUES (10);
INSERT INTO temp1 SELECT * FROM t1;
INSERT INTO temp2 SELECT * FROM t2;
SELECT * FROM temp1 ORDER BY a;
a
1
10
SELECT * FROM temp2 ORDER BY a;
a
2
10
UNLOCK TABLES;
DELETE temp1, temp2 FROM temp1, temp2;
INSERT INTO temp1 VALUES (10);
INSERT INTO temp2 VALUES (10);
INSERT INTO temp1 SELECT * FROM t1;
INSERT INTO temp2 SELECT * FROM t2;
SELECT * FROM temp1 ORDER BY a;
a
1
10
SELECT * FROM temp2 ORDER BY a;
a
2
10
DROP TABLE temp1, temp2;
# INSERT and INSERT SELECT that uses subqueries:
CREATE TEMPORARY TABLE temp1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE temp2 LIKE temp1;
INSERT INTO temp1 (a) VALUES ((SELECT MAX(a) FROM t1));
LOCK TABLES t2 READ;
INSERT INTO temp2 (a) VALUES ((SELECT MAX(a) FROM t2));
UNLOCK TABLES;
LOCK TABLES t1 READ, t2 READ;
INSERT INTO temp1 SELECT * FROM t1 WHERE a < (SELECT MAX(a) FROM t2);
INSERT INTO temp2 SELECT * FROM t2 WHERE a > (SELECT MAX(a) FROM t1);
UNLOCK TABLES;
INSERT INTO temp1 SELECT * FROM t1 WHERE a < (SELECT MAX(a) FROM t2);
INSERT INTO temp2 SELECT * FROM t2 WHERE a > (SELECT MAX(a) FROM t1);
SELECT * FROM temp1 ORDER BY a;
a
1
1
1
SELECT * FROM temp2 ORDER BY a;
a
2
2
2
DROP TABLE temp1, temp2;
# Multiple table update:
CREATE TEMPORARY TABLE temp1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE temp2 LIKE temp1;
INSERT INTO temp1 VALUES (1),(2);
INSERT INTO temp2 VALUES (3),(4);
UPDATE temp1,temp2 SET temp1.a = 5, temp2.a = 10;
SELECT * FROM temp1, temp2;
a a
5 10
5 10
5 10
5 10
DROP TABLE temp1, temp2;
# Disconnect and cleanup
SET GLOBAL READ_ONLY = OFF;
DROP USER bug33669@localhost;
DROP DATABASE db1;
...@@ -324,3 +324,34 @@ disconnect con1; ...@@ -324,3 +324,34 @@ disconnect con1;
--source include/wait_until_disconnected.inc --source include/wait_until_disconnected.inc
connection default; connection default;
drop table t1, t2, t3; drop table t1, t2, t3;
--echo #
--echo # Bug#51710 FLUSH TABLES <view> WITH READ LOCK kills the server
--echo #
--disable_warnings
drop view if exists v1, v2, v3;
drop table if exists t1, v1;
--enable_warnings
create table t1 (a int);
create view v1 as select 1;
create view v2 as select * from t1;
create view v3 as select * from v2;
--error ER_WRONG_OBJECT
flush table v1, v2, v3 with read lock;
--error ER_WRONG_OBJECT
flush table v1 with read lock;
--error ER_WRONG_OBJECT
flush table v2 with read lock;
--error ER_WRONG_OBJECT
flush table v3 with read lock;
create temporary table v1 (a int);
--error ER_WRONG_OBJECT
flush table v1 with read lock;
drop view v1;
create table v1 (a int);
flush table v1 with read lock;
drop temporary table v1;
unlock tables;
drop view v2, v3;
drop table t1, v1;
...@@ -83,3 +83,149 @@ DROP USER test@localhost; ...@@ -83,3 +83,149 @@ DROP USER test@localhost;
disconnect con1; disconnect con1;
--echo echo End of 5.1 tests --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, DELETE, UPDATE,
SELECT, LOCK TABLES ON db1.* TO bug33669@localhost;
SET GLOBAL READ_ONLY = ON;
connect(con1,localhost,bug33669,,db1);
--echo # Connection con1 (user bug33669):
--echo
--echo # Create, insert and drop temporary table:
--echo
CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB;
INSERT INTO temp VALUES (1);
DROP TABLE temp;
--echo
--echo # Lock base tables and use temporary table:
--echo
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
--echo # Transaction
--echo
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
--echo # Lock base table as READ and temporary table as WRITE:
--echo
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
--echo # Lock temporary table that shadows a base table:
--echo
CREATE TEMPORARY TABLE t1 (a INT) ENGINE=INNODB;
LOCK TABLES t1 WRITE;
DROP TABLE t1;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM t1;
--echo
--echo # INSERT SELECT from base table into temporary table:
--echo
CREATE TEMPORARY TABLE temp1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE temp2 LIKE temp1;
BEGIN;
INSERT INTO temp1 VALUES (10);
INSERT INTO temp2 VALUES (10);
INSERT INTO temp1 SELECT * FROM t1;
INSERT INTO temp2 SELECT * FROM t2;
SELECT * FROM temp1 ORDER BY a;
SELECT * FROM temp2 ORDER BY a;
ROLLBACK;
SELECT * FROM temp1,temp2;
LOCK TABLES t1 READ, t2 READ;
INSERT INTO temp1 VALUES (10);
INSERT INTO temp2 VALUES (10);
INSERT INTO temp1 SELECT * FROM t1;
INSERT INTO temp2 SELECT * FROM t2;
SELECT * FROM temp1 ORDER BY a;
SELECT * FROM temp2 ORDER BY a;
UNLOCK TABLES;
DELETE temp1, temp2 FROM temp1, temp2;
INSERT INTO temp1 VALUES (10);
INSERT INTO temp2 VALUES (10);
INSERT INTO temp1 SELECT * FROM t1;
INSERT INTO temp2 SELECT * FROM t2;
SELECT * FROM temp1 ORDER BY a;
SELECT * FROM temp2 ORDER BY a;
DROP TABLE temp1, temp2;
--echo
--echo # INSERT and INSERT SELECT that uses subqueries:
CREATE TEMPORARY TABLE temp1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE temp2 LIKE temp1;
INSERT INTO temp1 (a) VALUES ((SELECT MAX(a) FROM t1));
LOCK TABLES t2 READ;
INSERT INTO temp2 (a) VALUES ((SELECT MAX(a) FROM t2));
UNLOCK TABLES;
LOCK TABLES t1 READ, t2 READ;
INSERT INTO temp1 SELECT * FROM t1 WHERE a < (SELECT MAX(a) FROM t2);
INSERT INTO temp2 SELECT * FROM t2 WHERE a > (SELECT MAX(a) FROM t1);
UNLOCK TABLES;
INSERT INTO temp1 SELECT * FROM t1 WHERE a < (SELECT MAX(a) FROM t2);
INSERT INTO temp2 SELECT * FROM t2 WHERE a > (SELECT MAX(a) FROM t1);
SELECT * FROM temp1 ORDER BY a;
SELECT * FROM temp2 ORDER BY a;
DROP TABLE temp1, temp2;
--echo
--echo # Multiple table update:
--echo
CREATE TEMPORARY TABLE temp1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE temp2 LIKE temp1;
INSERT INTO temp1 VALUES (1),(2);
INSERT INTO temp2 VALUES (3),(4);
UPDATE temp1,temp2 SET temp1.a = 5, temp2.a = 10;
SELECT * FROM temp1, temp2;
DROP TABLE temp1, temp2;
--echo
--echo # Disconnect and cleanup
--echo
disconnect con1;
connection default;
SET GLOBAL READ_ONLY = OFF;
DROP USER bug33669@localhost;
DROP DATABASE db1;
# Copyright (C) 2005-2006 MySQL AB # Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -24,5 +24,10 @@ EXTRA_DIST = fulltext/configure.in ...@@ -24,5 +24,10 @@ EXTRA_DIST = fulltext/configure.in
SUBDIRS = @mysql_pg_dirs@ SUBDIRS = @mysql_pg_dirs@
DIST_SUBDIRS = @mysql_pg_distdirs@ DIST_SUBDIRS = @mysql_pg_distdirs@
# As of 5.5.3-m3, we want to include the plugin files of a debug build in the package
install-exec-hook:
$(mkinstalldirs) $(DESTDIR)$(pkglibdir) $(DESTDIR)$(pkglibdir)/plugin
test ! -d debug || $(TAR) cf - debug | ( cd $(DESTDIR)$(pkglibdir) && $(TAR) xvf - )
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
...@@ -54,6 +54,8 @@ Usage: $0 [OPTIONS] ...@@ -54,6 +54,8 @@ Usage: $0 [OPTIONS]
--mysqld=FILE Use the specified file as mysqld --mysqld=FILE Use the specified file as mysqld
--mysqld-version=VERSION Use "mysqld-VERSION" as mysqld --mysqld-version=VERSION Use "mysqld-VERSION" as mysqld
--nice=NICE Set the scheduling priority of mysqld --nice=NICE Set the scheduling priority of mysqld
--plugin-dir=DIR Plugins are under DIR or DIR/VERSION, if
VERSION is given
--skip-kill-mysqld Don't try to kill stray mysqld processes --skip-kill-mysqld Don't try to kill stray mysqld processes
--syslog Log messages to syslog with 'logger' --syslog Log messages to syslog with 'logger'
--skip-syslog Log messages to error log (default) --skip-syslog Log messages to error log (default)
...@@ -172,6 +174,7 @@ parse_arguments() { ...@@ -172,6 +174,7 @@ parse_arguments() {
--basedir=*) MY_BASEDIR_VERSION="$val" ;; --basedir=*) MY_BASEDIR_VERSION="$val" ;;
--datadir=*) DATADIR="$val" ;; --datadir=*) DATADIR="$val" ;;
--pid-file=*) pid_file="$val" ;; --pid-file=*) pid_file="$val" ;;
--plugin-dir=*) PLUGIN_DIR="$val" ;;
--user=*) user="$val"; SET_USER=1 ;; --user=*) user="$val"; SET_USER=1 ;;
# these might have been set in a [mysqld_safe] section of my.cnf # these might have been set in a [mysqld_safe] section of my.cnf
...@@ -189,6 +192,7 @@ parse_arguments() { ...@@ -189,6 +192,7 @@ parse_arguments() {
if test -n "$val" if test -n "$val"
then then
MYSQLD="mysqld-$val" MYSQLD="mysqld-$val"
PLUGIN_VARIANT="/$val"
else else
MYSQLD="mysqld" MYSQLD="mysqld"
fi fi
...@@ -695,8 +699,10 @@ fi ...@@ -695,8 +699,10 @@ fi
cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS" cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS"
plugin_dir="${PLUGIN_DIR:-@PLUGINDIR@}${PLUGIN_VARIANT}"
for i in "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \ for i in "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \
"--datadir=$DATADIR" "$USER_OPTION" "--datadir=$DATADIR" "--plugin-dir=$plugin_dir" "$USER_OPTION"
do do
cmd="$cmd "`shell_quote_string "$i"` cmd="$cmd "`shell_quote_string "$i"`
done done
......
...@@ -89,8 +89,8 @@ extern HASH open_cache; ...@@ -89,8 +89,8 @@ extern HASH open_cache;
#define GET_LOCK_UNLOCK 1 #define GET_LOCK_UNLOCK 1
#define GET_LOCK_STORE_LOCKS 2 #define GET_LOCK_STORE_LOCKS 2
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count, static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
uint flags, TABLE **write_locked); uint flags);
static int lock_external(THD *thd, TABLE **table,uint count); static int lock_external(THD *thd, TABLE **table,uint count);
static int unlock_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 *); static void print_lock_error(int error, const char *);
...@@ -107,15 +107,18 @@ static int thr_lock_errno_to_mysql[]= ...@@ -107,15 +107,18 @@ static int thr_lock_errno_to_mysql[]=
@param flags Lock flags @param flags Lock flags
@return 0 if all the check passed, non zero if a check failed. @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 log_table_write_query; uint system_count, i;
uint system_count; bool is_superuser, log_table_write_query;
uint i;
DBUG_ENTER("mysql_lock_tables_check"); DBUG_ENTER("lock_tables_check");
system_count= 0; system_count= 0;
*write_lock_used= FALSE;
is_superuser= thd->security_ctx->master_access & SUPER_ACL;
log_table_write_query= (is_log_table_write_query(thd->lex->sql_command) log_table_write_query= (is_log_table_write_query(thd->lex->sql_command)
|| ((flags & MYSQL_LOCK_PERF_SCHEMA) != 0)); || ((flags & MYSQL_LOCK_PERF_SCHEMA) != 0));
...@@ -148,10 +151,18 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags) ...@@ -148,10 +151,18 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
} }
} }
if ((t->s->table_category == TABLE_CATEGORY_SYSTEM) && if (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE)
(t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE))
{ {
*write_lock_used= TRUE;
if (t->s->table_category == TABLE_CATEGORY_SYSTEM)
system_count++; system_count++;
if (t->db_stat & HA_READ_ONLY)
{
my_error(ER_OPEN_AS_READONLY, MYF(0), t->alias);
DBUG_RETURN(1);
}
} }
/* /*
...@@ -172,6 +183,20 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags) ...@@ -172,6 +183,20 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
thd->mdl_context.is_lock_owner(MDL_key::TABLE, thd->mdl_context.is_lock_owner(MDL_key::TABLE,
t->s->db.str, t->s->table_name.str, t->s->db.str, t->s->table_name.str,
MDL_SHARED))); 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 &&
!is_superuser && opt_readonly && !thd->slave_thread)
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
DBUG_RETURN(1);
}
}
} }
/* /*
...@@ -267,15 +292,15 @@ static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock) ...@@ -267,15 +292,15 @@ static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock)
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
uint flags, bool *need_reopen) uint flags, bool *need_reopen)
{ {
MYSQL_LOCK *sql_lock;
TABLE *write_lock_used;
int rc; int rc;
MYSQL_LOCK *sql_lock;
bool write_lock_used;
DBUG_ENTER("mysql_lock_tables"); DBUG_ENTER("mysql_lock_tables");
*need_reopen= FALSE; *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); DBUG_RETURN (NULL);
ulong timeout= (flags & MYSQL_LOCK_IGNORE_TIMEOUT) ? ulong timeout= (flags & MYSQL_LOCK_IGNORE_TIMEOUT) ?
...@@ -283,8 +308,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, ...@@ -283,8 +308,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
for (;;) for (;;)
{ {
if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS, if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS)))
&write_lock_used)))
break; break;
if (global_read_lock && write_lock_used && if (global_read_lock && write_lock_used &&
...@@ -308,21 +332,6 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, ...@@ -308,21 +332,6 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
} }
} }
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"); thd_proc_info(thd, "System lock");
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
if (sql_lock->table_count && lock_external(thd, sql_lock->table, if (sql_lock->table_count && lock_external(thd, sql_lock->table,
...@@ -459,9 +468,7 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock) ...@@ -459,9 +468,7 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count) void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
{ {
MYSQL_LOCK *sql_lock; MYSQL_LOCK *sql_lock;
TABLE *write_lock_used; if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK)))
if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK,
&write_lock_used)))
mysql_unlock_tables(thd, sql_lock); mysql_unlock_tables(thd, sql_lock);
} }
...@@ -603,9 +610,7 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table, ...@@ -603,9 +610,7 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
thr_lock_type new_lock_type) thr_lock_type new_lock_type)
{ {
MYSQL_LOCK *locked; MYSQL_LOCK *locked;
TABLE *write_lock_used; if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK)))
if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
&write_lock_used)))
{ {
for (uint i=0; i < locked->lock_count; i++) for (uint i=0; i < locked->lock_count; i++)
thr_downgrade_write_lock(locked->locks[i], new_lock_type); thr_downgrade_write_lock(locked->locks[i], new_lock_type);
...@@ -619,11 +624,9 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table, ...@@ -619,11 +624,9 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock) void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
{ {
MYSQL_LOCK *locked; MYSQL_LOCK *locked;
TABLE *write_lock_used;
DBUG_ENTER("mysql_lock_abort"); DBUG_ENTER("mysql_lock_abort");
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK, if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK)))
&write_lock_used)))
{ {
for (uint i=0; i < locked->lock_count; i++) for (uint i=0; i < locked->lock_count; i++)
thr_abort_locks(locked->locks[i]->lock, upgrade_lock); thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
...@@ -648,12 +651,10 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock) ...@@ -648,12 +651,10 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table) bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
{ {
MYSQL_LOCK *locked; MYSQL_LOCK *locked;
TABLE *write_lock_used;
bool result= FALSE; bool result= FALSE;
DBUG_ENTER("mysql_lock_abort_for_thread"); DBUG_ENTER("mysql_lock_abort_for_thread");
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK, if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK)))
&write_lock_used)))
{ {
for (uint i=0; i < locked->lock_count; i++) for (uint i=0; i < locked->lock_count; i++)
{ {
...@@ -848,11 +849,10 @@ static int unlock_external(THD *thd, TABLE **table,uint count) ...@@ -848,11 +849,10 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
@param flags One of: @param flags One of:
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock - GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE - 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, 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; uint i,tables,lock_count;
MYSQL_LOCK *sql_lock; MYSQL_LOCK *sql_lock;
...@@ -861,9 +861,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ...@@ -861,9 +861,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
DBUG_ENTER("get_lock_data"); DBUG_ENTER("get_lock_data");
DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS)); DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
DBUG_PRINT("info", ("count %d", count)); DBUG_PRINT("info", ("count %d", count));
*write_lock_used=0;
for (i=tables=lock_count=0 ; i < count ; i++) for (i=tables=lock_count=0 ; i < count ; i++)
{ {
TABLE *t= table_ptr[i]; TABLE *t= table_ptr[i];
...@@ -895,24 +894,12 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ...@@ -895,24 +894,12 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
{ {
TABLE *table; TABLE *table;
enum thr_lock_type lock_type; enum thr_lock_type lock_type;
THR_LOCK_DATA **org_locks = locks;
if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
continue; continue;
lock_type= table->reginfo.lock_type; lock_type= table->reginfo.lock_type;
DBUG_ASSERT(lock_type != TL_WRITE_DEFAULT && lock_type != TL_READ_DEFAULT); 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_start= locks;
locks= table->file->store_lock(thd, locks, locks= table->file->store_lock(thd, locks,
(flags & GET_LOCK_UNLOCK) ? TL_IGNORE : (flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
......
...@@ -1631,6 +1631,14 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, ...@@ -1631,6 +1631,14 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
- you can't flush WITH READ LOCK a non-existent table - you can't flush WITH READ LOCK a non-existent table
- you can't flush WITH READ LOCK under LOCK TABLES - you can't flush WITH READ LOCK under LOCK TABLES
- currently incompatible with the GRL (@todo: fix) - currently incompatible with the GRL (@todo: fix)
Effect on views and temporary tables.
------------------------------------
You can only apply this command to existing base tables.
If a view with such name exists, ER_WRONG_OBJECT is returned.
If a temporary table with such name exists, it's ignored:
if there is a base table, it's used, otherwise ER_NO_SUCH_TABLE
is returned.
*/ */
static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables) static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
...@@ -1665,6 +1673,21 @@ static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables) ...@@ -1665,6 +1673,21 @@ static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
if (lock_table_names(thd, all_tables)) if (lock_table_names(thd, all_tables))
goto error; goto error;
for (table_list= all_tables; table_list;
table_list= table_list->next_global)
{
/* Remove the table from cache. */
mysql_mutex_lock(&LOCK_open);
tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
table_list->db,
table_list->table_name);
mysql_mutex_unlock(&LOCK_open);
/* Skip views and temporary tables. */
table_list->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
table_list->open_type= OT_BASE_ONLY; /* Ignore temporary tables. */
}
if (open_and_lock_tables(thd, all_tables, FALSE, if (open_and_lock_tables(thd, all_tables, FALSE,
MYSQL_OPEN_HAS_MDL_LOCK, MYSQL_OPEN_HAS_MDL_LOCK,
&lock_tables_prelocking_strategy) || &lock_tables_prelocking_strategy) ||
......
...@@ -561,6 +561,14 @@ install -d $RBR%{_libdir} ...@@ -561,6 +561,14 @@ install -d $RBR%{_libdir}
install -d $RBR%{_mandir} install -d $RBR%{_mandir}
install -d $RBR%{_sbindir} install -d $RBR%{_sbindir}
# Get the plugin files from the debug build
mkdir $RBR/tmp-debug-plugin $MBD/plugin/debug
( cd $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-debug-%{mysql_version}/plugin
make install DESTDIR=$RBR/tmp-debug-plugin
mv $RBR/tmp-debug-plugin/usr/local/mysql/lib/mysql/plugin/* $MBD/plugin/debug/
# From here, the install hook in "plugin/Makefile.am" will do the rest.
)
rmdir -p $RBR/tmp-debug-plugin/usr/local/mysql/lib/mysql/plugin
# Install all binaries # Install all binaries
(cd $MBD && make install DESTDIR=$RBR testroot=%{_datadir}) (cd $MBD && make install DESTDIR=$RBR testroot=%{_datadir})
...@@ -859,10 +867,6 @@ fi ...@@ -859,10 +867,6 @@ fi
%attr(755, root, root) %{_bindir}/resolve_stack_dump %attr(755, root, root) %{_bindir}/resolve_stack_dump
%attr(755, root, root) %{_bindir}/resolveip %attr(755, root, root) %{_bindir}/resolveip
%attr(755, root, root) %{_libdir}/mysql/plugin/ha_example.so*
%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so*
%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so*
%if %{WITH_TCMALLOC} %if %{WITH_TCMALLOC}
%attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target} %attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target}
%endif %endif
...@@ -873,6 +877,9 @@ fi ...@@ -873,6 +877,9 @@ fi
%attr(755, root, root) %{_libdir}/mysql/plugin/ha_example.so* %attr(755, root, root) %{_libdir}/mysql/plugin/ha_example.so*
%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so* %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so*
%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so* %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so*
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/ha_example.so*
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_master.so*
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_slave.so*
%if %{WITH_TCMALLOC} %if %{WITH_TCMALLOC}
%attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target} %attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target}
...@@ -1007,6 +1014,12 @@ fi ...@@ -1007,6 +1014,12 @@ fi
%{_libdir}/mysql/plugin/semisync_master.la %{_libdir}/mysql/plugin/semisync_master.la
%{_libdir}/mysql/plugin/semisync_slave.a %{_libdir}/mysql/plugin/semisync_slave.a
%{_libdir}/mysql/plugin/semisync_slave.la %{_libdir}/mysql/plugin/semisync_slave.la
%{_libdir}/mysql/plugin/debug/ha_example.a
%{_libdir}/mysql/plugin/debug/ha_example.la
%{_libdir}/mysql/plugin/debug/semisync_master.a
%{_libdir}/mysql/plugin/debug/semisync_master.la
%{_libdir}/mysql/plugin/debug/semisync_slave.a
%{_libdir}/mysql/plugin/debug/semisync_slave.la
%files shared %files shared
%defattr(-, root, root, 0755) %defattr(-, root, root, 0755)
...@@ -1042,6 +1055,12 @@ fi ...@@ -1042,6 +1055,12 @@ fi
# merging BK trees) # merging BK trees)
############################################################################## ##############################################################################
%changelog %changelog
* Wed Mar 10 2010 Joerg Bruehe <joerg.bruehe@sun.com>
- Take the result of the debug plugin build and put it into the optimized tree,
so that it becomes part of the final installation;
include the files in the packlist. Part of the fixes for bug#49022.
* Mon Mar 01 2010 Joerg Bruehe <joerg.bruehe@sun.com> * Mon Mar 01 2010 Joerg Bruehe <joerg.bruehe@sun.com>
- Set "Oracle and/or its affiliates" as the vendor and copyright owner, - Set "Oracle and/or its affiliates" as the vendor and copyright owner,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment