mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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
This commit is contained in:
20
mysql-test/r/temp_table_frm.result
Normal file
20
mysql-test/r/temp_table_frm.result
Normal file
@ -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;
|
13
mysql-test/t/temp_table_frm.test
Normal file
13
mysql-test/t/temp_table_frm.test
Normal file
@ -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;
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -261,52 +261,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.
|
||||
|
||||
@ -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
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user