Fixed that HA_EXTRA_FLUSH in Aria and MyISAM flushes all data to disk

This is needed to support Atomic CREATE TABLE t1 SELECT * FROM ...
on non transactional tables.
This commit is contained in:
Monty 2025-02-26 14:38:54 +02:00
parent 7728b90a0d
commit 2c4fee8376
2 changed files with 48 additions and 13 deletions

View File

@ -416,9 +416,25 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
break;
case HA_EXTRA_FLUSH:
if (!share->temporary)
error= _ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
FLUSH_KEEP, FLUSH_KEEP);
{
if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
FLUSH_KEEP, FLUSH_KEEP))
error= my_errno;
if (!error && share->changed)
{
mysql_mutex_lock(&share->intern_lock);
if (_ma_state_info_write(share,
MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET |
MA_STATE_INFO_WRITE_FULL_INFO))
error= my_errno;
mysql_mutex_unlock(&share->intern_lock);
}
if (info->opt_flag & WRITE_CACHE_USED)
{
if ((my_b_flush_io_cache(&info->rec_cache, 0)))
error= my_errno;
}
}
mysql_mutex_lock(&share->intern_lock);
/* Tell maria_lock_database() that we locked the intern_lock mutex */
info->intern_lock_locked= 1;
@ -429,12 +445,12 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
share->not_flushed= 0;
if (_ma_sync_table_files(info))
error= my_errno;
if (error)
{
/* Fatal error found */
share->changed= 1;
_ma_set_fatal_error(info, HA_ERR_CRASHED);
}
}
if (error)
{
/* Fatal error found */
share->changed= 1;
_ma_set_fatal_error(info, HA_ERR_CRASHED);
}
mysql_mutex_unlock(&share->intern_lock);
break;

View File

@ -37,7 +37,7 @@ static void mi_extra_keyflag(MI_INFO *info, enum ha_extra_function function);
int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
{
int error=0;
int error=0, error2;
ulong cache_size;
MYISAM_SHARE *share=info->s;
DBUG_ENTER("mi_extra");
@ -277,10 +277,29 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
break;
case HA_EXTRA_END_ALTER_COPY:
case HA_EXTRA_FLUSH:
if (!share->temporary)
flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map,
FLUSH_KEEP);
mysql_mutex_lock(&share->intern_lock);
if (!share->temporary)
{
if (flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map,
FLUSH_KEEP))
error= my_errno;
/*
Check if this is the primary table holding the state of the table
If there are multiple usage of the same table, only one is holding
the true state.
*/
if (info->state == &info->save_state)
{
info->s->state.state= *info->state;
if (info->opt_flag & WRITE_CACHE_USED)
{
if ((error2= my_b_flush_io_cache(&info->rec_cache, 0)))
error= error2;
}
if ((error2= mi_state_info_write(share->kfile, &share->state, 1)))
error= error2;
}
}
/* Tell mi_lock_database() that we locked the intern_lock mutex */
info->intern_lock_locked= 1;
_mi_decrement_open_count(info);