#At file:///Users/tnurnberg/forest/40281f/51-40281f/ based on revid:joro@stripped
3015 Tatiana A. Nurnberg 2009-07-31
Bug#40281, partitioning the general log table crashes the server
We disallow the partitioning of a log table. You could however
partition a table first, and then point logging to it. This is
not only against the docs, it also crashes the server.
We catch this case now.
@ mysql-test/r/partition.result
results for 40281
@ mysql-test/t/partition.test
test for 40281: show that trying to log to partitioned table fails rather
to crash the server
@ sql/ha_partition.cc
Signal that we no longer support logging to partitioned tables,
as per the docs.
@ sql/sql_partition.cc
Some commands like "USE ..." have no select, yet we may try
to parse partition info after their execution if user set a
partitioned table as log target. This shouldn't lead to a
NULL-deref/crash.
modified:
mysql-test/r/partition.result
mysql-test/t/partition.test
sql/ha_partition.cc
sql/sql_partition.cc
=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result 2009-07-02 14:42:00 +0000
+++ b/mysql-test/r/partition.result 2009-07-31 12:38:18 +0000
@@ -1991,5 +1991,39 @@ CREATE TABLE t1(id INT,KEY(id)) ENGINE=M
PARTITION BY HASH(id) PARTITIONS 2;
DROP TABLE t1;
SET SESSION SQL_MODE=DEFAULT;
+
+Bug#40281: partitioning the general log table crashes the server
+
+--- set up partitioned log, and switch to it
+USE mysql;
+SET GLOBAL general_log =0;
+CREATE TABLE gl_partitioned LIKE general_log;
+ALTER TABLE gl_partitioned ENGINE=myisam;
+ALTER TABLE gl_partitioned PARTITION BY HASH (thread_id) PARTITIONS 10;
+ALTER TABLE general_log RENAME TO gl_nonpartitioned;
+ALTER TABLE gl_partitioned RENAME TO general_log;
+SELECT @@global.log_output INTO @old_glo;
+SET GLOBAL log_output='table';
+SET GLOBAL general_log =1;
+--- do some things to be logged to partitioned log, should fail
+USE /* 1 */ test;
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+i
+1
+USE mysql;
+SET GLOBAL general_log =0;
+ALTER TABLE general_log RENAME TO gl_partitioned;
+ALTER TABLE gl_nonpartitioned RENAME TO general_log;
+--- show whether we actually logged anything (no) to general_log
+SELECT COUNT(argument) FROM gl_partitioned;
+COUNT(argument)
+0
+DROP TABLE gl_partitioned;
+SET GLOBAL log_output=@old_glo;
+SET GLOBAL general_log =1;
+USE /* 2 */ test;
+DROP TABLE t1;
End of 5.1 tests
SET @@global.general_log= @old_general_log;
=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test 2009-07-02 14:42:00 +0000
+++ b/mysql-test/t/partition.test 2009-07-31 12:38:18 +0000
@@ -1987,6 +1987,53 @@ CREATE TABLE t1(id INT,KEY(id)) ENGINE=M
DROP TABLE t1;
SET SESSION SQL_MODE=DEFAULT;
+--echo
+--echo Bug#40281: partitioning the general log table crashes the server
+--echo
+
+--echo --- set up partitioned log, and switch to it
+
+USE mysql;
+SET GLOBAL general_log =0;
+CREATE TABLE gl_partitioned LIKE general_log;
+ALTER TABLE gl_partitioned ENGINE=myisam;
+ALTER TABLE gl_partitioned PARTITION BY HASH (thread_id) PARTITIONS 10;
+ALTER TABLE general_log RENAME TO gl_nonpartitioned;
+ALTER TABLE gl_partitioned RENAME TO general_log;
+
+SELECT @@global.log_output INTO @old_glo;
+SET GLOBAL log_output='table';
+SET GLOBAL general_log =1;
+
+--echo --- do some things to be logged to partitioned log, should fail
+USE /* 1 */ test;
+
+CREATE TABLE t1 (i INT);
+
+connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connection master;
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+disconnect master;
+
+connection default;
+
+USE mysql;
+SET GLOBAL general_log =0;
+ALTER TABLE general_log RENAME TO gl_partitioned;
+ALTER TABLE gl_nonpartitioned RENAME TO general_log;
+
+--echo --- show whether we actually logged anything (no) to general_log
+SELECT COUNT(argument) FROM gl_partitioned;
+
+DROP TABLE gl_partitioned;
+
+SET GLOBAL log_output=@old_glo;
+SET GLOBAL general_log =1;
+
+USE /* 2 */ test;
+DROP TABLE t1;
+
--echo End of 5.1 tests
SET @@global.general_log= @old_general_log;
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2009-02-20 15:56:32 +0000
+++ b/sql/ha_partition.cc 2009-07-31 12:38:18 +0000
@@ -5381,6 +5381,13 @@ int ha_partition::extra(enum ha_extra_fu
/* Currently only NDB use the *_CANNOT_BATCH */
break;
}
+ /*
+ http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html
+ says we no longer support logging to partitioned tables, so we fail
+ here.
+ */
+ case HA_EXTRA_MARK_AS_LOG_TABLE:
+ DBUG_RETURN(ER_UNSUPORTED_LOG_ENGINE);
default:
{
/* Temporary crash to discover what is wrong */
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2009-07-08 10:12:27 +0000
+++ b/sql/sql_partition.cc 2009-07-31 12:38:18 +0000
@@ -3824,8 +3824,13 @@ bool mysql_unpack_partition(THD *thd,
Item_field objects.
This is not a nice solution since if the parser uses current_select
for anything else it will corrupt the current LEX object.
+ Also, we need to make sure there even is a select -- if the statement
+ was a "USE ...", current_select will be NULL, but we may still end up
+ here if we try to log to a partitioned table. This is currently
+ unsupported, but should still fail rather than crash!
*/
- thd->lex->current_select= old_lex->current_select;
+ if (!(thd->lex->current_select= old_lex->current_select))
+ goto end;
/*
All Items created is put into a free list on the THD object. This list
is used to free all Item objects after completing a query. We don't
Attachment: [text/bzr-bundle] bzr/azundris@mysql.com-20090731123818-vzqc6nz17h6v0obu.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-bugteam branch (azundris:3015) Bug#40281 | Tatiana A. Nurnberg | 31 Jul |