summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2004-12-23 20:11:38 +0100
committerunknown <ingo@mysql.com>2004-12-23 20:11:38 +0100
commitbec3feaa0bdf4d89bc3c3f1255ebf70a624f4850 (patch)
tree50e9e32282ae9dd90825e12f5be6e80b9e77f31f /myisam
parent1a1974544d0be772edc20806ec881b2c5df61a6d (diff)
downloadmariadb-git-bec3feaa0bdf4d89bc3c3f1255ebf70a624f4850.tar.gz
WL#1895 - Print message to error log in case of detected MyISAM corruption
Changed my_error() to print error messages, which come from arbitrary registered ranges of error messages. Messages can be unregistered (and should be at end of the program). Added registration of handler error messages. Added a new mi_print_error() macro and a new mi_report_error() function, which supply error messages with a table name. Added calls to mi_print_error() or mi_report_error() at all places in MyISAM, where table corruption is detected. extra/comp_err.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added prints for ER_ERROR_FIRST and ER_ERROR_LAST. Removed print for ER_ERROR_MESSAGES. include/errmsg.h: WL#1895 - Print message to error log in case of detected MyISAM corruption Added declaration for a new function. Added first and last error number defines. include/my_base.h: WL#1895 - Print message to error log in case of detected MyISAM corruption Added first and last error number defines. include/my_sys.h: WL#1895 - Print message to error log in case of detected MyISAM corruption Removed obsolete defines. Removed a global variable, which held pointers to the error message arrays. Added declarations for new functions. include/mysys_err.h: WL#1895 - Print message to error log in case of detected MyISAM corruption Removed an obsolete define. Changed two defines to use the new defines. Added first and last error number defines. libmysql/errmsg.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Replaced global array initialization by proper registration and unregistration of client error messages. libmysql/libmysql.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added a call for unregistration of client error messages. myisam/mi_delete.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. Added a debugging call to pretend MyISAM corruption in case a special debug string is set. Added a debugging call to test undefined error numbers in case a special debug string is set. myisam/mi_extra.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. myisam/mi_info.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added the error logging function. myisam/mi_key.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. myisam/mi_keycache.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. myisam/mi_locking.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. myisam/mi_open.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. Added a debugging call to pretend MyISAM corruption in case a special debug string is set. myisam/mi_page.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. myisam/mi_range.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. myisam/mi_rkey.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. myisam/mi_search.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. myisam/mi_update.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. Added a debugging call to pretend MyISAM corruption in case a special debug string is set. myisam/mi_write.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Added calls to the new error logging function at all places, where corruption is detected. Added a debugging call to pretend MyISAM corruption in case a special debug string is set. myisam/myisamdef.h: WL#1895 - Print message to error log in case of detected MyISAM corruption Added the declaration of the new error logging function and a new macro. mysql-test/r/merge.result: WL#1895 - Print message to error log in case of detected MyISAM corruption Changed test results. These come from the changed error reporting in openfrm(). mysql-test/r/repair.result: WL#1895 - Print message to error log in case of detected MyISAM corruption Changed test results. These come from the changed error reporting in openfrm(). mysql-test/t/merge.test: WL#1895 - Print message to error log in case of detected MyISAM corruption Changederror numbers. These come from the changed error reporting in openfrm(). mysys/errors.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Dropped the assignment of the global errors to the dropped global pointer array. mysys/my_error.c: WL#1895 - Print message to error log in case of detected MyISAM corruption Changed my_error() from using a static array of pointers to error message arrays to using a linked list of structures with pointers to array message arrays. Added functions for registering and unregistering error message arrays to the chain. sql/derror.cc: WL#1895 - Print message to error log in case of detected MyISAM corruption Changed reading of mysqld error messages to using the new registering and unregistering functions. sql/handler.cc: WL#1895 - Print message to error log in case of detected MyISAM corruption Added initialization and deinitialization of handler error messages. Included more handler error messages in the mapping to mysqld error messages. sql/mysqld.cc: WL#1895 - Print message to error log in case of detected MyISAM corruption Changed deinitialization of error messages to proper unregistration. sql/table.cc: WL#1895 - Print message to error log in case of detected MyISAM corruption Changed error reporting in openfrm() so that error messages from handler::ha_open() are reported by handler::print_error(). This changed messages from "Can't open 't1.MYI' (errno: 130)" to "Incorrect file format 't1'" for example. sql/unireg.h: WL#1895 - Print message to error log in case of detected MyISAM corruption Changed two defines to use the new defines.
Diffstat (limited to 'myisam')
-rw-r--r--myisam/mi_delete.c32
-rw-r--r--myisam/mi_extra.c5
-rw-r--r--myisam/mi_info.c33
-rw-r--r--myisam/mi_key.c1
-rw-r--r--myisam/mi_keycache.c1
-rw-r--r--myisam/mi_locking.c6
-rw-r--r--myisam/mi_open.c13
-rw-r--r--myisam/mi_page.c2
-rw-r--r--myisam/mi_range.c4
-rw-r--r--myisam/mi_rkey.c1
-rw-r--r--myisam/mi_search.c17
-rw-r--r--myisam/mi_update.c9
-rw-r--r--myisam/mi_write.c20
-rw-r--r--myisam/myisamdef.h3
14 files changed, 144 insertions, 3 deletions
diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c
index b964cb35dd8..d79d9040ee7 100644
--- a/myisam/mi_delete.c
+++ b/myisam/mi_delete.c
@@ -45,6 +45,12 @@ int mi_delete(MI_INFO *info,const byte *record)
/* Test if record is in datafile */
+ DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage",
+ mi_print_error(info, HA_ERR_CRASHED);
+ DBUG_RETURN(my_errno= HA_ERR_CRASHED););
+ DBUG_EXECUTE_IF("my_error_test_undefined_error",
+ mi_print_error(info, INT_MAX);
+ DBUG_RETURN(my_errno= INT_MAX););
if (!(info->update & HA_STATE_AKTIV))
{
DBUG_RETURN(my_errno=HA_ERR_KEY_NOT_FOUND); /* No database read */
@@ -109,13 +115,19 @@ err:
mi_sizestore(lastpos,info->lastpos);
myisam_log_command(MI_LOG_DELETE,info,(byte*) lastpos, sizeof(lastpos),0);
if (save_errno != HA_ERR_RECORD_CHANGED)
+ {
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info); /* mark table crashed */
+ }
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
info->update|=HA_STATE_WRITTEN; /* Buffer changed */
allow_break(); /* Allow SIGHUP & SIGINT */
my_errno=save_errno;
if (save_errno == HA_ERR_KEY_NOT_FOUND)
+ {
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
+ }
DBUG_RETURN(my_errno);
} /* mi_delete */
@@ -142,6 +154,7 @@ static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo,
if ((old_root=*root) == HA_OFFSET_ERROR)
{
+ mi_print_error(info, HA_ERR_CRASHED);
DBUG_RETURN(my_errno=HA_ERR_CRASHED);
}
if (!(root_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
@@ -253,7 +266,9 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
my_off_t root;
uchar *kpos=keypos;
- tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&kpos,lastkey);
+ if (!(tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&kpos,lastkey))
+ && (my_errno == HA_ERR_CRASHED))
+ mi_print_error(info, HA_ERR_CRASHED);
root=_mi_dpos(info,nod_flag,kpos);
if (subkeys == -1)
{
@@ -302,6 +317,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (!nod_flag)
{
DBUG_PRINT("error",("Didn't find key"));
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED; /* This should newer happend */
goto err;
}
@@ -317,6 +333,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
&next_block);
if (tmp == 0)
{
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
DBUG_PRINT("exit",("Return: %d",0));
DBUG_RETURN(0);
}
@@ -473,6 +491,8 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
(info->quick_mode ? MI_MIN_KEYBLOCK_LENGTH :
(uint) keyinfo->underflow_block_length));
err:
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
DBUG_RETURN(-1);
} /* del */
@@ -562,7 +582,11 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
s_length=remove_key(keyinfo,key_reflength,keypos,anc_key,
anc_buff+anc_length,(my_off_t *) 0);
if (!s_length)
+ {
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
goto err;
+ }
anc_length-=s_length;
mi_putint(anc_buff,anc_length,key_reflength);
@@ -671,7 +695,11 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
s_length=remove_key(keyinfo,key_reflength,keypos,anc_key,
anc_buff+anc_length,(my_off_t *) 0);
if (!s_length)
+ {
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
goto err;
+ }
anc_length-=s_length;
mi_putint(anc_buff,anc_length,key_reflength);
@@ -732,6 +760,8 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
goto err;
DBUG_RETURN(anc_length <= (uint) keyinfo->block_length/2);
err:
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
DBUG_RETURN(-1);
} /* underflow */
diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c
index 4b011ca424f..999c4ba8f3d 100644
--- a/myisam/mi_extra.c
+++ b/myisam/mi_extra.c
@@ -186,7 +186,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
if (info->opt_flag & WRITE_CACHE_USED)
{
if ((error=flush_io_cache(&info->rec_cache)))
+ {
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info); /* Fatal error found */
+ }
}
break;
case HA_EXTRA_NO_READCHECK:
@@ -285,6 +288,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
{
error=my_errno;
share->changed=1;
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info); /* Fatal error found */
}
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
@@ -339,6 +343,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
if (error)
{
share->changed=1;
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info); /* Fatal error found */
}
}
diff --git a/myisam/mi_info.c b/myisam/mi_info.c
index cf63ef63618..bdece9c2ee3 100644
--- a/myisam/mi_info.c
+++ b/myisam/mi_info.c
@@ -105,3 +105,36 @@ int mi_status(MI_INFO *info, register MI_ISAMINFO *x, uint flag)
}
DBUG_RETURN(0);
}
+
+
+/*
+ Write a message to the error log.
+
+ SYNOPSIS
+ mi_report_error()
+ file_name Name of table file (e.g. index_file_name).
+ errcode Error number.
+
+ DESCRIPTION
+ This function supplies my_error() with a table name. Most error
+ messages need one. Since string arguments in error messages are limited
+ to 64 characters by convention, we ensure that in case of truncation,
+ that the end of the index file path is in the message. This contains
+ the most valuable information (the table name and the database name).
+
+ RETURN
+ void
+*/
+
+void mi_report_error(int errcode, const char *file_name)
+{
+ size_t lgt;
+ DBUG_ENTER("mi_report_error");
+ DBUG_PRINT("enter",("errcode %d, table '%s'", errcode, file_name));
+
+ if ((lgt= strlen(file_name)) > 64)
+ file_name+= lgt - 64;
+ my_error(errcode, MYF(ME_NOREFRESH), file_name);
+ DBUG_VOID_RETURN;
+}
+
diff --git a/myisam/mi_key.c b/myisam/mi_key.c
index caca63452b0..eaaee617f32 100644
--- a/myisam/mi_key.c
+++ b/myisam/mi_key.c
@@ -477,6 +477,7 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf)
{ /* Read only key */
if (_mi_put_key_in_record(info,(uint) info->lastinx,buf))
{
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
return -1;
}
diff --git a/myisam/mi_keycache.c b/myisam/mi_keycache.c
index 99a2fd6db15..33d0ac4f6bc 100644
--- a/myisam/mi_keycache.c
+++ b/myisam/mi_keycache.c
@@ -79,6 +79,7 @@ int mi_assign_to_key_cache(MI_INFO *info,
if (flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE))
{
error= my_errno;
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info); /* Mark that table must be checked */
}
diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c
index 66950f62321..91e9f09b9fb 100644
--- a/myisam/mi_locking.c
+++ b/myisam/mi_locking.c
@@ -66,6 +66,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
share->kfile,FLUSH_KEEP))
{
error=my_errno;
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info); /* Mark that table must be checked */
}
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
@@ -73,6 +74,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
if (end_io_cache(&info->rec_cache))
{
error=my_errno;
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info);
}
}
@@ -98,7 +100,10 @@ int mi_lock_database(MI_INFO *info, int lock_type)
else
share->not_flushed=1;
if (error)
+ {
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info);
+ }
}
if (info->lock_type != F_EXTRA_LCK)
{
@@ -285,6 +290,7 @@ void mi_update_status(void* param)
{
if (end_io_cache(&info->rec_cache))
{
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info);
}
info->opt_flag&= ~WRITE_CACHE_USED;
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index 58db2e47c1f..040bc1503aa 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -106,6 +106,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share_buff.state.key_del=key_del;
share_buff.key_cache= multi_key_cache_search(name_buff, strlen(name_buff));
+ DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open",
+ if (strstr(name, "/t1"))
+ {
+ my_errno= HA_ERR_CRASHED;
+ goto err;
+ });
if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
{
if ((errno != EROFS && errno != EACCES) ||
@@ -601,6 +607,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
err:
save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
+ if ((save_errno == HA_ERR_CRASHED) ||
+ (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
+ (save_errno == HA_ERR_CRASHED_ON_REPAIR))
+ mi_report_error(save_errno, name);
switch (errpos) {
case 6:
my_free((gptr) m_info,MYF(0));
@@ -1223,7 +1233,10 @@ int mi_enable_indexes(MI_INFO *info)
if (share->state.state.data_file_length ||
(share->state.state.key_file_length != share->base.keystart))
+ {
+ mi_print_error(info, HA_ERR_CRASHED);
error= HA_ERR_CRASHED;
+ }
else
share->state.key_map= ((ulonglong) 1L << share->base.keys) - 1;
return error;
diff --git a/myisam/mi_page.c b/myisam/mi_page.c
index 16713c87e10..dc2bc75f1a0 100644
--- a/myisam/mi_page.c
+++ b/myisam/mi_page.c
@@ -40,6 +40,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
{
DBUG_PRINT("error",("Got errno: %d from key_cache_read",my_errno));
info->last_keypage=HA_OFFSET_ERROR;
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0);
}
@@ -51,6 +52,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
(ulong) page, page_size));
DBUG_DUMP("page", (char*) tmp, keyinfo->block_length);
info->last_keypage = HA_OFFSET_ERROR;
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno = HA_ERR_CRASHED;
tmp = 0;
}
diff --git a/myisam/mi_range.c b/myisam/mi_range.c
index 789607c9889..0d8f8763b92 100644
--- a/myisam/mi_range.c
+++ b/myisam/mi_range.c
@@ -233,7 +233,11 @@ static uint _mi_keynr(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, u
while (page < end)
{
if (!(*keyinfo->get_key)(keyinfo,nod_flag,&page,t_buff))
+ {
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
return 0; /* Error */
+ }
max_key++;
if (page == keypos)
keynr=max_key;
diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c
index 12db00337ee..d564c672f19 100644
--- a/myisam/mi_rkey.c
+++ b/myisam/mi_rkey.c
@@ -78,6 +78,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
case HA_KEY_ALG_RTREE:
if (rtree_find_first(info,inx,key_buff,use_key_length,nextflag) < 0)
{
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
goto err;
}
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index 2259dd17fcd..f252719d29c 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -161,6 +161,8 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_RETURN(0);
err:
DBUG_PRINT("exit",("Error: %d",my_errno));
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
info->lastpos= HA_OFFSET_ERROR;
info->page_changed=1;
DBUG_RETURN (-1);
@@ -234,6 +236,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,t_buff);
if (length == 0 || page > end)
{
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_PRINT("error",("Found wrong key: length: %u page: %p end: %p",
length, page, end));
@@ -380,6 +383,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
if (page > end)
{
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_PRINT("error",("Found wrong key: length: %u page: %p end: %p",
length, page, end));
@@ -969,6 +973,7 @@ uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key);
if (*return_key_length == 0)
{
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0);
}
@@ -1006,6 +1011,7 @@ static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key);
if (*return_key_length == 0)
{
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(1);
}
@@ -1046,6 +1052,7 @@ uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
if (*return_key_length == 0)
{
DBUG_PRINT("error",("Couldn't find last key: page: %p", page));
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0);
}
@@ -1178,7 +1185,11 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
memcpy(lastkey,key,key_length);
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,
&info->int_keypos,lastkey)))
+ {
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
DBUG_RETURN(-1);
+ }
}
else /* Previous key */
{
@@ -1236,8 +1247,10 @@ int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
page=info->buff+2+nod_flag;
} while ((pos=_mi_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
- info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
- info->lastkey);
+ if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
+ info->lastkey)) &&
+ (my_errno == HA_ERR_CRASHED))
+ mi_print_error(info, HA_ERR_CRASHED);
info->int_keypos=page; info->int_maxpos=info->buff+mi_getint(info->buff)-1;
info->int_nod_flag=nod_flag;
info->int_keytree_version=keyinfo->version;
diff --git a/myisam/mi_update.c b/myisam/mi_update.c
index f62be133ed9..2936e29a01c 100644
--- a/myisam/mi_update.c
+++ b/myisam/mi_update.c
@@ -34,6 +34,9 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
LINT_INIT(changed);
LINT_INIT(old_checksum);
+ DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage",
+ mi_print_error(info, HA_ERR_CRASHED);
+ DBUG_RETURN(my_errno= HA_ERR_CRASHED););
if (!(info->update & HA_STATE_AKTIV))
{
DBUG_RETURN(my_errno=HA_ERR_KEY_NOT_FOUND);
@@ -205,7 +208,10 @@ err:
} while (i-- != 0);
}
else
+ {
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info);
+ }
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_ROW_CHANGED |
key_changed);
@@ -214,6 +220,9 @@ err:
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */
if (save_errno == HA_ERR_KEY_NOT_FOUND)
+ {
+ mi_print_error(info, HA_ERR_CRASHED);
save_errno=HA_ERR_CRASHED;
+ }
DBUG_RETURN(my_errno=save_errno);
} /* mi_update */
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index c2f24ae1ae3..8ff653bdd2d 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -52,6 +52,9 @@ int mi_write(MI_INFO *info, byte *record)
DBUG_ENTER("mi_write");
DBUG_PRINT("enter",("isam: %d data: %d",info->s->kfile,info->dfile));
+ DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage",
+ mi_print_error(info, HA_ERR_CRASHED);
+ DBUG_RETURN(my_errno= HA_ERR_CRASHED););
if (share->options & HA_OPTION_READ_ONLY_DATA)
{
DBUG_RETURN(my_errno=EACCES);
@@ -202,7 +205,10 @@ err:
}
}
else
+ {
+ mi_print_error(info, HA_ERR_CRASHED);
mi_mark_crashed(info);
+ }
info->update= (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED);
my_errno=save_errno;
err2:
@@ -346,7 +352,11 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (tmp_key_length)
dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length);
else
+ {
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
dupp_key_pos= HA_OFFSET_ERROR;
+ }
if (keyinfo->flag & HA_FULLTEXT)
{
uint off;
@@ -455,6 +465,7 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
{
if (t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
{
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(-1);
}
@@ -464,6 +475,7 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
{
if (-t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
{
+ mi_print_error(info, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(-1);
}
@@ -558,7 +570,11 @@ int _mi_split_page(register MI_INFO *info, register MI_KEYDEF *keyinfo,
key_pos=_mi_find_half_pos(nod_flag,keyinfo,buff,key_buff, &key_length,
&after_key);
if (!key_pos)
+ {
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
DBUG_RETURN(-1);
+ }
length=(uint) (key_pos-buff);
a_length=mi_getint(buff);
mi_putint(buff,length,nod_flag);
@@ -578,7 +594,11 @@ int _mi_split_page(register MI_INFO *info, register MI_KEYDEF *keyinfo,
/* Store new page */
if (!(*keyinfo->get_key)(keyinfo,nod_flag,&key_pos,key_buff))
+ {
+ if (my_errno == HA_ERR_CRASHED)
+ mi_print_error(info, HA_ERR_CRASHED);
DBUG_RETURN(-1);
+ }
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar *) 0,
(uchar*) 0, (uchar*) 0,
key_buff, &s_temp);
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index 12ce112dbe0..c0f56a7b720 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -356,6 +356,8 @@ typedef struct st_mi_sort_param
#define mi_mark_crashed_on_repair(x) { (x)->s->state.changed|=STATE_CRASHED|STATE_CRASHED_ON_REPAIR ; (x)->update|= HA_STATE_CHANGED; }
#define mi_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED)
#define mi_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR)
+#define mi_print_error(INFO, ERRNO) \
+ mi_report_error((ERRNO), (INFO)->s->index_file_name)
/* Functions to store length of space packed keys, VARCHAR or BLOB keys */
@@ -667,6 +669,7 @@ extern void _myisam_log_command(enum myisam_log_commands command,
extern void _myisam_log_record(enum myisam_log_commands command,MI_INFO *info,
const byte *record,my_off_t filepos,
int result);
+extern void mi_report_error(int errcode, const char *file_name);
extern my_bool _mi_memmap_file(MI_INFO *info);
extern void _mi_unmap_file(MI_INFO *info);
extern uint save_pack_length(byte *block_buff,ulong length);