summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mysql.com>2008-08-28 20:52:23 +0200
committerSergei Golubchik <serg@mysql.com>2008-08-28 20:52:23 +0200
commit4be86917fe47645cae08b8e0e9c59da25c8d8e3e (patch)
treed9bd68b3a2e5b53d42bb02ed74d51b5bdcec4995 /storage
parent942651ea6cc2b7537aa45ff1d55d64be4e191a16 (diff)
parentdd406c1e7ebeede6506c3f8c1bc62c671ea880a1 (diff)
downloadmariadb-git-4be86917fe47645cae08b8e0e9c59da25c8d8e3e.tar.gz
merge
Diffstat (limited to 'storage')
-rw-r--r--storage/maria/ha_maria.cc40
-rw-r--r--storage/maria/ma_blockrec.c2
-rw-r--r--storage/maria/ma_check.c16
-rw-r--r--storage/maria/ma_checkpoint.c9
-rw-r--r--storage/maria/ma_close.c6
-rw-r--r--storage/maria/ma_create.c4
-rw-r--r--storage/maria/ma_dbug.c2
-rw-r--r--storage/maria/ma_delete.c9
-rw-r--r--storage/maria/ma_extra.c4
-rw-r--r--storage/maria/ma_info.c11
-rw-r--r--storage/maria/ma_key_recover.c72
-rw-r--r--storage/maria/ma_key_recover.h2
-rw-r--r--storage/maria/ma_keycache.c4
-rw-r--r--storage/maria/ma_locking.c2
-rw-r--r--storage/maria/ma_loghandler.c14
-rw-r--r--storage/maria/ma_open.c53
-rw-r--r--storage/maria/ma_page.c20
-rw-r--r--storage/maria/ma_pagecache.c57
-rw-r--r--storage/maria/ma_recovery.c18
-rw-r--r--storage/maria/ma_search.c18
-rw-r--r--storage/maria/ma_state.c36
-rw-r--r--storage/maria/ma_update.c5
-rw-r--r--storage/maria/ma_write.c10
-rw-r--r--storage/maria/maria_def.h22
-rw-r--r--storage/maria/maria_ftdump.c3
-rw-r--r--storage/maria/maria_pack.c10
-rw-r--r--storage/myisam/mi_search.c2
27 files changed, 267 insertions, 184 deletions
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 78edf7d6545..62a813415b7 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -44,6 +44,7 @@ C_MODE_END
#ifdef MARIA_CANNOT_ROLLBACK
#define trans_register_ha(A, B, C) do { /* nothing */ } while(0)
#endif
+#define THD_TRN (*(TRN **)thd_ha_data(thd, maria_hton))
ulong pagecache_division_limit, pagecache_age_threshold;
ulonglong pagecache_buffer_size;
@@ -1278,7 +1279,7 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
param.op_name= "zerofill";
param.testflag= check_opt->flags | T_SILENT | T_ZEROFILL;
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
- error=maria_zerofill(&param, file, share->open_file_name);
+ error=maria_zerofill(&param, file, share->open_file_name.str);
if (!error)
{
@@ -1355,7 +1356,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
param->thd= thd;
param->tmpdir= &mysql_tmpdir_list;
param->out_flag= 0;
- strmov(fixed_name, share->open_file_name);
+ strmov(fixed_name, share->open_file_name.str);
// Don't lock tables if we have used LOCK TABLE
if (!thd->locked_tables &&
@@ -1958,10 +1959,18 @@ bool ha_maria::is_crashed() const
(my_disable_locking && file->s->state.open_count));
}
+#define CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING(msg) \
+ do { \
+ if (file->lock.type == TL_WRITE_CONCURRENT_INSERT) \
+ { \
+ my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), msg); \
+ return 1; \
+ } \
+ } while(0)
int ha_maria::update_row(const uchar * old_data, uchar * new_data)
{
- DBUG_ASSERT(file->lock.type != TL_WRITE_CONCURRENT_INSERT);
+ CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING("UPDATE in WRITE CONCURRENT");
ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
@@ -1971,7 +1980,7 @@ int ha_maria::update_row(const uchar * old_data, uchar * new_data)
int ha_maria::delete_row(const uchar * buf)
{
- DBUG_ASSERT(file->lock.type != TL_WRITE_CONCURRENT_INSERT);
+ CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING("DELETE in WRITE CONCURRENT");
ha_statistic_increment(&SSV::ha_delete_count);
return maria_delete(file, buf);
}
@@ -2175,11 +2184,11 @@ int ha_maria::info(uint flag)
if table is symlinked (Ie; Real name is not same as generated name)
*/
data_file_name= index_file_name= 0;
- fn_format(name_buff, file->s->open_file_name, "", MARIA_NAME_DEXT,
+ fn_format(name_buff, file->s->open_file_name.str, "", MARIA_NAME_DEXT,
MY_APPEND_EXT | MY_UNPACK_FILENAME);
if (strcmp(name_buff, maria_info.data_file_name))
- data_file_name=maria_info.data_file_name;
- fn_format(name_buff, file->s->open_file_name, "", MARIA_NAME_IEXT,
+ data_file_name =maria_info.data_file_name;
+ fn_format(name_buff, file->s->open_file_name.str, "", MARIA_NAME_IEXT,
MY_APPEND_EXT | MY_UNPACK_FILENAME);
if (strcmp(name_buff, maria_info.index_file_name))
index_file_name=maria_info.index_file_name;
@@ -2201,6 +2210,21 @@ int ha_maria::extra(enum ha_extra_function operation)
{
if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_KEYREAD)
return 0;
+
+ /*
+ We have to set file->trn here because in some cases we call
+ extern_lock(F_UNLOCK) (which resets file->trn) followed by maria_close()
+ without calling commit/rollback in between. If file->trn is not set
+ we can't remove file->share from the transaction list in the extra() call.
+ */
+
+ if (!file->trn &&
+ (operation == HA_EXTRA_PREPARE_FOR_DROP ||
+ operation == HA_EXTRA_PREPARE_FOR_RENAME))
+ {
+ THD *thd= table->in_use;
+ file->trn= THD_TRN;
+ }
return maria_extra(file, operation, 0);
}
@@ -2240,8 +2264,6 @@ int ha_maria::delete_table(const char *name)
return maria_delete_table(name);
}
-#define THD_TRN (*(TRN **)thd_ha_data(thd, maria_hton))
-
int ha_maria::external_lock(THD *thd, int lock_type)
{
TRN *trn= THD_TRN;
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 71a81edb680..a1e3fabfcca 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -3073,7 +3073,7 @@ static my_bool write_block_record(MARIA_HA *info,
}
else
{
- if (my_multi_malloc(MY_WME, &log_array,
+ if (!my_multi_malloc(MY_WME, &log_array,
(uint) ((bitmap_blocks->count +
TRANSLOG_INTERNAL_PARTS + 2) *
sizeof(*log_array)),
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index fa987673914..c64c879992c 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -2476,7 +2476,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
{
/* Get real path for data file */
if ((new_file= my_create(fn_format(param->temp_filename,
- share->data_file_name, "",
+ share->data_file_name.str, "",
DATA_TMP_EXT, 2+4),
0,param->tmpfile_createflag,
MYF(0))) < 0)
@@ -2680,7 +2680,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
my_close(new_file, MYF(MY_WME));
new_file= -1;
change_data_file_descriptor(info, -1);
- if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
+ if (maria_change_to_newfile(share->data_file_name.str, MARIA_NAME_DEXT,
DATA_TMP_EXT,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0)) |
@@ -2993,7 +2993,7 @@ int maria_sort_index(HA_CHECK *param, register MARIA_HA *info, char *name)
share->kfile.file = -1;
pthread_mutex_unlock(&share->intern_lock);
VOID(my_close(new_file,MYF(MY_WME)));
- if (maria_change_to_newfile(share->index_file_name, MARIA_NAME_IEXT,
+ if (maria_change_to_newfile(share->index_file_name.str, MARIA_NAME_IEXT,
INDEX_TMP_EXT, sync_dir) ||
_ma_open_keyfile(share))
goto err2;
@@ -3524,7 +3524,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
{
/* Get real path for data file */
if ((new_file=my_create(fn_format(param->temp_filename,
- share->data_file_name, "",
+ share->data_file_name.str, "",
DATA_TMP_EXT, 2+4),
0,param->tmpfile_createflag,
MYF(0))) < 0)
@@ -3789,7 +3789,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
new_file= -1;
}
change_data_file_descriptor(info, -1);
- if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
+ if (maria_change_to_newfile(share->data_file_name.str, MARIA_NAME_DEXT,
DATA_TMP_EXT,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0)) |
@@ -4070,7 +4070,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
{
/* Get real path for data file */
if ((new_file= my_create(fn_format(param->temp_filename,
- share->data_file_name, "",
+ share->data_file_name.str, "",
DATA_TMP_EXT,
2+4),
0,param->tmpfile_createflag,
@@ -4397,7 +4397,7 @@ err:
{
my_close(new_file,MYF(0));
info->dfile.file= new_file= -1;
- if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
+ if (maria_change_to_newfile(share->data_file_name.str, MARIA_NAME_DEXT,
DATA_TMP_EXT,
MYF((param->testflag & T_BACKUP_DATA ?
MY_REDEL_MAKE_BACKUP : 0) |
@@ -6236,7 +6236,7 @@ static my_bool create_new_data_handle(MARIA_SORT_PARAM *param, File new_file)
MARIA_HA *new_info;
DBUG_ENTER("create_new_data_handle");
- if (!(sort_info->new_info= maria_open(info->s->open_file_name, O_RDWR,
+ if (!(sort_info->new_info= maria_open(info->s->open_file_name.str, O_RDWR,
HA_OPEN_COPY | HA_OPEN_FOR_REPAIR)))
DBUG_RETURN(1);
diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c
index 35ae71ecb1c..91cb026d5ed 100644
--- a/storage/maria/ma_checkpoint.c
+++ b/storage/maria/ma_checkpoint.c
@@ -820,7 +820,7 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
*/
share->in_checkpoint= MARIA_CHECKPOINT_LOOKS_AT_ME;
/** @todo avoid strlen() */
- total_names_length+= strlen(share->open_file_name);
+ total_names_length+= share->open_file_name.length;
}
}
@@ -894,7 +894,7 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
@todo We should not look at tables which didn't change since last
checkpoint.
*/
- DBUG_PRINT("info",("looking at table '%s'", share->open_file_name));
+ DBUG_PRINT("info",("looking at table '%s'", share->open_file_name.str));
if (state_copy == state_copies_end) /* we have no more cached states */
{
/*
@@ -978,8 +978,7 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
DBUG_PRINT("info", ("ignore_share: %d", ignore_share));
if (!ignore_share)
{
- /** @todo avoid strlen */
- uint open_file_name_len= strlen(share->open_file_name) + 1;
+ uint open_file_name_len= share->open_file_name.length + 1;
/* remember the descriptors for background flush */
*(dfiles_end++)= dfile;
*(kfiles_end++)= kfile;
@@ -1000,7 +999,7 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
If no crash, maria_close() will write the exact value.
*/
state_copy->state.first_bitmap_with_space= ~(ulonglong)0;
- memcpy(ptr, share->open_file_name, open_file_name_len);
+ memcpy(ptr, share->open_file_name.str, open_file_name_len);
ptr+= open_file_name_len;
if (cmp_translog_addr(share->state.is_of_horizon,
checkpoint_start_log_horizon) >= 0)
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index c520fdccaa7..266a095dd52 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -33,7 +33,7 @@ int maria_close(register MARIA_HA *info)
(uint) share->tot_locks));
/* Check that we have unlocked key delete-links properly */
- DBUG_ASSERT(info->used_key_del == 0);
+ DBUG_ASSERT(info->key_del_used == 0);
pthread_mutex_lock(&THR_LOCK_maria);
if (info->lock_type == F_EXTRA_LCK)
@@ -69,6 +69,10 @@ int maria_close(register MARIA_HA *info)
if (flag)
{
/* Last close of file; Flush everything */
+
+ /* Check that we don't have any dangling pointers from the transaction */
+ DBUG_ASSERT(share->in_trans == 0);
+
if (share->kfile.file >= 0)
{
if ((*share->once_end)(share))
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 4eb97e6578a..417397f0882 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -1348,9 +1348,9 @@ int _ma_update_state_lsns_sub(MARIA_SHARE *share, LSN lsn, TrID create_trid,
int res;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
/* table name is logged only for information */
- log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (uchar*)share->open_file_name;
+ log_array[TRANSLOG_INTERNAL_PARTS + 0].str= share->open_file_name.str;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length=
- strlen(share->open_file_name) + 1;
+ share->open_file_name.length + 1;
if ((res= translog_write_record(&lsn, LOGREC_IMPORTED_TABLE,
&dummy_transaction_object, NULL,
(translog_size_t)
diff --git a/storage/maria/ma_dbug.c b/storage/maria/ma_dbug.c
index 149cc74fbe9..4ae45ca9b7a 100644
--- a/storage/maria/ma_dbug.c
+++ b/storage/maria/ma_dbug.c
@@ -184,7 +184,7 @@ my_bool _ma_check_table_is_closed(const char *name, const char *where)
{
MARIA_HA *info=(MARIA_HA*) pos->data;
MARIA_SHARE *share= info->s;
- if (!strcmp(share->unique_file_name,filename))
+ if (!strcmp(share->unique_file_name.str, filename))
{
if (share->last_version)
{
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index 1d6bb565e02..26cc202f542 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -122,8 +122,9 @@ int maria_delete(MARIA_HA *info,const uchar *record)
allow_break(); /* Allow SIGHUP & SIGINT */
if (info->invalidator != 0)
{
- DBUG_PRINT("info", ("invalidator... '%s' (delete)", share->open_file_name));
- (*info->invalidator)(share->open_file_name);
+ DBUG_PRINT("info", ("invalidator... '%s' (delete)",
+ share->open_file_name.str));
+ (*info->invalidator)(share->open_file_name.str);
info->invalidator=0;
}
DBUG_RETURN(0);
@@ -780,6 +781,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
first_key)
{
size_t tmp_length;
+ uint next_page_flag;
/* Use page right of anc-page */
DBUG_PRINT("test",("use right page"));
@@ -805,6 +807,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
DFLT_INIT_HITS, buff, 0, &next_page_link))
goto err;
next_buff_length= _ma_get_page_used(share, buff);
+ next_page_flag= _ma_get_keypage_flag(share,buff);
DBUG_DUMP("next", buff, next_buff_length);
/* find keys to make a big key-page */
@@ -829,7 +832,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
_ma_store_page_used(share, buff, buff_length);
/* Set page flag from combination of both key pages and parting key */
- page_flag= (_ma_get_keypage_flag(share, buff) |
+ page_flag= (next_page_flag |
_ma_get_keypage_flag(share, leaf_buff));
if (anc_key.flag & (SEARCH_USER_KEY_HAS_TRANSID |
SEARCH_PAGE_KEY_HAS_TRANSID))
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index 8c4f44df91c..7fab28edf42 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -326,7 +326,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
{
_ma_remove_table_from_trnman(share, info->trn);
/* Ensure we don't point to the deleted data in trn */
- info->state= &share->state.state;
+ info->state= info->state_start= &share->state.state;
}
type= do_flush ? FLUSH_RELEASE : FLUSH_IGNORE_CHANGED;
@@ -347,7 +347,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
if (do_flush)
{
/* Save the state so that others can find it from disk. */
- if (_ma_state_info_write(share, 1 | 2) ||
+ if ((share->changed && _ma_state_info_write(share, 1 | 2)) ||
my_sync(share->kfile.file, MYF(0)))
error= my_errno;
else
diff --git a/storage/maria/ma_info.c b/storage/maria/ma_info.c
index 1bb351bfbb5..1bbfa3cbf7e 100644
--- a/storage/maria/ma_info.c
+++ b/storage/maria/ma_info.c
@@ -81,8 +81,8 @@ int maria_status(MARIA_HA *info, register MARIA_INFO *x, uint flag)
x->sortkey= -1; /* No clustering */
x->rec_per_key = share->state.rec_per_key_part;
x->key_map = share->state.key_map;
- x->data_file_name = share->data_file_name;
- x->index_file_name = share->index_file_name;
+ x->data_file_name = share->data_file_name.str;
+ x->index_file_name = share->index_file_name.str;
x->data_file_type = share->data_file_type;
}
if ((flag & HA_STATUS_TIME) && !my_fstat(info->dfile.file, &state, MYF(0)))
@@ -118,13 +118,14 @@ int maria_status(MARIA_HA *info, register MARIA_INFO *x, uint flag)
void
*/
-void _ma_report_error(int errcode, const char *file_name)
+void _ma_report_error(int errcode, const LEX_STRING *name)
{
- size_t length;
+ size_t length;
+ const char *file_name= name->str;
DBUG_ENTER("_ma_report_error");
DBUG_PRINT("enter",("errcode %d, table '%s'", errcode, file_name));
- if ((length= strlen(file_name)) > 64)
+ if ((length= name->length) > 64)
{
/* we first remove the directory */
size_t dir_length= dirname_length(file_name);
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index b7e67f1d8a7..3787e69f4a0 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -203,16 +203,6 @@ my_bool write_hook_for_undo_key(enum translog_record_type type,
(struct st_msg_to_write_hook_for_undo_key *) hook_arg;
*msg->root= msg->value;
- /**
- @todo BUG
- so we have log mutex and then intern_lock.
- While in checkpoint we have intern_lock and then log mutex, like when we
- flush bitmap (flushing bitmap pages can call hook which takes log mutex);
- and in _ma_update_state_lsns_sub() this is the same.
- So we can deadlock.
- Another one is that in translog_assign_id_to_share() we have intern_lock
- and then log mutex.
- */
_ma_fast_unlock_key_del(tbl_info);
return write_hook_for_undo(type, trn, tbl_info, lsn, 0);
}
@@ -1209,14 +1199,14 @@ my_bool _ma_apply_undo_key_delete(MARIA_HA *info, LSN undo_lsn,
@note
To allow higher concurrency in the common case where we do inserts
and we don't have any linked blocks we do the following:
- - Mark in info->used_key_del that we are not using key_del
+ - Mark in info->key_del_used that we are not using key_del
- Return at once (without marking key_del as used)
- This is safe as we in this case don't write current_key_del into
+ This is safe as we in this case don't write key_del_current into
the redo log and during recover we are not updating key_del.
@retval 1 Use page at end of file
- @retval 0 Use page at share->current_key_del
+ @retval 0 Use page at share->key_del_current
*/
my_bool _ma_lock_key_del(MARIA_HA *info, my_bool insert_at_end)
@@ -1224,68 +1214,72 @@ my_bool _ma_lock_key_del(MARIA_HA *info, my_bool insert_at_end)
MARIA_SHARE *share= info->s;
/*
- info->used_key_del is 0 initially.
+ info->key_del_used is 0 initially.
If the caller needs a block (_ma_new()), we look at the free list:
- looks empty? then caller will create a new block at end of file and
- remember (through info->used_key_del==2) that it will not change
+ remember (through info->key_del_used==2) that it will not change
state.key_del and does not need to wake up waiters as nobody will wait for
it.
- non-empty? then we wait for other users of the state.key_del list to
- have finished, then we lock this list (through share->used_key_del==1)
+ have finished, then we lock this list (through share->key_del_used==1)
because we need to prevent some other thread to also read state.key_del
- and use the same page as ours. We remember through info->used_key_del==1
+ and use the same page as ours. We remember through info->key_del_used==1
that we will have to set state.key_del at unlock time and wake up
waiters.
If the caller wants to free a block (_ma_dispose()), "empty" and
"non-empty" are treated as "non-empty" is treated above.
- When we are ready to unlock, we copy share->current_key_del into
+ When we are ready to unlock, we copy share->key_del_current into
state.key_del. Unlocking happens when writing the UNDO log record, that
can make a long lock time.
Why we wrote "*looks* empty": because we are looking at state.key_del
- which may be slightly old (share->current_key_del may be more recent and
+ which may be slightly old (share->key_del_current may be more recent and
exact): when we want a new page, we tolerate to treat "there was no free
page 1 millisecond ago" as "there is no free page". It's ok to non-pop
(_ma_new(), page will be found later anyway) but it's not ok to non-push
(_ma_dispose(), page would be lost).
- When we leave this function, info->used_key_del is always 1 or 2.
+ When we leave this function, info->key_del_used is always 1 or 2.
*/
- if (info->used_key_del != 1)
+ if (info->key_del_used != 1)
{
- pthread_mutex_lock(&share->intern_lock);
+ pthread_mutex_lock(&share->key_del_lock);
if (share->state.key_del == HA_OFFSET_ERROR && insert_at_end)
{
- pthread_mutex_unlock(&share->intern_lock);
- info->used_key_del= 2; /* insert-with-append */
+ pthread_mutex_unlock(&share->key_del_lock);
+ info->key_del_used= 2; /* insert-with-append */
return 1;
}
#ifdef THREAD
- while (share->used_key_del)
- pthread_cond_wait(&share->intern_cond, &share->intern_lock);
+ while (share->key_del_used)
+ pthread_cond_wait(&share->key_del_cond, &share->key_del_lock);
#endif
- info->used_key_del= 1;
- share->used_key_del= 1;
- share->current_key_del= share->state.key_del;
- pthread_mutex_unlock(&share->intern_lock);
+ info->key_del_used= 1;
+ share->key_del_used= 1;
+ share->key_del_current= share->state.key_del;
+ pthread_mutex_unlock(&share->key_del_lock);
}
- return share->current_key_del == HA_OFFSET_ERROR;
+ return share->key_del_current == HA_OFFSET_ERROR;
}
/**
@brief copy changes to key_del and unlock it
+
+ @notes
+ In case of many threads using the maria table, we always have a lock
+ on the translog when comming here.
*/
void _ma_unlock_key_del(MARIA_HA *info)
{
- DBUG_ASSERT(info->used_key_del);
- if (info->used_key_del == 1) /* Ignore insert-with-append */
+ DBUG_ASSERT(info->key_del_used);
+ if (info->key_del_used == 1) /* Ignore insert-with-append */
{
MARIA_SHARE *share= info->s;
- pthread_mutex_lock(&share->intern_lock);
- share->used_key_del= 0;
- share->state.key_del= share->current_key_del;
- pthread_mutex_unlock(&share->intern_lock);
- pthread_cond_signal(&share->intern_cond);
+ pthread_mutex_lock(&share->key_del_lock);
+ share->key_del_used= 0;
+ share->state.key_del= share->key_del_current;
+ pthread_mutex_unlock(&share->key_del_lock);
+ pthread_cond_signal(&share->key_del_cond);
}
- info->used_key_del= 0;
+ info->key_del_used= 0;
}
diff --git a/storage/maria/ma_key_recover.h b/storage/maria/ma_key_recover.h
index e8973082777..2366d53f143 100644
--- a/storage/maria/ma_key_recover.h
+++ b/storage/maria/ma_key_recover.h
@@ -114,6 +114,6 @@ extern my_bool _ma_lock_key_del(MARIA_HA *info, my_bool insert_at_end);
extern void _ma_unlock_key_del(MARIA_HA *info);
static inline void _ma_fast_unlock_key_del(MARIA_HA *info)
{
- if (info->used_key_del)
+ if (info->key_del_used)
_ma_unlock_key_del(info);
}
diff --git a/storage/maria/ma_keycache.c b/storage/maria/ma_keycache.c
index 9295904dbcf..39fc7d421ae 100644
--- a/storage/maria/ma_keycache.c
+++ b/storage/maria/ma_keycache.c
@@ -105,8 +105,8 @@ int maria_assign_to_pagecache(MARIA_HA *info,
share->pagecache= pagecache;
/* store the key cache in the global hash structure for future opens */
- if (multi_pagecache_set((uchar*) share->unique_file_name,
- share->unique_name_length,
+ if (multi_pagecache_set((uchar*) share->unique_file_name.str,
+ share->unique_file_name.length,
share->pagecache))
error= my_errno;
pthread_mutex_unlock(&share->intern_lock);
diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c
index 4ddfa285d37..1ad41e5b213 100644
--- a/storage/maria/ma_locking.c
+++ b/storage/maria/ma_locking.c
@@ -34,7 +34,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type)
lock_type, info->lock_type, share->r_locks,
share->w_locks,
share->global_changed, share->state.open_count,
- share->index_file_name));
+ share->index_file_name.str));
if (share->options & HA_OPTION_READ_ONLY_DATA ||
info->lock_type == lock_type)
DBUG_RETURN(0);
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 42937f22103..f8b264fe450 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -7686,7 +7686,7 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn)
DBUG_ASSERT(share->data_file_type == BLOCK_RECORD);
/* re-check under mutex to avoid having 2 ids for the same share */
pthread_mutex_lock(&share->intern_lock);
- if (likely(share->id == 0))
+ if (unlikely(share->id == 0))
{
LSN lsn;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
@@ -7717,13 +7717,13 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn)
is not realpath-ed, etc) which is good: the log can be moved to another
directory and continue working.
*/
- log_array[TRANSLOG_INTERNAL_PARTS + 1].str= (uchar*)share->open_file_name;
- /**
- @todo if we had the name's length in MARIA_SHARE we could avoid this
- strlen()
- */
+ log_array[TRANSLOG_INTERNAL_PARTS + 1].str= share->open_file_name.str;
log_array[TRANSLOG_INTERNAL_PARTS + 1].length=
- strlen(share->open_file_name) + 1;
+ share->open_file_name.length + 1;
+ /*
+ We can't unlock share->intern_lock before the log entry is written to
+ ensure no one uses the id before it's logged.
+ */
if (unlikely(translog_write_record(&lsn, LOGREC_FILE_ID, trn, tbl_info,
(translog_size_t)
(sizeof(log_data) +
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index e35b5eaac86..d1cbeb1310c 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -62,7 +62,7 @@ MARIA_HA *_ma_test_if_reopen(const char *filename)
{
MARIA_HA *info=(MARIA_HA*) pos->data;
MARIA_SHARE *share= info->s;
- if (!strcmp(share->unique_file_name,filename) && share->last_version)
+ if (!strcmp(share->unique_file_name.str,filename) && share->last_version)
return info;
}
return 0;
@@ -212,7 +212,7 @@ err:
if ((save_errno == HA_ERR_CRASHED) ||
(save_errno == HA_ERR_CRASHED_ON_USAGE) ||
(save_errno == HA_ERR_CRASHED_ON_REPAIR))
- _ma_report_error(save_errno, share->open_file_name);
+ _ma_report_error(save_errno, &share->open_file_name);
switch (errpos) {
case 6:
(*share->end)(&info);
@@ -480,6 +480,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
/* Add space for node pointer */
share->base.max_key_length+= share->base.key_reflength;
+ share->unique_file_name.length= strlen(name_buff);
+ share->index_file_name.length= strlen(index_name);
+ share->data_file_name.length= strlen(data_name);
+ share->open_file_name.length= strlen(name);
if (!my_multi_malloc(MY_WME,
&share,sizeof(*share),
&share->state.rec_per_key_part,
@@ -495,10 +499,14 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
(share->base.fields+1)*sizeof(MARIA_COLUMNDEF),
&share->column_nr, share->base.fields*sizeof(uint16),
&share->blobs,sizeof(MARIA_BLOB)*share->base.blobs,
- &share->unique_file_name,strlen(name_buff)+1,
- &share->index_file_name,strlen(index_name)+1,
- &share->data_file_name,strlen(data_name)+1,
- &share->open_file_name,strlen(name)+1,
+ &share->unique_file_name.str,
+ share->unique_file_name.length+1,
+ &share->index_file_name.str,
+ share->index_file_name.length+1,
+ &share->data_file_name.str,
+ share->data_file_name.length+1,
+ &share->open_file_name.str,
+ share->open_file_name.length+1,
&share->state.key_root,keys*sizeof(my_off_t),
&share->mmap_lock,sizeof(rw_lock_t),
NullS))
@@ -512,11 +520,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
(char*) nulls_per_key_part, sizeof(long)*key_parts);
memcpy((char*) share->state.key_root,
(char*) key_root, sizeof(my_off_t)*keys);
- strmov(share->unique_file_name, name_buff);
- share->unique_name_length= (uint) strlen(name_buff);
- strmov(share->index_file_name, index_name);
- strmov(share->data_file_name, data_name);
- strmov(share->open_file_name, name);
+ strmov(share->unique_file_name.str, name_buff);
+ strmov(share->index_file_name.str, index_name);
+ strmov(share->data_file_name.str, data_name);
+ strmov(share->open_file_name.str, name);
share->block_size= share->base.block_size; /* Convenience */
{
@@ -800,8 +807,9 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
}
#ifdef THREAD
thr_lock_init(&share->lock);
- VOID(pthread_mutex_init(&share->intern_lock, MY_MUTEX_INIT_FAST));
- VOID(pthread_cond_init(&share->intern_cond, 0));
+ pthread_mutex_init(&share->intern_lock, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&share->key_del_lock, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&share->key_del_cond, 0);
for (i=0; i<keys; i++)
VOID(my_rwlock_init(&share->keyinfo[i].root_lock, NULL));
VOID(my_rwlock_init(&share->mmap_lock, NULL));
@@ -886,7 +894,12 @@ err:
if ((save_errno == HA_ERR_CRASHED) ||
(save_errno == HA_ERR_CRASHED_ON_USAGE) ||
(save_errno == HA_ERR_CRASHED_ON_REPAIR))
- _ma_report_error(save_errno, name);
+ {
+ LEX_STRING tmp_name;
+ tmp_name.str= (char*) name;
+ tmp_name.length= strlen(name);
+ _ma_report_error(save_errno, &tmp_name);
+ }
if (save_errno == HA_ERR_OLD_FILE) /* uuid is different ? */
save_errno= HA_ERR_CRASHED_ON_USAGE; /* the code to trigger auto-repair */
switch (errpos) {
@@ -1186,6 +1199,7 @@ uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite)
res= _ma_state_info_write_sub(share->kfile.file, &share->state, pWrite);
if (pWrite & 4)
pthread_mutex_unlock(&share->intern_lock);
+ share->changed= 0;
return res;
}
@@ -1202,6 +1216,13 @@ uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite)
(should only be needed after ALTER TABLE
ENABLE/DISABLE KEYS, and REPAIR/OPTIMIZE).
+ @notes
+ For transactional multiuser tables, this function is called
+ with intern_lock & translog_lock or when the last thread who
+ is using the table is closing it.
+ Because of the translog_lock we don't need to have a lock on
+ key_del_lock.
+
@return Operation status
@retval 0 OK
@retval 1 Error
@@ -1711,7 +1732,7 @@ int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share,
File file_to_dup __attribute__((unused)))
{
info->dfile.file= share->bitmap.file.file=
- my_open(share->data_file_name, share->mode | O_SHARE,
+ my_open(share->data_file_name.str, share->mode | O_SHARE,
MYF(MY_WME));
return info->dfile.file >= 0 ? 0 : 1;
}
@@ -1724,7 +1745,7 @@ int _ma_open_keyfile(MARIA_SHARE *share)
against a concurrent checkpoint.
*/
pthread_mutex_lock(&share->intern_lock);
- share->kfile.file= my_open(share->unique_file_name,
+ share->kfile.file= my_open(share->unique_file_name.str,
share->mode | O_SHARE,
MYF(MY_WME));
pthread_mutex_unlock(&share->intern_lock);
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index 2cbaf3ec690..afe40aad399 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -223,8 +223,8 @@ int _ma_dispose(register MARIA_HA *info, my_off_t pos, my_bool page_not_read)
(void) _ma_lock_key_del(info, 0);
- old_link= share->current_key_del;
- share->current_key_del= pos;
+ old_link= share->key_del_current;
+ share->key_del_current= pos;
page_no= pos / block_size;
bzero(buff, share->keypage_header);
_ma_store_keynr(share, buff, (uchar) MARIA_DELETE_KEY_NR);
@@ -347,7 +347,7 @@ my_off_t _ma_new(register MARIA_HA *info, int level,
else
{
uchar *buff;
- pos= share->current_key_del; /* Protected */
+ pos= share->key_del_current; /* Protected */
DBUG_ASSERT(share->pagecache->block_size == block_size);
if (!(buff= pagecache_read(share->pagecache,
&share->kfile,
@@ -362,15 +362,15 @@ my_off_t _ma_new(register MARIA_HA *info, int level,
(single linked list):
*/
#ifndef DBUG_OFF
- my_off_t current_key_del;
+ my_off_t key_del_current;
#endif
- share->current_key_del= mi_sizekorr(buff+share->keypage_header);
+ share->key_del_current= mi_sizekorr(buff+share->keypage_header);
#ifndef DBUG_OFF
- current_key_del= share->current_key_del;
- DBUG_ASSERT(current_key_del != share->state.key_del &&
- (current_key_del != 0) &&
- ((current_key_del == HA_OFFSET_ERROR) ||
- (current_key_del <=
+ key_del_current= share->key_del_current;
+ DBUG_ASSERT(key_del_current != share->state.key_del &&
+ (key_del_current != 0) &&
+ ((key_del_current == HA_OFFSET_ERROR) ||
+ (key_del_current <=
(share->state.state.key_file_length - block_size))));
#endif
}
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index 3e28835d4a8..8972ee94fc1 100644
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -305,12 +305,13 @@ struct st_pagecache_block_link
ulonglong last_hit_time; /* timestamp of the last hit */
WQUEUE
wqueue[COND_SIZE]; /* queues on waiting requests for new/old pages */
- uint requests; /* number of requests for the block */
- uint status; /* state of the block */
- uint pins; /* pin counter */
- uint wlocks; /* write locks counter */
- uint rlocks; /* read locks counter */
- uint rlocks_queue; /* rd. locks waiting wr. lock of this thread */
+ uint32 requests; /* number of requests for the block */
+ uint32 pins; /* pin counter */
+ uint32 wlocks; /* write locks counter */
+ uint32 rlocks; /* read locks counter */
+ uint32 rlocks_queue; /* rd. locks waiting wr. lock of this thread */
+ uint16 status; /* state of the block */
+ int16 error; /* error code for block in case of error */
enum PCBLOCK_TEMPERATURE temperature; /* block temperature: cold, warm, hot*/
enum pagecache_page_type type; /* type of the block */
uint hits_left; /* number of hits left until promotion */
@@ -592,16 +593,16 @@ extern my_bool translog_flush(TRANSLOG_ADDRESS lsn);
RETURN
0 - OK
- !=0 - Error
+ 1 - Error
*/
-static uint pagecache_fwrite(PAGECACHE *pagecache,
- PAGECACHE_FILE *filedesc,
- uchar *buffer,
- pgcache_page_no_t pageno,
- enum pagecache_page_type type
- __attribute__((unused)),
- myf flags)
+static my_bool pagecache_fwrite(PAGECACHE *pagecache,
+ PAGECACHE_FILE *filedesc,
+ uchar *buffer,
+ pgcache_page_no_t pageno,
+ enum pagecache_page_type type
+ __attribute__((unused)),
+ myf flags)
{
DBUG_ENTER("pagecache_fwrite");
DBUG_ASSERT(type != PAGECACHE_READ_UNKNOWN_PAGE);
@@ -2068,6 +2069,7 @@ restart:
(my_bool)(block->hash_link ? 1 : 0));
PCBLOCK_INFO(block);
block->status= error ? PCBLOCK_ERROR : 0;
+ block->error= (int16) my_errno;
#ifndef DBUG_OFF
block->type= PAGECACHE_EMPTY_PAGE;
if (error)
@@ -2606,6 +2608,7 @@ static void read_block(PAGECACHE *pagecache,
if (error)
{
block->status|= PCBLOCK_ERROR;
+ block->error= (int16) my_errno;
my_debug_put_break_here();
}
else
@@ -2618,6 +2621,7 @@ static void read_block(PAGECACHE *pagecache,
{
DBUG_PRINT("error", ("read callback problem"));
block->status|= PCBLOCK_ERROR;
+ block->error= (int16) my_errno;
my_debug_put_break_here();
}
}
@@ -3107,7 +3111,7 @@ uchar *pagecache_read(PAGECACHE *pagecache,
enum pagecache_page_lock lock,
PAGECACHE_BLOCK_LINK **page_link)
{
- int error= 0;
+ my_bool error= 0;
enum pagecache_page_pin pin= lock_to_pin[test(buff==0)][lock];
PAGECACHE_BLOCK_LINK *fake_link;
my_bool reg_request;
@@ -3229,6 +3233,8 @@ restart:
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
#endif
}
+ else
+ my_errno= block->error;
}
remove_reader(block);
@@ -3286,7 +3292,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache,
PAGECACHE_HASH_LINK *page_link,
my_bool flush)
{
- int error= 0;
+ my_bool error= 0;
if (block->status & PCBLOCK_CHANGED)
{
if (flush)
@@ -3313,6 +3319,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache,
if (error)
{
block->status|= PCBLOCK_ERROR;
+ block->error= (int16) my_errno;
my_debug_put_break_here();
goto err;
}
@@ -3361,7 +3368,7 @@ my_bool pagecache_delete_by_link(PAGECACHE *pagecache,
enum pagecache_page_lock lock,
my_bool flush)
{
- int error= 0;
+ my_bool error= 0;
enum pagecache_page_pin pin= PAGECACHE_PIN_LEFT_PINNED;
DBUG_ENTER("pagecache_delete_by_link");
DBUG_PRINT("enter", ("fd: %d block 0x%lx %s %s",
@@ -3460,7 +3467,7 @@ my_bool pagecache_delete(PAGECACHE *pagecache,
enum pagecache_page_lock lock,
my_bool flush)
{
- int error= 0;
+ my_bool error= 0;
enum pagecache_page_pin pin= lock_to_pin[0][lock];
DBUG_ENTER("pagecache_delete");
DBUG_PRINT("enter", ("fd: %u page: %lu %s %s",
@@ -3648,7 +3655,7 @@ my_bool pagecache_write_part(PAGECACHE *pagecache,
{
PAGECACHE_BLOCK_LINK *block= NULL;
PAGECACHE_BLOCK_LINK *fake_link;
- int error= 0;
+ my_bool error= 0;
int need_lock_change= write_lock_change_table[lock].need_lock_change;
my_bool reg_request;
#ifndef DBUG_OFF
@@ -3771,6 +3778,7 @@ restart:
{
DBUG_PRINT("error", ("read callback problem"));
block->status|= PCBLOCK_ERROR;
+ block->error= (int16) my_errno;
my_debug_put_break_here();
}
KEYCACHE_DBUG_PRINT("key_cache_insert",
@@ -3860,10 +3868,10 @@ no_key_cache:
uchar *page_buffer= (uchar *) alloca(pagecache->block_size);
pagecache->global_cache_read++;
- if ((error= pagecache_fread(pagecache, file,
- page_buffer,
- pageno,
- pagecache->readwrite_flags)))
+ if ((error= (pagecache_fread(pagecache, file,
+ page_buffer,
+ pageno,
+ pagecache->readwrite_flags) != 0)))
goto end;
if ((file->read_callback)(page_buffer, pageno, file->callback_data))
{
@@ -3987,7 +3995,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
int *first_errno)
{
int rc= PCFLUSH_OK;
- int error;
+ my_bool error;
uint count= (uint) (end-cache);
DBUG_ENTER("flush_cached_blocks");
*first_errno= 0;
@@ -4067,6 +4075,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
if (error)
{
block->status|= PCBLOCK_ERROR;
+ block->error= (int16) my_errno;
my_debug_put_break_here();
if (!*first_errno)
*first_errno= my_errno ? my_errno : -1;
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index ad75a84aa1f..26d29aec4be 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -866,7 +866,7 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE)
ALERT_USER();
goto end;
}
- if (close_one_table(info->s->open_file_name, rec->lsn) ||
+ if (close_one_table(info->s->open_file_name.str, rec->lsn) ||
maria_close(info))
goto end;
info= NULL;
@@ -1008,7 +1008,7 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE)
tprint(tracef, " repairing...\n");
maria_chk_init(&param);
- param.isam_file_name= name= info->s->open_file_name;
+ param.isam_file_name= name= info->s->open_file_name.str;
param.testflag= uint8korr(rec->header + FILEID_STORE_SIZE);
param.tmpdir= maria_tmpdir;
DBUG_ASSERT(maria_tmpdir);
@@ -1085,7 +1085,7 @@ prototype_redo_exec_hook(REDO_DROP_TABLE)
ALERT_USER();
goto end;
}
- if (close_one_table(info->s->open_file_name, rec->lsn) ||
+ if (close_one_table(info->s->open_file_name.str, rec->lsn) ||
maria_close(info))
goto end;
info= NULL;
@@ -1141,7 +1141,7 @@ prototype_redo_exec_hook(FILE_ID)
info= all_tables[sid].info;
if (info != NULL)
{
- tprint(tracef, " Closing table '%s'\n", info->s->open_file_name);
+ tprint(tracef, " Closing table '%s'\n", info->s->open_file_name.str);
prepare_table_for_close(info, rec->lsn);
if (maria_close(info))
{
@@ -1201,7 +1201,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
It could be that we have in the log
FILE_ID(t1,10) ... (t1 was flushed) ... FILE_ID(t1,12);
*/
- if (close_one_table(share->open_file_name, lsn_of_file_id))
+ if (close_one_table(share->open_file_name.str, lsn_of_file_id))
goto end;
}
if (!share->base.born_transactional)
@@ -1230,7 +1230,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
if (maria_is_crashed(info))
{
eprint(tracef, "Table '%s' is crashed, skipping it. Please repair it with"
- " maria_chk -r", share->open_file_name);
+ " maria_chk -r", share->open_file_name.str);
error= -1; /* not fatal, try with other tables */
goto end;
/*
@@ -2828,7 +2828,7 @@ static MARIA_HA *get_MARIA_HA_from_REDO_record(const
return NULL;
}
share= info->s;
- tprint(tracef, ", '%s'", share->open_file_name);
+ tprint(tracef, ", '%s'", share->open_file_name.str);
DBUG_ASSERT(in_redo_phase);
if (cmp_translog_addr(rec->lsn, share->lsn_of_file_id) <= 0)
{
@@ -2899,7 +2899,7 @@ static MARIA_HA *get_MARIA_HA_from_UNDO_record(const
return NULL;
}
share= info->s;
- tprint(tracef, ", '%s'", share->open_file_name);
+ tprint(tracef, ", '%s'", share->open_file_name.str);
if (cmp_translog_addr(rec->lsn, share->lsn_of_file_id) <= 0)
{
tprint(tracef, ", table's LOGREC_FILE_ID has LSN (%lu,0x%lx) more recent"
@@ -3188,7 +3188,7 @@ static my_bool close_one_table(const char *name, TRANSLOG_ADDRESS addr)
internal_table++)
{
MARIA_HA *info= internal_table->info;
- if ((info != NULL) && !strcmp(info->s->open_file_name, name))
+ if ((info != NULL) && !strcmp(info->s->open_file_name.str, name))
{
prepare_table_for_close(info, addr);
if (maria_close(info))
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index 98bac11e8d4..cf7ec5f9724 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -116,7 +116,8 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
(key->flag & SEARCH_PART_KEY) || info->s->base.born_transactional))
{
- if ((error= _ma_search(info, key, nextflag,
+ if ((error= _ma_search(info, key, (nextflag | SEARCH_FIND) &
+ ~(SEARCH_BIGGER | SEARCH_SMALLER | SEARCH_LAST),
_ma_kpos(nod_flag,keypos))) >= 0 ||
my_errno != HA_ERR_KEY_NOT_FOUND)
DBUG_RETURN(error);
@@ -338,10 +339,8 @@ int _ma_seq_search(const MARIA_KEY *key, uchar *page,
comp_flag | tmp_key.flag,
not_used)) >= 0)
break;
-#ifdef EXTRA_DEBUG
- DBUG_PRINT("loop",("page: 0x%lx key: '%s' flag: %d", (long) page, t_buff,
- flag));
-#endif
+ DBUG_PRINT("loop_extra",("page: 0x%lx key: '%s' flag: %d",
+ (long) page, t_buff, flag));
memcpy(buff,t_buff,length);
*ret_pos=page;
}
@@ -2195,9 +2194,10 @@ int _ma_calc_bin_pack_key_length(const MARIA_KEY *int_key,
if (next_length > ref_length)
{
- /* We put a key with different case between two keys with the same prefix
- Extend next key to have same prefix as
- this key */
+ /*
+ We put a key with different case between two keys with the same prefix
+ Extend next key to have same prefix as this key
+ */
s_temp->n_ref_length= ref_length;
s_temp->prev_length= next_length-ref_length;
s_temp->prev_key+= ref_length;
@@ -2207,13 +2207,13 @@ int _ma_calc_bin_pack_key_length(const MARIA_KEY *int_key,
}
/* Check how many characters are identical to next key */
key= s_temp->key+next_length;
+ s_temp->prev_length= 0;
while (*key++ == *next_key++) ;
if ((ref_length= (uint) (key - s_temp->key)-1) == next_length)
{
s_temp->next_key_pos=0;
return (s_temp->move_length= length); /* Can't pack next key */
}
- s_temp->prev_length=0;
s_temp->n_ref_length=ref_length;
return s_temp->move_length= (int) (length-(ref_length - next_length) -
next_length_pack +
diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c
index 422e35795bd..cfe0de62929 100644
--- a/storage/maria/ma_state.c
+++ b/storage/maria/ma_state.c
@@ -79,6 +79,9 @@ my_bool _ma_setup_live_state(MARIA_HA *info)
pthread_mutex_lock(&share->intern_lock);
share->in_trans++;
+ DBUG_PRINT("info", ("share: 0x%lx in_trans: %d",
+ (ulong) share, share->in_trans));
+
history= share->state_history;
/*
@@ -359,15 +362,16 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
{
my_bool error= 0;
MARIA_USED_TABLES *tables, *next;
+ DBUG_ENTER("_ma_trnman_end_trans_hook");
for (tables= (MARIA_USED_TABLES*) trn->used_tables;
tables;
tables= next)
{
+ MARIA_SHARE *share= tables->share;
next= tables->next;
if (commit)
{
- MARIA_SHARE *share= tables->share;
MARIA_STATE_HISTORY *history;
pthread_mutex_lock(&share->intern_lock);
@@ -405,13 +409,27 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
/* Remove not visible states */
share->state_history= _ma_remove_not_visible_states(history, 0, 1);
}
+ DBUG_PRINT("info", ("share: 0x%lx in_trans: %d",
+ (ulong) share, share->in_trans));
+ share->in_trans--;
+ pthread_mutex_unlock(&share->intern_lock);
+ }
+ else
+ {
+#ifndef DBUG_OFF
+ /*
+ We need to keep share->in_trans correct in the debug library
+ because of the assert in maria_close()
+ */
+ pthread_mutex_lock(&share->intern_lock);
share->in_trans--;
pthread_mutex_unlock(&share->intern_lock);
+#endif
}
my_free(tables, MYF(0));
}
trn->used_tables= 0;
- return error;
+ DBUG_RETURN(error);
}
@@ -421,11 +439,18 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
@notes
This is used when we unlock a table from a group of locked tables
just before doing a rename or drop table.
+
+ share->internal_lock must be locked when function is called
*/
void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
{
MARIA_USED_TABLES *tables, **prev;
+ DBUG_ENTER("_ma_remove_table_from_trnman");
+ DBUG_PRINT("enter", ("share: 0x%lx in_trans: %d",
+ (ulong) share, share->in_trans));
+
+ safe_mutex_assert_owner(&share->intern_lock);
for (prev= (MARIA_USED_TABLES**) &trn->used_tables, tables= *prev;
tables;
@@ -434,11 +459,14 @@ void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
if (tables->share == share)
{
*prev= tables->next;
+ share->in_trans--;
+ DBUG_PRINT("info", ("in_trans: %d", share->in_trans));
my_free(tables, MYF(0));
+ break;
}
- else
- prev= &tables->next;
+ prev= &tables->next;
}
+ DBUG_VOID_RETURN;
}
diff --git a/storage/maria/ma_update.c b/storage/maria/ma_update.c
index 29246d2d07e..a178f5d47a7 100644
--- a/storage/maria/ma_update.c
+++ b/storage/maria/ma_update.c
@@ -188,8 +188,9 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
allow_break(); /* Allow SIGHUP & SIGINT */
if (info->invalidator != 0)
{
- DBUG_PRINT("info", ("invalidator... '%s' (update)", share->open_file_name));
- (*info->invalidator)(share->open_file_name);
+ DBUG_PRINT("info", ("invalidator... '%s' (update)",
+ share->open_file_name.str));
+ (*info->invalidator)(share->open_file_name.str);
info->invalidator=0;
}
DBUG_RETURN(0);
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 8add20d46ef..fb380b6d3e2 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -280,8 +280,8 @@ int maria_write(MARIA_HA *info, uchar *record)
if (info->invalidator != 0)
{
DBUG_PRINT("info", ("invalidator... '%s' (update)",
- share->open_file_name));
- (*info->invalidator)(share->open_file_name);
+ share->open_file_name.str));
+ (*info->invalidator)(share->open_file_name.str);
info->invalidator=0;
}
@@ -1823,11 +1823,11 @@ my_bool _ma_log_new(MARIA_HA *info, my_off_t page, const uchar *buff,
page_store(log_data + FILEID_STORE_SIZE, page);
/* Store link to next unused page */
- if (info->used_key_del == 2)
+ if (info->key_del_used == 2)
page= 0; /* key_del not changed */
else
- page= ((share->current_key_del == HA_OFFSET_ERROR) ? IMPOSSIBLE_PAGE_NO :
- share->current_key_del / share->block_size);
+ page= ((share->key_del_current == HA_OFFSET_ERROR) ? IMPOSSIBLE_PAGE_NO :
+ share->key_del_current / share->block_size);
page_store(log_data + FILEID_STORE_SIZE + PAGE_STORE_SIZE, page);
key_nr_store(log_data + FILEID_STORE_SIZE + PAGE_STORE_SIZE*2, key_nr);
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 060432c4696..42a78261d20 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -275,10 +275,10 @@ typedef struct st_maria_share
MARIA_PACK pack; /* Data about packed records */
MARIA_BLOB *blobs; /* Pointer to blobs */
uint16 *column_nr; /* Original column order */
- char *unique_file_name; /* realpath() of index file */
- char *data_file_name; /* Resolved path names from symlinks */
- char *index_file_name;
- char *open_file_name; /* parameter to open filename */
+ LEX_STRING unique_file_name; /* realpath() of index file */
+ LEX_STRING data_file_name; /* Resolved path names from symlinks */
+ LEX_STRING index_file_name;
+ LEX_STRING open_file_name; /* parameter to open filename */
uchar *file_map; /* mem-map of file if possible */
PAGECACHE *pagecache; /* ref to the current key cache */
MARIA_DECODE_TREE *decode_trees;
@@ -337,7 +337,7 @@ typedef struct st_maria_share
size_t (*file_read)(MARIA_HA *, uchar *, size_t, my_off_t, myf);
size_t (*file_write)(MARIA_HA *, const uchar *, size_t, my_off_t, myf);
invalidator_by_filename invalidator; /* query cache invalidator */
- my_off_t current_key_del; /* delete links for index pages */
+ my_off_t key_del_current; /* delete links for index pages */
ulong this_process; /* processid */
ulong last_process; /* For table-change-check */
ulong last_version; /* Version on start */
@@ -346,7 +346,6 @@ typedef struct st_maria_share
ulong max_pack_length;
ulong state_diff_length;
uint rec_reflength; /* rec_reflength in use now */
- uint unique_name_length;
uint keypage_header;
uint32 ftparsers; /* Number of distinct ftparsers
+ 1 */
@@ -382,12 +381,13 @@ typedef struct st_maria_share
*/
my_bool now_transactional;
my_bool have_versioning;
- my_bool used_key_del; /* != 0 if key_del is locked */
+ my_bool key_del_used; /* != 0 if key_del is locked */
#ifdef THREAD
THR_LOCK lock;
void (*lock_restore_status)(void *);
pthread_mutex_t intern_lock; /* Locking for use with _locking */
- pthread_cond_t intern_cond;
+ pthread_mutex_t key_del_lock;
+ pthread_cond_t key_del_cond;
#endif
my_off_t mmaped_length;
uint nonmmaped_inserts; /* counter of writing in
@@ -537,7 +537,7 @@ struct st_maria_handler
int save_lastinx;
uint preload_buff_size; /* When preloading indexes */
uint16 last_used_keyseg; /* For MARIAMRG */
- uint8 used_key_del; /* != 0 if key_del is used */
+ uint8 key_del_used; /* != 0 if key_del is used */
my_bool was_locked; /* Was locked in panic */
my_bool append_insert_at_end; /* Set if concurrent insert */
my_bool quick_mode;
@@ -663,7 +663,7 @@ struct st_maria_handler
*/
#define maria_print_error(SHARE, ERRNO) \
do{ if (!maria_in_ha_maria) \
- _ma_report_error((ERRNO), (SHARE)->index_file_name); } \
+ _ma_report_error((ERRNO), &(SHARE)->index_file_name); } \
while(0)
#else
#define maria_print_error(SHARE, ERRNO) while (0)
@@ -1030,7 +1030,7 @@ extern uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff,
size_t *rec_buff_size,
File file, my_off_t filepos);
extern void _ma_store_blob_length(uchar *pos, uint pack_length, uint length);
-extern void _ma_report_error(int errcode, const char *file_name);
+extern void _ma_report_error(int errcode, const LEX_STRING *file_name);
extern my_bool _ma_memmap_file(MARIA_HA *info);
extern void _ma_unmap_file(MARIA_HA *info);
extern uint _ma_save_pack_length(uint version, uchar * block_buff,
diff --git a/storage/maria/maria_ftdump.c b/storage/maria/maria_ftdump.c
index 978082adb78..5e3b47b956e 100644
--- a/storage/maria/maria_ftdump.c
+++ b/storage/maria/maria_ftdump.c
@@ -100,7 +100,8 @@ int main(int argc,char *argv[])
if ((inx >= info->s->base.keys) ||
!(info->s->keyinfo[inx].flag & HA_FULLTEXT))
{
- printf("Key %d in table %s is not a FULLTEXT key\n", inx, info->s->open_file_name);
+ printf("Key %d in table %s is not a FULLTEXT key\n", inx,
+ info->s->open_file_name.str);
goto err;
}
diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c
index 858f054a9f5..b9466475548 100644
--- a/storage/maria/maria_pack.c
+++ b/storage/maria/maria_pack.c
@@ -510,11 +510,11 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
/* Create temporary or join file */
if (backup)
- VOID(fn_format(org_name,isam_file->s->open_file_name,"",MARIA_NAME_DEXT,
- 2));
+ VOID(fn_format(org_name,isam_file->s->open_file_name.str,
+ "",MARIA_NAME_DEXT, 2));
else
- VOID(fn_format(org_name,isam_file->s->open_file_name,"",MARIA_NAME_DEXT,
- 2+4+16));
+ VOID(fn_format(org_name,isam_file->s->open_file_name.str,
+ "",MARIA_NAME_DEXT, 2+4+16));
if (init_pagecache(maria_pagecache, MARIA_MIN_PAGE_CACHE_SIZE, 0, 0,
maria_block_size, MY_WME) == 0)
@@ -709,7 +709,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
if (backup)
{
if (my_rename(org_name,make_old_name(temp_name,
- isam_file->s->open_file_name),
+ isam_file->s->open_file_name.str),
MYF(MY_WME)))
error=1;
else
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index f7d8d2c901c..2c346ea18f7 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -1802,13 +1802,13 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
}
/* Check how many characters are identical to next key */
key= s_temp->key+next_length;
+ s_temp->prev_length= 0;
while (*key++ == *next_key++) ;
if ((ref_length= (uint) (key - s_temp->key)-1) == next_length)
{
s_temp->next_key_pos=0;
return length; /* can't pack next key */
}
- s_temp->prev_length=0;
s_temp->n_ref_length=ref_length;
return (int) (length-(ref_length - next_length) - next_length_pack +
get_pack_length(ref_length));