summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@nosik.monty.fi>2008-01-31 03:11:10 +0200
committerunknown <monty@nosik.monty.fi>2008-01-31 03:11:10 +0200
commit0857a6930d38602ec8d17fa1aa80bcf9e4ee1f5d (patch)
tree8d8c68727c21b96332949081b7da5f02bc1bceab
parentb51c819ce1f949a127dce99e1c63e541ebb80d03 (diff)
parentab0fa111fef1afbd04156624cdb29781f08adcac (diff)
downloadmariadb-git-0857a6930d38602ec8d17fa1aa80bcf9e4ee1f5d.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-maria
into mysql.com:/home/my/mysql-maria mysys/my_pread.c: Auto merged mysys/my_read.c: Auto merged storage/maria/ha_maria.cc: Auto merged storage/maria/ma_blockrec.c: Auto merged storage/maria/ma_check.c: Auto merged storage/maria/ma_loghandler.c: Auto merged storage/maria/ma_page.c: Auto merged storage/maria/ma_write.c: Auto merged storage/maria/maria_chk.c: Auto merged storage/maria/maria_def.h: Auto merged
-rw-r--r--cmd-line-utils/readline/readline.c15
-rw-r--r--mysql-test/r/maria.result42
-rw-r--r--mysql-test/t/maria.test27
-rw-r--r--mysys/my_pread.c5
-rw-r--r--mysys/my_read.c3
-rw-r--r--storage/maria/ha_maria.cc3
-rw-r--r--storage/maria/ma_blockrec.c2
-rw-r--r--storage/maria/ma_check.c75
-rw-r--r--storage/maria/ma_create.c56
-rw-r--r--storage/maria/ma_delete.c7
-rw-r--r--storage/maria/ma_key_recover.c32
-rw-r--r--storage/maria/ma_key_recover.h3
-rw-r--r--storage/maria/ma_loghandler.c4
-rw-r--r--storage/maria/ma_open.c2
-rw-r--r--storage/maria/ma_page.c4
-rw-r--r--storage/maria/ma_search.c16
-rw-r--r--storage/maria/ma_update.c3
-rw-r--r--storage/maria/ma_write.c3
-rw-r--r--storage/maria/maria_chk.c6
-rw-r--r--storage/maria/maria_def.h8
20 files changed, 203 insertions, 113 deletions
diff --git a/cmd-line-utils/readline/readline.c b/cmd-line-utils/readline/readline.c
index c2b74006b05..d363c922fb5 100644
--- a/cmd-line-utils/readline/readline.c
+++ b/cmd-line-utils/readline/readline.c
@@ -90,7 +90,6 @@ static void bind_arrow_keys_internal PARAMS((Keymap));
static void bind_arrow_keys PARAMS((void));
static void readline_default_bindings PARAMS((void));
-static void reset_default_bindings PARAMS((void));
static int _rl_subseq_result PARAMS((int, Keymap, int, int));
static int _rl_subseq_getchar PARAMS((int));
@@ -287,7 +286,7 @@ rl_set_prompt (prompt)
{
FREE (rl_prompt);
rl_prompt = prompt ? savestring (prompt) : (char *)NULL;
- rl_display_prompt = rl_prompt ? rl_prompt : "";
+ rl_display_prompt = rl_prompt ? rl_prompt : (char*) "";
rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
return 0;
@@ -1072,18 +1071,6 @@ readline_default_bindings ()
rl_tty_set_default_bindings (_rl_keymap);
}
-/* Reset the default bindings for the terminal special characters we're
- interested in back to rl_insert and read the new ones. */
-static void
-reset_default_bindings ()
-{
- if (_rl_bind_stty_chars)
- {
- rl_tty_unset_default_bindings (_rl_keymap);
- rl_tty_set_default_bindings (_rl_keymap);
- }
-}
-
/* Bind some common arrow key sequences in MAP. */
static void
bind_arrow_keys_internal (map)
diff --git a/mysql-test/r/maria.result b/mysql-test/r/maria.result
index bf412e0af2d..13ad2b4617e 100644
--- a/mysql-test/r/maria.result
+++ b/mysql-test/r/maria.result
@@ -2200,3 +2200,45 @@ id f1
2 test2
drop table t1;
SET SQL_MODE = 'TRADITIONAL';
+create table t1 (n int not null primary key auto_increment, c char(1), unique(c));
+insert into t1 values(100, "a");
+insert into t1 values(300, "b");
+insert into t1 values(50, "a");
+ERROR 23000: Duplicate entry 'a' for key 'c'
+insert into t1 values(null, "c");
+select * from t1;
+n c
+100 a
+300 b
+301 c
+update t1 set n=400,c='a' where n=301;
+ERROR 23000: Duplicate entry 'a' for key 'c'
+insert into t1 values(null, "d");
+select * from t1;
+n c
+100 a
+300 b
+301 c
+302 d
+drop table t1;
+create table t1 (n int not null primary key auto_increment, c char(1), unique(c)) transactional=0 row_format=dynamic;
+insert into t1 values(100, "a");
+insert into t1 values(300, "b");
+insert into t1 values(50, "a");
+ERROR 23000: Duplicate entry 'a' for key 'c'
+insert into t1 values(null, "c");
+select * from t1;
+n c
+100 a
+300 b
+301 c
+update t1 set n=400,c='a' where n=301;
+ERROR 23000: Duplicate entry 'a' for key 'c'
+insert into t1 values(null, "d");
+select * from t1;
+n c
+100 a
+300 b
+301 c
+302 d
+drop table t1;
diff --git a/mysql-test/t/maria.test b/mysql-test/t/maria.test
index d4e9a20e7b9..3c47e363ddc 100644
--- a/mysql-test/t/maria.test
+++ b/mysql-test/t/maria.test
@@ -1426,6 +1426,33 @@ SELECT * FROM t1;
drop table t1;
SET SQL_MODE = 'TRADITIONAL';
+create table t1 (n int not null primary key auto_increment, c char(1), unique(c));
+insert into t1 values(100, "a");
+insert into t1 values(300, "b");
+--error 1062
+insert into t1 values(50, "a");
+insert into t1 values(null, "c");
+select * from t1;
+--error 1062
+update t1 set n=400,c='a' where n=301;
+insert into t1 values(null, "d");
+select * from t1;
+drop table t1;
+
+create table t1 (n int not null primary key auto_increment, c char(1), unique(c)) transactional=0 row_format=dynamic;
+insert into t1 values(100, "a");
+insert into t1 values(300, "b");
+--error 1062
+insert into t1 values(50, "a");
+insert into t1 values(null, "c");
+select * from t1;
+--error 1062
+update t1 set n=400,c='a' where n=301;
+insert into t1 values(null, "d");
+select * from t1;
+drop table t1;
+
+
# End of 5.2 tests
--disable_result_log
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index cfccc40a782..3dff034c15b 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -70,11 +70,12 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count)))
{
my_errno= errno;
- if (errno == 0 || (errno == -1 && (MyFlags & (MY_NABP | MY_FNABP))))
+ if (errno == 0 || (readbytes == (size_t) -1 &&
+ (MyFlags & (MY_NABP | MY_FNABP))))
my_errno= HA_ERR_FILE_TOO_SHORT;
}
#endif
- if (error || readbytes != Count)
+ if (error)
{
DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d",
(int) readbytes, (uint) Count,Filedes,my_errno));
diff --git a/mysys/my_read.c b/mysys/my_read.c
index 0d6c8d14416..64f2cf42b4c 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -51,7 +51,8 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
if ((readbytes= read(Filedes, Buffer, Count)) != Count)
{
my_errno= errno;
- if (errno == 0 || (errno == -1 && (MyFlags & (MY_NABP | MY_FNABP))))
+ if (errno == 0 || (readbytes == (size_t) -1 &&
+ (MyFlags & (MY_NABP | MY_FNABP))))
my_errno= HA_ERR_FILE_TOO_SHORT;
DBUG_PRINT("warning",("Read only %d bytes off %lu from %d, errno: %d",
(int) readbytes, (ulong) Count, Filedes,
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 7f8f985354b..20ad7ff5933 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -1498,6 +1498,7 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
maria_extra(file, HA_EXTRA_PRELOAD_BUFFER_SIZE,
(void*) &thd->variables.preload_buff_size);
+#ifndef NOT_YET
if ((error= maria_preload(file, map, ignore_leaves)))
{
switch (error) {
@@ -1515,7 +1516,7 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
error= HA_ADMIN_FAILED;
goto err;
}
-
+#endif
DBUG_RETURN(HA_ADMIN_OK);
err:
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index f4e59fe34e0..369f697bc83 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -6432,6 +6432,7 @@ my_bool _ma_apply_undo_row_insert(MARIA_HA *info, LSN undo_lsn,
checksum= 0;
if (share->calc_checksum)
checksum= (ha_checksum) 0 - ha_checksum_korr(header);
+ info->last_auto_increment= ~ (ulonglong) 0;
if (_ma_write_clr(info, undo_lsn, LOGREC_UNDO_ROW_INSERT,
share->calc_checksum != 0, checksum, &lsn, (void*) 0))
goto err;
@@ -6832,6 +6833,7 @@ my_bool _ma_apply_undo_row_update(MARIA_HA *info, LSN undo_lsn,
(*share->calc_checksum)(info, current_record));
}
+ info->last_auto_increment= ~ (ulonglong) 0;
/* Now records are up to date, execute the update to original values */
if (_ma_update_at_original_place(info, page, rownr, length_on_head_page,
extent_count, extent_info,
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index cee1e7a9b65..efde12d36a2 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -2362,11 +2362,11 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
if (my_errno != HA_ERR_FOUND_DUPP_KEY)
goto err;
DBUG_DUMP("record",(uchar*) sort_param.record,share->base.pack_reclength);
- _ma_check_print_info(param,
- "Duplicate key %2d for record at %10s against new record at %10s",
- info->errkey+1,
- llstr(sort_param.start_recpos,llbuff),
- llstr(info->dup_key_pos,llbuff2));
+ _ma_check_print_warning(param,
+ "Duplicate key %2d for record at %10s against new record at %10s",
+ info->errkey+1,
+ llstr(sort_param.current_filepos, llbuff),
+ llstr(info->dup_key_pos,llbuff2));
if (param->testflag & T_VERBOSE)
{
VOID(_ma_make_key(info,(uint) info->errkey,info->lastkey,
@@ -4973,13 +4973,14 @@ static int sort_key_write(MARIA_SORT_PARAM *sort_param, const uchar *a)
sort_param->keyinfo,
a);
_ma_check_print_warning(param,
- "Duplicate key for record at %10s against record at %10s",
- llstr(sort_info->info->cur_row.lastpos, llbuff),
- llstr(get_record_for_key(sort_info->info,
- sort_param->keyinfo,
- sort_info->key_block->
- lastkey),
- llbuff2));
+ "Duplicate key %2u for record at %10s against record at %10s",
+ sort_param->key + 1,
+ llstr(sort_info->info->cur_row.lastpos, llbuff),
+ llstr(get_record_for_key(sort_info->info,
+ sort_param->keyinfo,
+ sort_info->key_block->
+ lastkey),
+ llbuff2));
param->testflag|=T_RETRY_WITHOUT_QUICK;
if (sort_info->param->testflag & T_VERBOSE)
_ma_print_key(stdout,sort_param->seg, a, USE_WHOLE_KEY);
@@ -5410,7 +5411,8 @@ int maria_test_if_almost_full(MARIA_HA *info)
(my_off_t) share->base.max_data_file_length;
}
- /* Recreate table with bigger more alloced record-data */
+
+/* Recreate table with bigger more alloced record-data */
int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
{
@@ -5433,8 +5435,8 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
status_info= (*org_info)->state[0];
info.state= &status_info;
share= *(*org_info)->s;
- unpack= (share.options & HA_OPTION_COMPRESS_RECORD) &&
- (param->testflag & T_UNPACK);
+ unpack= ((share.data_file_type == COMPRESSED_RECORD) &&
+ (param->testflag & T_UNPACK));
if (!(keyinfo=(MARIA_KEYDEF*) my_alloca(sizeof(MARIA_KEYDEF) *
share.base.keys)))
DBUG_RETURN(0);
@@ -5464,19 +5466,11 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
DBUG_RETURN(1);
}
- /* Copy the column definitions */
- memcpy((uchar*) columndef,(uchar*) share.columndef,
- (size_t) (sizeof(MARIA_COLUMNDEF)*(share.base.fields+1)));
- for (column=columndef, end= columndef+share.base.fields;
+ /* Copy the column definitions in their original order */
+ for (column= share.columndef, end= share.columndef+share.base.fields;
column != end ;
column++)
- {
- if (unpack && !(share.options & HA_OPTION_PACK_RECORD) &&
- column->type != FIELD_BLOB &&
- column->type != FIELD_VARCHAR &&
- column->type != FIELD_CHECK)
- column->type=(int) FIELD_NORMAL;
- }
+ columndef[column->column_nr]= *column;
/* Change the new key to point at the saved key segments */
memcpy((uchar*) keysegs,(uchar*) share.keyparts,
@@ -5506,25 +5500,23 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
u_ptr->seg=keyseg;
keyseg+=u_ptr->keysegs+1;
}
+
+ file_length=(ulonglong) my_seek(info.dfile.file, 0L, MY_SEEK_END, MYF(0));
if (share.options & HA_OPTION_COMPRESS_RECORD)
share.base.records=max_records=info.state->records;
else if (share.base.min_pack_length)
- max_records=(ha_rows) (my_seek(info.dfile.file, 0L, MY_SEEK_END,
- MYF(0)) /
- (ulong) share.base.min_pack_length);
+ max_records=(ha_rows) (file_length / share.base.min_pack_length);
else
max_records=0;
- unpack= (share.data_file_type == COMPRESSED_RECORD) &&
- (param->testflag & T_UNPACK);
share.options&= ~HA_OPTION_TEMP_COMPRESS_RECORD;
- file_length=(ulonglong) my_seek(info.dfile.file, 0L, MY_SEEK_END, MYF(0));
tmp_length= file_length+file_length/10;
set_if_bigger(file_length,param->max_data_file_length);
set_if_bigger(file_length,tmp_length);
set_if_bigger(file_length,(ulonglong) share.base.max_data_file_length);
VOID(maria_close(*org_info));
+
bzero((char*) &create_info,sizeof(create_info));
create_info.max_rows=max(max_records,share.base.records);
create_info.reloc_rows=share.base.reloc;
@@ -5545,6 +5537,8 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
*/
create_info.with_auto_increment= TRUE;
create_info.null_bytes= share.base.null_bytes;
+ create_info.transactional= share.base.born_transactional;
+
/*
We don't have to handle symlinks here because we are using
HA_DONT_TOUCH_DATA
@@ -5561,10 +5555,13 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
my_errno);
goto end;
}
- *org_info=maria_open(filename,O_RDWR,
- (param->testflag & T_WAIT_FOREVER) ? HA_OPEN_WAIT_IF_LOCKED :
- (param->testflag & T_DESCRIPT) ? HA_OPEN_IGNORE_IF_LOCKED :
- HA_OPEN_ABORT_IF_LOCKED);
+ *org_info= maria_open(filename,O_RDWR,
+ (HA_OPEN_FOR_REPAIR |
+ ((param->testflag & T_WAIT_FOREVER) ?
+ HA_OPEN_WAIT_IF_LOCKED :
+ (param->testflag & T_DESCRIPT) ?
+ HA_OPEN_IGNORE_IF_LOCKED :
+ HA_OPEN_ABORT_IF_LOCKED)));
if (!*org_info)
{
_ma_check_print_error(param,
@@ -6144,7 +6141,11 @@ read_next_page:
sort_info->page++; /* In case of errors */
page++;
if (!(page % share->bitmap.pages_covered))
- page++; /* Skip bitmap */
+ {
+ /* Skip bitmap */
+ page++;
+ sort_info->page++;
+ }
if ((my_off_t) (page + 1) * share->block_size > sort_info->filelength)
DBUG_RETURN(HA_ERR_END_OF_FILE);
if (!(pagecache_read(share->pagecache,
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index df981fb7171..acdf7b7972b 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -97,15 +97,18 @@ int maria_create(const char *name, enum data_file_type datafile_type,
{
org_datafile_type= ci->org_data_file_type;
if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
- options=ci->old_options &
- (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
- HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
- HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
+ options= (ci->old_options &
+ (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
+ HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
+ HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
+ HA_OPTION_LONG_BLOB_PTR | HA_OPTION_PAGE_CHECKSUM));
else
{
/* Uncompressing rows */
- options=ci->old_options &
- (HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
+ options= (ci->old_options &
+ (HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE |
+ HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_LONG_BLOB_PTR |
+ HA_OPTION_PAGE_CHECKSUM));
}
}
@@ -257,31 +260,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
else
min_pack_length+= 5; /* Min row overhead */
- if ((packed & 7) == 1)
- {
- /*
- Not optimal packing, try to remove a 1 uchar length zero-field as
- this will get same record length, but smaller pack overhead
- */
- while (column != columndef)
- {
- column--;
- if (column->type == (int) FIELD_SKIP_ZERO && column->length == 1)
- {
- /*
- NOTE1: here we change a field type FIELD_SKIP_ZERO ->
- FIELD_NORMAL
- */
- column->type=(int) FIELD_NORMAL;
- column->empty_pos= 0;
- column->empty_bit= 0;
- packed--;
- min_pack_length++;
- break;
- }
- }
- }
-
if (flags & HA_CREATE_TMP_TABLE)
{
options|= HA_OPTION_TMP_TABLE;
@@ -641,7 +619,9 @@ int maria_create(const char *name, enum data_file_type datafile_type,
if (length > max_key_length)
max_key_length= length;
- tot_length+= ((max_rows/(ulong) (((uint) maria_block_size-5)/
+ tot_length+= ((max_rows/(ulong) (((uint) maria_block_size -
+ MAX_KEYPAGE_HEADER_SIZE -
+ KEYPAGE_CHECKSUM_SIZE)/
(length*2))) *
maria_block_size);
}
@@ -652,7 +632,9 @@ int maria_create(const char *name, enum data_file_type datafile_type,
uniquedef->key=keys+i;
unique_key_parts+=uniquedef->keysegs;
share.state.key_root[keys+i]= HA_OFFSET_ERROR;
- tot_length+= (max_rows/(ulong) (((uint) maria_block_size-5)/
+ tot_length+= (max_rows/(ulong) (((uint) maria_block_size -
+ MAX_KEYPAGE_HEADER_SIZE -
+ KEYPAGE_CHECKSUM_SIZE) /
((MARIA_UNIQUE_HASH_LENGTH + pointer)*2)))*
(ulong) maria_block_size;
}
@@ -704,12 +686,16 @@ int maria_create(const char *name, enum data_file_type datafile_type,
share.base.rec_reflength=pointer;
share.base.block_size= maria_block_size;
- /* Get estimate for index file length (this may be wrong for FT keys) */
+ /*
+ Get estimate for index file length (this may be wrong for FT keys)
+ This is used for pointers to other key pages.
+ */
tmp= (tot_length + maria_block_size * keys *
MARIA_INDEX_BLOCK_MARGIN) / maria_block_size;
+
/*
use maximum of key_file_length we calculated and key_file_length value we
- got from MYI file header (see also mariapack.c:save_state)
+ got from MAI file header (see also mariapack.c:save_state)
*/
share.base.key_reflength=
maria_get_pointer_length(max(ci->key_file_length,tmp),3);
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index b46d4216269..2fade42a313 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -71,6 +71,8 @@ int maria_delete(MARIA_HA *info,const uchar *record)
if (_ma_mark_file_changed(info))
goto err;
+ /* Ensure we don't change the autoincrement value */
+ info->last_auto_increment= ~(ulonglong) 0;
/* Remove all keys from the index file */
old_key= info->lastkey2;
@@ -212,6 +214,11 @@ int _ma_ck_delete(register MARIA_HA *info, uint keynr, uchar *key,
msg.root= &share->state.key_root[keynr];
msg.value= new_root;
+ /*
+ set autoincrement to 1 if this is an auto_increment key
+ This is only used if we are now in a rollback of a duplicate key
+ */
+ msg.auto_increment= share->base.auto_key == keynr + 1;
if (translog_write_record(&lsn, log_type,
info->trn, info,
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index 4925620e6cd..d93c863974d 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -159,10 +159,6 @@ my_bool write_hook_for_clr_end(enum translog_record_type type
case LOGREC_UNDO_ROW_INSERT:
share->state.state.records--;
share->state.state.checksum+= msg->checksum_delta;
- /* Restore auto increment if no one has changed it in between */
- if (share->last_auto_increment == tbl_info->last_auto_increment)
- share->state.auto_increment= tbl_info->last_auto_increment;
- break;
break;
case LOGREC_UNDO_ROW_UPDATE:
share->state.state.checksum+= msg->checksum_delta;
@@ -212,7 +208,7 @@ my_bool write_hook_for_undo_key(enum translog_record_type type,
/**
- Upates "auto_increment" and calls the generic UNDO_KEY hook
+ Updates "auto_increment" and calls the generic UNDO_KEY hook
@return Operation status, always 0 (success)
*/
@@ -264,6 +260,32 @@ my_bool write_hook_for_undo_key_insert(enum translog_record_type type,
}
+/**
+ @brief Updates "share->auto_increment" in case of abort and calls
+ generic UNDO_KEY hook
+
+ @return Operation status, always 0 (success)
+*/
+
+my_bool write_hook_for_undo_key_delete(enum translog_record_type type,
+ TRN *trn, MARIA_HA *tbl_info,
+ LSN *lsn, void *hook_arg)
+{
+ struct st_msg_to_write_hook_for_undo_key *msg=
+ (struct st_msg_to_write_hook_for_undo_key *) hook_arg;
+ MARIA_SHARE *share= tbl_info->s;
+ if (msg->auto_increment > 0) /* If auto increment key */
+ {
+ /* Restore auto increment if no one has changed it in between */
+ if (share->last_auto_increment == tbl_info->last_auto_increment &&
+ tbl_info->last_auto_increment != ~(ulonglong) 0)
+ share->state.auto_increment= tbl_info->last_auto_increment;
+ }
+ return write_hook_for_undo_key(type, trn, tbl_info, lsn, hook_arg);
+}
+
+
+
/*****************************************************************************
Functions for logging of key page changes
*****************************************************************************/
diff --git a/storage/maria/ma_key_recover.h b/storage/maria/ma_key_recover.h
index e8eb157bb9d..196d0506609 100644
--- a/storage/maria/ma_key_recover.h
+++ b/storage/maria/ma_key_recover.h
@@ -55,6 +55,9 @@ extern my_bool write_hook_for_undo_key(enum translog_record_type type,
extern my_bool write_hook_for_undo_key_insert(enum translog_record_type type,
TRN *trn, MARIA_HA *tbl_info,
LSN *lsn, void *hook_arg);
+extern my_bool write_hook_for_undo_key_delete(enum translog_record_type type,
+ TRN *trn, MARIA_HA *tbl_info,
+ LSN *lsn, void *hook_arg);
void _ma_unpin_all_pages(MARIA_HA *info, LSN undo_lsn);
my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page,
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 9f36366a798..b77c774e1a4 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -543,13 +543,13 @@ static LOG_DESC INIT_LOGREC_UNDO_KEY_INSERT_WITH_ROOT=
static LOG_DESC INIT_LOGREC_UNDO_KEY_DELETE=
{LOGRECTYPE_VARIABLE_LENGTH, 0,
LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE,
- NULL, write_hook_for_undo_key, NULL, 1,
+ NULL, write_hook_for_undo_key_delete, NULL, 1,
"undo_key_delete", LOGREC_LAST_IN_GROUP, NULL, NULL};
static LOG_DESC INIT_LOGREC_UNDO_KEY_DELETE_WITH_ROOT=
{LOGRECTYPE_VARIABLE_LENGTH, 0,
LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE + PAGE_STORE_SIZE,
- NULL, write_hook_for_undo_key, NULL, 1,
+ NULL, write_hook_for_undo_key_delete, NULL, 1,
"undo_key_delete_with_root", LOGREC_LAST_IN_GROUP, NULL, NULL};
static LOG_DESC INIT_LOGREC_PREPARE=
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 37925ae0b60..7f1676c5d85 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -449,7 +449,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
(ulonglong) 1 << (share->base.rec_reflength*8))-1);
max_key_file_length=
- _ma_safe_mul(MARIA_MIN_KEY_BLOCK_LENGTH,
+ _ma_safe_mul(maria_block_size,
((ulonglong) 1 << (share->base.key_reflength*8))-1);
#if SIZEOF_OFF_T == 4
set_if_smaller(max_data_file_length, INT_MAX32);
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index 99325dc63b2..9a16a737610 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -101,7 +101,7 @@ int _ma_write_keypage(register MARIA_HA *info,
_ma_get_used_and_nod(share, buff, page_length, nod);
if (pos < share->base.keystart ||
pos+block_size > info->state->key_file_length ||
- (pos & (MARIA_MIN_KEY_BLOCK_LENGTH-1)))
+ (pos & (maria_block_size-1)))
{
DBUG_PRINT("error",("Trying to write inside key status region: "
"key_start: %lu length: %lu page: %lu",
@@ -182,7 +182,7 @@ int _ma_write_keypage(register MARIA_HA *info,
int _ma_dispose(register MARIA_HA *info, my_off_t pos, my_bool page_not_read)
{
my_off_t old_link;
- uchar buff[MAX_KEYPAGE_HEADER_SIZE+8];
+ uchar buff[MAX_KEYPAGE_HEADER_SIZE+ 8 + 2];
ulonglong page_no;
MARIA_SHARE *share= info->s;
MARIA_PINNED_PAGE page_link;
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index a76e9dfd63d..2c3326b803a 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -590,11 +590,11 @@ my_off_t _ma_kpos(uint nod_flag, uchar *after_key)
switch (nod_flag) {
#if SIZEOF_OFF_T > 4
case 7:
- return mi_uint7korr(after_key)*MARIA_MIN_KEY_BLOCK_LENGTH;
+ return mi_uint7korr(after_key)*maria_block_size;
case 6:
- return mi_uint6korr(after_key)*MARIA_MIN_KEY_BLOCK_LENGTH;
+ return mi_uint6korr(after_key)*maria_block_size;
case 5:
- return mi_uint5korr(after_key)*MARIA_MIN_KEY_BLOCK_LENGTH;
+ return mi_uint5korr(after_key)*maria_block_size;
#else
case 7:
after_key++;
@@ -604,13 +604,13 @@ my_off_t _ma_kpos(uint nod_flag, uchar *after_key)
after_key++;
#endif
case 4:
- return ((my_off_t) mi_uint4korr(after_key))*MARIA_MIN_KEY_BLOCK_LENGTH;
+ return ((my_off_t) mi_uint4korr(after_key))*maria_block_size;
case 3:
- return ((my_off_t) mi_uint3korr(after_key))*MARIA_MIN_KEY_BLOCK_LENGTH;
+ return ((my_off_t) mi_uint3korr(after_key))*maria_block_size;
case 2:
- return (my_off_t) (mi_uint2korr(after_key)*MARIA_MIN_KEY_BLOCK_LENGTH);
+ return (my_off_t) (mi_uint2korr(after_key)*maria_block_size);
case 1:
- return (uint) (*after_key)*MARIA_MIN_KEY_BLOCK_LENGTH;
+ return (uint) (*after_key)*maria_block_size;
case 0: /* At leaf page */
default: /* Impossible */
return(HA_OFFSET_ERROR);
@@ -622,7 +622,7 @@ my_off_t _ma_kpos(uint nod_flag, uchar *after_key)
void _ma_kpointer(register MARIA_HA *info, register uchar *buff, my_off_t pos)
{
- pos/=MARIA_MIN_KEY_BLOCK_LENGTH;
+ pos/=maria_block_size;
switch (info->s->base.key_reflength) {
#if SIZEOF_OFF_T > 4
case 7: mi_int7store(buff,pos); break;
diff --git a/storage/maria/ma_update.c b/storage/maria/ma_update.c
index c117dc844dc..09d95b758f3 100644
--- a/storage/maria/ma_update.c
+++ b/storage/maria/ma_update.c
@@ -76,6 +76,9 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
goto err_end;
}
+ /* Ensure we don't try to restore auto_increment if it doesn't change */
+ info->last_auto_increment= ~(ulonglong) 0;
+
/* Check which keys changed from the original row */
new_key= info->lastkey2;
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 0310e72a71e..81c5220a513 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -138,6 +138,9 @@ int maria_write(MARIA_HA *info, uchar *record)
goto err2;
}
+ /* Ensure we don't try to restore auto_increment if it doesn't change */
+ info->last_auto_increment= ~(ulonglong) 0;
+
if ((info->opt_flag & OPT_NO_ROWS))
filepos= HA_OFFSET_ERROR;
else
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 423ba64b723..69d833e49fb 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -332,7 +332,7 @@ static struct my_option my_long_options[] =
{ "page_buffer_size", OPT_PAGE_BUFFER_SIZE,
"Size of page buffer. Used by --safe-repair",
(uchar**) &check_param.use_buffers, (uchar**) &check_param.use_buffers, 0,
- GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) USE_BUFFER_INIT,
+ GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, 1024L*1024L,
(long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0},
{ "read_buffer_size", OPT_READ_BUFFER_SIZE, "",
(uchar**) &check_param.read_buffer_length,
@@ -1466,14 +1466,14 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
pos=strmov(pos,null_txt);
*pos=0;
- printf("%-4d%-6ld%-3d %-8s%-21s",
+ printf("%-4d%-6ld%-3d %-8s%-23s",
key+1,(long) keyseg->start+1,keyseg->length,text,buff);
if (share->state.key_root[key] != HA_OFFSET_ERROR)
llstr(share->state.key_root[key],buff);
else
buff[0]=0;
if (param->testflag & T_VERBOSE)
- printf("%11.0f %12s %10d",
+ printf("%9.0f %12s %10d",
share->state.rec_per_key_part[keyseg_nr++],
buff,keyinfo->block_length);
VOID(putchar('\n'));
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 5d21355db91..aaf0b850f69 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -65,7 +65,7 @@ typedef struct st_maria_status_info
typedef struct st_maria_state_info
{
struct
- { /* Fileheader */
+ { /* Fileheader (24 bytes) */
uchar file_version[4];
uchar options[2];
uchar header_length[2];
@@ -285,6 +285,10 @@ typedef struct st_maria_share
uchar *file_map; /* mem-map of file if possible */
PAGECACHE *pagecache; /* ref to the current key cache */
MARIA_DECODE_TREE *decode_trees;
+ /*
+ Previous auto-increment value. Used to verify if we can restore the
+ auto-increment counter if we have to abort an insert (duplicate key).
+ */
ulonglong last_auto_increment;
uint16 *decode_tables;
uint16 id; /**< 2-byte id by which log records refer to the table */
@@ -485,7 +489,7 @@ struct st_maria_handler
uint32 int_keytree_version; /* -""- */
int (*read_record)(MARIA_HA *, uchar*, MARIA_RECORD_POS);
invalidator_by_filename invalidator; /* query cache invalidator */
- ulonglong last_auto_increment;
+ ulonglong last_auto_increment; /* auto value at start of statement */
ulong this_unique; /* uniq filenumber or thread */
ulong last_unique; /* last unique number */
ulong this_loop; /* counter for this open */