summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2014-06-20 11:34:24 +0200
committerSergei Golubchik <serg@mariadb.org>2014-06-20 15:47:44 +0200
commitce6a63ec41160ef6b7c0110d3f40aea79b8f3129 (patch)
tree4be27ef7152fd4f557bb09ad8943893f2d62ea1c
parentcc5b3998b6767523792f7e4ec8c9a100db2d06ce (diff)
downloadmariadb-git-ce6a63ec41160ef6b7c0110d3f40aea79b8f3129.tar.gz
MDEV-4260 Don't create frm files for temporary tables
* Don't write frm for tmp tables * pass frm image down to open_table_uncached, when possible * don't use truncate-by-recreate for temp tables - cannot recreate without frm, and delete_all_rows is faster anyway
-rw-r--r--mysql-test/r/temp_table_frm.result20
-rw-r--r--mysql-test/t/temp_table_frm.test13
-rw-r--r--sql/sql_base.cc14
-rw-r--r--sql/sql_base.h3
-rw-r--r--sql/sql_table.cc9
-rw-r--r--sql/sql_truncate.cc68
-rw-r--r--sql/unireg.cc3
7 files changed, 55 insertions, 75 deletions
diff --git a/mysql-test/r/temp_table_frm.result b/mysql-test/r/temp_table_frm.result
new file mode 100644
index 00000000000..ff809957a3d
--- /dev/null
+++ b/mysql-test/r/temp_table_frm.result
@@ -0,0 +1,20 @@
+create table t1 select * from information_schema.session_status where variable_name like 'Opened%';
+create temporary table t2 (a int) engine=memory;
+select variable_name, session_status.variable_value - t1.variable_value
+from information_schema.session_status join t1 using (variable_name);
+variable_name session_status.variable_value - t1.variable_value
+OPENED_FILES 0
+OPENED_PLUGIN_LIBRARIES 0
+OPENED_TABLE_DEFINITIONS 2
+OPENED_TABLES 2
+OPENED_VIEWS 0
+truncate table t2;
+select variable_name, session_status.variable_value - t1.variable_value
+from information_schema.session_status join t1 using (variable_name);
+variable_name session_status.variable_value - t1.variable_value
+OPENED_FILES 0
+OPENED_PLUGIN_LIBRARIES 0
+OPENED_TABLE_DEFINITIONS 2
+OPENED_TABLES 2
+OPENED_VIEWS 0
+drop table t1;
diff --git a/mysql-test/t/temp_table_frm.test b/mysql-test/t/temp_table_frm.test
new file mode 100644
index 00000000000..5a523cda37d
--- /dev/null
+++ b/mysql-test/t/temp_table_frm.test
@@ -0,0 +1,13 @@
+#
+# MDEV-4260 Don't create frm files for temporary tables
+#
+create table t1 select * from information_schema.session_status where variable_name like 'Opened%';
+create temporary table t2 (a int) engine=memory;
+select variable_name, session_status.variable_value - t1.variable_value
+from information_schema.session_status join t1 using (variable_name);
+let $tmpdir= `select @@tmpdir`;
+--list_files $tmpdir/
+truncate table t2;
+select variable_name, session_status.variable_value - t1.variable_value
+from information_schema.session_status join t1 using (variable_name);
+drop table t1;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 055806609e7..d60506dcad7 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -5508,6 +5508,7 @@ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
@param thd Thread context.
@param hton Storage engine of the table, if known,
or NULL otherwise.
+ @param frm frm image
@param path Path (without .frm)
@param db Database name.
@param table_name Table name.
@@ -5527,6 +5528,7 @@ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
*/
TABLE *open_table_uncached(THD *thd, handlerton *hton,
+ LEX_CUSTRING *frm,
const char *path, const char *db,
const char *table_name,
bool add_to_temporary_tables_list,
@@ -5561,7 +5563,17 @@ TABLE *open_table_uncached(THD *thd, handlerton *hton,
strend(saved_cache_key)+1, tmp_path);
share->db_plugin= ha_lock_engine(thd, hton);
- if (open_table_def(thd, share, GTS_TABLE | GTS_USE_DISCOVERY))
+ /*
+ Use the frm image, if possible, open the file otherwise.
+
+ The image might be unavailable in ALTER TABLE, when the discovering
+ engine took over the ownership (see TABLE::read_frm_image).
+ */
+ int res= frm->str
+ ? share->init_from_binary_frm_image(thd, false, frm->str, frm->length)
+ : open_table_def(thd, share, GTS_TABLE | GTS_USE_DISCOVERY);
+
+ if (res)
{
/* No need to lock share->mutex as this is not needed for tmp tables */
free_table_share(share);
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 61442843a39..6f8e9c1c03b 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -127,7 +127,8 @@ bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
bool get_key_map_from_key_list(key_map *map, TABLE *table,
List<String> *index_list);
-TABLE *open_table_uncached(THD *thd, handlerton *hton, const char *path,
+TABLE *open_table_uncached(THD *thd, handlerton *hton,
+ LEX_CUSTRING *frm, const char *path,
const char *db, const char *table_name,
bool add_to_temporary_tables_list,
bool open_in_engine);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index c3410d9c0cd..80ac0978834 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4847,7 +4847,7 @@ int create_table_impl(THD *thd,
THD::temporary_tables list.
*/
- TABLE *table= open_table_uncached(thd, create_info->db_type, path,
+ TABLE *table= open_table_uncached(thd, create_info->db_type, frm, path,
db, table_name, true, true);
if (!table)
@@ -8691,7 +8691,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
// We assume that the table is non-temporary.
DBUG_ASSERT(!table->s->tmp_table);
- if (!(altered_table= open_table_uncached(thd, new_db_type,
+ if (!(altered_table= open_table_uncached(thd, new_db_type, &frm,
alter_ctx.get_tmp_path(),
alter_ctx.new_db,
alter_ctx.tmp_name,
@@ -8845,7 +8845,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (create_info->tmp_table())
{
- if (!open_table_uncached(thd, new_db_type,
+ if (!open_table_uncached(thd, new_db_type, &frm,
alter_ctx.get_tmp_path(),
alter_ctx.new_db, alter_ctx.tmp_name,
true, true))
@@ -8867,7 +8867,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
/* table is a normal table: Create temporary table in same directory */
/* Open our intermediate table. */
- new_table= open_table_uncached(thd, new_db_type, alter_ctx.get_tmp_path(),
+ new_table= open_table_uncached(thd, new_db_type, &frm,
+ alter_ctx.get_tmp_path(),
alter_ctx.new_db, alter_ctx.tmp_name,
true, true);
}
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index fe2ea02a8e2..e98679b1d51 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -262,52 +262,6 @@ Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref,
/*
- Close and recreate a temporary table. In case of success,
- write truncate statement into the binary log if in statement
- mode.
-
- @param thd Thread context.
- @param table The temporary table.
-
- @retval FALSE Success.
- @retval TRUE Error.
-*/
-
-static bool recreate_temporary_table(THD *thd, TABLE *table)
-{
- bool error= TRUE;
- TABLE_SHARE *share= table->s;
- handlerton *table_type= table->s->db_type();
- TABLE *new_table;
- DBUG_ENTER("recreate_temporary_table");
-
- table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
-
- /* Don't free share. */
- close_temporary_table(thd, table, FALSE, FALSE);
-
- dd_recreate_table(thd, share->db.str, share->table_name.str,
- share->normalized_path.str);
-
- if ((new_table= open_table_uncached(thd, table_type, share->path.str,
- share->db.str,
- share->table_name.str, true, true)))
- {
- error= FALSE;
- thd->thread_specific_used= TRUE;
- new_table->s->table_creation_was_logged= share->table_creation_was_logged;
- }
- else
- rm_temporary_table(table_type, share->path.str);
-
- free_table_share(share);
- my_free(table);
-
- DBUG_RETURN(error);
-}
-
-
-/*
Handle locking a base table for truncate.
@param[in] thd Thread context.
@@ -441,30 +395,10 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
/* If it is a temporary table, no need to take locks. */
if (is_temporary_table(table_ref))
{
- TABLE *tmp_table= table_ref->table;
-
/* In RBR, the statement is not binlogged if the table is temporary. */
binlog_stmt= !thd->is_current_stmt_binlog_format_row();
- /* Note that a temporary table cannot be partitioned. */
- if (ha_check_storage_engine_flag(tmp_table->s->db_type(),
- HTON_CAN_RECREATE))
- {
- if ((error= recreate_temporary_table(thd, tmp_table)))
- binlog_stmt= FALSE; /* No need to binlog failed truncate-by-recreate. */
-
- DBUG_ASSERT(! thd->transaction.stmt.modified_non_trans_table);
- }
- else
- {
- /*
- The engine does not support truncate-by-recreate. Open the
- table and invoke the handler truncate. In such a manner this
- can in fact open several tables if it's a temporary MyISAMMRG
- table.
- */
- error= handler_truncate(thd, table_ref, TRUE);
- }
+ error= handler_truncate(thd, table_ref, TRUE);
/*
No need to invalidate the query cache, queries with temporary
diff --git a/sql/unireg.cc b/sql/unireg.cc
index b7ac8b17c38..3eb7a8ce5eb 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -354,8 +354,7 @@ int rea_create_table(THD *thd, LEX_CUSTRING *frm,
{
DBUG_ENTER("rea_create_table");
- // TODO don't write frm for temp tables
- if (no_ha_create_table || create_info->tmp_table())
+ if (no_ha_create_table)
{
if (writefrm(path, db, table_name, true, frm->str, frm->length))
goto err_frm;