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 thd Thread context.
|
||||||
@param hton Storage engine of the table, if known,
|
@param hton Storage engine of the table, if known,
|
||||||
or NULL otherwise.
|
or NULL otherwise.
|
||||||
|
@param frm frm image
|
||||||
@param path Path (without .frm)
|
@param path Path (without .frm)
|
||||||
@param db Database name.
|
@param db Database name.
|
||||||
@param table_name Table 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,
|
TABLE *open_table_uncached(THD *thd, handlerton *hton,
|
||||||
|
LEX_CUSTRING *frm,
|
||||||
const char *path, const char *db,
|
const char *path, const char *db,
|
||||||
const char *table_name,
|
const char *table_name,
|
||||||
bool add_to_temporary_tables_list,
|
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);
|
strend(saved_cache_key)+1, tmp_path);
|
||||||
share->db_plugin= ha_lock_engine(thd, hton);
|
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 */
|
/* No need to lock share->mutex as this is not needed for tmp tables */
|
||||||
free_table_share(share);
|
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,
|
bool get_key_map_from_key_list(key_map *map, TABLE *table,
|
||||||
List<String> *index_list);
|
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,
|
const char *db, const char *table_name,
|
||||||
bool add_to_temporary_tables_list,
|
bool add_to_temporary_tables_list,
|
||||||
bool open_in_engine);
|
bool open_in_engine);
|
||||||
|
@ -4847,7 +4847,7 @@ int create_table_impl(THD *thd,
|
|||||||
THD::temporary_tables list.
|
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);
|
db, table_name, true, true);
|
||||||
|
|
||||||
if (!table)
|
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.
|
// We assume that the table is non-temporary.
|
||||||
DBUG_ASSERT(!table->s->tmp_table);
|
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.get_tmp_path(),
|
||||||
alter_ctx.new_db,
|
alter_ctx.new_db,
|
||||||
alter_ctx.tmp_name,
|
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 (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.get_tmp_path(),
|
||||||
alter_ctx.new_db, alter_ctx.tmp_name,
|
alter_ctx.new_db, alter_ctx.tmp_name,
|
||||||
true, true))
|
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 */
|
/* table is a normal table: Create temporary table in same directory */
|
||||||
/* Open our intermediate table. */
|
/* 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,
|
alter_ctx.new_db, alter_ctx.tmp_name,
|
||||||
true, true);
|
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.
|
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 it is a temporary table, no need to take locks. */
|
||||||
if (is_temporary_table(table_ref))
|
if (is_temporary_table(table_ref))
|
||||||
{
|
{
|
||||||
TABLE *tmp_table= table_ref->table;
|
|
||||||
|
|
||||||
/* In RBR, the statement is not binlogged if the table is temporary. */
|
/* In RBR, the statement is not binlogged if the table is temporary. */
|
||||||
binlog_stmt= !thd->is_current_stmt_binlog_format_row();
|
binlog_stmt= !thd->is_current_stmt_binlog_format_row();
|
||||||
|
|
||||||
/* Note that a temporary table cannot be partitioned. */
|
error= handler_truncate(thd, table_ref, TRUE);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
No need to invalidate the query cache, queries with temporary
|
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");
|
DBUG_ENTER("rea_create_table");
|
||||||
|
|
||||||
// TODO don't write frm for temp tables
|
if (no_ha_create_table)
|
||||||
if (no_ha_create_table || create_info->tmp_table())
|
|
||||||
{
|
{
|
||||||
if (writefrm(path, db, table_name, true, frm->str, frm->length))
|
if (writefrm(path, db, table_name, true, frm->str, frm->length))
|
||||||
goto err_frm;
|
goto err_frm;
|
||||||
|
Reference in New Issue
Block a user