Commit 572ce24f authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-maria

into  mysql.com:/home/my/mysql-maria

parents 0a2220b6 5183a4b0
...@@ -135,7 +135,7 @@ enum ha_extra_function { ...@@ -135,7 +135,7 @@ enum ha_extra_function {
HA_EXTRA_RESET_STATE, /* Reset positions */ HA_EXTRA_RESET_STATE, /* Reset positions */
HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/ HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/
HA_EXTRA_NO_IGNORE_DUP_KEY, 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_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
HA_EXTRA_PRELOAD_BUFFER_SIZE, /* Set buffer size for preloading */ HA_EXTRA_PRELOAD_BUFFER_SIZE, /* Set buffer size for preloading */
/* /*
...@@ -185,7 +185,9 @@ enum ha_extra_function { ...@@ -185,7 +185,9 @@ enum ha_extra_function {
Inform handler that an "INSERT...ON DUPLICATE KEY UPDATE" will be Inform handler that an "INSERT...ON DUPLICATE KEY UPDATE" will be
executed. This condition is unset by HA_EXTRA_NO_IGNORE_DUP_KEY. 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() */ /* The following is parameter to ha_panic() */
......
...@@ -1598,6 +1598,9 @@ insert into t1 values (1),(2),(3),(4),(NULL),(NULL),(NULL),(NULL); ...@@ -1598,6 +1598,9 @@ insert into t1 values (1),(2),(3),(4),(NULL),(NULL),(NULL),(NULL);
analyze table t1; analyze table t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 analyze status OK 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; show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment 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 t1 1 a 1 a A 8 NULL NULL YES BTREE
...@@ -1887,10 +1890,79 @@ t1_name varchar(255) default null, ...@@ -1887,10 +1890,79 @@ t1_name varchar(255) default null,
t1_id int(10) unsigned not null auto_increment, t1_id int(10) unsigned not null auto_increment,
key (t1_name), key (t1_name),
primary key (t1_id) primary key (t1_id)
) auto_increment = 1000 default charset=latin1; ) engine=maria auto_increment = 1000 default charset=latin1;
lock tables t1 write; lock tables t1 write;
INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002); INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002);
check table t1; check table t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
unlock tables; 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;
...@@ -711,6 +711,7 @@ analyze table t1; ...@@ -711,6 +711,7 @@ analyze table t1;
show index from t1; show index from t1;
set maria_stats_method=DEFAULT; set maria_stats_method=DEFAULT;
drop table t1; drop table t1;
# #
...@@ -952,6 +953,7 @@ create table t1 (a int, key(a)); ...@@ -952,6 +953,7 @@ create table t1 (a int, key(a));
insert into t1 values (1),(2),(3),(4),(NULL),(NULL),(NULL),(NULL); insert into t1 values (1),(2),(3),(4),(NULL),(NULL),(NULL),(NULL);
analyze table t1; analyze table t1;
analyze table t1;
show keys from t1; show keys from t1;
alter table t1 disable keys; alter table t1 disable keys;
...@@ -1155,17 +1157,103 @@ drop table t1; ...@@ -1155,17 +1157,103 @@ drop table t1;
# CHECK TABLE was reporting # CHECK TABLE was reporting
# "Size of datafile is: 0 Should be: 16384" # "Size of datafile is: 0 Should be: 16384"
#
create table `t1` ( create table `t1` (
t1_name varchar(255) default null, t1_name varchar(255) default null,
t1_id int(10) unsigned not null auto_increment, t1_id int(10) unsigned not null auto_increment,
key (t1_name), key (t1_name),
primary key (t1_id) primary key (t1_id)
) auto_increment = 1000 default charset=latin1; ) engine=maria auto_increment = 1000 default charset=latin1;
lock tables t1 write; lock tables t1 write;
INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002); INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002);
check table t1; check table t1;
unlock tables; 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 # End of 5.2 tests
--disable_result_log --disable_result_log
......
...@@ -4621,11 +4621,14 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, ...@@ -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 about this call). We pass this along to all underlying MyISAM handlers
and ignore it for the rest. 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. Only used by MyISAM, called in preparation for a DROP TABLE.
It's used mostly by Windows that cannot handle dropping an open file. 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. 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_READCHECK:
HA_EXTRA_NO_READCHECK: HA_EXTRA_NO_READCHECK:
Only one call to HA_EXTRA_NO_READCHECK from ha_open where it says that 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) ...@@ -4751,14 +4754,15 @@ int ha_partition::extra(enum ha_extra_function operation)
} }
/* Category 3), used by MyISAM handlers */ /* Category 3), used by MyISAM handlers */
case HA_EXTRA_PREPARE_FOR_DELETE: case HA_EXTRA_PREPARE_FOR_RENAME:
DBUG_RETURN(prepare_for_delete()); DBUG_RETURN(prepare_for_rename());
break; break;
case HA_EXTRA_NORMAL: case HA_EXTRA_NORMAL:
case HA_EXTRA_QUICK: case HA_EXTRA_QUICK:
case HA_EXTRA_NO_READCHECK: case HA_EXTRA_NO_READCHECK:
case HA_EXTRA_PREPARE_FOR_UPDATE: case HA_EXTRA_PREPARE_FOR_UPDATE:
case HA_EXTRA_FORCE_REOPEN: case HA_EXTRA_FORCE_REOPEN:
case HA_EXTRA_PREPARE_FOR_DROP:
case HA_EXTRA_FLUSH_CACHE: case HA_EXTRA_FLUSH_CACHE:
{ {
if (m_myisam) if (m_myisam)
...@@ -4910,24 +4914,24 @@ void ha_partition::prepare_extra_cache(uint cachesize) ...@@ -4910,24 +4914,24 @@ void ha_partition::prepare_extra_cache(uint cachesize)
0 Success 0 Success
*/ */
int ha_partition::prepare_for_delete() int ha_partition::prepare_for_rename()
{ {
int result= 0, tmp; int result= 0, tmp;
handler **file; handler **file;
DBUG_ENTER("ha_partition::prepare_for_delete()"); DBUG_ENTER("ha_partition::prepare_for_rename()");
if (m_new_file != NULL) if (m_new_file != NULL)
{ {
for (file= m_new_file; *file; file++) 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; result= tmp;
for (file= m_reorged_file; *file; file++) 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; result= tmp;
DBUG_RETURN(result); DBUG_RETURN(result);
} }
DBUG_RETURN(loop_extra(HA_EXTRA_PREPARE_FOR_DELETE)); DBUG_RETURN(loop_extra(HA_EXTRA_PREPARE_FOR_RENAME));
} }
/* /*
......
...@@ -211,7 +211,7 @@ class ha_partition :public handler ...@@ -211,7 +211,7 @@ class ha_partition :public handler
} }
virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share); virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
private: private:
int prepare_for_delete(); int prepare_for_rename();
int copy_partitions(ulonglong *copied, ulonglong *deleted); int copy_partitions(ulonglong *copied, ulonglong *deleted);
void cleanup_new_partition(uint part_count); void cleanup_new_partition(uint part_count);
int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info, int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info,
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
This is followed by a call to thr_multi_lock() for all tables. This is followed by a call to thr_multi_lock() for all tables.
- When statement is done, we call mysql_unlock_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) followed by
table_handler->external_lock(thd, F_UNLCK) for each table. thr_multi_unlock() for each table.
- Note that mysql_unlock_tables() may be called several times as - Note that mysql_unlock_tables() may be called several times as
MySQL in some cases can free some tables earlier than others. MySQL in some cases can free some tables earlier than others.
......
...@@ -3694,8 +3694,9 @@ mysql_rename_table(handlerton *base, const char *old_db, ...@@ -3694,8 +3694,9 @@ mysql_rename_table(handlerton *base, const char *old_db,
wait_while_table_is_used() wait_while_table_is_used()
thd Thread handler thd Thread handler
table Table to remove from cache 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_FORCE_REOPEN if table is not be used
HA_EXTRA_PREPARE_FOR_REANME if table is to be renamed
NOTES NOTES
When returning, the table will be unusable for other threads until When returning, the table will be unusable for other threads until
the table is closed. the table is closed.
...@@ -3745,7 +3746,7 @@ void close_cached_table(THD *thd, TABLE *table) ...@@ -3745,7 +3746,7 @@ void close_cached_table(THD *thd, TABLE *table)
{ {
DBUG_ENTER("close_cached_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 */ /* Close lock if this is not got with LOCK TABLES */
if (thd->lock) if (thd->lock)
{ {
...@@ -6532,7 +6533,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -6532,7 +6533,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (lower_case_table_names) if (lower_case_table_names)
my_casedn_str(files_charset_info, old_name); 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); close_data_files_and_morph_locks(thd, db, table_name);
error=0; error=0;
......
...@@ -1324,7 +1324,10 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize) ...@@ -1324,7 +1324,10 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
} }
thd->proc_info= old_proc_info; thd->proc_info= old_proc_info;
if (!thd->locked_tables) if (!thd->locked_tables)
{
_ma_reenable_logging_for_table(file->s);
maria_lock_database(file, F_UNLCK); maria_lock_database(file, F_UNLCK);
}
DBUG_RETURN(error ? HA_ADMIN_FAILED : DBUG_RETURN(error ? HA_ADMIN_FAILED :
!optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK); !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
} }
...@@ -1624,10 +1627,8 @@ void ha_maria::start_bulk_insert(ha_rows rows) ...@@ -1624,10 +1627,8 @@ void ha_maria::start_bulk_insert(ha_rows rows)
if (!rows || (rows > MARIA_MIN_ROWS_TO_USE_WRITE_CACHE)) if (!rows || (rows > MARIA_MIN_ROWS_TO_USE_WRITE_CACHE))
maria_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size); maria_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size);
can_enable_indexes= maria_is_all_keys_active(file->s->state.key_map, can_enable_indexes= (maria_is_all_keys_active(file->s->state.key_map,
file->s->base.keys); file->s->base.keys));
/* TODO: Remove when we have repair() working */
can_enable_indexes= 0;
if (!(specialflag & SPECIAL_SAFE_MODE)) if (!(specialflag & SPECIAL_SAFE_MODE))
{ {
...@@ -1640,9 +1641,8 @@ void ha_maria::start_bulk_insert(ha_rows rows) ...@@ -1640,9 +1641,8 @@ void ha_maria::start_bulk_insert(ha_rows rows)
if (file->state->records == 0 && can_enable_indexes && if (file->state->records == 0 && can_enable_indexes &&
(!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES)) (!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES))
maria_disable_non_unique_index(file, rows); maria_disable_non_unique_index(file, rows);
else else if (!file->bulk_insert &&
if (!file->bulk_insert && (!rows || rows >= MARIA_MIN_ROWS_TO_USE_BULK_INSERT))
(!rows || rows >= MARIA_MIN_ROWS_TO_USE_BULK_INSERT))
{ {
maria_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows); maria_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows);
} }
......
...@@ -451,6 +451,10 @@ static void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap) ...@@ -451,6 +451,10 @@ static void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap)
fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n", fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n",
(ulong) bitmap->page); (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; page= (ulong) bitmap->page+1;
for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ; for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ;
pos < end ; pos < end ;
...@@ -536,14 +540,14 @@ static my_bool _ma_read_bitmap_page(MARIA_SHARE *share, ...@@ -536,14 +540,14 @@ static my_bool _ma_read_bitmap_page(MARIA_SHARE *share,
} }
bitmap->used_size= bitmap->total_size; bitmap->used_size= bitmap->total_size;
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_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, (PAGECACHE_FILE*)&bitmap->file, page, 0,
(uchar*) bitmap->map, (uchar*) bitmap->map,
PAGECACHE_PLAIN_PAGE, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL) | PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL) ||
memcmp(bitmap->map + bitmap->block_size - memcmp(bitmap->map + bitmap->block_size -
sizeof(maria_bitmap_marker), sizeof(maria_bitmap_marker),
maria_bitmap_marker, sizeof(maria_bitmap_marker)); maria_bitmap_marker, sizeof(maria_bitmap_marker)));
#ifndef DBUG_OFF #ifndef DBUG_OFF
if (!res) if (!res)
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size); 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) ...@@ -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) */ /* Handle all full pages and tail pages (for head page and blob) */
for (block++; block < end; block++) for (block++; block < end; block++)
{ {
uint page_count;
if (!block->page_count) if (!block->page_count)
continue; /* Skip 'filler blocks' */ continue; /* Skip 'filler blocks' */
page_count= block->page_count;
if (block->used & BLOCKUSED_TAIL) if (block->used & BLOCKUSED_TAIL)
{ {
/* The bitmap page is only one page */
page_count= 1;
if (block->used & BLOCKUSED_USED) if (block->used & BLOCKUSED_USED)
{ {
DBUG_PRINT("info", ("tail empty_space: %u", block->empty_space)); 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) ...@@ -1861,7 +1869,7 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
} }
if (!(block->used & BLOCKUSED_USED) && if (!(block->used & BLOCKUSED_USED) &&
_ma_reset_full_page_bits(info, bitmap, _ma_reset_full_page_bits(info, bitmap,
block->page, block->page_count)) block->page, page_count))
goto err; goto err;
} }
pthread_mutex_unlock(&info->s->bitmap.bitmap_lock); pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
......
...@@ -288,8 +288,10 @@ typedef struct st_maria_extent_cursor ...@@ -288,8 +288,10 @@ typedef struct st_maria_extent_cursor
uint extent_count; uint extent_count;
/* <> 0 if current extent is a tail page; Set while using cursor */ /* <> 0 if current extent is a tail page; Set while using cursor */
uint tail; 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). the row header, not an extent that is stored as part of the row data).
*/ */
my_bool first_extent; my_bool first_extent;
...@@ -299,7 +301,7 @@ typedef struct st_maria_extent_cursor ...@@ -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_tails(MARIA_HA *info, MARIA_RECORD_POS *tails);
static my_bool delete_head_or_tail(MARIA_HA *info, static my_bool delete_head_or_tail(MARIA_HA *info,
ulonglong page, uint record_number, 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 _ma_print_directory(uchar *buff, uint block_size);
static void compact_page(uchar *buff, uint block_size, uint rownr, static void compact_page(uchar *buff, uint block_size, uint rownr,
my_bool extend_block); my_bool extend_block);
...@@ -461,7 +463,7 @@ my_bool _ma_init_block_record(MARIA_HA *info) ...@@ -461,7 +463,7 @@ my_bool _ma_init_block_record(MARIA_HA *info)
/* The following should be big enough for all purposes */ /* The following should be big enough for all purposes */
if (my_init_dynamic_array(&info->pinned_pages, if (my_init_dynamic_array(&info->pinned_pages,
sizeof(MARIA_PINNED_PAGE), sizeof(MARIA_PINNED_PAGE),
max(info->s->base.blobs + 2, max(info->s->base.blobs*2 + 4,
MARIA_MAX_TREE_LEVELS*2), 16)) MARIA_MAX_TREE_LEVELS*2), 16))
goto err; goto err;
row->base_length= new_row->base_length= info->s->base_length; 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, ...@@ -840,6 +842,7 @@ static void calc_record_size(MARIA_HA *info, const uchar *record,
MARIA_COLUMNDEF *column, *end_column; MARIA_COLUMNDEF *column, *end_column;
uint *null_field_lengths= row->null_field_lengths; uint *null_field_lengths= row->null_field_lengths;
ulong *blob_lengths= row->blob_lengths; ulong *blob_lengths= row->blob_lengths;
DBUG_ENTER("calc_record_size");
row->normal_length= row->char_length= row->varchar_length= row->normal_length= row->char_length= row->varchar_length=
row->blob_length= row->extents_count= 0; row->blob_length= row->extents_count= 0;
...@@ -968,6 +971,9 @@ static void calc_record_size(MARIA_HA *info, const uchar *record, ...@@ -968,6 +971,9 @@ static void calc_record_size(MARIA_HA *info, const uchar *record,
row->total_length= (row->head_length + row->blob_length); row->total_length= (row->head_length + row->blob_length);
if (row->total_length < share->base.min_row_length) if (row->total_length < share->base.min_row_length)
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, ...@@ -1395,6 +1401,7 @@ static my_bool write_full_pages(MARIA_HA *info,
DBUG_PRINT("enter", ("length: %lu page: %lu page_count: %lu", DBUG_PRINT("enter", ("length: %lu page: %lu page_count: %lu",
(ulong) length, (ulong) block->page, (ulong) length, (ulong) block->page,
(ulong) block->page_count)); (ulong) block->page_count));
DBUG_ASSERT((block->page_count & TAIL_BIT) == 0);
info->keyread_buff_used= 1; info->keyread_buff_used= 1;
page= block->page; page= block->page;
...@@ -1938,13 +1945,10 @@ static my_bool write_block_record(MARIA_HA *info, ...@@ -1938,13 +1945,10 @@ static my_bool write_block_record(MARIA_HA *info,
ulong length; ulong length;
ulong data_length= (tmp_data - info->rec_buff); ulong data_length= (tmp_data - info->rec_buff);
#ifdef MONTY_WILL_KNOW
#ifdef SANITY_CHECKS #ifdef SANITY_CHECKS
if (cur_block->sub_blocks == 1) if (head_block->sub_blocks == 1)
goto crashed; /* no reserved full or tails */ goto crashed; /* no reserved full or tails */
#endif #endif
#endif
/* /*
Find out where to write tail for non-blob fields. Find out where to write tail for non-blob fields.
...@@ -2073,6 +2077,11 @@ static my_bool write_block_record(MARIA_HA *info, ...@@ -2073,6 +2077,11 @@ static my_bool write_block_record(MARIA_HA *info,
length)) length))
goto disk_err; goto disk_err;
tmp_data-= length; /* Remove the tail */ 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 */ /* Store the tail position for the non-blob fields */
if (head_tail_block == head_block + 1) if (head_tail_block == head_block + 1)
...@@ -2319,8 +2328,8 @@ static my_bool write_block_record(MARIA_HA *info, ...@@ -2319,8 +2328,8 @@ static my_bool write_block_record(MARIA_HA *info,
if (block[block->sub_blocks - 1].used & BLOCKUSED_TAIL) if (block[block->sub_blocks - 1].used & BLOCKUSED_TAIL)
blob_length-= (blob_length % FULL_PAGE_SIZE(block_size)); blob_length-= (blob_length % FULL_PAGE_SIZE(block_size));
if (write_full_pages(info, info->trn->undo_lsn, block, if (blob_length && write_full_pages(info, info->trn->undo_lsn, block,
blob_pos, blob_length)) blob_pos, blob_length))
goto disk_err; goto disk_err;
block+= block->sub_blocks; block+= block->sub_blocks;
} }
...@@ -2356,8 +2365,11 @@ static my_bool write_block_record(MARIA_HA *info, ...@@ -2356,8 +2365,11 @@ static my_bool write_block_record(MARIA_HA *info,
@todo RECOVERY we should distinguish below between log write error and @todo RECOVERY we should distinguish below between log write error and
table write error. The former should stop Maria immediately, the latter table write error. The former should stop Maria immediately, the latter
should mark the table corrupted. 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); _ma_unpin_all_pages(info, 0);
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -2445,7 +2457,8 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info) ...@@ -2445,7 +2457,8 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
if (delete_head_or_tail(info, if (delete_head_or_tail(info,
ma_recordpos_to_page(info->cur_row.lastpos), 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; res= 1;
for (block= blocks->block + 1, end= block + blocks->count - 1; block < end; for (block= blocks->block + 1, end= block + blocks->count - 1; block < end;
block++) block++)
...@@ -2457,7 +2470,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info) ...@@ -2457,7 +2470,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
write_block_record() write_block_record()
*/ */
if (delete_head_or_tail(info, block->page, block->page_count & ~TAIL_BIT, if (delete_head_or_tail(info, block->page, block->page_count & ~TAIL_BIT,
0)) 0, 0))
res= 1; res= 1;
} }
else if (block->used & BLOCKUSED_USED) else if (block->used & BLOCKUSED_USED)
...@@ -2533,7 +2546,6 @@ my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos, ...@@ -2533,7 +2546,6 @@ my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos,
ulonglong page; ulonglong page;
struct st_row_pos_info row_pos; struct st_row_pos_info row_pos;
MARIA_SHARE *share= info->s; MARIA_SHARE *share= info->s;
my_bool res;
DBUG_ENTER("_ma_update_block_record"); DBUG_ENTER("_ma_update_block_record");
DBUG_PRINT("enter", ("rowid: %lu", (long) record_pos)); 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, ...@@ -2621,8 +2633,8 @@ my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos,
row_pos.dir= dir; row_pos.dir= dir;
row_pos.data= buff + uint2korr(dir); row_pos.data= buff + uint2korr(dir);
row_pos.length= head_length; row_pos.length= head_length;
res= write_block_record(info, oldrec, record, new_row, blocks, 1, &row_pos); DBUG_RETURN(write_block_record(info, oldrec, record, new_row, blocks, 1,
DBUG_RETURN(res); &row_pos));
err: err:
_ma_unpin_all_pages(info, 0); _ma_unpin_all_pages(info, 0);
...@@ -2710,6 +2722,9 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number, ...@@ -2710,6 +2722,9 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
info Maria handler info Maria handler
page Page (not file offset!) on which the row is page Page (not file offset!) on which the row is
head 1 if this is a head page 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 NOTES
Uses info->keyread_buff Uses info->keyread_buff
...@@ -2721,7 +2736,7 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number, ...@@ -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, static my_bool delete_head_or_tail(MARIA_HA *info,
ulonglong page, uint record_number, ulonglong page, uint record_number,
my_bool head) my_bool head, my_bool from_update)
{ {
MARIA_SHARE *share= info->s; MARIA_SHARE *share= info->s;
uint empty_space; uint empty_space;
...@@ -2730,6 +2745,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info, ...@@ -2730,6 +2745,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
LSN lsn; LSN lsn;
MARIA_PINNED_PAGE page_link; MARIA_PINNED_PAGE page_link;
int res; int res;
enum pagecache_page_lock lock_at_write, lock_at_unpin;
DBUG_ENTER("delete_head_or_tail"); DBUG_ENTER("delete_head_or_tail");
info->keyread_buff_used= 1; info->keyread_buff_used= 1;
...@@ -2743,6 +2759,17 @@ static my_bool delete_head_or_tail(MARIA_HA *info, ...@@ -2743,6 +2759,17 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK; page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
push_dynamic(&info->pinned_pages, (void*) &page_link); 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); res= delete_dir_entry(buff, block_size, record_number, &empty_space);
if (res < 0) if (res < 0)
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -2769,7 +2796,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info, ...@@ -2769,7 +2796,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
if (pagecache_write(share->pagecache, if (pagecache_write(share->pagecache,
&info->dfile, page, 0, &info->dfile, page, 0,
buff, share->page_type, buff, share->page_type,
PAGECACHE_LOCK_WRITE_TO_READ, lock_at_write,
PAGECACHE_PIN_LEFT_PINNED, PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_WRITE_DELAY, &page_link.link)) PAGECACHE_WRITE_DELAY, &page_link.link))
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -2797,15 +2824,15 @@ static my_bool delete_head_or_tail(MARIA_HA *info, ...@@ -2797,15 +2824,15 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
if (pagecache_write(share->pagecache, if (pagecache_write(share->pagecache,
&info->dfile, page, 0, &info->dfile, page, 0,
buff, share->page_type, buff, share->page_type,
PAGECACHE_LOCK_WRITE_TO_READ, lock_at_write,
PAGECACHE_PIN_LEFT_PINNED, PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_WRITE_DELAY, &page_link.link)) PAGECACHE_WRITE_DELAY, &page_link.link))
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_ASSERT(empty_space >= info->s->bitmap.sizes[0]); DBUG_ASSERT(empty_space >= info->s->bitmap.sizes[0]);
} }
/* Change the lock used when we read the page */ /* The page is pinned with a read lock */
page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK; page_link.unlock= lock_at_unpin;
set_dynamic(&info->pinned_pages, (void*) &page_link, set_dynamic(&info->pinned_pages, (void*) &page_link,
info->pinned_pages.elements-1); info->pinned_pages.elements-1);
...@@ -2838,7 +2865,7 @@ static my_bool delete_tails(MARIA_HA *info, MARIA_RECORD_POS *tails) ...@@ -2838,7 +2865,7 @@ static my_bool delete_tails(MARIA_HA *info, MARIA_RECORD_POS *tails)
{ {
if (delete_head_or_tail(info, if (delete_head_or_tail(info,
ma_recordpos_to_page(*tails), ma_recordpos_to_page(*tails),
ma_recordpos_to_dir_entry(*tails), 0)) ma_recordpos_to_dir_entry(*tails), 0, 1))
res= 1; res= 1;
} }
DBUG_RETURN(res); DBUG_RETURN(res);
...@@ -2863,7 +2890,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record) ...@@ -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); page= ma_recordpos_to_page(info->cur_row.lastpos);
record_number= ma_recordpos_to_dir_entry(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)) delete_tails(info, info->cur_row.tail_positions))
goto err; goto err;
...@@ -2987,8 +3014,14 @@ static void init_extent(MARIA_EXTENT_CURSOR *extent, uchar *extent_info, ...@@ -2987,8 +3014,14 @@ static void init_extent(MARIA_EXTENT_CURSOR *extent, uchar *extent_info,
extent->extent_count= extents; extent->extent_count= extents;
extent->page= page_korr(extent_info); /* First extent */ extent->page= page_korr(extent_info); /* First extent */
page_count= uint2korr(extent_info + ROW_EXTENT_PAGE_SIZE); page_count= uint2korr(extent_info + ROW_EXTENT_PAGE_SIZE);
extent->page_count= page_count & ~TAIL_BIT;
extent->tail= 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; extent->tail_positions= tail_positions;
} }
...@@ -3030,12 +3063,15 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent, ...@@ -3030,12 +3063,15 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
if (!page_count) if (!page_count)
goto crashed; goto crashed;
extent->tail= page_count & TAIL_BIT; extent->tail= page_count & TAIL_BIT;
extent->page_count= (page_count & ~TAIL_BIT); if (extent->tail)
extent->first_extent= 0; 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", DBUG_PRINT("info",("New extent. Page: %lu page_count: %u tail_flag: %d",
(ulong) extent->page, extent->page_count, (ulong) extent->page, extent->page_count,
extent->tail != 0)); extent->tail != 0));
} }
extent->first_extent= 0;
DBUG_ASSERT(share->pagecache->block_size == share->block_size); DBUG_ASSERT(share->pagecache->block_size == share->block_size);
if (!(buff= pagecache_read(share->pagecache, if (!(buff= pagecache_read(share->pagecache,
...@@ -3059,16 +3095,16 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent, ...@@ -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 */ info->cur_row.full_page_count++; /* For maria_chk */
DBUG_RETURN(extent->data_start= buff + LSN_SIZE + PAGE_TYPE_SIZE); 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) if ((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != TAIL_PAGE)
goto crashed; goto crashed;
*(extent->tail_positions++)= ma_recordpos(extent->page, *(extent->tail_positions++)= ma_recordpos(extent->page,
extent->page_count); extent->tail_row_nr);
info->cur_row.tail_count++; /* For maria_chk */ info->cur_row.tail_count++; /* For maria_chk */
if (!(data= get_record_position(buff, share->block_size, if (!(data= get_record_position(buff, share->block_size,
extent->page_count, extent->tail_row_nr,
end_of_data))) end_of_data)))
goto crashed; goto crashed;
extent->data_start= data; extent->data_start= data;
...@@ -3124,7 +3160,7 @@ static my_bool read_long_data(MARIA_HA *info, uchar *to, ulong length, ...@@ -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 This may change in the future, which is why we have the loop written
the way it's 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; *end_of_data= *data;
for(;;) for(;;)
......
...@@ -1706,8 +1706,13 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend, ...@@ -1706,8 +1706,13 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
full_dir ? 0 : empty_space, full_dir ? 0 : empty_space,
&bitmap_pattern)) &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, _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, llstr(pos, llbuff), page_type, empty_space,
bitmap_pattern); bitmap_pattern);
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE)) if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
......
...@@ -65,6 +65,7 @@ int maria_close(register MARIA_HA *info) ...@@ -65,6 +65,7 @@ int maria_close(register MARIA_HA *info)
if (flag) if (flag)
{ {
/* Last close of file; Flush everything */
if (share->kfile.file >= 0) if (share->kfile.file >= 0)
{ {
if ((*share->once_end)(share)) if ((*share->once_end)(share))
...@@ -87,7 +88,7 @@ int maria_close(register MARIA_HA *info) ...@@ -87,7 +88,7 @@ int maria_close(register MARIA_HA *info)
may be using the file at this point may be using the file at this point
IF using --external-locking, which does not apply to Maria. 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); _ma_state_info_write(share->kfile.file, &share->state, 1);
if (my_close(share->kfile.file, MYF(0))) if (my_close(share->kfile.file, MYF(0)))
error= my_errno; error= my_errno;
......
...@@ -1694,7 +1694,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, ...@@ -1694,7 +1694,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info,
{ /* Check if changed */ { /* Check if changed */
info_read=1; info_read=1;
info->rec_cache.seek_not_done=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; goto panic;
} }
if (filepos >= info->state->data_file_length) if (filepos >= info->state->data_file_length)
......
...@@ -264,8 +264,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, ...@@ -264,8 +264,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
share->last_version= 0L; /* Impossible version */ share->last_version= 0L; /* Impossible version */
pthread_mutex_unlock(&THR_LOCK_maria); pthread_mutex_unlock(&THR_LOCK_maria);
break; break;
case HA_EXTRA_PREPARE_FOR_DELETE: case HA_EXTRA_PREPARE_FOR_DROP:
/* QQ: suggest to rename it to "PREPARE_FOR_DROP" */ case HA_EXTRA_PREPARE_FOR_RENAME:
pthread_mutex_lock(&THR_LOCK_maria); pthread_mutex_lock(&THR_LOCK_maria);
share->last_version= 0L; /* Impossible version */ share->last_version= 0L; /* Impossible version */
#ifdef __WIN__ #ifdef __WIN__
...@@ -284,7 +284,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, ...@@ -284,7 +284,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
Does ENABLE KEYS rebuild them too? Does ENABLE KEYS rebuild them too?
*/ */
if (flush_pagecache_blocks(share->pagecache, &share->kfile, 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; error=my_errno;
share->changed=1; share->changed=1;
......
...@@ -153,7 +153,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type) ...@@ -153,7 +153,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type)
} }
if (!share->r_locks && !share->w_locks) 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; error=my_errno;
break; break;
...@@ -181,7 +181,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type) ...@@ -181,7 +181,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type)
{ {
if (!share->r_locks) 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; error=my_errno;
break; break;
...@@ -364,7 +364,7 @@ int _ma_readinfo(register MARIA_HA *info, int lock_type, int check_keybuffer) ...@@ -364,7 +364,7 @@ int _ma_readinfo(register MARIA_HA *info, int lock_type, int check_keybuffer)
MARIA_SHARE *share=info->s; MARIA_SHARE *share=info->s;
if (!share->tot_locks) 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; int error=my_errno ? my_errno : -1;
my_errno=error; my_errno=error;
......
...@@ -1110,18 +1110,13 @@ uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state) ...@@ -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() @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]; char buff[MARIA_STATE_INFO_SIZE + MARIA_STATE_EXTRA_SIZE];
if (!maria_single_user) if (!maria_single_user)
{ {
if (pRead) if (my_pread(file, buff, state->state_length, 0L, MYF(MY_NABP)))
{
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)))
return 1; return 1;
_ma_state_info_read(buff, state); _ma_state_info_read(buff, state);
} }
......
...@@ -300,23 +300,24 @@ struct st_pagecache_block_link ...@@ -300,23 +300,24 @@ struct st_pagecache_block_link
*next_changed, **prev_changed; /* for lists of file dirty/clean blocks */ *next_changed, **prev_changed; /* for lists of file dirty/clean blocks */
struct st_pagecache_hash_link struct st_pagecache_hash_link
*hash_link; /* backward ptr to referring 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
wqueue[COND_SIZE]; /* queues on waiting requests for new/old pages */ wqueue[COND_SIZE]; /* queues on waiting requests for new/old pages */
uint requests; /* number of requests for the block */ uint requests; /* number of requests for the block */
uchar *buffer; /* buffer for the block page */
uint status; /* state of the block */ uint status; /* state of the block */
uint pins; /* pin counter */ 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 PCBLOCK_TEMPERATURE temperature; /* block temperature: cold, warm, hot */
enum pagecache_page_type type; /* type of the block */ enum pagecache_page_type type; /* type of the block */
uint hits_left; /* number of hits left until promotion */ 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" */ /** @brief LSN when first became dirty; LSN_MAX means "not yet set" */
LSN rec_lsn; LSN rec_lsn;
KEYCACHE_CONDVAR *condvar; /* condition variable for 'no readers' event */
}; };
#ifndef DBUG_OFF #ifndef DBUG_OFF
...@@ -2147,6 +2148,9 @@ static void info_change_lock(PAGECACHE_BLOCK_LINK *block, my_bool wl) ...@@ -2147,6 +2148,9 @@ static void info_change_lock(PAGECACHE_BLOCK_LINK *block, my_bool wl)
get_wrlock() get_wrlock()
pagecache pointer to a page cache data structure pagecache pointer to a page cache data structure
block the block to work with 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 RETURN
0 - OK 0 - OK
...@@ -2154,7 +2158,8 @@ static void info_change_lock(PAGECACHE_BLOCK_LINK *block, my_bool wl) ...@@ -2154,7 +2158,8 @@ static void info_change_lock(PAGECACHE_BLOCK_LINK *block, my_bool wl)
*/ */
static my_bool get_wrlock(PAGECACHE *pagecache, 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; PAGECACHE_FILE file= block->hash_link->file;
pgcache_page_no_t pageno= block->hash_link->pageno; pgcache_page_no_t pageno= block->hash_link->pageno;
...@@ -2165,7 +2170,7 @@ static my_bool get_wrlock(PAGECACHE *pagecache, ...@@ -2165,7 +2170,7 @@ static my_bool get_wrlock(PAGECACHE *pagecache,
file.file, block->hash_link->file.file, file.file, block->hash_link->file.file,
pageno, block->hash_link->pageno)); pageno, block->hash_link->pageno));
PCBLOCK_INFO(block); PCBLOCK_INFO(block);
while (block->status & PCBLOCK_WRLOCK) while ((block->status & PCBLOCK_WRLOCK) && block->write_locker != user_file)
{ {
/* Lock failed we will wait */ /* Lock failed we will wait */
#ifdef THREAD #ifdef THREAD
...@@ -2197,9 +2202,9 @@ static my_bool get_wrlock(PAGECACHE *pagecache, ...@@ -2197,9 +2202,9 @@ static my_bool get_wrlock(PAGECACHE *pagecache,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
DBUG_ASSERT(block->pins == 0);
/* we are doing it by global cache mutex protection, so it is OK */ /* we are doing it by global cache mutex protection, so it is OK */
block->status|= PCBLOCK_WRLOCK; block->status|= PCBLOCK_WRLOCK;
block->write_locker= user_file;
DBUG_PRINT("info", ("WR lock set, block 0x%lx", (ulong)block)); DBUG_PRINT("info", ("WR lock set, block 0x%lx", (ulong)block));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -2223,6 +2228,8 @@ static void release_wrlock(PAGECACHE_BLOCK_LINK *block) ...@@ -2223,6 +2228,8 @@ static void release_wrlock(PAGECACHE_BLOCK_LINK *block)
PCBLOCK_INFO(block); PCBLOCK_INFO(block);
DBUG_ASSERT(block->status & PCBLOCK_WRLOCK); DBUG_ASSERT(block->status & PCBLOCK_WRLOCK);
DBUG_ASSERT(block->pins > 0); DBUG_ASSERT(block->pins > 0);
if (block->pins > 1)
DBUG_VOID_RETURN; /* Multiple write locked */
block->status&= ~PCBLOCK_WRLOCK; block->status&= ~PCBLOCK_WRLOCK;
DBUG_PRINT("info", ("WR lock reset, block 0x%lx", (ulong)block)); DBUG_PRINT("info", ("WR lock reset, block 0x%lx", (ulong)block));
#ifdef THREAD #ifdef THREAD
...@@ -2244,6 +2251,7 @@ static void release_wrlock(PAGECACHE_BLOCK_LINK *block) ...@@ -2244,6 +2251,7 @@ static void release_wrlock(PAGECACHE_BLOCK_LINK *block)
block the block to work with block the block to work with
lock lock change mode lock lock change mode
pin pinchange mode pin pinchange mode
file File handler requesting pin
RETURN RETURN
0 - OK 0 - OK
...@@ -2253,7 +2261,8 @@ static void release_wrlock(PAGECACHE_BLOCK_LINK *block) ...@@ -2253,7 +2261,8 @@ static void release_wrlock(PAGECACHE_BLOCK_LINK *block)
static my_bool make_lock_and_pin(PAGECACHE *pagecache, static my_bool make_lock_and_pin(PAGECACHE *pagecache,
PAGECACHE_BLOCK_LINK *block, PAGECACHE_BLOCK_LINK *block,
enum pagecache_page_lock lock, enum pagecache_page_lock lock,
enum pagecache_page_pin pin) enum pagecache_page_pin pin,
PAGECACHE_FILE *file)
{ {
DBUG_ENTER("make_lock_and_pin"); DBUG_ENTER("make_lock_and_pin");
...@@ -2274,7 +2283,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache, ...@@ -2274,7 +2283,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
switch (lock) { switch (lock) {
case PAGECACHE_LOCK_WRITE: /* free -> write */ case PAGECACHE_LOCK_WRITE: /* free -> write */
/* Writelock and pin the buffer */ /* Writelock and pin the buffer */
if (get_wrlock(pagecache, block)) if (get_wrlock(pagecache, block, file))
{ {
/* can't lock => need retry */ /* can't lock => need retry */
goto retry; goto retry;
...@@ -2291,6 +2300,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache, ...@@ -2291,6 +2300,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
implementation) implementation)
*/ */
release_wrlock(block); release_wrlock(block);
/* fall through */
case PAGECACHE_LOCK_READ_UNLOCK: /* read -> free */ case PAGECACHE_LOCK_READ_UNLOCK: /* read -> free */
case PAGECACHE_LOCK_LEFT_READLOCKED: /* read -> read */ case PAGECACHE_LOCK_LEFT_READLOCKED: /* read -> read */
if (pin == PAGECACHE_UNPIN) if (pin == PAGECACHE_UNPIN)
...@@ -2549,7 +2559,7 @@ void pagecache_unlock(PAGECACHE *pagecache, ...@@ -2549,7 +2559,7 @@ void pagecache_unlock(PAGECACHE *pagecache,
if (lsn != LSN_IMPOSSIBLE) if (lsn != LSN_IMPOSSIBLE)
check_and_set_lsn(pagecache, lsn, block); 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 */ DBUG_ASSERT(0); /* should not happend */
} }
...@@ -2617,7 +2627,7 @@ void pagecache_unpin(PAGECACHE *pagecache, ...@@ -2617,7 +2627,7 @@ void pagecache_unpin(PAGECACHE *pagecache,
*/ */
if (make_lock_and_pin(pagecache, block, if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_LEFT_READLOCKED, PAGECACHE_LOCK_LEFT_READLOCKED,
PAGECACHE_UNPIN)) PAGECACHE_UNPIN, file))
DBUG_ASSERT(0); /* should not happend */ DBUG_ASSERT(0); /* should not happend */
remove_reader(block); remove_reader(block);
...@@ -2678,7 +2688,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache, ...@@ -2678,7 +2688,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
lock == PAGECACHE_LOCK_READ_UNLOCK) lock == PAGECACHE_LOCK_READ_UNLOCK)
{ {
/* block do not need here so we do not provide it */ /* 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_ASSERT(0); /* should not happend */
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -2710,7 +2720,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache, ...@@ -2710,7 +2720,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
if (lsn != LSN_IMPOSSIBLE) if (lsn != LSN_IMPOSSIBLE)
check_and_set_lsn(pagecache, lsn, block); 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 */ DBUG_ASSERT(0); /* should not happend */
/* /*
...@@ -2772,7 +2782,7 @@ void pagecache_unpin_by_link(PAGECACHE *pagecache, ...@@ -2772,7 +2782,7 @@ void pagecache_unpin_by_link(PAGECACHE *pagecache,
*/ */
if (make_lock_and_pin(pagecache, block, if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_LEFT_READLOCKED, PAGECACHE_LOCK_LEFT_READLOCKED,
PAGECACHE_UNPIN)) PAGECACHE_UNPIN, 0))
DBUG_ASSERT(0); /* should not happend */ DBUG_ASSERT(0); /* should not happend */
/* /*
...@@ -2889,7 +2899,7 @@ uchar *pagecache_valid_read(PAGECACHE *pagecache, ...@@ -2889,7 +2899,7 @@ uchar *pagecache_valid_read(PAGECACHE *pagecache,
validator, validator_data); validator, validator_data);
DBUG_PRINT("info", ("read is done")); 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, We failed to write lock the block, cache is unlocked,
...@@ -3009,7 +3019,7 @@ my_bool pagecache_delete(PAGECACHE *pagecache, ...@@ -3009,7 +3019,7 @@ my_bool pagecache_delete(PAGECACHE *pagecache,
if (pin == PAGECACHE_PIN) if (pin == PAGECACHE_PIN)
reg_requests(pagecache, block, 1); reg_requests(pagecache, block, 1);
DBUG_ASSERT(block != 0); 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 We failed to writelock the block, cache is unlocked, and last write
...@@ -3059,7 +3069,7 @@ my_bool pagecache_delete(PAGECACHE *pagecache, ...@@ -3059,7 +3069,7 @@ my_bool pagecache_delete(PAGECACHE *pagecache,
/* Cache is locked, so we can relese page before freeing it */ /* Cache is locked, so we can relese page before freeing it */
make_lock_and_pin(pagecache, block, make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN); PAGECACHE_UNPIN, file);
DBUG_ASSERT(link->requests > 0); DBUG_ASSERT(link->requests > 0);
link->requests--; link->requests--;
/* See NOTE for pagecache_unlock about registering requests. */ /* See NOTE for pagecache_unlock about registering requests. */
...@@ -3254,7 +3264,7 @@ my_bool pagecache_write_part(PAGECACHE *pagecache, ...@@ -3254,7 +3264,7 @@ my_bool pagecache_write_part(PAGECACHE *pagecache,
write_lock_change_table[lock].new_lock, write_lock_change_table[lock].new_lock,
(need_lock_change ? (need_lock_change ?
write_pin_change_table[pin].new_pin : write_pin_change_table[pin].new_pin :
pin))) pin), file))
{ {
/* /*
We failed to writelock the block, cache is unlocked, and last write We failed to writelock the block, cache is unlocked, and last write
...@@ -3307,7 +3317,6 @@ my_bool pagecache_write_part(PAGECACHE *pagecache, ...@@ -3307,7 +3317,6 @@ my_bool pagecache_write_part(PAGECACHE *pagecache,
} }
} }
if (need_lock_change) if (need_lock_change)
{ {
/* /*
...@@ -3316,7 +3325,7 @@ my_bool pagecache_write_part(PAGECACHE *pagecache, ...@@ -3316,7 +3325,7 @@ my_bool pagecache_write_part(PAGECACHE *pagecache,
*/ */
if (make_lock_and_pin(pagecache, block, if (make_lock_and_pin(pagecache, block,
write_lock_change_table[lock].unlock_lock, 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); DBUG_ASSERT(0);
} }
...@@ -3474,7 +3483,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache, ...@@ -3474,7 +3483,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
DBUG_ASSERT((block->status & PCBLOCK_WRLOCK) == 0); DBUG_ASSERT((block->status & PCBLOCK_WRLOCK) == 0);
DBUG_ASSERT(block->pins == 0); DBUG_ASSERT(block->pins == 0);
if (make_lock_and_pin(pagecache, block, if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE, PAGECACHE_PIN)) PAGECACHE_LOCK_WRITE, PAGECACHE_PIN, 0))
DBUG_ASSERT(0); DBUG_ASSERT(0);
KEYCACHE_DBUG_PRINT("flush_cached_blocks", KEYCACHE_DBUG_PRINT("flush_cached_blocks",
...@@ -3497,7 +3506,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache, ...@@ -3497,7 +3506,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
make_lock_and_pin(pagecache, block, make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN); PAGECACHE_UNPIN, 0);
pagecache->global_cache_write++; pagecache->global_cache_write++;
if (error) if (error)
......
...@@ -507,7 +507,7 @@ prototype_exec_hook(REDO_DROP_TABLE) ...@@ -507,7 +507,7 @@ prototype_exec_hook(REDO_DROP_TABLE)
this table should not be used anymore, and (only on Windows) to close this table should not be used anymore, and (only on Windows) to close
open files so they can be deleted 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)) maria_close(info))
goto end; goto end;
info= NULL; info= NULL;
......
...@@ -864,8 +864,7 @@ extern uint _ma_nommap_pwrite(MARIA_HA *info, uchar *Buffer, ...@@ -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); uint _ma_state_info_write(File file, MARIA_STATE_INFO *state, uint pWrite);
uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state); uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state);
uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state, uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state);
my_bool pRead);
uint _ma_base_info_write(File file, MARIA_BASE_INFO *base); uint _ma_base_info_write(File file, MARIA_BASE_INFO *base);
int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg); int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg);
char *_ma_keyseg_read(char *ptr, HA_KEYSEG *keyseg); char *_ma_keyseg_read(char *ptr, HA_KEYSEG *keyseg);
......
...@@ -255,15 +255,16 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) ...@@ -255,15 +255,16 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
share->last_version= 0L; /* Impossible version */ share->last_version= 0L; /* Impossible version */
pthread_mutex_unlock(&THR_LOCK_myisam); pthread_mutex_unlock(&THR_LOCK_myisam);
break; 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); pthread_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */ share->last_version= 0L; /* Impossible version */
#ifdef __WIN__ #ifdef __WIN__
/* Close the isam and data files as Win32 can't drop an open table */ /* Close the isam and data files as Win32 can't drop an open table */
pthread_mutex_lock(&share->intern_lock); pthread_mutex_lock(&share->intern_lock);
if (flush_key_blocks(share->key_cache, share->kfile, if (flush_key_blocks(share->key_cache, share->kfile,
(function == HA_EXTRA_FORCE_REOPEN ? (function == HA_EXTRA_PREPARE_FOR_DROP ?
FLUSH_RELEASE : FLUSH_IGNORE_CHANGED))) FLUSH_IGNORE_CHANGED : FLUSH_RELEASE)))
{ {
error=my_errno; error=my_errno;
share->changed=1; share->changed=1;
......
...@@ -392,7 +392,8 @@ int ha_myisammrg::extra(enum ha_extra_function operation) ...@@ -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 /* As this is just a mapping, we don't have to force the underlying
tables to be closed */ tables to be closed */
if (operation == HA_EXTRA_FORCE_REOPEN || 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 0;
return myrg_extra(file,operation,0); return myrg_extra(file,operation,0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment