3427 Jon Olav Hauglid 2011-11-16 [merge]
Merge from mysql-trunk to mysql-trunk-wl5534
No conflicts
removed:
mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test
mysql-test/suite/rpl/t/rpl_parallel_benchmark-master.opt
mysql-test/suite/rpl/t/rpl_parallel_benchmark-slave.opt
mysql-test/suite/rpl/t/rpl_parallel_benchmark.test
added:
mysql-test/suite/rpl/r/rpl_row_find_row_debug.result
mysql-test/suite/rpl/t/rpl_row_find_row_debug.test
mysql-test/suite/sys_vars/r/metadata_locks_cache_size_basic.result
mysql-test/suite/sys_vars/t/metadata_locks_cache_size_basic-master.opt
mysql-test/suite/sys_vars/t/metadata_locks_cache_size_basic.test
modified:
client/mysql_upgrade.c
mysql-test/extra/rpl_tests/rpl_parallel_load.test
mysql-test/r/mysql_upgrade.result
mysql-test/r/mysqld--help-notwin.result
mysql-test/r/mysqld--help-win.result
mysql-test/t/mysql_upgrade.test
sql/item_func.cc
sql/log_event.cc
sql/log_event.h
sql/mdl.cc
sql/mdl.h
sql/rpl_rli.cc
sql/rpl_rli.h
sql/sql_class.h
sql/sql_partition.cc
sql/sql_plist.h
sql/sys_vars.cc
3426 Dmitry Lenev 2011-11-16
WL#5534 Online ALTER, Phase 1.
Patch #50: Review fix.
Move check for potentially broken .FRMs to
is_inplace_alter_impossible().
modified:
sql/sql_table.cc
=== modified file 'client/mysql_upgrade.c'
--- a/client/mysql_upgrade.c 2011-08-29 12:08:58 +0000
+++ b/client/mysql_upgrade.c 2011-11-15 12:34:23 +0000
@@ -286,6 +286,8 @@ get_one_option(int optid, const struct m
case 'v': /* --verbose */
case 'f': /* --force */
+ case 's': /* --upgrade-system-tables */
+ case OPT_WRITE_BINLOG: /* --write-binlog */
add_option= FALSE;
break;
=== removed file 'mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test'
--- a/mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test 2011-08-19 13:04:28 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test 1970-01-01 00:00:00 +0000
@@ -1,308 +0,0 @@
-#
-# This is a load generator to call from rpl_parallel and rpl_sequential tests
-#
-
-#
-# load volume parameter
-#
-
-let $iter= 02;
-let $tables= 2;
-let $wk_i_queries= 2;
-let $wk_m_queries= 0;
-let $nk_i_queries= 0;
-let $nk_m_queries= 0;
-let $pre_inserted_rows= 50;
-
-connection slave;
-
-call mtr.add_suppression('Slave: Error dropping database'); ## todo: fix
-
-source include/stop_slave.inc;
-start slave;
-
-connection master;
-
---disable_query_log
---disable_result_log
-
-use test;
-delimiter |;
-create procedure one_session(k int)
-begin
- while k > 0 do
- insert into tm_nk values(k, 0);
- insert into tm_wk values(null, 0);
- insert into ti_nk values(k, 0);
- insert into ti_wk values(null, 0);
- set k = k - 1;
- end while;
-end|
-delimiter ;|
-
-## let $i = $workers + 1;
-##eval
-# delimiter |;
-# create procedure p1(i int)
-# begin
-# while i > 0
-# ##while ($i)
-# ##{
-# ## let $i1=$i;
-# ## dec $i1;
-# ## use test$i1;
-# ## call on_session();
-# ## dec $i;
-# ##}
-# use test0;
-# call one_session();
-# use test1;
-# call one_session();
-# use test2;
-# call one_session();
-# use test3;
-# call one_session();
-# i= i-1;
-# end while;
-# end|
-# delimiter ;|
-
-
-let $i = $databases;
-while($i)
-{
- eval create database test$i;
-
- let $m= $tables;
- while ($m)
- {
- eval create table test$i.tm_nk_$m (a int, b int, c text) engine=myisam;
- eval create table test$i.tm_wk_$m (a int auto_increment primary key, b int, c text) engine=myisam;
- eval create table test$i.ti_nk_$m (a int, b int, c text) engine=innodb;
- eval create table test$i.ti_wk_$m (a int auto_increment primary key, b int, c text) engine=innodb;
- let $k= $pre_inserted_rows;
- while ($k)
- {
- eval insert into test$i.ti_wk_$m values(null, $i, uuid());
- eval insert into test$i.ti_nk_$m values(null, $i, uuid());
- eval insert into test$i.tm_wk_$m values(null, $i, uuid());
- eval insert into test$i.tm_nk_$m values(null, $i, uuid());
-
- dec $k;
- }
- dec $m;
- }
-
-
- # this table is special - just for timing. It's more special on test1 db
- # where it contains master timing of the load as well.
- eval create table test$i.benchmark (state text) engine=myisam; # timestamp keep on the slave side
-
- dec $i;
-}
-
---enable_result_log
---enable_query_log
-
-
-sync_slave_with_master;
-#connection slave;
-
---disable_query_log
---disable_result_log
-
-let $i = $databases;
-while($i)
-{
- eval alter table test$i.benchmark add ts timestamp not null default current_timestamp;
-
- dec $i;
-}
---enable_result_log
---enable_query_log
-
-
-# not gather events into relay log w/o executing yet
-stop slave sql_thread;
-
-##call p1(1);
-
-connection master;
-
---disable_query_log
---disable_result_log
-
-#
-# Load producer
-#
-
-# initial timestamp to record
-
-# the extra ts col on slave is effective only with the STMT format (todo: bug-report)
-set @save.binlog_format= @@session.binlog_format;
-set @@session.binlog_format=STATEMENT;
-let $i = $databases;
-while($i)
-{
- eval insert into test$i.benchmark set state='slave takes on load';
-
- dec $i;
-}
-set @@session.binlog_format= @save.binlog_format;
-
-connection slave;
-
-insert into test1.benchmark set state='master started load';
-
-
-connection master;
-
-while ($iter)
-{
- let $i = $databases;
-
- while ($i)
- {
-
- begin;
- ###eval insert into tm_nk values($iter, $i1, repeat('a', round(rand()*10)));
-
- let $q= $wk_m_queries;
- while ($q)
- {
- let $m= `select 1 + floor(rand() * $tables)`;
- eval update test$i.tm_wk_$m set c= uuid();
- eval insert into test$i.tm_wk_$m values(null, $i, uuid());
-
- dec $q;
- }
-
- let $q= $wk_i_queries;
- while ($q)
- {
- let $m= `select 1 + floor(rand() * $tables)`;
- eval update test$i.ti_wk_$m set c= uuid();
-
- eval insert into test$i.ti_wk_$m values(null, $i, uuid());
-
- dec $q;
- }
-
- # NK
-
- let $q= $nk_m_queries;
- while ($q)
- {
- let $m= `select 1 + floor(rand() * $tables)`;
- eval update test$i.tm_nk_$m set c= uuid();
- eval insert into test$i.tm_nk_$m values(null, $i, uuid());
-
- dec $q;
- }
-
- let $q= $nk_i_queries;
- while ($q)
- {
- let $m= `select 1 + floor(rand() * $tables)`;
- eval update test$i.ti_nk_$m set c= uuid();
- eval insert into test$i.ti_nk_$m values(null, $i, uuid());
-
- dec $q;
- }
- commit;
-
- dec $i;
- }
-
- dec $iter;
-}
-
-connection slave;
-
-##use test1;
-insert into test1.benchmark set state='master ends load';
-
-connection master;
-
-# terminal timestamp to record
-
-let $i = $databases;
-set @save.binlog_format= @@session.binlog_format;
-set @@session.binlog_format=STATEMENT;
-while($i)
-{
- eval insert into test$i.benchmark set state='slave ends load';
-
- dec $i;
-}
-set @@session.binlog_format= @save.binlog_format;
-
---enable_result_log
---enable_query_log
-
-connection slave;
-
-## todo: record start and end time of appying to compare times of
-# parallel and sequential execution.
-
---disable_query_log
---disable_result_log
-
-insert into test1.benchmark set state='slave is processing load';
-
-# To force filling timestamp cols with the slave local clock values
-# to implement benchmarking.
-
-# TODO: replace with another alg
-#set @save.mts_exp_slave_local_timestamp=@@global.mts_exp_slave_local_timestamp;
-#set @@global.mts_exp_slave_local_timestamp=1;
-
---sleep 1
-
-start slave sql_thread;
-
-let $wait_timeout= 600;
-let $wait_condition= SELECT count(*)+sleep(1) = 5 FROM test1.benchmark;
-source include/wait_condition.inc;
-
-# cleanup for files that could not be removed in the end of previous invocation.
-let $MYSQLD_DATADIR= `select @@datadir`;
---remove_files_wildcard $MYSQLD_DATADIR *.out
-
-use test;
-let $benchmark_file= `select replace(concat("benchmark_",uuid(),".out"),"-","_")`;
---replace_regex /benchmark_.*.out/benchmark.out/
-eval select * from test1.benchmark into outfile '$benchmark_file';
-select ts from test1.benchmark where state like 'master started load' into @m_0;
-select ts from test1.benchmark where state like 'master ends load' into @m_1;
-select ts from test1.benchmark where state like 'slave takes on load' into @s_0;
-select ts from test1.benchmark where state like 'slave ends load' into @s_1;
-let $delta_file= `select replace(concat("delta_",uuid(),".out"),"-","_")`;
---replace_regex /delta_.*.out/delta.out/
-eval select time_to_sec(@m_1) - time_to_sec(@m_0) as 'delta_m',
- time_to_sec(@s_1) - time_to_sec(@s_0) as 'delta_s' into outfile '$delta_file';
-
---enable_result_log
---enable_query_log
-
-
-connection master;
-
---disable_query_log
---disable_result_log
-
-let $i = $databases;
-while($i)
-{
- eval drop database test$i;
-
- dec $i;
-}
-
-use test;
-drop procedure one_session;
-
---enable_result_log
---enable_query_log
-
-sync_slave_with_master;
=== modified file 'mysql-test/extra/rpl_tests/rpl_parallel_load.test'
--- a/mysql-test/extra/rpl_tests/rpl_parallel_load.test 2011-10-31 13:52:32 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_parallel_load.test 2011-11-14 15:44:42 +0000
@@ -6,16 +6,9 @@
# load volume parameter
#
-let $iter = 50;
-
-# windows run on PB2 is too slow to time out
-disable_query_log;
-if (`select convert(@@version_compile_os using latin1) IN ("Win32","Win64","Windows") as "TRUE"`)
-{
- let $iter = 30;
-}
-enable_query_log;
-
+# The value of iteration is chosen to be rather low to satisfy
+# slow PB environments that are not just Win.
+let $iter = 20;
let $databases = 16;
connection slave;
=== modified file 'mysql-test/r/mysql_upgrade.result'
--- a/mysql-test/r/mysql_upgrade.result 2011-08-19 13:04:28 +0000
+++ b/mysql-test/r/mysql_upgrade.result 2011-11-15 12:34:23 +0000
@@ -224,3 +224,41 @@ GRANT ALL PRIVILEGES ON `roelt`.`test2`
DROP USER 'user3'@'%';
End of 5.1 tests
The --upgrade-system-tables option was used, databases won't be touched.
+#
+# Bug#11827359 60223: MYSQL_UPGRADE PROBLEM WITH OPTION
+# SKIP-WRITE-BINLOG
+#
+# Droping the previously created mysql_upgrade_info file..
+# Running mysql_upgrade with --skip-write-binlog..
+mtr.global_suppressions OK
+mtr.test_suppressions OK
+mysql.columns_priv OK
+mysql.db OK
+mysql.event OK
+mysql.func OK
+mysql.general_log OK
+mysql.help_category OK
+mysql.help_keyword OK
+mysql.help_relation OK
+mysql.help_topic OK
+mysql.host OK
+mysql.innodb_index_stats OK
+mysql.innodb_table_stats OK
+mysql.ndb_binlog_index OK
+mysql.plugin OK
+mysql.proc OK
+mysql.procs_priv OK
+mysql.proxies_priv OK
+mysql.servers OK
+mysql.slave_master_info OK
+mysql.slave_relay_log_info OK
+mysql.slave_worker_info OK
+mysql.slow_log 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
+End of tests
=== modified file 'mysql-test/r/mysqld--help-notwin.result'
--- a/mysql-test/r/mysqld--help-notwin.result 2011-11-11 12:36:01 +0000
+++ b/mysql-test/r/mysqld--help-notwin.result 2011-11-15 18:51:44 +0000
@@ -353,6 +353,8 @@ The following options may be given as th
After this many write locks, allow some read locks to run
in between
--memlock Lock mysqld in memory.
+ --metadata-locks-cache-size=#
+ Size of unused metadata locks cache
--min-examined-row-limit=#
Don't write queries to slow log that examine fewer rows
than that
@@ -929,6 +931,7 @@ max-tmp-tables 32
max-user-connections 0
max-write-lock-count 18446744073709551615
memlock FALSE
+metadata-locks-cache-size 1024
min-examined-row-limit 0
multi-range-count 256
myisam-block-size 1024
=== modified file 'mysql-test/r/mysqld--help-win.result'
--- a/mysql-test/r/mysqld--help-win.result 2011-11-11 12:36:01 +0000
+++ b/mysql-test/r/mysqld--help-win.result 2011-11-15 18:51:44 +0000
@@ -352,6 +352,8 @@ The following options may be given as th
After this many write locks, allow some read locks to run
in between
--memlock Lock mysqld in memory.
+ --metadata-locks-cache-size=#
+ Size of unused metadata locks cache
--min-examined-row-limit=#
Don't write queries to slow log that examine fewer rows
than that
@@ -932,6 +934,7 @@ max-tmp-tables 32
max-user-connections 0
max-write-lock-count 18446744073709551615
memlock FALSE
+metadata-locks-cache-size 1024
min-examined-row-limit 0
multi-range-count 256
myisam-block-size 1024
=== added file 'mysql-test/suite/rpl/r/rpl_row_find_row_debug.result'
--- a/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result 2011-11-11 17:26:56 +0000
@@ -0,0 +1,18 @@
+include/master-slave.inc
+[connection master]
+include/stop_slave.inc
+SET GLOBAL log_warnings = 2;
+SET GLOBAL debug="d,inject_long_find_row_note";
+include/start_slave.inc
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1), (2);
+UPDATE t1 SET c1= 1000 WHERE c1=2;
+DELETE FROM t1;
+DROP TABLE t1;
+# Check if any note related to long DELETE_ROWS and UPDATE_ROWS appears in the error log
+Occurrences: update=1, delete=1
+include/stop_slave.inc
+SET GLOBAL debug = '';
+SET GLOBAL log_warnings = 1;
+include/start_slave.inc
+include/rpl_end.inc
=== removed file 'mysql-test/suite/rpl/t/rpl_parallel_benchmark-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_parallel_benchmark-master.opt 2011-08-19 13:04:28 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_benchmark-master.opt 1970-01-01 00:00:00 +0000
@@ -1 +0,0 @@
---log-warnings=0
=== removed file 'mysql-test/suite/rpl/t/rpl_parallel_benchmark-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_parallel_benchmark-slave.opt 2011-08-19 13:04:28 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_benchmark-slave.opt 1970-01-01 00:00:00 +0000
@@ -1 +0,0 @@
---log-warnings=0 --slave-transaction-retries=0
=== removed file 'mysql-test/suite/rpl/t/rpl_parallel_benchmark.test'
--- a/mysql-test/suite/rpl/t/rpl_parallel_benchmark.test 2011-08-19 13:04:28 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_benchmark.test 1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
-#
-# WL#5569 MTS
-#
-# The test is similar to rpl_parallel but focuses more to
-# provide benchmarking data.
-# See rpl_parallel.test comments and rpl_parallel_benchmark_load for
-# how to vary running configuration.
-#
-
---source include/master-slave.inc
-
-connection slave;
-set @save.slave_parallel_workers= @@global.slave_parallel_workers;
-###select @@global.slave_parallel_workers as 'non-zero means parallel';
-
-let $workers = `select @@global.slave_parallel_workers`;
-###let $databases= $workers;
-# workers vary db:s do not
-let $databases= 16;
-
-connection master;
-source extra/rpl_tests/rpl_parallel_benchmark_load.test;
-
-connection slave;
---disable_query_log
-set @@global.slave_parallel_workers= @save.slave_parallel_workers;
---enable_result_log
-
---source include/rpl_end.inc
=== added file 'mysql-test/suite/rpl/t/rpl_row_find_row_debug.test'
--- a/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test 2011-11-15 13:04:11 +0000
@@ -0,0 +1,64 @@
+#
+# Bug#11760927: 53375: RBR + NO PK => HIGH LOAD ON SLAVE (TABLE SCAN/CPU) => SLAVE FAILURE
+#
+--disable_warnings
+--source include/master-slave.inc
+--enable_warnings
+--source include/have_binlog_format_row.inc
+--source include/have_debug.inc
+
+# SETUP
+# - setup log_warnings and debug
+--connection slave
+--source include/stop_slave.inc
+--let $debug_save= `SELECT @@GLOBAL.debug`
+--let $log_warnings_save= `SELECT @@GLOBAL.log_warnings`
+
+SET GLOBAL log_warnings = 2;
+
+let $log_error_= `SELECT @@GLOBAL.log_error`;
+if(!$log_error_)
+{
+ # MySQL Server on windows is started with --console and thus
+ # does not know the location of its .err log, use default location
+ let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err;
+}
+
+# Assign env variable LOG_ERROR
+let LOG_ERROR=$log_error_;
+
+# force printing the notes to the error log
+SET GLOBAL debug="d,inject_long_find_row_note";
+--source include/start_slave.inc
+
+# test
+--connection master
+CREATE TABLE t1 (c1 INT);
+--sync_slave_with_master
+--connection master
+
+INSERT INTO t1 VALUES (1), (2);
+UPDATE t1 SET c1= 1000 WHERE c1=2;
+DELETE FROM t1;
+DROP TABLE t1;
+--sync_slave_with_master
+
+--echo # Check if any note related to long DELETE_ROWS and UPDATE_ROWS appears in the error log
+perl;
+ use strict;
+ my $log_error= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set";
+ open(FILE, "$log_error") or die("Unable to open $log_error: $!\n");
+ my $upd_count = () = grep(/The slave is applying a ROW event on behalf of an UPDATE statement on table t1 and is currently taking a considerable amount/g,<FILE>);
+ seek(FILE, 0, 0) or die "Can't seek to beginning of file: $!";
+ my $del_count = () = grep(/The slave is applying a ROW event on behalf of a DELETE statement on table t1 and is currently taking a considerable amount/g,<FILE>);
+ print "Occurrences: update=$upd_count, delete=$del_count\n";
+ close(FILE);
+EOF
+
+# cleanup
+--source include/stop_slave.inc
+--eval SET GLOBAL debug = '$debug_save'
+--eval SET GLOBAL log_warnings = $log_warnings_save
+--source include/start_slave.inc
+
+--source include/rpl_end.inc
=== added file 'mysql-test/suite/sys_vars/r/metadata_locks_cache_size_basic.result'
--- a/mysql-test/suite/sys_vars/r/metadata_locks_cache_size_basic.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/metadata_locks_cache_size_basic.result 2011-11-15 18:00:14 +0000
@@ -0,0 +1,21 @@
+#
+# Check that the paremeter is correctly set by start-up
+# option (.opt file sets it to 256 while default is 1024).
+select @@global.metadata_locks_cache_size = 256;
+@@global.metadata_locks_cache_size = 256
+1
+#
+# Check that variable is read only
+#
+set @@global.metadata_locks_cache_size= 1024;
+ERROR HY000: Variable 'metadata_locks_cache_size' is a read only variable
+select @@global.metadata_locks_cache_size = 256;
+@@global.metadata_locks_cache_size = 256
+1
+#
+# And only GLOBAL
+#
+select @@session.metadata_locks_cache_size;
+ERROR HY000: Variable 'metadata_locks_cache_size' is a GLOBAL variable
+set @@session.metadata_locks_cache_size= 1024;
+ERROR HY000: Variable 'metadata_locks_cache_size' is a read only variable
=== added file 'mysql-test/suite/sys_vars/t/metadata_locks_cache_size_basic-master.opt'
--- a/mysql-test/suite/sys_vars/t/metadata_locks_cache_size_basic-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/metadata_locks_cache_size_basic-master.opt 2011-11-15 18:00:14 +0000
@@ -0,0 +1 @@
+--metadata-locks-cache-size=256
=== added file 'mysql-test/suite/sys_vars/t/metadata_locks_cache_size_basic.test'
--- a/mysql-test/suite/sys_vars/t/metadata_locks_cache_size_basic.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/metadata_locks_cache_size_basic.test 2011-11-15 18:00:14 +0000
@@ -0,0 +1,25 @@
+#
+# Basic test coverage for --metadata-locks-cache-size startup
+# parameter and corresponding read-only global @@metadata_locks_cache_size
+# variable.
+#
+
+--echo #
+--echo # Check that the paremeter is correctly set by start-up
+--echo # option (.opt file sets it to 256 while default is 1024).
+select @@global.metadata_locks_cache_size = 256;
+
+--echo #
+--echo # Check that variable is read only
+--echo #
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set @@global.metadata_locks_cache_size= 1024;
+select @@global.metadata_locks_cache_size = 256;
+
+--echo #
+--echo # And only GLOBAL
+--echo #
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.metadata_locks_cache_size;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set @@session.metadata_locks_cache_size= 1024;
=== modified file 'mysql-test/t/mysql_upgrade.test'
--- a/mysql-test/t/mysql_upgrade.test 2010-08-11 17:56:56 +0000
+++ b/mysql-test/t/mysql_upgrade.test 2011-11-15 12:18:42 +0000
@@ -102,5 +102,24 @@ DROP USER 'user3'@'%';
# Test the --upgrade-system-tables option
#
--replace_result $MYSQLTEST_VARDIR var
---exec $MYSQL_UPGRADE --skip-verbose --upgrade-system-tables
+--exec $MYSQL_UPGRADE --skip-verbose --force --upgrade-system-tables
+--echo #
+--echo # Bug#11827359 60223: MYSQL_UPGRADE PROBLEM WITH OPTION
+--echo # SKIP-WRITE-BINLOG
+--echo #
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+--echo # Droping the previously created mysql_upgrade_info file..
+--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
+
+--echo # Running mysql_upgrade with --skip-write-binlog..
+--replace_result $MYSQLTEST_VARDIR var
+--exec $MYSQL_UPGRADE --skip-verbose --skip-write-binlog
+
+# mysql_upgrade must have created mysql_upgrade_info file,
+# so the following command should never fail.
+--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
+
+--echo End of tests
=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc 2011-10-13 07:26:28 +0000
+++ b/sql/item_func.cc 2011-11-15 09:24:13 +0000
@@ -2352,25 +2352,31 @@ double my_double_round(double value, lon
/*
tmp2 is here to avoid return the value with 80 bit precision
This will fix that the test round(0.1,1) = round(0.1,1) is true
+ Tagging with volatile is no guarantee, it may still be optimized away...
*/
volatile double tmp2;
tmp=(abs_dec < array_elements(log_10) ?
log_10[abs_dec] : pow(10.0,(double) abs_dec));
+ // Pre-compute these, to avoid optimizing away e.g. 'floor(v/tmp) * tmp'.
+ volatile double value_div_tmp= value / tmp;
+ volatile double value_mul_tmp= value * tmp;
+
if (dec_negative && my_isinf(tmp))
- tmp2= 0;
- else if (!dec_negative && my_isinf(value * tmp))
+ tmp2= 0.0;
+ else if (!dec_negative && my_isinf(value_mul_tmp))
tmp2= value;
else if (truncate)
{
- if (value >= 0)
- tmp2= dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp;
+ if (value >= 0.0)
+ tmp2= dec < 0 ? floor(value_div_tmp) * tmp : floor(value_mul_tmp) / tmp;
else
- tmp2= dec < 0 ? ceil(value/tmp)*tmp : ceil(value*tmp)/tmp;
+ tmp2= dec < 0 ? ceil(value_div_tmp) * tmp : ceil(value_mul_tmp) / tmp;
}
else
- tmp2=dec < 0 ? rint(value/tmp)*tmp : rint(value*tmp)/tmp;
+ tmp2=dec < 0 ? rint(value_div_tmp) * tmp : rint(value_mul_tmp) / tmp;
+
return tmp2;
}
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2011-11-10 06:53:27 +0000
+++ b/sql/log_event.cc 2011-11-15 14:40:04 +0000
@@ -8872,6 +8872,12 @@ int Rows_log_event::do_apply_event(Relay
// row processing loop
+ /*
+ set the initial time of this ROWS statement if it was not done
+ before in some other ROWS event.
+ */
+ const_cast<Relay_log_info*>(rli)->set_row_stmt_start_timestamp();
+
const uchar *saved_m_curr_row= m_curr_row;
while (error == 0)
{
@@ -10610,6 +10616,50 @@ search_key_in_table(TABLE *table, MY_BIT
return res;
}
+/*
+ Check if we are already spending too much time on this statement.
+ if we are, warn user that it might be because table does not have
+ a PK, but only if the warning was not printed before for this STMT.
+
+ @param type The event type code.
+ @param table_name The name of the table that the slave is
+ operating.
+ @param is_index_scan States whether the slave is doing an index scan
+ or not.
+ @param rli The relay metadata info.
+*/
+static inline
+void issue_long_find_row_warning(Log_event_type type,
+ const char *table_name,
+ bool is_index_scan,
+ const Relay_log_info *rli)
+{
+ if ((log_warnings > 1 &&
+ !const_cast<Relay_log_info*>(rli)->is_long_find_row_note_printed()))
+ {
+ time_t now= my_time(0);
+ time_t stmt_ts= const_cast<Relay_log_info*>(rli)->get_row_stmt_start_timestamp();
+
+ DBUG_EXECUTE_IF("inject_long_find_row_note",
+ stmt_ts-=(LONG_FIND_ROW_THRESHOLD*2););
+
+ long delta= (long) (now - stmt_ts);
+
+ if (delta > LONG_FIND_ROW_THRESHOLD)
+ {
+ const_cast<Relay_log_info*>(rli)->set_long_find_row_note_printed();
+ const char* evt_type= type == DELETE_ROWS_EVENT ? " DELETE" : "n UPDATE";
+ const char* scan_type= is_index_scan ? "scanning an index" : "scanning the table";
+
+ sql_print_information("The slave is applying a ROW event on behalf of a%s statement "
+ "on table %s and is currently taking a considerable amount "
+ "of time (%ld seconds). This is due to the fact that it is %s "
+ "while looking up records to be processed. Consider adding a "
+ "primary key (or unique key) to the table to improve "
+ "performance.", evt_type, table_name, delta, scan_type);
+ }
+ }
+}
/**
Locate the current row in event's table.
@@ -10649,6 +10699,7 @@ int Rows_log_event::find_row(const Relay
int error= 0;
KEY *keyinfo;
uint key;
+ bool is_table_scan= false, is_index_scan= false;
/*
rpl_row_tabledefs.test specifies that
@@ -10838,6 +10889,8 @@ INDEX_SCAN:
}
}
+ is_index_scan=true;
+
/*
In case key is not unique, we still have to iterate over records found
and find the one which is identical to the row given. A copy of the
@@ -10898,6 +10951,8 @@ TABLE_SCAN:
goto err;
}
+ is_table_scan= true;
+
/* Continue until we find the right record or have made a full loop */
do
{
@@ -10951,10 +11006,18 @@ TABLE_SCAN:
goto err;
}
ok:
+ if (is_table_scan || is_index_scan)
+ issue_long_find_row_warning(get_type_code(), m_table->alias,
+ is_index_scan, rli);
+
table->default_column_bitmaps();
DBUG_RETURN(0);
err:
+ if (is_table_scan || is_index_scan)
+ issue_long_find_row_warning(get_type_code(), m_table->alias,
+ is_index_scan, rli);
+
table->default_column_bitmaps();
DBUG_RETURN(error);
}
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2011-08-29 12:08:58 +0000
+++ b/sql/log_event.h 2011-11-15 13:04:11 +0000
@@ -51,6 +51,7 @@ typedef ulonglong sql_mode_t;
typedef struct st_db_worker_hash_entry db_worker_hash_entry;
#define PREFIX_SQL_LOAD "SQL_LOAD-"
+#define LONG_FIND_ROW_THRESHOLD 60 /* seconds */
/**
Either assert or return an error.
=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc 2011-11-14 15:41:08 +0000
+++ b/sql/mdl.cc 2011-11-16 16:21:20 +0000
@@ -107,6 +107,10 @@ void MDL_key::init_psi_keys()
static bool mdl_initialized= 0;
+class MDL_object_lock;
+class MDL_object_lock_cache_adapter;
+
+
/**
A collection of all MDL locks. A singleton,
there is only one instance of the map in the server.
@@ -127,6 +131,25 @@ private:
HASH m_locks;
/* Protects access to m_locks hash. */
mysql_mutex_t m_mutex;
+ /**
+ Cache of (unused) MDL_lock objects available for re-use.
+
+ On some systems (e.g. Windows XP) constructing/destructing
+ MDL_lock objects can be fairly expensive. We use this cache
+ to avoid these costs in scenarios in which they can have
+ significant negative effect on performance. For example, when
+ there is only one thread constantly executing statements in
+ auto-commit mode and thus constantly causing creation/
+ destruction of MDL_lock objects for the tables it uses.
+
+ Note that this cache contains only MDL_object_lock objects.
+
+ Protected by m_mutex mutex.
+ */
+ typedef I_P_List<MDL_object_lock, MDL_object_lock_cache_adapter,
+ I_P_List_counter>
+ Lock_cache;
+ Lock_cache m_unused_locks_cache;
/** Pre-allocated MDL_lock object for GLOBAL namespace. */
MDL_lock *m_global_lock;
/** Pre-allocated MDL_lock object for COMMIT namespace. */
@@ -395,7 +418,8 @@ public:
: key(key_arg),
m_ref_usage(0),
m_ref_release(0),
- m_is_destroyed(FALSE)
+ m_is_destroyed(FALSE),
+ m_version(0)
{
mysql_prlock_init(key_MDL_lock_rwlock, &m_rwlock);
}
@@ -430,6 +454,22 @@ public:
uint m_ref_usage;
uint m_ref_release;
bool m_is_destroyed;
+ /**
+ We use the same idea and an additional version counter to support
+ caching of unused MDL_lock object for further re-use.
+ This counter is incremented while holding both MDL_map::m_mutex and
+ MDL_lock::m_rwlock locks each time when a MDL_lock is moved from
+ the hash to the unused objects list (or destroyed).
+ A thread, which has found a MDL_lock object for the key in the hash
+ and then released the MDL_map::m_mutex before acquiring the
+ MDL_lock::m_rwlock, can determine that this object was moved to the
+ unused objects list (or destroyed) while it held no locks by comparing
+ the version value which it read while holding the MDL_map::m_mutex
+ with the value read after acquiring the MDL_lock::m_rwlock.
+ Note that since it takes several years to overflow this counter such
+ theoretically possible overflows should not have any practical effects.
+ */
+ ulonglong m_version;
};
@@ -478,6 +518,26 @@ public:
: MDL_lock(key_arg)
{ }
+ /**
+ Reset unused MDL_object_lock object to represent the lock context for a
+ different object.
+ */
+ void reset(const MDL_key *new_key)
+ {
+ /* We need to change only object's key. */
+ key.mdl_key_init(new_key);
+ /* m_granted and m_waiting should be already in the empty/initial state. */
+ DBUG_ASSERT(is_empty());
+ /* Object should not be marked as destroyed. */
+ DBUG_ASSERT(! m_is_destroyed);
+ /*
+ Values of the rest of the fields should be preserved between old and
+ new versions of the object. E.g., m_version and m_ref_usage/release
+ should be kept intact to properly handle possible remaining references
+ to the old version of the object.
+ */
+ }
+
virtual const bitmap_t *incompatible_granted_types_bitmap() const
{
return m_granted_incompatible;
@@ -495,10 +555,29 @@ public:
private:
static const bitmap_t m_granted_incompatible[MDL_TYPE_END];
static const bitmap_t m_waiting_incompatible[MDL_TYPE_END];
+
+public:
+ /** Members for linking the object into the list of unused objects. */
+ MDL_object_lock *next_in_cache, **prev_in_cache;
+};
+
+
+/**
+ Helper class for linking MDL_object_lock objects into the unused objects list.
+*/
+class MDL_object_lock_cache_adapter :
+ public I_P_List_adapter<MDL_object_lock, &MDL_object_lock::next_in_cache,
+ &MDL_object_lock::prev_in_cache>
+{
};
static MDL_map mdl_locks;
+/**
+ Start-up parameter for the maximum size of the unused MDL_lock objects cache.
+*/
+ulong mdl_locks_cache_size;
+
extern "C"
{
@@ -581,6 +660,10 @@ void MDL_map::destroy()
my_hash_free(&m_locks);
MDL_lock::destroy(m_global_lock);
MDL_lock::destroy(m_commit_lock);
+
+ MDL_object_lock *lock;
+ while ((lock= m_unused_locks_cache.pop_front()))
+ MDL_lock::destroy(lock);
}
@@ -630,11 +713,49 @@ retry:
mdl_key->ptr(),
mdl_key->length())))
{
- lock= MDL_lock::create(mdl_key);
+ MDL_object_lock *unused_lock= NULL;
+
+ /*
+ No lock object found so we need to create a new one
+ or reuse an existing unused object.
+ */
+ if (mdl_key->mdl_namespace() != MDL_key::SCHEMA &&
+ m_unused_locks_cache.elements())
+ {
+ /*
+ We need a MDL_object_lock type of object and the unused objects
+ cache has some. Get the first object from the cache and set a new
+ key for it.
+ */
+ DBUG_ASSERT(mdl_key->mdl_namespace() != MDL_key::GLOBAL &&
+ mdl_key->mdl_namespace() != MDL_key::COMMIT);
+
+ unused_lock= m_unused_locks_cache.pop_front();
+ unused_lock->reset(mdl_key);
+
+ lock= unused_lock;
+ }
+ else
+ {
+ lock= MDL_lock::create(mdl_key);
+ }
+
if (!lock || my_hash_insert(&m_locks, (uchar*)lock))
{
+ if (unused_lock)
+ {
+ /*
+ Note that we can't easily destroy an object from cache here as it
+ still might be referenced by other threads. So we simply put it
+ back into the cache.
+ */
+ m_unused_locks_cache.push_front(unused_lock);
+ }
+ else
+ {
+ MDL_lock::destroy(lock);
+ }
mysql_mutex_unlock(&m_mutex);
- MDL_lock::destroy(lock);
return NULL;
}
}
@@ -649,7 +770,7 @@ retry:
/**
Release mdl_locks.m_mutex mutex and lock MDL_lock::m_rwlock for lock
object from the hash. Handle situation when object was released
- while the held no mutex.
+ while we held no locks.
@retval FALSE - Success.
@retval TRUE - Object was released while we held no mutex, caller
@@ -658,6 +779,8 @@ retry:
bool MDL_map::move_from_hash_to_lock_mutex(MDL_lock *lock)
{
+ ulonglong version;
+
DBUG_ASSERT(! lock->m_is_destroyed);
mysql_mutex_assert_owner(&m_mutex);
@@ -667,26 +790,50 @@ bool MDL_map::move_from_hash_to_lock_mut
m_is_destroyed is FALSE.
*/
lock->m_ref_usage++;
+ /* Read value of the version counter under protection of m_mutex lock. */
+ version= lock->m_version;
mysql_mutex_unlock(&m_mutex);
mysql_prlock_wrlock(&lock->m_rwlock);
lock->m_ref_release++;
- if (unlikely(lock->m_is_destroyed))
+
+ if (unlikely(lock->m_version != version))
{
/*
- Object was released while we held no mutex, we need to
- release it if no others hold references to it, while our own
- reference count ensured that the object as such haven't got
- its memory released yet. We can also safely compare
- m_ref_usage and m_ref_release since the object is no longer
- present in the hash so no one will be able to find it and
- increment m_ref_usage anymore.
+ If the current value of version differs from one that was read while
+ we held m_mutex mutex, this MDL_lock object was moved to the unused
+ objects list or destroyed while we held no locks.
+ We should retry our search. But first we should destroy the MDL_lock
+ object if necessary.
*/
- uint ref_usage= lock->m_ref_usage;
- uint ref_release= lock->m_ref_release;
- mysql_prlock_unlock(&lock->m_rwlock);
- if (ref_usage == ref_release)
- MDL_lock::destroy(lock);
+ if (unlikely(lock->m_is_destroyed))
+ {
+ /*
+ Object was released while we held no locks, we need to
+ release it if no others hold references to it, while our own
+ reference count ensured that the object as such haven't got
+ its memory released yet. We can also safely compare
+ m_ref_usage and m_ref_release since the object is no longer
+ present in the hash (or unused objects list) so no one will
+ be able to find it and increment m_ref_usage anymore.
+ */
+ uint ref_usage= lock->m_ref_usage;
+ uint ref_release= lock->m_ref_release;
+ mysql_prlock_unlock(&lock->m_rwlock);
+ if (ref_usage == ref_release)
+ MDL_lock::destroy(lock);
+ }
+ else
+ {
+ /*
+ Object was not destroyed but its version has changed.
+ This means that it was moved to the unused objects list
+ (and even might be already re-used). So now it might
+ correspond to a different key, therefore we should simply
+ retry our search.
+ */
+ mysql_prlock_unlock(&lock->m_rwlock);
+ }
return TRUE;
}
return FALSE;
@@ -701,8 +848,6 @@ bool MDL_map::move_from_hash_to_lock_mut
void MDL_map::remove(MDL_lock *lock)
{
- uint ref_usage, ref_release;
-
if (lock->key.mdl_namespace() == MDL_key::GLOBAL ||
lock->key.mdl_namespace() == MDL_key::COMMIT)
{
@@ -714,31 +859,65 @@ void MDL_map::remove(MDL_lock *lock)
return;
}
- /*
- Destroy the MDL_lock object, but ensure that anyone that is
- holding a reference to the object is not remaining, if so he
- has the responsibility to release it.
-
- Setting of m_is_destroyed to TRUE while holding _both_
- mdl_locks.m_mutex and MDL_lock::m_rwlock mutexes transfers the
- protection of m_ref_usage from mdl_locks.m_mutex to
- MDL_lock::m_rwlock while removal of object from the hash makes
- it read-only. Therefore whoever acquires MDL_lock::m_rwlock next
- will see most up to date version of m_ref_usage.
-
- This means that when m_is_destroyed is TRUE and we hold the
- MDL_lock::m_rwlock we can safely read the m_ref_usage
- member.
- */
mysql_mutex_lock(&m_mutex);
my_hash_delete(&m_locks, (uchar*) lock);
- lock->m_is_destroyed= TRUE;
- ref_usage= lock->m_ref_usage;
- ref_release= lock->m_ref_release;
- mysql_prlock_unlock(&lock->m_rwlock);
- mysql_mutex_unlock(&m_mutex);
- if (ref_usage == ref_release)
- MDL_lock::destroy(lock);
+ /*
+ To let threads holding references to the MDL_lock object know that it was
+ moved to the list of unused objects or destroyed, we increment the version
+ counter under protection of both MDL_map::m_mutex and MDL_lock::m_rwlock
+ locks. This allows us to read the version value while having either one
+ of those locks.
+ */
+ lock->m_version++;
+
+ if ((lock->key.mdl_namespace() != MDL_key::SCHEMA) &&
+ (m_unused_locks_cache.elements() < mdl_locks_cache_size))
+ {
+ /*
+ This is an object of MDL_object_lock type and the cache of unused
+ objects has not reached its maximum size yet. So instead of destroying
+ object we move it to the list of unused objects to allow its later
+ re-use with possibly different key. Any threads holding references to
+ this object (owning MDL_map::m_mutex or MDL_lock::m_rwlock) will notice
+ this thanks to the fact that we have changed the MDL_lock::m_version
+ counter.
+ */
+ DBUG_ASSERT(lock->key.mdl_namespace() != MDL_key::GLOBAL &&
+ lock->key.mdl_namespace() != MDL_key::COMMIT);
+
+ m_unused_locks_cache.push_front((MDL_object_lock*)lock);
+ mysql_mutex_unlock(&m_mutex);
+ mysql_prlock_unlock(&lock->m_rwlock);
+ }
+ else
+ {
+ /*
+ Destroy the MDL_lock object, but ensure that anyone that is
+ holding a reference to the object is not remaining, if so he
+ has the responsibility to release it.
+
+ Setting of m_is_destroyed to TRUE while holding _both_
+ mdl_locks.m_mutex and MDL_lock::m_rwlock mutexes transfers the
+ protection of m_ref_usage from mdl_locks.m_mutex to
+ MDL_lock::m_rwlock while removal of the object from the hash
+ (and cache of unused objects) makes it read-only. Therefore
+ whoever acquires MDL_lock::m_rwlock next will see the most up
+ to date version of m_ref_usage.
+
+ This means that when m_is_destroyed is TRUE and we hold the
+ MDL_lock::m_rwlock we can safely read the m_ref_usage
+ member.
+ */
+ uint ref_usage, ref_release;
+
+ lock->m_is_destroyed= TRUE;
+ ref_usage= lock->m_ref_usage;
+ ref_release= lock->m_ref_release;
+ mysql_mutex_unlock(&m_mutex);
+ mysql_prlock_unlock(&lock->m_rwlock);
+ if (ref_usage == ref_release)
+ MDL_lock::destroy(lock);
+ }
}
@@ -837,9 +1016,6 @@ void MDL_request::init(const MDL_key *ke
Auxiliary functions needed for creation/destruction of MDL_lock objects.
@note Also chooses an MDL_lock descendant appropriate for object namespace.
-
- @todo This naive implementation should be replaced with one that saves
- on memory allocation by reusing released objects.
*/
inline MDL_lock *MDL_lock::create(const MDL_key *mdl_key)
=== modified file 'sql/mdl.h'
--- a/sql/mdl.h 2011-11-14 15:41:08 +0000
+++ b/sql/mdl.h 2011-11-16 16:21:20 +0000
@@ -941,4 +941,12 @@ void mdl_destroy();
extern mysql_mutex_t LOCK_open;
#endif
+
+/*
+ Start-up parameter for the maximum size of the unused MDL_lock objects cache
+ and a constant for its default value.
+*/
+extern ulong mdl_locks_cache_size;
+static const ulong MDL_LOCKS_CACHE_SIZE_DEFAULT = 1024;
+
#endif
=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc 2011-10-28 12:45:35 +0000
+++ b/sql/rpl_rli.cc 2011-11-16 01:19:40 +0000
@@ -85,7 +85,8 @@ Relay_log_info::Relay_log_info(bool is_s
checkpoint_group(mts_checkpoint_group), mts_recovery_group_cnt(0),
mts_recovery_index(0), mts_recovery_group_seen_begin(0),
mts_group_status(MTS_NOT_IN_GROUP), reported_unsafe_warning(false),
- sql_delay(0), sql_delay_end(0), m_flags(0)
+ sql_delay(0), sql_delay_end(0), m_flags(0), row_stmt_start_timestamp(0),
+ long_find_row_note_printed(false)
{
DBUG_ENTER("Relay_log_info::Relay_log_info");
@@ -1142,6 +1143,15 @@ void Relay_log_info::cleanup_context(THD
*/
thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
+
+ /*
+ Reset state related to long_find_row notes in the error log:
+ - timestamp
+ - flag that decides whether the slave prints or not
+ */
+ reset_row_stmt_start_timestamp();
+ unset_long_find_row_note_printed();
+
DBUG_VOID_RETURN;
}
=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h 2011-10-13 14:01:50 +0000
+++ b/sql/rpl_rli.h 2011-11-15 13:04:11 +0000
@@ -758,6 +758,40 @@ public:
with several warning messages.
*/
bool reported_unsafe_warning;
+
+ time_t get_row_stmt_start_timestamp()
+ {
+ return row_stmt_start_timestamp;
+ }
+
+ time_t set_row_stmt_start_timestamp()
+ {
+ if (row_stmt_start_timestamp == 0)
+ row_stmt_start_timestamp= my_time(0);
+
+ return row_stmt_start_timestamp;
+ }
+
+ void reset_row_stmt_start_timestamp()
+ {
+ row_stmt_start_timestamp= 0;
+ }
+
+ void set_long_find_row_note_printed()
+ {
+ long_find_row_note_printed= true;
+ }
+
+ void unset_long_find_row_note_printed()
+ {
+ long_find_row_note_printed= false;
+ }
+
+ bool is_long_find_row_note_printed()
+ {
+ return long_find_row_note_printed;
+ }
+
private:
/**
Delay slave SQL thread by this amount, compared to master (in
@@ -799,6 +833,13 @@ private:
Relay_log_info(const Relay_log_info& info);
Relay_log_info& operator=(const Relay_log_info& info);
+
+ /*
+ Runtime state for printing a note when slave is taking
+ too long while processing a row event.
+ */
+ time_t row_stmt_start_timestamp;
+ bool long_find_row_note_printed;
};
bool mysql_show_relaylog_events(THD* thd);
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2011-11-14 15:41:08 +0000
+++ b/sql/sql_class.h 2011-11-16 16:21:20 +0000
@@ -2361,16 +2361,16 @@ public:
/** Current statement instrumentation. */
PSI_statement_locker *m_statement_psi;
-#ifndef EMBEDDED_LIBRARY
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
/** Current statement instrumentation state. */
PSI_statement_locker_state m_statement_state;
-#endif /* EMBEDDED_LIBRARY */
+#endif /* HAVE_PSI_STATEMENT_INTERFACE */
/** Idle instrumentation. */
PSI_idle_locker *m_idle_psi;
-#ifndef EMBEDDED_LIBRARY
+#ifdef HAVE_PSI_IDLE_INTERFACE
/** Idle instrumentation state. */
PSI_idle_locker_state m_idle_state;
-#endif /* EMBEDDED_LIBRARY */
+#endif /* HAVE_PSI_IDLE_INTERFACE */
/** True if the server code is IDLE for this connection. */
bool m_server_idle;
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2011-11-16 12:27:09 +0000
+++ b/sql/sql_partition.cc 2011-11-16 16:21:20 +0000
@@ -6470,8 +6470,24 @@ static void alter_partition_lock_handlin
lpt->table= 0;
lpt->old_table= 0;
lpt->table_list->table= 0;
- if (thd->locked_tables_list.reopen_tables(thd))
- sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE");
+ if (thd->locked_tables_mode)
+ {
+ Diagnostics_area *stmt_da= NULL;
+ Diagnostics_area tmp_stmt_da;
+
+ if (thd->is_error())
+ {
+ /* reopen might fail if we have a previous error, use a temporary da. */
+ stmt_da= thd->get_stmt_da();
+ thd->set_stmt_da(&tmp_stmt_da);
+ }
+
+ if (thd->locked_tables_list.reopen_tables(thd))
+ sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE");
+
+ if (stmt_da)
+ thd->set_stmt_da(stmt_da);
+ }
}
=== modified file 'sql/sql_plist.h'
--- a/sql/sql_plist.h 2011-07-03 23:56:47 +0000
+++ b/sql/sql_plist.h 2011-11-15 18:51:44 +0000
@@ -128,6 +128,15 @@ public:
}
inline T* front() { return m_first; }
inline const T *front() const { return m_first; }
+ inline T* pop_front()
+ {
+ T *result= front();
+
+ if (result)
+ remove(result);
+
+ return result;
+ }
void swap(I_P_List<T, B, C> &rhs)
{
swap_variables(T *, m_first, rhs.m_first);
=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc 2011-11-10 06:53:27 +0000
+++ b/sql/sys_vars.cc 2011-11-15 18:51:44 +0000
@@ -1425,6 +1425,12 @@ static Sys_var_ulonglong Sys_max_heap_ta
VALID_RANGE(16384, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
BLOCK_SIZE(1024));
+static Sys_var_ulong Sys_metadata_locks_cache_size(
+ "metadata_locks_cache_size", "Size of unused metadata locks cache",
+ READ_ONLY GLOBAL_VAR(mdl_locks_cache_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, 1024*1024), DEFAULT(MDL_LOCKS_CACHE_SIZE_DEFAULT),
+ BLOCK_SIZE(1));
+
static Sys_var_ulong Sys_pseudo_thread_id(
"pseudo_thread_id",
"This variable is for internal server use",
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk-wl5534 branch (jon.hauglid:3426 to 3427) | Jon Olav Hauglid | 17 Nov |