diff --git a/include/my_base.h b/include/my_base.h index 57446e6136ffec7b82f45d87902703310889b540..473ed46ff1975462933bd42351b4796022c86489 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 53063c9c7abd1aebd7b0986ee1d09c9a82e7dff6..68ae0cb267b1ff43562610246348c1535798175c 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 aca85b1442eeeb867371bef9ebd56a94afbf33f3..d45f4c2ec6bf03ecc1a8944e9895dc18dda981a2 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 e4924e8e8f21da66a51480529e4ca3abd4731d83..15d7353c03c2d40136c77967cffd9d90c33fb136 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 895f001fa6a1566af9a2c374abbce5e037c9ee2e..bc4747be85b5dae1f3e9a39539b318b3878ae048 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -211,7 +211,7 @@ class ha_partition :public handler } 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 e129da27005520b2f89dfe11ad66a4446d3043f5..12b69edc3d3ef05d1dd2cc61426d1a4a55112069 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 6fc1c235ebfa62e88b438d7030ed6435c861db1b..158f415317c9e94c2ae3183a975c41ea24ad0ed7 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 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, 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 c2fa0ec14b17e24d489a2e5d56292be7499f930e..55ce800d59615a158abdd42920dfd79cb864ff01 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 ¶m, 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 6637717287759786191f2203e1946a6eaad3a5c7..2a2308637b6157d1e4443313e8dc743937e8cfff 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 555949dfa84ab4f7fb8c948f6c3a6ba23e085e36..7f29f0754634253609656474c49dbd0f0bb1a201 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 @@ static my_bool write_block_record(MARIA_HA *info, @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 1ac1fb3454fc6dcf225b43f47a872cc423ec0c24..a5e64cb555ce879fb5643b51e63f9888c3c524cd 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 a9d31a6c75fa79b15a491afff04e67a688085324..cc9f0005a4d3cfad234d211cdf0d7b2baf976845 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 246f9787b092d719ae8af51ac6594b2944383c18..52ade04db984ae0b2c54d52271f51fddc409281d 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 0ee5990844bdbb6876b9492ec8006cde0ab5bad3..a3fb9569290b653007066f6ec2b833dd1cdfc02a 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 f709d7e5759998aa971b508b438fd5bb42517c67..dad4071edf8a419e7c2fe7718663241c56b4906e 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 6cdfadf5d6d168cb231cfa84bfe92efb07d8678b..4c623ac56f381e94f9b1495d98a3ec530650cf6f 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 eb1d1ad9b0ac1b6981583f3058b83dbd2a92d2cb..735f1aeb504d60d03cc4a24508f607b2a8c9fa46 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 @@ uchar *pagecache_valid_read(PAGECACHE *pagecache, 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 @@ my_bool pagecache_delete(PAGECACHE *pagecache, 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 @@ my_bool pagecache_delete(PAGECACHE *pagecache, /* 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 @@ my_bool pagecache_write_part(PAGECACHE *pagecache, 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 @@ my_bool pagecache_write_part(PAGECACHE *pagecache, } } - if (need_lock_change) { /* @@ -3316,7 +3325,7 @@ my_bool pagecache_write_part(PAGECACHE *pagecache, */ 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 b45346725e6fd9db8d543e3d53675eacdb8f79db..d5d758da4d6eec4b1dcb9c7d45edfeeb0740a1e0 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 ab2546b72f39d8a4622bd1204cd5d22cf4da0cef..f5e143fe6f8fadadfed49379433cab991adcd5ef 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 72c40741a22f1515fd2deba944164454c95e7622..f425d41a27e1b964428c0d746aad3161faa25c29 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 f3df1e82c4b4ee7f33a8677aa7726edc99531ad8..601c24794737da179550d6656fc9344671c6ef80 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); }