summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_base.h6
-rw-r--r--mysql-test/r/maria.result74
-rw-r--r--mysql-test/t/maria.test90
-rw-r--r--sql/ha_partition.cc20
-rw-r--r--sql/ha_partition.h2
-rw-r--r--sql/lock.cc4
-rw-r--r--sql/sql_table.cc7
-rw-r--r--storage/maria/ha_maria.cc14
-rw-r--r--storage/maria/ma_bitmap.c20
-rw-r--r--storage/maria/ma_blockrec.c96
-rw-r--r--storage/maria/ma_check.c7
-rw-r--r--storage/maria/ma_close.c3
-rw-r--r--storage/maria/ma_dynrec.c2
-rw-r--r--storage/maria/ma_extra.c7
-rw-r--r--storage/maria/ma_locking.c6
-rw-r--r--storage/maria/ma_open.c9
-rwxr-xr-xstorage/maria/ma_pagecache.c59
-rw-r--r--storage/maria/ma_recovery.c2
-rw-r--r--storage/maria/maria_def.h3
-rw-r--r--storage/myisam/mi_extra.c7
-rw-r--r--storage/myisammrg/ha_myisammrg.cc3
21 files changed, 332 insertions, 109 deletions
diff --git a/include/my_base.h b/include/my_base.h
index 57446e6136f..473ed46ff19 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -135,7 +135,7 @@ enum ha_extra_function {
HA_EXTRA_RESET_STATE, /* Reset positions */
HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/
HA_EXTRA_NO_IGNORE_DUP_KEY,
- HA_EXTRA_PREPARE_FOR_DELETE,
+ HA_EXTRA_PREPARE_FOR_DROP,
HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
HA_EXTRA_PRELOAD_BUFFER_SIZE, /* Set buffer size for preloading */
/*
@@ -185,7 +185,9 @@ enum ha_extra_function {
Inform handler that an "INSERT...ON DUPLICATE KEY UPDATE" will be
executed. This condition is unset by HA_EXTRA_NO_IGNORE_DUP_KEY.
*/
- HA_EXTRA_INSERT_WITH_UPDATE
+ HA_EXTRA_INSERT_WITH_UPDATE,
+ /* Inform handler that we will do a rename */
+ HA_EXTRA_PREPARE_FOR_RENAME
};
/* The following is parameter to ha_panic() */
diff --git a/mysql-test/r/maria.result b/mysql-test/r/maria.result
index 53063c9c7ab..68ae0cb267b 100644
--- a/mysql-test/r/maria.result
+++ b/mysql-test/r/maria.result
@@ -1598,6 +1598,9 @@ insert into t1 values (1),(2),(3),(4),(NULL),(NULL),(NULL),(NULL);
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Table is already up to date
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A 8 NULL NULL YES BTREE
@@ -1887,10 +1890,79 @@ t1_name varchar(255) default null,
t1_id int(10) unsigned not null auto_increment,
key (t1_name),
primary key (t1_id)
-) auto_increment = 1000 default charset=latin1;
+) engine=maria auto_increment = 1000 default charset=latin1;
lock tables t1 write;
INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002);
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
unlock tables;
+create table t2 like t1;
+insert into t2 select * from t1;
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+delete from t2;
+insert into t2 select * from t1;
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+drop table t1,t2;
+create table t1 (a bigint auto_increment, primary key(a), b char(255), c varchar(20000));
+update t1 set b=repeat('a',100) where a between 1 and 100;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+update t1 set c=repeat('a',8192*2) where a between 200 and 202;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+CREATE TABLE t1 (
+auto int(5) unsigned NOT NULL auto_increment,
+string char(10) default "hello",
+tiny tinyint(4) DEFAULT '0' NOT NULL ,
+short smallint(6) DEFAULT '1' NOT NULL ,
+medium mediumint(8) DEFAULT '0' NOT NULL,
+long_int int(11) DEFAULT '0' NOT NULL,
+longlong bigint(13) DEFAULT '0' NOT NULL,
+real_float float(13,1) DEFAULT 0.0 NOT NULL,
+real_double double(16,4),
+utiny tinyint(3) unsigned DEFAULT '0' NOT NULL,
+ushort smallint(5) unsigned zerofill DEFAULT '00000' NOT NULL,
+umedium mediumint(8) unsigned DEFAULT '0' NOT NULL,
+ulong int(11) unsigned DEFAULT '0' NOT NULL,
+ulonglong bigint(13) unsigned DEFAULT '0' NOT NULL,
+time_stamp timestamp,
+date_field date,
+time_field time,
+date_time datetime,
+blob_col blob,
+tinyblob_col tinyblob,
+mediumblob_col mediumblob not null default '',
+longblob_col longblob not null default '',
+options enum('one','two','tree') not null ,
+flags set('one','two','tree') not null default '',
+PRIMARY KEY (auto),
+KEY (utiny),
+KEY (tiny),
+KEY (short),
+KEY any_name (medium),
+KEY (longlong),
+KEY (real_float),
+KEY (ushort),
+KEY (umedium),
+KEY (ulong),
+KEY (ulonglong,ulong),
+KEY (options,flags)
+) engine=maria;
+insert into t1 values (10,1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one');
+create table t2 (primary key (auto)) engine=maria row_format=page select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1;
+check table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+select t1,t2,length(t3),length(t4),length(t5),length(t6),t7,t8 from t2;
+t1 t2 length(t3) length(t4) length(t5) length(t6) t7 t8
+1 a 256 256 4096 4096
+drop table t1,t2;
diff --git a/mysql-test/t/maria.test b/mysql-test/t/maria.test
index aca85b1442e..d45f4c2ec6b 100644
--- a/mysql-test/t/maria.test
+++ b/mysql-test/t/maria.test
@@ -711,6 +711,7 @@ analyze table t1;
show index from t1;
set maria_stats_method=DEFAULT;
+
drop table t1;
#
@@ -952,6 +953,7 @@ create table t1 (a int, key(a));
insert into t1 values (1),(2),(3),(4),(NULL),(NULL),(NULL),(NULL);
analyze table t1;
+analyze table t1;
show keys from t1;
alter table t1 disable keys;
@@ -1155,17 +1157,103 @@ drop table t1;
# CHECK TABLE was reporting
# "Size of datafile is: 0 Should be: 16384"
+#
+
create table `t1` (
t1_name varchar(255) default null,
t1_id int(10) unsigned not null auto_increment,
key (t1_name),
primary key (t1_id)
-) auto_increment = 1000 default charset=latin1;
+) engine=maria auto_increment = 1000 default charset=latin1;
lock tables t1 write;
INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002);
check table t1;
unlock tables;
+#
+# Check that an empty table uses fast recreate of index when we fill it
+# with insert ... select.
+
+create table t2 like t1;
+insert into t2 select * from t1;
+
+# This should say that the table is already up to date
+analyze table t2;
+delete from t2;
+insert into t2 select * from t1;
+analyze table t2;
+
+drop table t1,t2;
+
+#
+# Test when expanding a row so that it doesn't fit into the same page
+#
+
+create table t1 (a bigint auto_increment, primary key(a), b char(255), c varchar(20000));
+
+let $1=1000;
+--disable_query_log
+--disable_warnings
+while ($1)
+{
+ insert into t1 () values();
+ dec $1;
+}
+--enable_query_log
+update t1 set b=repeat('a',100) where a between 1 and 100;
+check table t1;
+update t1 set c=repeat('a',8192*2) where a between 200 and 202;
+check table t1;
+drop table t1;
+
+#
+# Test tail pages for blobs
+#
+
+CREATE TABLE t1 (
+ auto int(5) unsigned NOT NULL auto_increment,
+ string char(10) default "hello",
+ tiny tinyint(4) DEFAULT '0' NOT NULL ,
+ short smallint(6) DEFAULT '1' NOT NULL ,
+ medium mediumint(8) DEFAULT '0' NOT NULL,
+ long_int int(11) DEFAULT '0' NOT NULL,
+ longlong bigint(13) DEFAULT '0' NOT NULL,
+ real_float float(13,1) DEFAULT 0.0 NOT NULL,
+ real_double double(16,4),
+ utiny tinyint(3) unsigned DEFAULT '0' NOT NULL,
+ ushort smallint(5) unsigned zerofill DEFAULT '00000' NOT NULL,
+ umedium mediumint(8) unsigned DEFAULT '0' NOT NULL,
+ ulong int(11) unsigned DEFAULT '0' NOT NULL,
+ ulonglong bigint(13) unsigned DEFAULT '0' NOT NULL,
+ time_stamp timestamp,
+ date_field date,
+ time_field time,
+ date_time datetime,
+ blob_col blob,
+ tinyblob_col tinyblob,
+ mediumblob_col mediumblob not null default '',
+ longblob_col longblob not null default '',
+ options enum('one','two','tree') not null ,
+ flags set('one','two','tree') not null default '',
+ PRIMARY KEY (auto),
+ KEY (utiny),
+ KEY (tiny),
+ KEY (short),
+ KEY any_name (medium),
+ KEY (longlong),
+ KEY (real_float),
+ KEY (ushort),
+ KEY (umedium),
+ KEY (ulong),
+ KEY (ulonglong,ulong),
+ KEY (options,flags)
+) engine=maria;
+insert into t1 values (10,1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one');
+create table t2 (primary key (auto)) engine=maria row_format=page select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1;
+check table t1,t2;
+select t1,t2,length(t3),length(t4),length(t5),length(t6),t7,t8 from t2;
+drop table t1,t2;
+
# End of 5.2 tests
--disable_result_log
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index e4924e8e8f2..15d7353c03c 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -4621,11 +4621,14 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
about this call). We pass this along to all underlying MyISAM handlers
and ignore it for the rest.
- HA_EXTRA_PREPARE_FOR_DELETE:
+ HA_EXTRA_PREPARE_FOR_DROP:
Only used by MyISAM, called in preparation for a DROP TABLE.
It's used mostly by Windows that cannot handle dropping an open file.
On other platforms it has the same effect as HA_EXTRA_FORCE_REOPEN.
+ HA_EXTRA_PREPARE_FOR_RENAME:
+ Informs the handler we are about to attempt a rename of the table.
+
HA_EXTRA_READCHECK:
HA_EXTRA_NO_READCHECK:
Only one call to HA_EXTRA_NO_READCHECK from ha_open where it says that
@@ -4751,14 +4754,15 @@ int ha_partition::extra(enum ha_extra_function operation)
}
/* Category 3), used by MyISAM handlers */
- case HA_EXTRA_PREPARE_FOR_DELETE:
- DBUG_RETURN(prepare_for_delete());
+ case HA_EXTRA_PREPARE_FOR_RENAME:
+ DBUG_RETURN(prepare_for_rename());
break;
case HA_EXTRA_NORMAL:
case HA_EXTRA_QUICK:
case HA_EXTRA_NO_READCHECK:
case HA_EXTRA_PREPARE_FOR_UPDATE:
case HA_EXTRA_FORCE_REOPEN:
+ case HA_EXTRA_PREPARE_FOR_DROP:
case HA_EXTRA_FLUSH_CACHE:
{
if (m_myisam)
@@ -4910,24 +4914,24 @@ void ha_partition::prepare_extra_cache(uint cachesize)
0 Success
*/
-int ha_partition::prepare_for_delete()
+int ha_partition::prepare_for_rename()
{
int result= 0, tmp;
handler **file;
- DBUG_ENTER("ha_partition::prepare_for_delete()");
+ DBUG_ENTER("ha_partition::prepare_for_rename()");
if (m_new_file != NULL)
{
for (file= m_new_file; *file; file++)
- if ((tmp= (*file)->extra(HA_EXTRA_PREPARE_FOR_DELETE)))
+ if ((tmp= (*file)->extra(HA_EXTRA_PREPARE_FOR_RENAME)))
result= tmp;
for (file= m_reorged_file; *file; file++)
- if ((tmp= (*file)->extra(HA_EXTRA_PREPARE_FOR_DELETE)))
+ if ((tmp= (*file)->extra(HA_EXTRA_PREPARE_FOR_RENAME)))
result= tmp;
DBUG_RETURN(result);
}
- DBUG_RETURN(loop_extra(HA_EXTRA_PREPARE_FOR_DELETE));
+ DBUG_RETURN(loop_extra(HA_EXTRA_PREPARE_FOR_RENAME));
}
/*
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 895f001fa6a..bc4747be85b 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -211,7 +211,7 @@ public:
}
virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
private:
- int prepare_for_delete();
+ int prepare_for_rename();
int copy_partitions(ulonglong *copied, ulonglong *deleted);
void cleanup_new_partition(uint part_count);
int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info,
diff --git a/sql/lock.cc b/sql/lock.cc
index e129da27005..12b69edc3d3 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -31,8 +31,8 @@
This is followed by a call to thr_multi_lock() for all tables.
- When statement is done, we call mysql_unlock_tables().
- This will call thr_multi_unlock() followed by
- table_handler->external_lock(thd, F_UNLCK) for each table.
+ table_handler->external_lock(thd, F_UNLCK) followed by
+ thr_multi_unlock() for each table.
- Note that mysql_unlock_tables() may be called several times as
MySQL in some cases can free some tables earlier than others.
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 6fc1c235ebf..158f415317c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3694,8 +3694,9 @@ mysql_rename_table(handlerton *base, const char *old_db,
wait_while_table_is_used()
thd Thread handler
table Table to remove from cache
- function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
+ function HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
HA_EXTRA_FORCE_REOPEN if table is not be used
+ HA_EXTRA_PREPARE_FOR_REANME if table is to be renamed
NOTES
When returning, the table will be unusable for other threads until
the table is closed.
@@ -3745,7 +3746,7 @@ void close_cached_table(THD *thd, TABLE *table)
{
DBUG_ENTER("close_cached_table");
- wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE);
+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
/* Close lock if this is not got with LOCK TABLES */
if (thd->lock)
{
@@ -6532,7 +6533,7 @@ view_err:
if (lower_case_table_names)
my_casedn_str(files_charset_info, old_name);
- wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE);
+ wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
close_data_files_and_morph_locks(thd, db, table_name);
error=0;
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index c2fa0ec14b1..55ce800d596 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -1324,7 +1324,10 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
}
thd->proc_info= old_proc_info;
if (!thd->locked_tables)
+ {
+ _ma_reenable_logging_for_table(file->s);
maria_lock_database(file, F_UNLCK);
+ }
DBUG_RETURN(error ? HA_ADMIN_FAILED :
!optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
}
@@ -1624,10 +1627,8 @@ void ha_maria::start_bulk_insert(ha_rows rows)
if (!rows || (rows > MARIA_MIN_ROWS_TO_USE_WRITE_CACHE))
maria_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size);
- can_enable_indexes= maria_is_all_keys_active(file->s->state.key_map,
- file->s->base.keys);
- /* TODO: Remove when we have repair() working */
- can_enable_indexes= 0;
+ can_enable_indexes= (maria_is_all_keys_active(file->s->state.key_map,
+ file->s->base.keys));
if (!(specialflag & SPECIAL_SAFE_MODE))
{
@@ -1640,9 +1641,8 @@ void ha_maria::start_bulk_insert(ha_rows rows)
if (file->state->records == 0 && can_enable_indexes &&
(!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES))
maria_disable_non_unique_index(file, rows);
- else
- if (!file->bulk_insert &&
- (!rows || rows >= MARIA_MIN_ROWS_TO_USE_BULK_INSERT))
+ else if (!file->bulk_insert &&
+ (!rows || rows >= MARIA_MIN_ROWS_TO_USE_BULK_INSERT))
{
maria_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows);
}
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index 66377172877..2a2308637b6 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -451,6 +451,10 @@ static void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap)
fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n",
(ulong) bitmap->page);
+ DBUG_ASSERT(memcmp(bitmap->map + bitmap->block_size -
+ sizeof(maria_bitmap_marker),
+ maria_bitmap_marker, sizeof(maria_bitmap_marker)) == 0);
+
page= (ulong) bitmap->page+1;
for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ;
pos < end ;
@@ -536,14 +540,14 @@ static my_bool _ma_read_bitmap_page(MARIA_SHARE *share,
}
bitmap->used_size= bitmap->total_size;
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_size);
- res= (pagecache_read(share->pagecache,
+ res= ((pagecache_read(share->pagecache,
(PAGECACHE_FILE*)&bitmap->file, page, 0,
(uchar*) bitmap->map,
PAGECACHE_PLAIN_PAGE,
- PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL) |
- memcmp(bitmap->map + bitmap->block_size -
- sizeof(maria_bitmap_marker),
- maria_bitmap_marker, sizeof(maria_bitmap_marker));
+ PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL) ||
+ memcmp(bitmap->map + bitmap->block_size -
+ sizeof(maria_bitmap_marker),
+ maria_bitmap_marker, sizeof(maria_bitmap_marker)));
#ifndef DBUG_OFF
if (!res)
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
@@ -1838,11 +1842,15 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
/* Handle all full pages and tail pages (for head page and blob) */
for (block++; block < end; block++)
{
+ uint page_count;
if (!block->page_count)
continue; /* Skip 'filler blocks' */
+ page_count= block->page_count;
if (block->used & BLOCKUSED_TAIL)
{
+ /* The bitmap page is only one page */
+ page_count= 1;
if (block->used & BLOCKUSED_USED)
{
DBUG_PRINT("info", ("tail empty_space: %u", block->empty_space));
@@ -1861,7 +1869,7 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
}
if (!(block->used & BLOCKUSED_USED) &&
_ma_reset_full_page_bits(info, bitmap,
- block->page, block->page_count))
+ block->page, page_count))
goto err;
}
pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 555949dfa84..7f29f075463 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -288,8 +288,10 @@ typedef struct st_maria_extent_cursor
uint extent_count;
/* <> 0 if current extent is a tail page; Set while using cursor */
uint tail;
+ /* Position for tail on tail page */
+ uint tail_row_nr;
/*
- <> 1 if we are working on the first extent (i.e., the one that is store in
+ == 1 if we are working on the first extent (i.e., the one that is stored in
the row header, not an extent that is stored as part of the row data).
*/
my_bool first_extent;
@@ -299,7 +301,7 @@ typedef struct st_maria_extent_cursor
static my_bool delete_tails(MARIA_HA *info, MARIA_RECORD_POS *tails);
static my_bool delete_head_or_tail(MARIA_HA *info,
ulonglong page, uint record_number,
- my_bool head);
+ my_bool head, my_bool from_update);
static void _ma_print_directory(uchar *buff, uint block_size);
static void compact_page(uchar *buff, uint block_size, uint rownr,
my_bool extend_block);
@@ -461,7 +463,7 @@ my_bool _ma_init_block_record(MARIA_HA *info)
/* The following should be big enough for all purposes */
if (my_init_dynamic_array(&info->pinned_pages,
sizeof(MARIA_PINNED_PAGE),
- max(info->s->base.blobs + 2,
+ max(info->s->base.blobs*2 + 4,
MARIA_MAX_TREE_LEVELS*2), 16))
goto err;
row->base_length= new_row->base_length= info->s->base_length;
@@ -840,6 +842,7 @@ static void calc_record_size(MARIA_HA *info, const uchar *record,
MARIA_COLUMNDEF *column, *end_column;
uint *null_field_lengths= row->null_field_lengths;
ulong *blob_lengths= row->blob_lengths;
+ DBUG_ENTER("calc_record_size");
row->normal_length= row->char_length= row->varchar_length=
row->blob_length= row->extents_count= 0;
@@ -968,6 +971,9 @@ static void calc_record_size(MARIA_HA *info, const uchar *record,
row->total_length= (row->head_length + row->blob_length);
if (row->total_length < share->base.min_row_length)
row->total_length= share->base.min_row_length;
+ DBUG_PRINT("exit", ("head_length: %lu total_length: %lu",
+ (ulong) row->head_length, (ulong) row->total_length));
+ DBUG_VOID_RETURN;
}
@@ -1395,6 +1401,7 @@ static my_bool write_full_pages(MARIA_HA *info,
DBUG_PRINT("enter", ("length: %lu page: %lu page_count: %lu",
(ulong) length, (ulong) block->page,
(ulong) block->page_count));
+ DBUG_ASSERT((block->page_count & TAIL_BIT) == 0);
info->keyread_buff_used= 1;
page= block->page;
@@ -1938,13 +1945,10 @@ static my_bool write_block_record(MARIA_HA *info,
ulong length;
ulong data_length= (tmp_data - info->rec_buff);
-#ifdef MONTY_WILL_KNOW
#ifdef SANITY_CHECKS
- if (cur_block->sub_blocks == 1)
+ if (head_block->sub_blocks == 1)
goto crashed; /* no reserved full or tails */
#endif
-#endif
-
/*
Find out where to write tail for non-blob fields.
@@ -2073,6 +2077,11 @@ static my_bool write_block_record(MARIA_HA *info,
length))
goto disk_err;
tmp_data-= length; /* Remove the tail */
+ if (tmp_data == info->rec_buff)
+ {
+ /* We have no full blocks to write for the head part */
+ tmp_data_used= 0;
+ }
/* Store the tail position for the non-blob fields */
if (head_tail_block == head_block + 1)
@@ -2319,8 +2328,8 @@ static my_bool write_block_record(MARIA_HA *info,
if (block[block->sub_blocks - 1].used & BLOCKUSED_TAIL)
blob_length-= (blob_length % FULL_PAGE_SIZE(block_size));
- if (write_full_pages(info, info->trn->undo_lsn, block,
- blob_pos, blob_length))
+ if (blob_length && write_full_pages(info, info->trn->undo_lsn, block,
+ blob_pos, blob_length))
goto disk_err;
block+= block->sub_blocks;
}
@@ -2356,8 +2365,11 @@ disk_err:
@todo RECOVERY we should distinguish below between log write error and
table write error. The former should stop Maria immediately, the latter
should mark the table corrupted.
- */
- /* Unpin all pinned pages to not cause problems for disk cache */
+ */
+ /*
+ Unpin all pinned pages to not cause problems for disk cache. This is
+ safe to call even if we already called _ma_unpin_all_pages() above.
+ */
_ma_unpin_all_pages(info, 0);
DBUG_RETURN(1);
@@ -2445,7 +2457,8 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
if (delete_head_or_tail(info,
ma_recordpos_to_page(info->cur_row.lastpos),
- ma_recordpos_to_dir_entry(info->cur_row.lastpos), 1))
+ ma_recordpos_to_dir_entry(info->cur_row.lastpos), 1,
+ 0))
res= 1;
for (block= blocks->block + 1, end= block + blocks->count - 1; block < end;
block++)
@@ -2457,7 +2470,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
write_block_record()
*/
if (delete_head_or_tail(info, block->page, block->page_count & ~TAIL_BIT,
- 0))
+ 0, 0))
res= 1;
}
else if (block->used & BLOCKUSED_USED)
@@ -2533,7 +2546,6 @@ my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos,
ulonglong page;
struct st_row_pos_info row_pos;
MARIA_SHARE *share= info->s;
- my_bool res;
DBUG_ENTER("_ma_update_block_record");
DBUG_PRINT("enter", ("rowid: %lu", (long) record_pos));
@@ -2621,8 +2633,8 @@ my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos,
row_pos.dir= dir;
row_pos.data= buff + uint2korr(dir);
row_pos.length= head_length;
- res= write_block_record(info, oldrec, record, new_row, blocks, 1, &row_pos);
- DBUG_RETURN(res);
+ DBUG_RETURN(write_block_record(info, oldrec, record, new_row, blocks, 1,
+ &row_pos));
err:
_ma_unpin_all_pages(info, 0);
@@ -2710,6 +2722,9 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
info Maria handler
page Page (not file offset!) on which the row is
head 1 if this is a head page
+ from_update 1 if we are called from update. In this case we
+ leave the page as write locked as we may put
+ the new row into the old position.
NOTES
Uses info->keyread_buff
@@ -2721,7 +2736,7 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
static my_bool delete_head_or_tail(MARIA_HA *info,
ulonglong page, uint record_number,
- my_bool head)
+ my_bool head, my_bool from_update)
{
MARIA_SHARE *share= info->s;
uint empty_space;
@@ -2730,6 +2745,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
LSN lsn;
MARIA_PINNED_PAGE page_link;
int res;
+ enum pagecache_page_lock lock_at_write, lock_at_unpin;
DBUG_ENTER("delete_head_or_tail");
info->keyread_buff_used= 1;
@@ -2743,6 +2759,17 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
push_dynamic(&info->pinned_pages, (void*) &page_link);
+ if (from_update)
+ {
+ lock_at_write= PAGECACHE_LOCK_LEFT_WRITELOCKED;
+ lock_at_unpin= PAGECACHE_LOCK_WRITE_UNLOCK;
+ }
+ else
+ {
+ lock_at_write= PAGECACHE_LOCK_WRITE_TO_READ;
+ lock_at_unpin= PAGECACHE_LOCK_READ_UNLOCK;
+ }
+
res= delete_dir_entry(buff, block_size, record_number, &empty_space);
if (res < 0)
DBUG_RETURN(1);
@@ -2769,7 +2796,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
if (pagecache_write(share->pagecache,
&info->dfile, page, 0,
buff, share->page_type,
- PAGECACHE_LOCK_WRITE_TO_READ,
+ lock_at_write,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_WRITE_DELAY, &page_link.link))
DBUG_RETURN(1);
@@ -2797,15 +2824,15 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
if (pagecache_write(share->pagecache,
&info->dfile, page, 0,
buff, share->page_type,
- PAGECACHE_LOCK_WRITE_TO_READ,
+ lock_at_write,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_WRITE_DELAY, &page_link.link))
DBUG_RETURN(1);
DBUG_ASSERT(empty_space >= info->s->bitmap.sizes[0]);
}
- /* Change the lock used when we read the page */
- page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK;
+ /* The page is pinned with a read lock */
+ page_link.unlock= lock_at_unpin;
set_dynamic(&info->pinned_pages, (void*) &page_link,
info->pinned_pages.elements-1);
@@ -2838,7 +2865,7 @@ static my_bool delete_tails(MARIA_HA *info, MARIA_RECORD_POS *tails)
{
if (delete_head_or_tail(info,
ma_recordpos_to_page(*tails),
- ma_recordpos_to_dir_entry(*tails), 0))
+ ma_recordpos_to_dir_entry(*tails), 0, 1))
res= 1;
}
DBUG_RETURN(res);
@@ -2863,7 +2890,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record)
page= ma_recordpos_to_page(info->cur_row.lastpos);
record_number= ma_recordpos_to_dir_entry(info->cur_row.lastpos);
- if (delete_head_or_tail(info, page, record_number, 1) ||
+ if (delete_head_or_tail(info, page, record_number, 1, 0) ||
delete_tails(info, info->cur_row.tail_positions))
goto err;
@@ -2987,8 +3014,14 @@ static void init_extent(MARIA_EXTENT_CURSOR *extent, uchar *extent_info,
extent->extent_count= extents;
extent->page= page_korr(extent_info); /* First extent */
page_count= uint2korr(extent_info + ROW_EXTENT_PAGE_SIZE);
- extent->page_count= page_count & ~TAIL_BIT;
extent->tail= page_count & TAIL_BIT;
+ if (extent->tail)
+ {
+ extent->page_count= 1;
+ extent->tail_row_nr= page_count & ~TAIL_BIT;
+ }
+ else
+ extent->page_count= page_count;
extent->tail_positions= tail_positions;
}
@@ -3030,12 +3063,15 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
if (!page_count)
goto crashed;
extent->tail= page_count & TAIL_BIT;
- extent->page_count= (page_count & ~TAIL_BIT);
- extent->first_extent= 0;
+ if (extent->tail)
+ extent->tail_row_nr= page_count & ~TAIL_BIT;
+ else
+ extent->page_count= page_count;
DBUG_PRINT("info",("New extent. Page: %lu page_count: %u tail_flag: %d",
(ulong) extent->page, extent->page_count,
extent->tail != 0));
}
+ extent->first_extent= 0;
DBUG_ASSERT(share->pagecache->block_size == share->block_size);
if (!(buff= pagecache_read(share->pagecache,
@@ -3059,16 +3095,16 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
info->cur_row.full_page_count++; /* For maria_chk */
DBUG_RETURN(extent->data_start= buff + LSN_SIZE + PAGE_TYPE_SIZE);
}
- /* Found tail. page_count is in this case the position in the tail page */
+ /* Found tail */
if ((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != TAIL_PAGE)
goto crashed;
*(extent->tail_positions++)= ma_recordpos(extent->page,
- extent->page_count);
+ extent->tail_row_nr);
info->cur_row.tail_count++; /* For maria_chk */
if (!(data= get_record_position(buff, share->block_size,
- extent->page_count,
+ extent->tail_row_nr,
end_of_data)))
goto crashed;
extent->data_start= data;
@@ -3124,7 +3160,7 @@ static my_bool read_long_data(MARIA_HA *info, uchar *to, ulong length,
This may change in the future, which is why we have the loop written
the way it's written.
*/
- if (length > (ulong) (*end_of_data - *data))
+ if (extent->first_extent && length > (ulong) (*end_of_data - *data))
*end_of_data= *data;
for(;;)
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 1ac1fb3454f..a5e64cb555c 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -1706,8 +1706,13 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
full_dir ? 0 : empty_space,
&bitmap_pattern))
{
+ if (bitmap_pattern == ~(uint) 0)
+ _ma_check_print_error(param,
+ "Page: %9s: Wrong bitmap for data on page",
+ llstr(pos, llbuff));
+ else
_ma_check_print_error(param,
- "Page %9s: Wrong data in bitmap. Page_type: %d empty_space: %u Bitmap: %d",
+ "Page %9s: Wrong data in bitmap. Page_type: %d empty_space: %u Bitmap-bits: %d",
llstr(pos, llbuff), page_type, empty_space,
bitmap_pattern);
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index a9d31a6c75f..cc9f0005a4d 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -65,6 +65,7 @@ int maria_close(register MARIA_HA *info)
if (flag)
{
+ /* Last close of file; Flush everything */
if (share->kfile.file >= 0)
{
if ((*share->once_end)(share))
@@ -87,7 +88,7 @@ int maria_close(register MARIA_HA *info)
may be using the file at this point
IF using --external-locking, which does not apply to Maria.
*/
- if (share->mode != O_RDONLY)
+ if (share->changed)
_ma_state_info_write(share->kfile.file, &share->state, 1);
if (my_close(share->kfile.file, MYF(0)))
error= my_errno;
diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c
index 246f9787b09..52ade04db98 100644
--- a/storage/maria/ma_dynrec.c
+++ b/storage/maria/ma_dynrec.c
@@ -1694,7 +1694,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info,
{ /* Check if changed */
info_read=1;
info->rec_cache.seek_not_done=1;
- if (_ma_state_info_read_dsk(share->kfile.file, &share->state, 1))
+ if (_ma_state_info_read_dsk(share->kfile.file, &share->state))
goto panic;
}
if (filepos >= info->state->data_file_length)
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index 0ee5990844b..a3fb9569290 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -264,8 +264,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
share->last_version= 0L; /* Impossible version */
pthread_mutex_unlock(&THR_LOCK_maria);
break;
- case HA_EXTRA_PREPARE_FOR_DELETE:
- /* QQ: suggest to rename it to "PREPARE_FOR_DROP" */
+ case HA_EXTRA_PREPARE_FOR_DROP:
+ case HA_EXTRA_PREPARE_FOR_RENAME:
pthread_mutex_lock(&THR_LOCK_maria);
share->last_version= 0L; /* Impossible version */
#ifdef __WIN__
@@ -284,7 +284,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
Does ENABLE KEYS rebuild them too?
*/
if (flush_pagecache_blocks(share->pagecache, &share->kfile,
- FLUSH_IGNORE_CHANGED))
+ (function == HA_EXTRA_PREPARE_FOR_DROP ?
+ FLUSH_IGNORE_CHANGED : FLUSH_RELEASE)))
{
error=my_errno;
share->changed=1;
diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c
index f709d7e5759..dad4071edf8 100644
--- a/storage/maria/ma_locking.c
+++ b/storage/maria/ma_locking.c
@@ -153,7 +153,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type)
}
if (!share->r_locks && !share->w_locks)
{
- if (_ma_state_info_read_dsk(share->kfile.file, &share->state, 1))
+ if (_ma_state_info_read_dsk(share->kfile.file, &share->state))
{
error=my_errno;
break;
@@ -181,7 +181,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type)
{
if (!share->r_locks)
{
- if (_ma_state_info_read_dsk(share->kfile.file, &share->state, 1))
+ if (_ma_state_info_read_dsk(share->kfile.file, &share->state))
{
error=my_errno;
break;
@@ -364,7 +364,7 @@ int _ma_readinfo(register MARIA_HA *info, int lock_type, int check_keybuffer)
MARIA_SHARE *share=info->s;
if (!share->tot_locks)
{
- if (_ma_state_info_read_dsk(share->kfile.file, &share->state, 1))
+ if (_ma_state_info_read_dsk(share->kfile.file, &share->state))
{
int error=my_errno ? my_errno : -1;
my_errno=error;
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 6cdfadf5d6d..4c623ac56f3 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -1110,18 +1110,13 @@ uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
@param pRead if true, use my_pread(), otherwise my_read()
*/
-uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state, my_bool pRead)
+uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state)
{
char buff[MARIA_STATE_INFO_SIZE + MARIA_STATE_EXTRA_SIZE];
if (!maria_single_user)
{
- if (pRead)
- {
- if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
- return 1;
- }
- else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
+ if (my_pread(file, buff, state->state_length, 0L, MYF(MY_NABP)))
return 1;
_ma_state_info_read(buff, state);
}
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index eb1d1ad9b0a..735f1aeb504 100755
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -300,23 +300,24 @@ struct st_pagecache_block_link
*next_changed, **prev_changed; /* for lists of file dirty/clean blocks */
struct st_pagecache_hash_link
*hash_link; /* backward ptr to referring hash_link */
+#ifndef DBUG_OFF
+ PAGECACHE_PIN_INFO *pin_list;
+ PAGECACHE_LOCK_INFO *lock_list;
+#endif
+ KEYCACHE_CONDVAR *condvar; /* condition variable for 'no readers' event */
+ uchar *buffer; /* buffer for the block page */
+ PAGECACHE_FILE *write_locker;
+ 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 */
- uchar *buffer; /* buffer for the block page */
uint status; /* state of the block */
uint pins; /* pin counter */
-#ifndef DBUG_OFF
- PAGECACHE_PIN_INFO *pin_list;
- PAGECACHE_LOCK_INFO *lock_list;
-#endif
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 */
- ulonglong last_hit_time; /* timestamp of the last hit */
/** @brief LSN when first became dirty; LSN_MAX means "not yet set" */
LSN rec_lsn;
- KEYCACHE_CONDVAR *condvar; /* condition variable for 'no readers' event */
};
#ifndef DBUG_OFF
@@ -2147,6 +2148,9 @@ static void info_change_lock(PAGECACHE_BLOCK_LINK *block, my_bool wl)
get_wrlock()
pagecache pointer to a page cache data structure
block the block to work with
+ user_file Unique handler per handler file. Used to check if
+ we request many write locks withing the same
+ statement
RETURN
0 - OK
@@ -2154,7 +2158,8 @@ static void info_change_lock(PAGECACHE_BLOCK_LINK *block, my_bool wl)
*/
static my_bool get_wrlock(PAGECACHE *pagecache,
- PAGECACHE_BLOCK_LINK *block)
+ PAGECACHE_BLOCK_LINK *block,
+ PAGECACHE_FILE *user_file)
{
PAGECACHE_FILE file= block->hash_link->file;
pgcache_page_no_t pageno= block->hash_link->pageno;
@@ -2165,7 +2170,7 @@ static my_bool get_wrlock(PAGECACHE *pagecache,
file.file, block->hash_link->file.file,
pageno, block->hash_link->pageno));
PCBLOCK_INFO(block);
- while (block->status & PCBLOCK_WRLOCK)
+ while ((block->status & PCBLOCK_WRLOCK) && block->write_locker != user_file)
{
/* Lock failed we will wait */
#ifdef THREAD
@@ -2197,9 +2202,9 @@ static my_bool get_wrlock(PAGECACHE *pagecache,
DBUG_RETURN(1);
}
}
- DBUG_ASSERT(block->pins == 0);
/* we are doing it by global cache mutex protection, so it is OK */
block->status|= PCBLOCK_WRLOCK;
+ block->write_locker= user_file;
DBUG_PRINT("info", ("WR lock set, block 0x%lx", (ulong)block));
DBUG_RETURN(0);
}
@@ -2223,6 +2228,8 @@ static void release_wrlock(PAGECACHE_BLOCK_LINK *block)
PCBLOCK_INFO(block);
DBUG_ASSERT(block->status & PCBLOCK_WRLOCK);
DBUG_ASSERT(block->pins > 0);
+ if (block->pins > 1)
+ DBUG_VOID_RETURN; /* Multiple write locked */
block->status&= ~PCBLOCK_WRLOCK;
DBUG_PRINT("info", ("WR lock reset, block 0x%lx", (ulong)block));
#ifdef THREAD
@@ -2244,6 +2251,7 @@ static void release_wrlock(PAGECACHE_BLOCK_LINK *block)
block the block to work with
lock lock change mode
pin pinchange mode
+ file File handler requesting pin
RETURN
0 - OK
@@ -2253,7 +2261,8 @@ static void release_wrlock(PAGECACHE_BLOCK_LINK *block)
static my_bool make_lock_and_pin(PAGECACHE *pagecache,
PAGECACHE_BLOCK_LINK *block,
enum pagecache_page_lock lock,
- enum pagecache_page_pin pin)
+ enum pagecache_page_pin pin,
+ PAGECACHE_FILE *file)
{
DBUG_ENTER("make_lock_and_pin");
@@ -2274,7 +2283,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
switch (lock) {
case PAGECACHE_LOCK_WRITE: /* free -> write */
/* Writelock and pin the buffer */
- if (get_wrlock(pagecache, block))
+ if (get_wrlock(pagecache, block, file))
{
/* can't lock => need retry */
goto retry;
@@ -2291,6 +2300,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
implementation)
*/
release_wrlock(block);
+ /* fall through */
case PAGECACHE_LOCK_READ_UNLOCK: /* read -> free */
case PAGECACHE_LOCK_LEFT_READLOCKED: /* read -> read */
if (pin == PAGECACHE_UNPIN)
@@ -2549,7 +2559,7 @@ void pagecache_unlock(PAGECACHE *pagecache,
if (lsn != LSN_IMPOSSIBLE)
check_and_set_lsn(pagecache, lsn, block);
- if (make_lock_and_pin(pagecache, block, lock, pin))
+ if (make_lock_and_pin(pagecache, block, lock, pin, file))
{
DBUG_ASSERT(0); /* should not happend */
}
@@ -2617,7 +2627,7 @@ void pagecache_unpin(PAGECACHE *pagecache,
*/
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_LEFT_READLOCKED,
- PAGECACHE_UNPIN))
+ PAGECACHE_UNPIN, file))
DBUG_ASSERT(0); /* should not happend */
remove_reader(block);
@@ -2678,7 +2688,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
lock == PAGECACHE_LOCK_READ_UNLOCK)
{
/* block do not need here so we do not provide it */
- if (make_lock_and_pin(pagecache, 0, lock, pin))
+ if (make_lock_and_pin(pagecache, 0, lock, pin, 0))
DBUG_ASSERT(0); /* should not happend */
DBUG_VOID_RETURN;
}
@@ -2710,7 +2720,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
if (lsn != LSN_IMPOSSIBLE)
check_and_set_lsn(pagecache, lsn, block);
- if (make_lock_and_pin(pagecache, block, lock, pin))
+ if (make_lock_and_pin(pagecache, block, lock, pin, 0))
DBUG_ASSERT(0); /* should not happend */
/*
@@ -2772,7 +2782,7 @@ void pagecache_unpin_by_link(PAGECACHE *pagecache,
*/
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_LEFT_READLOCKED,
- PAGECACHE_UNPIN))
+ PAGECACHE_UNPIN, 0))
DBUG_ASSERT(0); /* should not happend */
/*
@@ -2889,7 +2899,7 @@ restart:
validator, validator_data);
DBUG_PRINT("info", ("read is done"));
}
- if (make_lock_and_pin(pagecache, block, lock, pin))
+ if (make_lock_and_pin(pagecache, block, lock, pin, file))
{
/*
We failed to write lock the block, cache is unlocked,
@@ -3009,7 +3019,7 @@ restart:
if (pin == PAGECACHE_PIN)
reg_requests(pagecache, block, 1);
DBUG_ASSERT(block != 0);
- if (make_lock_and_pin(pagecache, block, lock, pin))
+ if (make_lock_and_pin(pagecache, block, lock, pin, file))
{
/*
We failed to writelock the block, cache is unlocked, and last write
@@ -3059,7 +3069,7 @@ restart:
/* Cache is locked, so we can relese page before freeing it */
make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK,
- PAGECACHE_UNPIN);
+ PAGECACHE_UNPIN, file);
DBUG_ASSERT(link->requests > 0);
link->requests--;
/* See NOTE for pagecache_unlock about registering requests. */
@@ -3254,7 +3264,7 @@ restart:
write_lock_change_table[lock].new_lock,
(need_lock_change ?
write_pin_change_table[pin].new_pin :
- pin)))
+ pin), file))
{
/*
We failed to writelock the block, cache is unlocked, and last write
@@ -3307,7 +3317,6 @@ restart:
}
}
-
if (need_lock_change)
{
/*
@@ -3316,7 +3325,7 @@ restart:
*/
if (make_lock_and_pin(pagecache, block,
write_lock_change_table[lock].unlock_lock,
- write_pin_change_table[pin].unlock_pin))
+ write_pin_change_table[pin].unlock_pin, file))
DBUG_ASSERT(0);
}
@@ -3474,7 +3483,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
DBUG_ASSERT((block->status & PCBLOCK_WRLOCK) == 0);
DBUG_ASSERT(block->pins == 0);
if (make_lock_and_pin(pagecache, block,
- PAGECACHE_LOCK_WRITE, PAGECACHE_PIN))
+ PAGECACHE_LOCK_WRITE, PAGECACHE_PIN, 0))
DBUG_ASSERT(0);
KEYCACHE_DBUG_PRINT("flush_cached_blocks",
@@ -3497,7 +3506,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK,
- PAGECACHE_UNPIN);
+ PAGECACHE_UNPIN, 0);
pagecache->global_cache_write++;
if (error)
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index b45346725e6..d5d758da4d6 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -507,7 +507,7 @@ prototype_exec_hook(REDO_DROP_TABLE)
this table should not be used anymore, and (only on Windows) to close
open files so they can be deleted
*/
- if (maria_extra(info, HA_EXTRA_PREPARE_FOR_DELETE, NULL) ||
+ if (maria_extra(info, HA_EXTRA_PREPARE_FOR_DROP, NULL) ||
maria_close(info))
goto end;
info= NULL;
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index ab2546b72f3..f5e143fe6f8 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -864,8 +864,7 @@ extern uint _ma_nommap_pwrite(MARIA_HA *info, uchar *Buffer,
uint _ma_state_info_write(File file, MARIA_STATE_INFO *state, uint pWrite);
uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state);
-uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state,
- my_bool pRead);
+uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state);
uint _ma_base_info_write(File file, MARIA_BASE_INFO *base);
int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg);
char *_ma_keyseg_read(char *ptr, HA_KEYSEG *keyseg);
diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c
index 72c40741a22..f425d41a27e 100644
--- a/storage/myisam/mi_extra.c
+++ b/storage/myisam/mi_extra.c
@@ -255,15 +255,16 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
share->last_version= 0L; /* Impossible version */
pthread_mutex_unlock(&THR_LOCK_myisam);
break;
- case HA_EXTRA_PREPARE_FOR_DELETE:
+ case HA_EXTRA_PREPARE_FOR_RENAME:
+ case HA_EXTRA_PREPARE_FOR_DROP:
pthread_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */
#ifdef __WIN__
/* Close the isam and data files as Win32 can't drop an open table */
pthread_mutex_lock(&share->intern_lock);
if (flush_key_blocks(share->key_cache, share->kfile,
- (function == HA_EXTRA_FORCE_REOPEN ?
- FLUSH_RELEASE : FLUSH_IGNORE_CHANGED)))
+ (function == HA_EXTRA_PREPARE_FOR_DROP ?
+ FLUSH_IGNORE_CHANGED : FLUSH_RELEASE)))
{
error=my_errno;
share->changed=1;
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index f3df1e82c4b..601c2479473 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -392,7 +392,8 @@ int ha_myisammrg::extra(enum ha_extra_function operation)
/* As this is just a mapping, we don't have to force the underlying
tables to be closed */
if (operation == HA_EXTRA_FORCE_REOPEN ||
- operation == HA_EXTRA_PREPARE_FOR_DELETE)
+ operation == HA_EXTRA_PREPARE_FOR_DROP ||
+ operation == HA_EXTRA_PREPARE_FOR_RENAME)
return 0;
return myrg_extra(file,operation,0);
}