summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2011-07-25 21:52:15 -0700
committerMichael Widenius <monty@askmonty.org>2011-07-25 21:52:15 -0700
commit1d61f71384f031fe7cc000fd7efd38bef44c0302 (patch)
treefa8b80f1a7240783ff4b159ed05afd6f51c8e973
parent678f4b2de17a6fa42a056422feb7d7c7f24092da (diff)
parentdb9291fa2201e51b29713966612a589c9aa025fd (diff)
downloadmariadb-git-1d61f71384f031fe7cc000fd7efd38bef44c0302.tar.gz
Merge with 5.1
Fixed lp:814237: Wrong mutex usage in Aria storage/maria/ma_bitmap.c: Added call to _ma_bitmap_mark_file_changed() when flushing bitmap. This fixes lp:814237
-rw-r--r--.bzrignore1
-rwxr-xr-xmysql-test/mysql-test-run.pl1
-rw-r--r--mysql-test/suite/maria/r/max_length.result56
-rw-r--r--mysql-test/suite/maria/t/max_length.test52
-rw-r--r--storage/maria/ma_bitmap.c92
-rw-r--r--storage/maria/ma_blockrec.c27
-rw-r--r--storage/maria/ma_blockrec.h3
-rw-r--r--storage/maria/ma_check.c55
-rw-r--r--storage/maria/ma_create.c16
-rw-r--r--storage/maria/ma_loghandler.c1
-rw-r--r--storage/maria/ma_open.c4
-rw-r--r--storage/maria/maria_chk.c4
-rw-r--r--storage/maria/maria_def.h7
13 files changed, 273 insertions, 46 deletions
diff --git a/.bzrignore b/.bzrignore
index 375381c4606..6b18d09723b 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1960,3 +1960,4 @@ scripts/convert-debug-for-diff
client/strings_def.h
libmysql/strings_def.h
libmysql_r/strings_def.h
+storage/maria/aria_log_control
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 38042d1f272..88f175b636f 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -4444,6 +4444,7 @@ sub extract_warning_lines ($) {
qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|,
qr|mysqld: Table '\./mtr/test_suppressions' is marked as crashed and should be repaired|,
qr|InnoDB: Error: table 'test/bug39438'|,
+ qr|table.*is full|,
);
my $matched_lines= [];
diff --git a/mysql-test/suite/maria/r/max_length.result b/mysql-test/suite/maria/r/max_length.result
new file mode 100644
index 00000000000..668ba01bba5
--- /dev/null
+++ b/mysql-test/suite/maria/r/max_length.result
@@ -0,0 +1,56 @@
+drop table if exists t1,t2;
+Warnings:
+Note 1051 Unknown table 't1'
+Note 1051 Unknown table 't2'
+create table t1 (id int(10) unsigned not null auto_increment primary key, v varchar(1000), b blob) row_format=page max_rows=2 engine=aria;
+create table t2 (id int(10) unsigned not null auto_increment primary key, v varchar(1000), b blob) row_format=page max_rows=20000000 engine=aria;
+lock tables t1 write,t2 write;
+show table status like "t_";
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+t1 MARIA 10 Page 0 0 8192 268320768 8192 0 1 # # # latin1_swedish_ci NULL max_rows=2 row_format=PAGE
+t2 MARIA 10 Page 0 0 8192 17592186011648 8192 0 1 # # # latin1_swedish_ci NULL max_rows=20000000 row_format=PAGE
+insert into t1 values(null, repeat("ab",100),repeat("def",1000));
+insert into t1 values(null, repeat("de",200),repeat("ghi",2000));
+insert into t1 values(null, repeat("fe",300),repeat("ghi",3000));
+insert into t1 values(null, repeat("gh",400),repeat("jkl",10000));
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+unlock tables;
+insert into t1 (v,b) select v,b from t2;
+ERROR HY000: The table 't1' is full
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Datafile is almost full, 268230656 of 268320768 used
+test.t1 check status OK
+insert into t1 values(null, repeat("gh",400),repeat("jkl",10000));
+ERROR HY000: The table 't1' is full
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Datafile is almost full, 268230656 of 268320768 used
+test.t1 check status OK
+truncate table t1;
+insert into t1 (v,b) select v,b from t2;
+ERROR HY000: The table 't1' is full
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Datafile is almost full, 268230656 of 268320768 used
+test.t1 check status OK
+drop table t1,t2;
diff --git a/mysql-test/suite/maria/t/max_length.test b/mysql-test/suite/maria/t/max_length.test
new file mode 100644
index 00000000000..68ad1e22aa9
--- /dev/null
+++ b/mysql-test/suite/maria/t/max_length.test
@@ -0,0 +1,52 @@
+# Test max data length
+# This test will use around 1.3G of disk space!
+
+--source include/have_maria.inc
+--source include/big_test.inc
+
+drop table if exists t1,t2;
+
+create table t1 (id int(10) unsigned not null auto_increment primary key, v varchar(1000), b blob) row_format=page max_rows=2 engine=aria;
+create table t2 (id int(10) unsigned not null auto_increment primary key, v varchar(1000), b blob) row_format=page max_rows=20000000 engine=aria;
+lock tables t1 write,t2 write;
+--replace_column 12 # 13 # 14 #
+show table status like "t_";
+insert into t1 values(null, repeat("ab",100),repeat("def",1000));
+insert into t1 values(null, repeat("de",200),repeat("ghi",2000));
+insert into t1 values(null, repeat("fe",300),repeat("ghi",3000));
+insert into t1 values(null, repeat("gh",400),repeat("jkl",10000));
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+unlock tables;
+
+--error ER_RECORD_FILE_FULL
+insert into t1 (v,b) select v,b from t2;
+check table t1;
+--error ER_RECORD_FILE_FULL
+insert into t1 values(null, repeat("gh",400),repeat("jkl",10000));
+check table t1;
+# Test also with inserting into empty table (different code)
+truncate table t1;
+--error ER_RECORD_FILE_FULL
+insert into t1 (v,b) select v,b from t2;
+check table t1;
+
+drop table t1,t2;
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index 30fbe3a8b93..86c721f75fa 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -211,7 +211,10 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
SYNOPSIS
_ma_bitmap_init()
share Share handler
- file data file handler
+ file Data file handler
+ last_page Pointer to last page (max_file_size) that needs to be
+ mapped by the bitmap. This is adjusted to bitmap
+ alignment.
NOTES
This is called the first time a file is opened.
@@ -221,7 +224,8 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
1 error
*/
-my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
+my_bool _ma_bitmap_init(MARIA_SHARE *share, File file,
+ pgcache_page_no_t *last_page)
{
uint aligned_bit_blocks;
uint max_page_size;
@@ -244,7 +248,7 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
/* Size needs to be aligned on 6 */
aligned_bit_blocks= (share->block_size - PAGE_SUFFIX_SIZE) / 6;
- bitmap->total_size= aligned_bit_blocks * 6;
+ bitmap->max_total_size= bitmap->total_size= aligned_bit_blocks * 6;
/*
In each 6 bytes, we have 6*8/3 = 16 pages covered
The +1 is to add the bitmap page, as this doesn't have to be covered
@@ -272,6 +276,27 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
first_bitmap_with_space= share->state.first_bitmap_with_space;
_ma_bitmap_reset_cache(share);
+ /*
+ The bitmap used to map the file are aligned on 6 bytes. We now
+ calculate the max file size that can be used by the bitmap. This
+ is needed to get ma_info() give a true file size so that the user can
+ estimate if there is still space free for records in the file.
+ */
+ {
+ pgcache_page_no_t last_bitmap_page;
+ ulong blocks, bytes;
+
+ last_bitmap_page= *last_page - *last_page % bitmap->pages_covered;
+ blocks= *last_page - last_bitmap_page;
+ bytes= (blocks * 3) / 8; /* 3 bit per page / 8 bits per byte */
+ /* Size needs to be aligned on 6 */
+ bytes/= 6;
+ bytes*= 6;
+ bitmap->last_bitmap_page= last_bitmap_page;
+ bitmap->last_total_size= bytes;
+ *last_page= ((last_bitmap_page + bytes*8/3));
+ }
+
/* Restore first_bitmap_with_space if it's resonable */
if (first_bitmap_with_space <= (share->state.state.data_file_length /
share->block_size))
@@ -322,11 +347,12 @@ my_bool _ma_bitmap_end(MARIA_SHARE *share)
and then mutex lock would happen in the wrong order.
*/
-static inline void _ma_bitmap_mark_file_changed(MARIA_SHARE *share)
+static inline void _ma_bitmap_mark_file_changed(MARIA_SHARE *share,
+ my_bool flush_translog)
{
- /*
- It's extremely unlikely that the following test is true as it
- only happens once if the table has changed.
+ /*
+ It's extremely unlikely that the following test is true as it
+ only happens once if the table has changed.
*/
if (unlikely(!share->global_changed &&
(share->state.changed & STATE_CHANGED)))
@@ -334,6 +360,14 @@ static inline void _ma_bitmap_mark_file_changed(MARIA_SHARE *share)
/* purecov: begin inspected */
/* unlock mutex as it can't be hold during _ma_mark_file_changed() */
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
+
+ /*
+ We have to flush the translog to ensure we have registered that the
+ table is open.
+ */
+ if (flush_translog && share->now_transactional)
+ (void) translog_flush(share->state.logrec_file_id);
+
_ma_mark_file_changed(share);
pthread_mutex_lock(&share->bitmap.bitmap_lock);
/* purecov: end */
@@ -375,6 +409,12 @@ my_bool _ma_bitmap_flush(MARIA_SHARE *share)
pthread_mutex_lock(&share->bitmap.bitmap_lock);
if (share->bitmap.changed)
{
+ /*
+ We have to mark the file changed here, as otherwise the following
+ write to pagecache may force a page out from this file, which would
+ cause _ma_mark_file_changed() to be called with bitmaplock hold!
+ */
+ _ma_bitmap_mark_file_changed(share, 1);
res= write_changed_bitmap(share, &share->bitmap);
share->bitmap.changed= 0;
}
@@ -442,7 +482,7 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
DBUG_RETURN(0);
}
- _ma_bitmap_mark_file_changed(share);
+ _ma_bitmap_mark_file_changed(share, 0);
/*
The following should be true as it was tested above. We have to test
@@ -634,7 +674,7 @@ void _ma_bitmap_delete_all(MARIA_SHARE *share)
bzero(bitmap->map, bitmap->block_size);
bitmap->changed= 1;
bitmap->page= 0;
- bitmap->used_size= bitmap->total_size;
+ bitmap->used_size= bitmap->total_size= bitmap->max_total_size;
}
DBUG_VOID_RETURN;
}
@@ -671,7 +711,7 @@ void _ma_bitmap_reset_cache(MARIA_SHARE *share)
(This can only happen if writing to a bitmap page fails)
*/
bitmap->page= ((pgcache_page_no_t) 0) - bitmap->pages_covered;
- bitmap->used_size= bitmap->total_size;
+ bitmap->used_size= bitmap->total_size= bitmap->max_total_size;
bfill(bitmap->map, share->block_size, 255);
#ifndef DBUG_OFF
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
@@ -946,6 +986,20 @@ void _ma_get_bitmap_description(MARIA_FILE_BITMAP *bitmap,
}
+/*
+ Adjust bitmap->total_size to not go over max_data_file_size
+*/
+
+static void adjust_total_size(MARIA_HA *info, pgcache_page_no_t page)
+{
+ MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
+
+ if (page < bitmap->last_bitmap_page)
+ bitmap->total_size= bitmap->max_total_size; /* Use all bits in bitmap */
+ else
+ bitmap->total_size= bitmap->last_total_size;
+}
+
/***************************************************************************
Reading & writing bitmap pages
***************************************************************************/
@@ -982,12 +1036,16 @@ static my_bool _ma_read_bitmap_page(MARIA_HA *info,
DBUG_ASSERT(!bitmap->changed);
bitmap->page= page;
- if (((page + 1) * bitmap->block_size) > share->state.state.data_file_length)
+ if ((page + 1) * bitmap->block_size > share->state.state.data_file_length)
{
/* Inexistent or half-created page */
res= _ma_bitmap_create_missing(info, bitmap, page);
+ if (!res)
+ adjust_total_size(info, page);
DBUG_RETURN(res);
}
+
+ adjust_total_size(info, page);
bitmap->used_size= bitmap->total_size;
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_size);
res= pagecache_read(share->pagecache,
@@ -1036,7 +1094,12 @@ static my_bool _ma_change_bitmap_page(MARIA_HA *info,
{
DBUG_ENTER("_ma_change_bitmap_page");
- _ma_bitmap_mark_file_changed(info->s);
+ /*
+ We have to mark the file changed here, as otherwise the following
+ read/write to pagecache may force a page out from this file, which would
+ cause _ma_mark_file_changed() to be called with bitmaplock hold!
+ */
+ _ma_bitmap_mark_file_changed(info->s, 1);
if (bitmap->changed)
{
@@ -2978,6 +3041,11 @@ static my_bool _ma_bitmap_create_missing(MARIA_HA *info,
/* First (in offset order) bitmap page to create */
if (data_file_length < block_size)
goto err; /* corrupted, should have first bitmap page */
+ if (page * block_size >= share->base.max_data_file_length)
+ {
+ my_errno= HA_ERR_RECORD_FILE_FULL;
+ goto err;
+ }
from= (data_file_length / block_size - 1) / bitmap->pages_covered + 1;
from*= bitmap->pages_covered;
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 7127ec6348b..3a5bbd6c6f2 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -414,14 +414,29 @@ void _ma_init_block_record_data(void)
my_bool _ma_once_init_block_record(MARIA_SHARE *share, File data_file)
{
+ my_bool res;
+ pgcache_page_no_t last_page;
+
+ /*
+ First calculate the max file length with can have with a pointer of size
+ rec_reflength.
- share->base.max_data_file_length=
- (((ulonglong) 1 << ((share->base.rec_reflength-1)*8))-1) *
- share->block_size;
+ The 'rec_reflength - 1' is because one byte is used for row
+ position withing the page.
+ The /2 comes from _ma_transaction_recpos_to_keypos() where we use
+ the lowest bit to mark if there is a transid following the rownr.
+ */
+ last_page= ((ulonglong) 1 << ((share->base.rec_reflength-1)*8))/2;
+ if (!last_page) /* Overflow; set max size */
+ last_page= ~(pgcache_page_no_t) 0;
+
+ res= _ma_bitmap_init(share, data_file, &last_page);
+ share->base.max_data_file_length= _ma_safe_mul(last_page + 1,
+ share->block_size);
#if SIZEOF_OFF_T == 4
- set_if_smaller(share->base.max_data_file_length, INT_MAX32);
+ set_if_smaller(share->base.max_data_file_length, INT_MAX32);
#endif
- return _ma_bitmap_init(share, data_file);
+ return res;
}
@@ -5187,7 +5202,7 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info)
(uchar *) my_malloc(share->block_size * 2, MYF(MY_WME))))))
DBUG_RETURN(1);
info->scan.page_buff= info->scan.bitmap_buff + share->block_size;
- info->scan.bitmap_end= info->scan.bitmap_buff + share->bitmap.total_size;
+ info->scan.bitmap_end= info->scan.bitmap_buff + share->bitmap.max_total_size;
/* Set scan variables to get _ma_scan_block() to start with reading bitmap */
info->scan.number_of_rows= 0;
diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h
index 3201998e31c..2a323d16ffa 100644
--- a/storage/maria/ma_blockrec.h
+++ b/storage/maria/ma_blockrec.h
@@ -187,7 +187,8 @@ maria_page_get_lsn(uchar *page, pgcache_page_no_t page_no, uchar* data_ptr);
/* ma_bitmap.c */
extern const char *bits_to_txt[];
-my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
+my_bool _ma_bitmap_init(MARIA_SHARE *share, File file,
+ pgcache_page_no_t *last_page);
my_bool _ma_bitmap_end(MARIA_SHARE *share);
my_bool _ma_bitmap_flush(MARIA_SHARE *share);
my_bool _ma_bitmap_flush_all(MARIA_SHARE *share);
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 74067abf011..a845ff50c64 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -407,7 +407,7 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
size= my_seek(share->kfile.file, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
if ((skr=(my_off_t) share->state.state.key_file_length) != size)
{
- /* Don't give error if file generated by mariapack */
+ /* Don't give error if file generated by maria_pack */
if (skr > size && maria_is_any_key_active(share->state.key_map))
{
error=1;
@@ -421,13 +421,20 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
"Size of indexfile is: %-8s Expected: %s",
llstr(size,buff), llstr(skr,buff2));
}
- if (!(param->testflag & T_VERY_SILENT) &&
- ! (share->options & HA_OPTION_COMPRESS_RECORD) &&
- ulonglong2double(share->state.state.key_file_length) >
- ulonglong2double(share->base.margin_key_file_length)*0.9)
+ if (size > share->base.max_key_file_length)
+ {
+ _ma_check_print_warning(param,
+ "Size of indexfile is: %-8s which is bigger than max indexfile size: %s",
+ ullstr(size,buff),
+ ullstr(share->base.max_key_file_length, buff2));
+ }
+ else if (!(param->testflag & T_VERY_SILENT) &&
+ ! (share->options & HA_OPTION_COMPRESS_RECORD) &&
+ ulonglong2double(share->state.state.key_file_length) >
+ ulonglong2double(share->base.margin_key_file_length)*0.9)
_ma_check_print_warning(param,"Keyfile is almost full, %10s of %10s used",
llstr(share->state.state.key_file_length,buff),
- llstr(share->base.max_key_file_length-1,buff));
+ llstr(share->base.max_key_file_length,buff));
size= my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
skr=(my_off_t) share->state.state.data_file_length;
@@ -455,13 +462,19 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
llstr(size,buff), llstr(skr,buff2));
}
}
- if (!(param->testflag & T_VERY_SILENT) &&
- !(share->options & HA_OPTION_COMPRESS_RECORD) &&
- ulonglong2double(share->state.state.data_file_length) >
- (ulonglong2double(share->base.max_data_file_length)*0.9))
+ if (size > share->base.max_data_file_length)
+ {
+ _ma_check_print_warning(param,
+ "Size of datafile is: %-8s which is bigger than max datafile size: %s",
+ ullstr(size,buff),
+ ullstr(share->base.max_data_file_length, buff2));
+ } else if (!(param->testflag & T_VERY_SILENT) &&
+ !(share->options & HA_OPTION_COMPRESS_RECORD) &&
+ ulonglong2double(share->state.state.data_file_length) >
+ (ulonglong2double(share->base.max_data_file_length)*0.9))
_ma_check_print_warning(param, "Datafile is almost full, %10s of %10s used",
llstr(share->state.state.data_file_length,buff),
- llstr(share->base.max_data_file_length-1,buff2));
+ llstr(share->base.max_data_file_length,buff2));
DBUG_RETURN(error);
} /* maria_chk_size */
@@ -1975,8 +1988,8 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
data= bitmap_buff + offset_page / 8;
bitmap_pattern= uint2korr(data);
if (((bitmap_pattern >> offset)) ||
- (data + 2 < bitmap_buff + share->bitmap.total_size &&
- _ma_check_if_zero(data+2, bitmap_buff + share->bitmap.total_size -
+ (data + 2 < bitmap_buff + share->bitmap.max_total_size &&
+ _ma_check_if_zero(data+2, bitmap_buff + share->bitmap.max_total_size -
data - 2)))
{
ulonglong bitmap_page;
@@ -2084,23 +2097,23 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
llstr(share->state.state.records,llbuff2));
error=1;
}
- else if (param->record_checksum &&
+ if (param->record_checksum &&
param->record_checksum != param->tmp_record_checksum)
{
_ma_check_print_error(param,
"Key pointers and record positions doesn't match");
error=1;
}
- else if (param->glob_crc != share->state.state.checksum &&
- (share->options &
- (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
+ if (param->glob_crc != share->state.state.checksum &&
+ (share->options &
+ (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
{
_ma_check_print_warning(param,
"Record checksum is not the same as checksum "
"stored in the index file");
error=1;
}
- else if (!extend)
+ if (!extend)
{
uint key;
for (key=0 ; key < share->base.keys; key++)
@@ -5266,7 +5279,10 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
if ((sort_param->current_filepos=
(*share->write_record_init)(info, sort_param->record)) ==
HA_OFFSET_ERROR)
+ {
+ _ma_check_print_error(param, "%d when writing to datafile", my_errno);
DBUG_RETURN(1);
+ }
/* Pointer to end of file */
sort_param->filepos= share->state.state.data_file_length;
break;
@@ -5886,6 +5902,9 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
MARIA_CREATE_INFO create_info;
DBUG_ENTER("maria_recreate_table");
+ if ((!(param->testflag & T_SILENT)))
+ printf("Recreating table '%s'\n", param->isam_file_name);
+
error=1; /* Default error */
info= **org_info;
status_info= (*org_info)->state[0];
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index a9a32d71c8b..54ebcdc709e 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -320,7 +320,15 @@ int maria_create(const char *name, enum data_file_type datafile_type,
(~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength)
ci->data_file_length= ~(ulonglong) 0;
else
- ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength;
+ {
+ ci->data_file_length= _ma_safe_mul(ci->max_rows, pack_reclength);
+ if (datafile_type == BLOCK_RECORD)
+ {
+ /* Assume that blocks are only half full (very pessimistic!) */
+ ci->data_file_length= _ma_safe_mul(ci->data_file_length, 2);
+ set_if_bigger(ci->data_file_length, maria_block_size*2);
+ }
+ }
}
else if (!ci->max_rows)
{
@@ -332,7 +340,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
ulonglong data_file_length= ci->data_file_length;
if (!data_file_length)
data_file_length= ((((ulonglong) 1 << ((BLOCK_RECORD_POINTER_SIZE-1) *
- 8)) -1) * maria_block_size);
+ 8))/2 -1) * maria_block_size);
if (rows_per_page > 0)
{
set_if_smaller(rows_per_page, MAX_ROWS_PER_PAGE);
@@ -354,11 +362,11 @@ int maria_create(const char *name, enum data_file_type datafile_type,
{
/*
The + 1 is for record position withing page
- The / 2 is because we need one bit for knowing if there is transid's
+ The * 2 is because we need one bit for knowing if there is transid's
after the row pointer
*/
pointer= maria_get_pointer_length((ci->data_file_length /
- (maria_block_size * 2)), 3) + 1;
+ maria_block_size) * 2, 3) + 1;
set_if_smaller(pointer, BLOCK_RECORD_POINTER_SIZE);
if (!max_rows)
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index fc8edbe36e4..a01e0949b68 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -8157,6 +8157,7 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn)
before it's written to the log.
*/
share->id= id;
+ share->state.logrec_file_id= lsn;
}
pthread_mutex_unlock(&share->intern_lock);
return 0;
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 659e46e190c..92f50b0756c 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -502,7 +502,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_block_size,
+ _ma_safe_mul(share->base.block_size,
((ulonglong) 1 << (share->base.key_reflength*8))-1);
#if SIZEOF_OFF_T == 4
set_if_smaller(max_data_file_length, INT_MAX32);
@@ -815,7 +815,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->base.margin_key_file_length=(share->base.max_key_file_length -
(keys ? MARIA_INDEX_BLOCK_MARGIN *
share->block_size * keys : 0));
- share->block_size= share->base.block_size;
+
my_free(disk_cache, MYF(0));
_ma_setup_functions(share);
if ((*share->once_init)(share, info.dfile.file))
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 4043457be17..52a30dce235 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -1576,8 +1576,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
if (share->base.max_data_file_length != HA_OFFSET_ERROR ||
share->base.max_key_file_length != HA_OFFSET_ERROR)
printf("Max datafile length: %16s Max keyfile length: %18s\n",
- llstr(share->base.max_data_file_length-1,llbuff),
- llstr(share->base.max_key_file_length-1,llbuff2));
+ ullstr(share->base.max_data_file_length,llbuff),
+ ullstr(share->base.max_key_file_length,llbuff2));
}
}
printf("Block_size: %16d\n",(int) share->block_size);
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 6f45dce5971..8ac33c51cc1 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -126,6 +126,8 @@ typedef struct st_maria_state_info
increased.
*/
LSN skip_redo_lsn;
+ /* LSN when we wrote file id to the log */
+ LSN logrec_file_id;
/* the following isn't saved on disk */
uint state_diff_length; /* Should be 0 */
@@ -245,9 +247,10 @@ typedef struct st_maria_file_bitmap
{
uchar *map;
pgcache_page_no_t page; /* Page number for current bitmap */
- uint used_size; /* Size of bitmap head that is not 0 */
+ pgcache_page_no_t last_bitmap_page; /* Last possible bitmap page */
my_bool changed; /* 1 if page needs to be written */
my_bool changed_not_flushed; /* 1 if some bitmap is not flushed */
+ uint used_size; /* Size of bitmap head that is not 0 */
uint flush_all_requested; /**< If _ma_bitmap_flush_all waiting */
uint waiting_for_flush_all_requested; /* If someone is waiting for above */
uint non_flushable; /**< 0 if bitmap and log are in sync */
@@ -261,6 +264,8 @@ typedef struct st_maria_file_bitmap
/* Constants, allocated when initiating bitmaps */
uint sizes[8]; /* Size per bit combination */
uint total_size; /* Total usable size of bitmap page */
+ uint max_total_size; /* Max value for total_size */
+ uint last_total_size; /* Size of bitmap on last_bitmap_page */
uint block_size; /* Block size of file */
ulong pages_covered; /* Pages covered by bitmap + 1 */
DYNAMIC_ARRAY pinned_pages; /**< not-yet-flushable bitmap pages */