mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
457172d992
Fixed configure problems with HPUX and openbsd SHOW SLAVE STATUS returns empty set if slave is not initialized SHOW MASTER STATUS returns empty set if binary logging is not enabled. Fixed shutdown problem on Solaris. BitKeeper/deleted/.del-set_var.cc~5374527de1955359: Delete: libmysqld/set_var.cc BitKeeper/etc/ignore: added libmysqld/set_var.cc Build-tools/Do-compile: Remove warnings from touch during compilation Docs/manual.texi: Changelog client/mysqltest.c: Added real_sleep command configure.in: Fixed type for HPUX10 innobase/configure.in: Fixed type for openbsd libmysql/libmysql.c: Fix for new SHOW SLAVE STATUS myisam/mi_update.c: Update key file if using external locking mysql-test/mysql-test-run.sh: Safety fix mysql-test/r/rpl000015.result: Update for new SHOW SLAVE STATUS mysql-test/r/rpl_empty_master_crash.result: Update for new SHOW SLAVE STATUS mysql-test/t/rpl000001.test: sleep -> real_sleep to avoid timing problem sql/mysqld.cc: Fixed bug with SIGTERM on Solaris sql/slave.cc: SHOW SLAVE STATUS returns empty sets if slave is not initialized. sql/sql_repl.cc: SHOW MASTER STAT returns empty set if no binary logging.
205 lines
6 KiB
C
205 lines
6 KiB
C
/* Copyright (C) 2000 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; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
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 */
|
|
|
|
/* Update an old row in a MyISAM table */
|
|
|
|
#include "fulltext.h"
|
|
#ifdef __WIN__
|
|
#include <errno.h>
|
|
#endif
|
|
|
|
|
|
int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
|
|
{
|
|
int flag,key_changed,save_errno;
|
|
reg3 my_off_t pos;
|
|
uint i;
|
|
uchar old_key[MI_MAX_KEY_BUFF],*new_key;
|
|
bool auto_key_changed=0;
|
|
ulonglong changed;
|
|
MYISAM_SHARE *share=info->s;
|
|
ha_checksum old_checksum;
|
|
DBUG_ENTER("mi_update");
|
|
LINT_INIT(new_key);
|
|
LINT_INIT(changed);
|
|
LINT_INIT(old_checksum);
|
|
|
|
if (!(info->update & HA_STATE_AKTIV))
|
|
{
|
|
DBUG_RETURN(my_errno=HA_ERR_KEY_NOT_FOUND);
|
|
}
|
|
if (share->options & HA_OPTION_READ_ONLY_DATA)
|
|
{
|
|
DBUG_RETURN(my_errno=EACCES);
|
|
}
|
|
if (info->state->key_file_length >= share->base.margin_key_file_length)
|
|
{
|
|
DBUG_RETURN(my_errno=HA_ERR_INDEX_FILE_FULL);
|
|
}
|
|
pos=info->lastpos;
|
|
if (_mi_readinfo(info,F_WRLCK,1))
|
|
DBUG_RETURN(my_errno);
|
|
|
|
if (share->calc_checksum)
|
|
old_checksum=info->checksum=(*share->calc_checksum)(info,oldrec);
|
|
if ((*share->compare_record)(info,oldrec))
|
|
{
|
|
save_errno=my_errno;
|
|
goto err_end; /* Record has changed */
|
|
}
|
|
|
|
/* Calculate and check all unique constraints */
|
|
key_changed=0;
|
|
for (i=0 ; i < share->state.header.uniques ; i++)
|
|
{
|
|
MI_UNIQUEDEF *def=share->uniqueinfo+i;
|
|
if (mi_unique_comp(def, newrec, oldrec,1) &&
|
|
mi_check_unique(info, def, newrec, mi_unique_hash(def, newrec),
|
|
info->lastpos))
|
|
{
|
|
save_errno=my_errno;
|
|
goto err_end;
|
|
}
|
|
}
|
|
if (_mi_mark_file_changed(info))
|
|
{
|
|
save_errno=my_errno;
|
|
goto err_end;
|
|
}
|
|
|
|
/* Check which keys changed from the original row */
|
|
|
|
new_key=info->lastkey2;
|
|
changed=0;
|
|
for (i=0 ; i < share->base.keys ; i++)
|
|
{
|
|
if (((ulonglong) 1 << i) & share->state.key_map)
|
|
{
|
|
/* The following code block is for text searching by SerG */
|
|
if (share->keyinfo[i].flag & HA_FULLTEXT )
|
|
{
|
|
if (_mi_ft_cmp(info,i,oldrec, newrec))
|
|
{
|
|
if ((int) i == info->lastinx)
|
|
key_changed|=HA_STATE_WRITTEN;
|
|
changed|=((ulonglong) 1 << i);
|
|
if (_mi_ft_update(info,i,(char*) old_key,oldrec,newrec,pos))
|
|
goto err;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uint new_length=_mi_make_key(info,i,new_key,newrec,pos);
|
|
uint old_length=_mi_make_key(info,i,old_key,oldrec,pos);
|
|
if (new_length != old_length ||
|
|
memcmp((byte*) old_key,(byte*) new_key,new_length))
|
|
{
|
|
if ((int) i == info->lastinx)
|
|
key_changed|=HA_STATE_WRITTEN; /* Mark that keyfile changed */
|
|
changed|=((ulonglong) 1 << i);
|
|
share->keyinfo[i].version++;
|
|
if (_mi_ck_delete(info,i,old_key,old_length)) goto err;
|
|
if (_mi_ck_write(info,i,new_key,new_length)) goto err;
|
|
if (share->base.auto_key == i+1)
|
|
auto_key_changed=1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
If we are running with external locking, we must update the index file
|
|
that something has changed
|
|
*/
|
|
if (changed || !my_disable_locking)
|
|
key_changed|= HA_STATE_KEY_CHANGED;
|
|
|
|
if (share->calc_checksum)
|
|
{
|
|
info->checksum=(*share->calc_checksum)(info,newrec);
|
|
key_changed|= HA_STATE_KEY_CHANGED; /* Must update index file */
|
|
}
|
|
{
|
|
/* Don't update index file if data file is not extended */
|
|
MI_STATUS_INFO state;
|
|
memcpy((char*) &state, (char*) info->state, sizeof(state));
|
|
if ((*share->update_record)(info,pos,newrec))
|
|
goto err;
|
|
if (!key_changed &&
|
|
memcmp((char*) &state, (char*) info->state, sizeof(state)))
|
|
key_changed|= HA_STATE_KEY_CHANGED; /* Must update index file */
|
|
}
|
|
if (auto_key_changed)
|
|
update_auto_increment(info,newrec);
|
|
if (share->calc_checksum)
|
|
share->state.checksum+=(info->checksum - old_checksum);
|
|
|
|
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV |
|
|
key_changed);
|
|
myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,0);
|
|
VOID(_mi_writeinfo(info,key_changed ? WRITEINFO_UPDATE_KEYFILE : 0));
|
|
allow_break(); /* Allow SIGHUP & SIGINT */
|
|
if (info->invalidator != 0)
|
|
{
|
|
DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
|
|
(*info->invalidator)(info->filename);
|
|
info->invalidator=0;
|
|
}
|
|
DBUG_RETURN(0);
|
|
|
|
err:
|
|
DBUG_PRINT("error",("key: %d errno: %d",i,my_errno));
|
|
save_errno=my_errno;
|
|
if (changed)
|
|
key_changed|= HA_STATE_KEY_CHANGED;
|
|
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
|
|
{
|
|
info->errkey= (int) i;
|
|
flag=0;
|
|
do
|
|
{
|
|
if (((ulonglong) 1 << i) & changed)
|
|
{
|
|
/* The following code block is for text searching by SerG */
|
|
if (share->keyinfo[i].flag & HA_FULLTEXT)
|
|
{
|
|
if ((flag++ && _mi_ft_del(info,i,(char*) new_key,newrec,pos)) ||
|
|
_mi_ft_add(info,i,(char*) old_key,oldrec,pos))
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
uint new_length=_mi_make_key(info,i,new_key,newrec,pos);
|
|
uint old_length= _mi_make_key(info,i,old_key,oldrec,pos);
|
|
if ((flag++ && _mi_ck_delete(info,i,new_key,new_length)) ||
|
|
_mi_ck_write(info,i,old_key,old_length))
|
|
break;
|
|
}
|
|
}
|
|
} while (i-- != 0);
|
|
}
|
|
else
|
|
mi_mark_crashed(info);
|
|
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_ROW_CHANGED |
|
|
key_changed);
|
|
|
|
err_end:
|
|
myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,my_errno);
|
|
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
|
|
allow_break(); /* Allow SIGHUP & SIGINT */
|
|
if (save_errno == HA_ERR_KEY_NOT_FOUND)
|
|
save_errno=HA_ERR_CRASHED;
|
|
DBUG_RETURN(my_errno=save_errno);
|
|
} /* mi_update */
|