mariadb/storage/maria/ma_delete_table.c
Michael Widenius 86fcfb1508 Fix for Bug#40311 Assert in MARIA_RECORD_POS during pushbuild 2 test:
Fixed bug when removing a newly inserted record (in case of duplicate key).
The bug caused a crash for rows with several blobs and the first blob was small enough to fit into the head page.
Don't change state_history if nothing changed (speed optimization that also simplifies logic).
Reset state_history if we added/deleted or updated rows without versioning.
Fixed wrong test in trnman_exists_active_transactions() if state is visible or not.

Other bugs fixed:
Fixed wrong argument to (lock->get_status) when we had to wait for TL_WRITE_CONCURRENT_INSERT.
Item_equal::update_used_tables() didn't calculate const_item_cache properly.
Added assert's to detect if join_read_const_table() was called under wrong assumptions..
Fixed that _ma_setup_live_state() is called from thr_lock() instead of handler::external_lock().
This was needed to get versioning information to be setup correctly.
Fixed error in debug binaries during a call to _ma_check_table_is_closed() when another thread was opening/closing a table.
Fixed wrong test when finding right history_state to use.

mysql-test/suite/maria/r/maria.result:
  Added test for Bug#40311 Assert in MARIA_RECORD_POS during pushbuild 2 test
mysql-test/suite/maria/t/maria.test:
  Added test for Bug#40311 Assert in MARIA_RECORD_POS during pushbuild 2 test
mysys/thr_lock.c:
  Fixed wrong argument to (lock->get_status) when we had to wait for TL_WRITE_CONCURRENT_INSERT
sql/item_cmpfunc.cc:
  Item_equal::update_used_tables() didn't calculate const_item_cache properly, which later caused a wrong result for item->const_item()
sql/sql_base.cc:
  In debug mode, Initilize record buffer with unexpected data to catch usage of uninitialized memory
sql/sql_select.cc:
  Fixed indentation
  Added assert's to detect if join_read_const_table() was called under wrong assumptions.
  One assert() is disabled for now as Item_equal() doesn't behave as expected.
storage/maria/ha_maria.cc:
  Move calling to _ma_setup_live_state() to ma_state.c::_ma_block_get_status()
  This was needed as _ma_setup_live_state() needed to know if the table will be used concurrently or not
storage/maria/ma_blockrec.c:
  Fixed bug when removing a newly inserted record (in case of duplicate key).
  The bug caused a crash for rows with several blobs and the first blob was small enough to fit into the head page.
storage/maria/ma_dbug.c:
  Added mutex to protect the open table list during _ma_check_table_is_closed().
  Without the protection we could get a error in debug binaries during a call to _ma_check_table_is_closed()
storage/maria/ma_delete_table.c:
  Removed not used code
storage/maria/ma_rename.c:
  Removed not used code
storage/maria/ma_state.c:
  Fixed wrong test when finding right history_state to use
  Mark in tables->state_current.no_transid if we are using transid's or not.
  Don't change state_history if nothing changed (speed optimization that also simplifies logic)
  Reset state_history if we added/deleted or updated rows without versioning.
  More DBUG_ASSERT's and more DBUG
  Updated maria_versioning() to initialize environment before calling _ma_blok_get_status(). This was needed because of the new logic in _ma_block_get_status()
storage/maria/ma_state.h:
  Added flags to detect if table changed and/or if we changed table without versioning
storage/maria/ma_write.c:
  Simple cleanups (No logic changes)
storage/maria/trnman.c:
  Fixed wrong test in trnman_exists_active_transactions() if state is visible or not.
2008-12-22 02:17:37 +02:00

107 lines
3.6 KiB
C

/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "ma_fulltext.h"
#include "trnman_public.h"
/**
@brief drops (deletes) a table
@param name table's name
@return Operation status
@retval 0 ok
@retval 1 error
*/
int maria_delete_table(const char *name)
{
char from[FN_REFLEN];
#ifdef USE_RAID
uint raid_type=0,raid_chunks=0;
#endif
MARIA_HA *info;
myf sync_dir;
DBUG_ENTER("maria_delete_table");
#ifdef EXTRA_DEBUG
_ma_check_table_is_closed(name,"delete");
#endif
/** @todo LOCK take X-lock on table */
/*
We need to know if this table is transactional.
When built with RAID support, we also need to determine if this table
makes use of the raid feature. If yes, we need to remove all raid
chunks. This is done with my_raid_delete(). Unfortunately it is
necessary to open the table just to check this. We use
'open_for_repair' to be able to open even a crashed table. If even
this open fails, we assume no raid configuration for this table
and try to remove the normal data file only. This may however
leave the raid chunks behind.
*/
if (!(info= maria_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR)))
{
#ifdef USE_RAID
raid_type= 0;
#endif
sync_dir= 0;
}
else
{
#ifdef USE_RAID
raid_type= info->s->base.raid_type;
raid_chunks= info->s->base.raid_chunks;
#endif
sync_dir= (info->s->now_transactional && !info->s->temporary &&
!maria_in_recovery) ?
MY_SYNC_DIR : 0;
maria_close(info);
}
if (sync_dir)
{
/*
For this log record to be of any use for Recovery, we need the upper
MySQL layer to be crash-safe in DDLs.
For now this record can serve when we apply logs to a backup, so we sync
it.
*/
LSN lsn;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (uchar*)name;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= strlen(name) + 1;
if (unlikely(translog_write_record(&lsn, LOGREC_REDO_DROP_TABLE,
&dummy_transaction_object, NULL,
(translog_size_t)
log_array[TRANSLOG_INTERNAL_PARTS +
0].length,
sizeof(log_array)/sizeof(log_array[0]),
log_array, NULL, NULL) ||
translog_flush(lsn)))
DBUG_RETURN(1);
}
fn_format(from,name,"",MARIA_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
if (my_delete_with_symlink(from, MYF(MY_WME | sync_dir)))
DBUG_RETURN(my_errno);
fn_format(from,name,"",MARIA_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
#ifdef USE_RAID
if (raid_type)
DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME | sync_dir)) ?
my_errno : 0);
#endif
DBUG_RETURN(my_delete_with_symlink(from, MYF(MY_WME | sync_dir)) ?
my_errno : 0);
}