summaryrefslogtreecommitdiff
path: root/mysql-test/t/log_tables.test
diff options
context:
space:
mode:
authorunknown <petr/cps@mysql.com/owlet.>2006-08-03 21:28:15 +0400
committerunknown <petr/cps@mysql.com/owlet.>2006-08-03 21:28:15 +0400
commit157c42de9713618c23116079f634fa8b54fd403e (patch)
treecb952c4fb976588566dd3442e145ab59847f7c7c /mysql-test/t/log_tables.test
parentd090462abc2925a22a4d2dee4c87d679a9ad32f1 (diff)
downloadmariadb-git-157c42de9713618c23116079f634fa8b54fd403e.tar.gz
Fix Bug #18559 "log tables cannot change engine, and
gets deadlocked when dropping w/ log on" Log tables rely on concurrent insert machinery to add data. This means that log tables are always opened and locked by special (artificial) logger threads. Because of this, the thread which tries to drop a log table starts to wait for the table to be unlocked. Which will happen only if the log table is disabled. Alike situation happens if one tries to alter a log table. However in addition to the problem above, alter table calls check_if_locking_is_allowed() routine for the engine. The routine does not allow alter for the log tables. So, alter doesn't start waiting forever for logs to be disabled, but returns with an error. Another problem is that not all engines could be used for the log tables. That's because they need concurrent insert. In this patch we: (1) Explicitly disallow to drop/alter a log table if it is currently used by the logger. (2) Update MyISAM to support log tables (3) Allow to drop log tables/alter log tables if log is disabled At the same time we (4) Disallow to alter log tables to unsupported engine (after this patch CSV and MyISAM are alowed) Recommit with review fixes. mysql-test/r/log_tables.result: Update result file. Note: there are warnings in result file. This is because of CSV bug (Bug #21328). They should go away after it is fixed. mysql-test/t/log_tables.test: Add a test for the bug sql/ha_myisam.cc: Add log table handling to myisam: as log tables use concurrent insert, they are typically locked with TL_CONCURRERENT_INSERT lock. So, disallow other threads to attempt locking of the log tables in incompatible modes. Because otherwise the threads will wait for the tables to be unlocked forever. sql/handler.cc: Add a function to check if a table we're going to lock is a log table and if the lock mode we want allowed sql/handler.h: Add a new function to check compatibility of the locking sql/log.cc: we shouldn't close the log table if and only if this particular table is already closed sql/log.h: add new functions to check if a log is enabled sql/share/errmsg.txt: add new error messages sql/sql_table.cc: DROP and ALTER TABLE should not work on log tables if the log tables are enabled storage/csv/ha_tina.cc: move function to check if the locking for the log tables allowed to handler class, so that we can reuse it in other engines. storage/myisam/mi_extra.c: add new ::extra() flag processing to myisam storage/myisam/mi_open.c: init log table flag storage/myisam/mi_write.c: update status after each write if it's a log table storage/myisam/myisamdef.h: Add new log table flag to myisam share. We need it to distinguish between usual and log tables, as for the log tables we should provide concurrent insert in a different way than for usual tables: we want new rows to be immediately visible to other threads.
Diffstat (limited to 'mysql-test/t/log_tables.test')
-rw-r--r--mysql-test/t/log_tables.test133
1 files changed, 133 insertions, 0 deletions
diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test
index 5b79e5e4625..df88b13a225 100644
--- a/mysql-test/t/log_tables.test
+++ b/mysql-test/t/log_tables.test
@@ -171,6 +171,139 @@ select sleep(2);
--replace_column 1 TIMESTAMP 2 USER_HOST 3 QUERY_TIME
select * from mysql.slow_log;
+#
+# Bug #18559 log tables cannot change engine, and gets deadlocked when
+# dropping w/ log on
+#
+
+# check that appropriate error messages are given when one attempts to alter
+# or drop a log tables, while corresponding logs are enabled
+--error ER_CANT_ALTER_LOG_TABLE
+alter table mysql.general_log engine=myisam;
+--error ER_CANT_ALTER_LOG_TABLE
+alter table mysql.slow_log engine=myisam;
+
+--error ER_CANT_DROP_LOG_TABLE
+drop table mysql.general_log;
+--error ER_CANT_DROP_LOG_TABLE
+drop table mysql.slow_log;
+
+# check that one can alter log tables to MyISAM
+set global general_log='OFF';
+
+# cannot convert another log table
+--error ER_CANT_ALTER_LOG_TABLE
+alter table mysql.slow_log engine=myisam;
+
+# alter both tables
+set global slow_query_log='OFF';
+# check that both tables use CSV engine
+show create table mysql.general_log;
+show create table mysql.slow_log;
+
+alter table mysql.general_log engine=myisam;
+alter table mysql.slow_log engine=myisam;
+
+# check that the tables were converted
+show create table mysql.general_log;
+show create table mysql.slow_log;
+
+# enable log tables and chek that new tables indeed work
+set global general_log='ON';
+set global slow_query_log='ON';
+
+--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID
+select * from mysql.general_log;
+
+# check that flush of myisam-based log tables work fine
+flush logs;
+
+# check locking of myisam-based log tables
+
+--error ER_CANT_WRITE_LOCK_LOG_TABLE
+lock tables mysql.general_log WRITE;
+
+--error ER_CANT_WRITE_LOCK_LOG_TABLE
+lock tables mysql.slow_log WRITE;
+
+#
+# This attemts to get TL_READ_NO_INSERT lock, which is incompatible with
+# TL_WRITE_CONCURRENT_INSERT. This should fail. We issue this error as log
+# tables are always opened and locked by the logger.
+#
+
+--error ER_CANT_READ_LOCK_LOG_TABLE
+lock tables mysql.general_log READ;
+
+--error ER_CANT_READ_LOCK_LOG_TABLE
+lock tables mysql.slow_log READ;
+
+#
+# This call should result in TL_READ lock on the log table. This is ok and
+# should pass.
+#
+
+lock tables mysql.slow_log READ LOCAL, mysql.general_log READ LOCAL;
+
+unlock tables;
+
+# check that we can drop them
+set global general_log='OFF';
+set global slow_query_log='OFF';
+
+# check that alter table doesn't work for other engines
+--error ER_BAD_LOG_ENGINE
+alter table mysql.slow_log engine=ndb;
+--error ER_BAD_LOG_ENGINE
+alter table mysql.slow_log engine=innodb;
+--error ER_BAD_LOG_ENGINE
+alter table mysql.slow_log engine=archive;
+--error ER_BAD_LOG_ENGINE
+alter table mysql.slow_log engine=blackhole;
+
+drop table mysql.slow_log;
+drop table mysql.general_log;
+
+# check that table share cleanup is performed correctly (double drop)
+
+--error ER_BAD_TABLE_ERROR
+drop table mysql.general_log;
+--error ER_BAD_TABLE_ERROR
+drop table mysql.slow_log;
+
+# recreate tables and enable logs
+
+use mysql;
+
+CREATE TABLE `general_log` (
+ `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
+ ON UPDATE CURRENT_TIMESTAMP,
+ `user_host` mediumtext,
+ `thread_id` int(11) DEFAULT NULL,
+ `server_id` int(11) DEFAULT NULL,
+ `command_type` varchar(64) DEFAULT NULL,
+ `argument` mediumtext
+) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log';
+
+CREATE TABLE `slow_log` (
+ `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
+ ON UPDATE CURRENT_TIMESTAMP,
+ `user_host` mediumtext NOT NULL,
+ `query_time` time NOT NULL,
+ `lock_time` time NOT NULL,
+ `rows_sent` int(11) NOT NULL,
+ `rows_examined` int(11) NOT NULL,
+ `db` varchar(512) DEFAULT NULL,
+ `last_insert_id` int(11) DEFAULT NULL,
+ `insert_id` int(11) DEFAULT NULL,
+ `server_id` int(11) DEFAULT NULL,
+ `sql_text` mediumtext NOT NULL
+) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log';
+
+set global general_log='ON';
+set global slow_query_log='ON';
+use test;
+
# kill all connections
disconnect con1;
disconnect con2;