summaryrefslogtreecommitdiff
path: root/storage/maria
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2019-03-10 18:55:35 +0100
committerSergei Golubchik <serg@mariadb.org>2019-03-12 09:51:42 +0100
commit69abd43703fcf68c4cf1056bf5bd56c690de5b4e (patch)
tree5a573a0a3c1105e7b96cebbf4a3fe130df36eaa8 /storage/maria
parent7025a51a7b85376b2f01b1f32e737278e9aa659b (diff)
downloadmariadb-git-69abd43703fcf68c4cf1056bf5bd56c690de5b4e.tar.gz
MDEV-17070 Table corruption or Assertion `table->file->stats.records > 0 || error' or Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' failed upon actions on temporary table
This was caused by a combination of factors: * MyISAM/Aria temporary tables historically never saved the state to disk (MYI/MAI), because the state never needed to persist * certain ALTER TABLE operations modify the original TABLE structure and if they fail, the original table has to be reopened to revert all changes (m_needs_reopen=1) as a result, when ALTER fails and MyISAM/Aria temp table gets reopened, it reads the stale state from the disk. As a fix, MyISAM/Aria tables now *always* write the state to disk on close, *unless* HA_EXTRA_PREPARE_FOR_DROP was done first. And the server now always does HA_EXTRA_PREPARE_FOR_DROP before dropping a temporary table.
Diffstat (limited to 'storage/maria')
-rw-r--r--storage/maria/ma_blockrec.c4
-rw-r--r--storage/maria/ma_close.c17
-rw-r--r--storage/maria/ma_extra.c2
-rw-r--r--storage/maria/ma_open.c2
4 files changed, 7 insertions, 18 deletions
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 0b55a03f902..4395613862e 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -449,9 +449,7 @@ my_bool _ma_once_end_block_record(MARIA_SHARE *share)
if (share->bitmap.file.file >= 0)
{
if (flush_pagecache_blocks(share->pagecache, &share->bitmap.file,
- ((share->temporary || share->deleting) ?
- FLUSH_IGNORE_CHANGED :
- FLUSH_RELEASE)))
+ share->deleting ? FLUSH_IGNORE_CHANGED : FLUSH_RELEASE))
res= 1;
/*
File must be synced as it is going out of the maria_open_list and so
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index 6e85551c24f..08bb7cee138 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -47,9 +47,7 @@ int maria_close(register MARIA_HA *info)
a global mutex
*/
if (flush_pagecache_blocks(share->pagecache, &share->kfile,
- ((share->temporary || share->deleting) ?
- FLUSH_IGNORE_CHANGED :
- FLUSH_RELEASE)))
+ share->deleting ? FLUSH_IGNORE_CHANGED : FLUSH_RELEASE))
error= my_errno;
}
@@ -113,23 +111,14 @@ int maria_close(register MARIA_HA *info)
since the start of the function (very unlikely)
*/
if (flush_pagecache_blocks(share->pagecache, &share->kfile,
- ((share->temporary || share->deleting) ?
- FLUSH_IGNORE_CHANGED :
- FLUSH_RELEASE)))
+ share->deleting ? FLUSH_IGNORE_CHANGED : FLUSH_RELEASE))
error= my_errno;
#ifdef HAVE_MMAP
if (share->file_map)
_ma_unmap_file(info);
#endif
- /*
- If we are crashed, we can safely flush the current state as it will
- not change the crashed state.
- We can NOT write the state in other cases as other threads
- may be using the file at this point
- IF using --external-locking, which does not apply to Maria.
- */
if (((share->changed && share->base.born_transactional) ||
- maria_is_crashed(info)))
+ maria_is_crashed(info) || (share->temporary && !share->deleting)))
{
if (save_global_changed)
{
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index 9feead42cf7..47c796daab3 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -314,6 +314,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
share->state.open_count= 1;
share->changed= 1;
_ma_mark_file_changed_now(share);
+ if (share->temporary)
+ break;
/* fall through */
case HA_EXTRA_PREPARE_FOR_RENAME:
{
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index a781b7e00d3..6d507cee7d8 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -1374,7 +1374,7 @@ uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite)
if (pWrite & MA_STATE_INFO_WRITE_LOCK)
mysql_mutex_lock(&share->intern_lock);
- else if (maria_multi_threaded)
+ else if (maria_multi_threaded && !share->temporary)
mysql_mutex_assert_owner(&share->intern_lock);
if (share->base.born_transactional && translog_status == TRANSLOG_OK &&
!maria_in_recovery)