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 {
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() */
......
......@@ -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;
......@@ -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
......
......@@ -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));
}
/*
......
......@@ -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,
......
......@@ -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.
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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);
......
This diff is collapsed.
......@@ -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))
......
......@@ -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;
......
......@@ -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)
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
}
......
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