mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
Merge with 5.1
This commit is contained in:
commit
215043b7c2
39 changed files with 303 additions and 52 deletions
|
@ -4,7 +4,10 @@ path=`dirname $0`
|
|||
. "$path/SETUP.sh"
|
||||
|
||||
extra_flags="$pentium64_cflags $fast_cflags"
|
||||
extra_configs="$pentium_configs $static_link"
|
||||
# On CentOS/Fedora Core 10 amd64, there is system libz.so but not
|
||||
# libz.a, so need to use bundled zlib when building static
|
||||
# binary. Hence we use --with-zlib-dir=bundled
|
||||
extra_configs="$pentium_configs $static_link --with-zlib-dir=bundled"
|
||||
CC="$CC --pipe"
|
||||
strip=yes
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ dnl
|
|||
dnl When changing the major version number please also check the switch
|
||||
dnl statement in mysqlbinlog::check_master_version(). You may also need
|
||||
dnl to update version.c in ndb.
|
||||
|
||||
AC_INIT([MariaDB Server], [5.2.5-MariaDB], [], [mysql])
|
||||
|
||||
AC_CONFIG_SRCDIR([sql/mysqld.cc])
|
||||
|
|
|
@ -4,13 +4,14 @@ this directory. It will fire up the newly built mysqld and test it.
|
|||
|
||||
Note that you do not have to have to do "make install", and you could
|
||||
actually have a co-existing MySQL installation. The tests will not
|
||||
conflict with it.
|
||||
conflict with it. To run the test suite in a source directory, you
|
||||
must do make first.
|
||||
|
||||
All tests must pass. If one or more of them fail on your system, please
|
||||
read the following manual section for instructions on how to report the
|
||||
problem:
|
||||
|
||||
http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html
|
||||
http://kb.askmonty.org/v/reporting-bugs
|
||||
|
||||
If you want to use an already running MySQL server for specific tests,
|
||||
use the --extern option to mysql-test-run. Please note that in this mode,
|
||||
|
@ -27,7 +28,6 @@ With no test cases named on the command line, mysql-test-run falls back
|
|||
to the normal "non-extern" behavior. The reason for this is that some
|
||||
tests cannot run with an external server.
|
||||
|
||||
|
||||
You can create your own test cases. To create a test case, create a new
|
||||
file in the t subdirectory using a text editor. The file should have a .test
|
||||
extension. For example:
|
||||
|
@ -67,7 +67,12 @@ extension. For example:
|
|||
edit the test result to the correct results so that we can verify
|
||||
that the bug is corrected in future releases.
|
||||
|
||||
To submit your test case, put your .test file and .result file(s) into
|
||||
a tar.gz archive, add a README that explains the problem, ftp the
|
||||
archive to ftp://support.mysql.com/pub/mysql/secret/ and send a mail
|
||||
to bugs@lists.mysql.com
|
||||
If you want to submit your test case you can send it
|
||||
to maria-developers@lists.launchpad.com or attach it to a bug report on
|
||||
https://bugs.launchpad.net/maria/.
|
||||
|
||||
If the test case is really big or if it contains 'not public' data,
|
||||
then put your .test file and .result file(s) into a tar.gz archive,
|
||||
add a README that explains the problem, ftp the archive to
|
||||
ftp://ftp.askmonty.org/private and send a mail to
|
||||
https://bugs.launchpad.net/maria/ about it.
|
||||
|
|
|
@ -42,6 +42,7 @@ send STOP SLAVE SQL_THREAD;
|
|||
connection slave1;
|
||||
--echo # To resume slave SQL thread
|
||||
SET DEBUG_SYNC= 'now SIGNAL signal.continue';
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR signal.continued';
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
|
||||
--echo
|
||||
|
|
4
mysql-test/include/long_test.inc
Normal file
4
mysql-test/include/long_test.inc
Normal file
|
@ -0,0 +1,4 @@
|
|||
# We use this --source include to mark a test as taking long to run.
|
||||
# We can use this to schedule such test early (to not be left with
|
||||
# only one or two long tests running, and rests of works idle), or to
|
||||
# run a quick test skipping long-running test cases.
|
|
@ -89,6 +89,20 @@ sub init_pattern {
|
|||
}
|
||||
|
||||
|
||||
sub testcase_sort_order {
|
||||
my ($a, $b, $sort_criteria)= @_;
|
||||
my $a_sort_criteria= $sort_criteria->{$a->fullname()};
|
||||
my $b_sort_criteria= $sort_criteria->{$b->fullname()};
|
||||
my $res= $a_sort_criteria cmp $b_sort_criteria;
|
||||
return $res if $res;
|
||||
# Run slow tests first, trying to avoid getting stuck at the end
|
||||
# with a slow test in one worker and the other workers idle.
|
||||
return -1 if $a->{'long_test'} && !$b->{'long_test'};
|
||||
return 1 if !$a->{'long_test'} && $b->{'long_test'};
|
||||
|
||||
return $a->fullname() cmp $b->fullname();
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Collect information about test cases to be run
|
||||
|
@ -177,9 +191,7 @@ sub collect_test_cases ($$$) {
|
|||
$sort_criteria{$tinfo->fullname()} = join(" ", @criteria);
|
||||
}
|
||||
|
||||
@$cases = sort {
|
||||
$sort_criteria{$a->fullname()} . $a->fullname() cmp
|
||||
$sort_criteria{$b->fullname()} . $b->fullname() } @$cases;
|
||||
@$cases = sort { testcase_sort_order($a, $b, \%sort_criteria) } @$cases;
|
||||
|
||||
# For debugging the sort-order
|
||||
# foreach my $tinfo (@$cases)
|
||||
|
@ -1065,6 +1077,7 @@ my @tags=
|
|||
["include/have_example_plugin.inc", "example_plugin_test", 1],
|
||||
["include/have_oqgraph_engine.inc", "oqgraph_test", 1],
|
||||
["include/have_ssl.inc", "need_ssl", 1],
|
||||
["include/long_test.inc", "long_test", 1],
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -729,9 +729,11 @@ sub run_test_server ($$$) {
|
|||
last;
|
||||
}
|
||||
|
||||
# Second best choice is the first that does not fulfill
|
||||
# any of the above conditions
|
||||
if (!defined $second_best){
|
||||
# From secondary choices, we prefer to pick a 'long-running' test if
|
||||
# possible; this helps avoid getting stuck with a few of those at the
|
||||
# end of high --parallel runs, with most workers being idle.
|
||||
if (!defined $second_best ||
|
||||
($t->{'long_test'} && !($tests->[$second_best]{'long_test'}))){
|
||||
#mtr_report("Setting second_best to $i");
|
||||
$second_best= $i;
|
||||
}
|
||||
|
|
|
@ -4749,4 +4749,15 @@ sum(a) sub
|
|||
1 3
|
||||
deallocate prepare stmt1;
|
||||
drop table t1,t2;
|
||||
#
|
||||
# Bug LP#693935/#58727: Assertion failure with
|
||||
# a single row subquery returning more than one row
|
||||
#
|
||||
create table t1 (a char(1) charset utf8);
|
||||
insert into t1 values ('a'), ('b');
|
||||
create table t2 (a binary(1));
|
||||
insert into t2 values ('x'), ('y');
|
||||
select * from t2 where a=(select a from t1) and a='x';
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
drop table t1,t2;
|
||||
End of 5.1 tests
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
--source include/have_debug.inc
|
||||
--source include/long_test.inc
|
||||
--source federated.inc
|
||||
|
||||
--echo #
|
||||
|
|
|
@ -2617,6 +2617,13 @@ rows 3
|
|||
Extra Using index
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# ALTER TABLE IGNORE didn't ignore duplicates for unique add index
|
||||
#
|
||||
create table t1 (a int primary key, b int) engine = innodb;
|
||||
insert into t1 values (1,1),(2,1);
|
||||
alter ignore table t1 add unique `main` (b);
|
||||
drop table t1;
|
||||
#
|
||||
End of 5.1 tests
|
||||
#
|
||||
# Test for bug #39932 "create table fails if column for FK is in different
|
||||
|
|
|
@ -840,6 +840,15 @@ CREATE INDEX b ON t1(a,b,c,d);
|
|||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # ALTER TABLE IGNORE didn't ignore duplicates for unique add index
|
||||
--echo #
|
||||
|
||||
create table t1 (a int primary key, b int) engine = innodb;
|
||||
insert into t1 values (1,1),(2,1);
|
||||
alter ignore table t1 add unique `main` (b);
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
|
||||
|
||||
|
|
|
@ -2624,3 +2624,19 @@ KEY (v3)
|
|||
INSERT INTO t1 ( f1 , f2 , f3 , f4 ) SELECT f1 , f4 , f1 , f4 FROM t1;
|
||||
DELETE FROM t1;
|
||||
drop table t1;
|
||||
create table t1 (a int not null primary key, b blob) engine=maria transactional=1;
|
||||
insert into t1 values(1,repeat('a',8000));
|
||||
insert into t1 values(2,repeat('b',8000));
|
||||
insert into t1 values(3,repeat('c',8000));
|
||||
flush tables;
|
||||
delete from t1 where a>1;
|
||||
insert into t1 values(1,repeat('d',8000*3));
|
||||
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||
flush tables;
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
repair table t1 extended;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 repair status OK
|
||||
drop table t1;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
# Binary must be compiled with debug for crash to occur
|
||||
--source include/have_debug.inc
|
||||
--source include/have_maria.inc
|
||||
--source include/long_test.inc
|
||||
|
||||
set global aria_log_file_size=4294967295;
|
||||
let $MARIA_LOG=.;
|
||||
|
|
|
@ -1910,6 +1910,24 @@ INSERT INTO t1 ( f1 , f2 , f3 , f4 ) SELECT f1 , f4 , f1 , f4 FROM t1;
|
|||
DELETE FROM t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test of problem where REPAIR finds old deleted rows.
|
||||
#
|
||||
|
||||
create table t1 (a int not null primary key, b blob) engine=maria transactional=1;
|
||||
insert into t1 values(1,repeat('a',8000));
|
||||
insert into t1 values(2,repeat('b',8000));
|
||||
insert into t1 values(3,repeat('c',8000));
|
||||
flush tables;
|
||||
delete from t1 where a>1;
|
||||
--error 1062
|
||||
insert into t1 values(1,repeat('d',8000*3));
|
||||
flush tables;
|
||||
check table t1;
|
||||
# This failed by finding 2 extra rows.
|
||||
repair table t1 extended;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# End of test
|
||||
#
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
# any of the variables.
|
||||
#
|
||||
|
||||
--source include/long_test.inc
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# General not engine specific settings and requirements
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
# any of the variables.
|
||||
#
|
||||
|
||||
--source include/long_test.inc
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# General not engine specific settings and requirements
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
# any of the variables.
|
||||
#
|
||||
|
||||
--source include/long_test.inc
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# General not engine specific settings and requirements
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
# any of the variables.
|
||||
#
|
||||
|
||||
--source include/long_test.inc
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# General not engine specific settings and requirements
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
# any of the variables.
|
||||
#
|
||||
|
||||
--source include/long_test.inc
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# General not engine specific settings and requirements
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
# any of the variables.
|
||||
#
|
||||
|
||||
--source include/long_test.inc
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# General not engine specific settings and requirements
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ STOP SLAVE SQL_THREAD;
|
|||
[ On Slave1 ]
|
||||
# To resume slave SQL thread
|
||||
SET DEBUG_SYNC= 'now SIGNAL signal.continue';
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR signal.continued';
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
|
||||
[ On Slave ]
|
||||
|
@ -63,6 +64,7 @@ STOP SLAVE SQL_THREAD;
|
|||
[ On Slave1 ]
|
||||
# To resume slave SQL thread
|
||||
SET DEBUG_SYNC= 'now SIGNAL signal.continue';
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR signal.continued';
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
|
||||
[ On Slave ]
|
||||
|
@ -89,6 +91,7 @@ STOP SLAVE SQL_THREAD;
|
|||
[ On Slave1 ]
|
||||
# To resume slave SQL thread
|
||||
SET DEBUG_SYNC= 'now SIGNAL signal.continue';
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR signal.continued';
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
|
||||
[ On Slave ]
|
||||
|
@ -115,6 +118,7 @@ STOP SLAVE SQL_THREAD;
|
|||
[ On Slave1 ]
|
||||
# To resume slave SQL thread
|
||||
SET DEBUG_SYNC= 'now SIGNAL signal.continue';
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR signal.continued';
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
|
||||
[ On Slave ]
|
||||
|
|
|
@ -7,5 +7,6 @@
|
|||
########################################################
|
||||
-- source include/not_ndb_default.inc
|
||||
-- source include/have_innodb.inc
|
||||
-- source include/long_test.inc
|
||||
let $engine_type=innodb;
|
||||
-- source extra/rpl_tests/rpl_deadlock.test
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
-- source include/have_binlog_format_row.inc
|
||||
# Slow test, don't run during staging part
|
||||
-- source include/not_staging.inc
|
||||
--source include/long_test.inc
|
||||
-- source include/master-slave.inc
|
||||
|
||||
let $engine_type=INNODB;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
--source include/long_test.inc
|
||||
|
||||
#
|
||||
# test of left outer join
|
||||
#
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
--source include/long_test.inc
|
||||
|
||||
#
|
||||
# Test of update statement that uses many tables.
|
||||
#
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
-- source include/have_pool_of_threads.inc
|
||||
# Slow test, don't run during staging part
|
||||
-- source include/not_staging.inc
|
||||
-- source include/long_test.inc
|
||||
-- source include/common-tests.inc
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
-- source include/have_query_cache.inc
|
||||
-- source include/long_test.inc
|
||||
|
||||
#
|
||||
# Tests with query cache
|
||||
|
|
|
@ -3759,4 +3759,19 @@ deallocate prepare stmt1;
|
|||
|
||||
drop table t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # Bug LP#693935/#58727: Assertion failure with
|
||||
--echo # a single row subquery returning more than one row
|
||||
--echo #
|
||||
|
||||
create table t1 (a char(1) charset utf8);
|
||||
insert into t1 values ('a'), ('b');
|
||||
create table t2 (a binary(1));
|
||||
insert into t2 values ('x'), ('y');
|
||||
|
||||
-- error ER_SUBQUERY_NO_1_ROW
|
||||
select * from t2 where a=(select a from t1) and a='x';
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
|
11
sql/item.h
11
sql/item.h
|
@ -574,10 +574,17 @@ public:
|
|||
Field *make_string_field(TABLE *table);
|
||||
virtual bool fix_fields(THD *, Item **);
|
||||
/*
|
||||
should be used in case where we are sure that we do not need
|
||||
This method should be used in case where we are sure that we do not need
|
||||
complete fix_fields() procedure.
|
||||
Usually this method is used by the optimizer when it has to create a new
|
||||
item out of other already fixed items. For example, if the optimizer has
|
||||
to create a new Item_func for an inferred equality whose left and right
|
||||
parts are already fixed items. In some cases the optimizer cannot use
|
||||
directly fixed items as the arguments of the created functional item,
|
||||
but rather uses intermediate type conversion items. Then the method is
|
||||
supposed to be applied recursively.
|
||||
*/
|
||||
inline void quick_fix_field() { fixed= 1; }
|
||||
virtual inline void quick_fix_field() { fixed= 1; }
|
||||
/* Function returns 1 on overflow and -1 on fatal errors */
|
||||
int save_in_field_no_warnings(Field *field, bool no_conversions);
|
||||
virtual int save_in_field(Field *field, bool no_conversions);
|
||||
|
|
|
@ -202,6 +202,21 @@ Item_func::fix_fields(THD *thd, Item **ref)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
Item_func::quick_fix_field()
|
||||
{
|
||||
Item **arg,**arg_end;
|
||||
if (arg_count)
|
||||
{
|
||||
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
|
||||
{
|
||||
if (!(*arg)->fixed)
|
||||
(*arg)->quick_fix_field();
|
||||
}
|
||||
}
|
||||
fixed= 1;
|
||||
}
|
||||
|
||||
|
||||
bool Item_func::walk(Item_processor processor, bool walk_subquery,
|
||||
uchar *argument)
|
||||
|
|
|
@ -117,6 +117,7 @@ public:
|
|||
// Constructor used for Item_cond_and/or (see Item comment)
|
||||
Item_func(THD *thd, Item_func *item);
|
||||
bool fix_fields(THD *, Item **ref);
|
||||
void quick_fix_field();
|
||||
table_map used_tables() const;
|
||||
table_map not_null_tables() const;
|
||||
void update_used_tables();
|
||||
|
|
|
@ -3233,12 +3233,17 @@ end_with_restore_list:
|
|||
|
||||
DBUG_EXECUTE_IF("after_mysql_insert",
|
||||
{
|
||||
const char act[]=
|
||||
const char act1[]=
|
||||
"now "
|
||||
"wait_for signal.continue";
|
||||
const char act2[]=
|
||||
"now "
|
||||
"signal signal.continued";
|
||||
DBUG_ASSERT(opt_debug_sync_timeout > 0);
|
||||
DBUG_ASSERT(!debug_sync_set_action(current_thd,
|
||||
STRING_WITH_LEN(act)));
|
||||
DBUG_ASSERT(!debug_sync_set_action(thd,
|
||||
STRING_WITH_LEN(act1)));
|
||||
DBUG_ASSERT(!debug_sync_set_action(thd,
|
||||
STRING_WITH_LEN(act2)));
|
||||
};);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -11214,6 +11214,11 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
|
|||
DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
|
||||
if (write_err)
|
||||
goto err;
|
||||
if (thd->killed)
|
||||
{
|
||||
thd->send_kill_message();
|
||||
goto err_killed;
|
||||
}
|
||||
}
|
||||
/* copy row that filled HEAP table */
|
||||
if ((write_err=new_table.file->ha_write_row(table->record[0])))
|
||||
|
@ -11244,6 +11249,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
|
|||
err:
|
||||
DBUG_PRINT("error",("Got error: %d",write_err));
|
||||
table->file->print_error(write_err, MYF(0));
|
||||
err_killed:
|
||||
(void) table->file->ha_rnd_end();
|
||||
(void) new_table.file->close();
|
||||
err1:
|
||||
|
|
|
@ -7228,6 +7228,16 @@ view_err:
|
|||
/* Non-primary unique key. */
|
||||
needed_online_flags|= HA_ONLINE_ADD_UNIQUE_INDEX;
|
||||
needed_fast_flags|= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES;
|
||||
if (ignore)
|
||||
{
|
||||
/*
|
||||
If ignore is used, we have to remove all duplicate rows,
|
||||
which require a full table copy.
|
||||
*/
|
||||
need_copy_table= ALTER_TABLE_DATA_CHANGED;
|
||||
pk_changed= 2; // Don't change need_copy_table
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -399,7 +399,8 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
|
|||
become false, wake them up.
|
||||
*/
|
||||
DBUG_PRINT("info", ("bitmap flusher waking up others"));
|
||||
pthread_cond_broadcast(&bitmap->bitmap_cond);
|
||||
if (bitmap->flush_all_requested)
|
||||
pthread_cond_broadcast(&bitmap->bitmap_cond);
|
||||
}
|
||||
pthread_mutex_unlock(&bitmap->bitmap_lock);
|
||||
DBUG_RETURN(res);
|
||||
|
@ -465,7 +466,8 @@ void _ma_bitmap_unlock(MARIA_SHARE *share)
|
|||
bitmap->flush_all_requested--;
|
||||
bitmap->non_flushable= 0;
|
||||
pthread_mutex_unlock(&bitmap->bitmap_lock);
|
||||
pthread_cond_broadcast(&bitmap->bitmap_cond);
|
||||
if (bitmap->flush_all_requested > 0)
|
||||
pthread_cond_broadcast(&bitmap->bitmap_cond);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
|
@ -2506,7 +2506,7 @@ static my_bool free_full_page_range(MARIA_HA *info, pgcache_page_no_t page,
|
|||
}
|
||||
if (delete_count &&
|
||||
pagecache_delete_pages(share->pagecache, &info->dfile,
|
||||
page, delete_count, PAGECACHE_LOCK_WRITE, 0))
|
||||
page, delete_count, PAGECACHE_LOCK_WRITE, 1))
|
||||
res= 1;
|
||||
|
||||
if (share->now_transactional)
|
||||
|
@ -2816,7 +2816,6 @@ static my_bool write_block_record(MARIA_HA *info,
|
|||
DBUG_PRINT("info", ("Used head length on page: %u header_length: %u",
|
||||
head_length,
|
||||
(uint) (flag & ROW_FLAG_TRANSID ? TRANSID_SIZE : 0)));
|
||||
DBUG_ASSERT(data <= end_of_data);
|
||||
if (head_length < share->base.min_block_length)
|
||||
{
|
||||
/* Extend row to be of size min_block_length */
|
||||
|
@ -2825,6 +2824,7 @@ static my_bool write_block_record(MARIA_HA *info,
|
|||
data+= diff_length;
|
||||
head_length= share->base.min_block_length;
|
||||
}
|
||||
DBUG_ASSERT(data <= end_of_data);
|
||||
/*
|
||||
If this is a redo entry (ie, undo_lsn != LSN_ERROR) then we should have
|
||||
written exactly head_length bytes (same as original record).
|
||||
|
@ -3492,7 +3492,9 @@ static my_bool allocate_and_write_block_record(MARIA_HA *info,
|
|||
|
||||
/* page will be pinned & locked by get_head_or_tail_page */
|
||||
if (get_head_or_tail_page(info, blocks->block, info->buff,
|
||||
row->space_on_head_page, HEAD_PAGE,
|
||||
max(row->space_on_head_page,
|
||||
info->s->base.min_block_length),
|
||||
HEAD_PAGE,
|
||||
PAGECACHE_LOCK_WRITE, &row_pos))
|
||||
goto err;
|
||||
row->lastpos= ma_recordpos(blocks->block->page, row_pos.rownr);
|
||||
|
@ -6485,7 +6487,13 @@ err:
|
|||
@param info Maria handler
|
||||
@param header Header (without FILEID)
|
||||
|
||||
@note It marks the pages free in the bitmap
|
||||
Mark the pages free in the bitmap.
|
||||
|
||||
We have to check against _ma_redo_not_needed_for_page()
|
||||
to guard against the case where we first clear a block and after
|
||||
that insert new data into the blocks. If we would unconditionally
|
||||
clear the bitmap here, future changes would be ignored for the page
|
||||
if it's not in the dirty list (ie, it would be flushed).
|
||||
|
||||
@return Operation status
|
||||
@retval 0 OK
|
||||
|
@ -6494,19 +6502,25 @@ err:
|
|||
|
||||
uint _ma_apply_redo_free_blocks(MARIA_HA *info,
|
||||
LSN lsn __attribute__((unused)),
|
||||
LSN redo_lsn,
|
||||
const uchar *header)
|
||||
{
|
||||
MARIA_SHARE *share= info->s;
|
||||
uint ranges;
|
||||
uint16 sid;
|
||||
DBUG_ENTER("_ma_apply_redo_free_blocks");
|
||||
|
||||
share->state.changed|= (STATE_CHANGED | STATE_NOT_ZEROFILLED |
|
||||
STATE_NOT_MOVABLE);
|
||||
|
||||
sid= fileid_korr(header);
|
||||
header+= FILEID_STORE_SIZE;
|
||||
ranges= pagerange_korr(header);
|
||||
header+= PAGERANGE_STORE_SIZE;
|
||||
DBUG_ASSERT(ranges > 0);
|
||||
|
||||
/** @todo leave bitmap lock to the bitmap code... */
|
||||
pthread_mutex_lock(&share->bitmap.bitmap_lock);
|
||||
while (ranges--)
|
||||
{
|
||||
my_bool res;
|
||||
|
@ -6523,18 +6537,22 @@ uint _ma_apply_redo_free_blocks(MARIA_HA *info,
|
|||
|
||||
DBUG_PRINT("info", ("page: %lu pages: %u", (long) page, page_range));
|
||||
|
||||
/** @todo leave bitmap lock to the bitmap code... */
|
||||
pthread_mutex_lock(&share->bitmap.bitmap_lock);
|
||||
res= _ma_bitmap_reset_full_page_bits(info, &share->bitmap, start_page,
|
||||
page_range);
|
||||
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
|
||||
if (res)
|
||||
for ( ; page_range-- ; start_page++)
|
||||
{
|
||||
_ma_mark_file_crashed(share);
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_RETURN(res);
|
||||
if (_ma_redo_not_needed_for_page(sid, redo_lsn, start_page, FALSE))
|
||||
continue;
|
||||
res= _ma_bitmap_reset_full_page_bits(info, &share->bitmap, start_page,
|
||||
1);
|
||||
if (res)
|
||||
{
|
||||
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
|
||||
_ma_mark_file_crashed(share);
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -6764,7 +6782,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
|
|||
PAGECACHE_LOCK_WRITE_UNLOCK,
|
||||
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
||||
LSN_IMPOSSIBLE, 0, FALSE);
|
||||
continue;
|
||||
goto fix_bitmap;
|
||||
}
|
||||
DBUG_ASSERT((found_page_type == (uchar) BLOB_PAGE) ||
|
||||
(found_page_type == (uchar) UNALLOCATED_PAGE));
|
||||
|
@ -6799,14 +6817,16 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
|
|||
unlock_method, unpin_method,
|
||||
PAGECACHE_WRITE_DELAY, 0, LSN_IMPOSSIBLE))
|
||||
goto err;
|
||||
}
|
||||
|
||||
fix_bitmap:
|
||||
/** @todo leave bitmap lock to the bitmap code... */
|
||||
pthread_mutex_lock(&share->bitmap.bitmap_lock);
|
||||
res= _ma_bitmap_set_full_page_bits(info, &share->bitmap, start_page,
|
||||
page_range);
|
||||
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
|
||||
if (res)
|
||||
goto err;
|
||||
pthread_mutex_lock(&share->bitmap.bitmap_lock);
|
||||
res= _ma_bitmap_set_full_page_bits(info, &share->bitmap, page,
|
||||
1);
|
||||
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
|
||||
if (res)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
*first_page= first_page2;
|
||||
|
|
|
@ -235,7 +235,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||
uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
uint page_type,
|
||||
const uchar *header);
|
||||
uint _ma_apply_redo_free_blocks(MARIA_HA *info, LSN lsn,
|
||||
uint _ma_apply_redo_free_blocks(MARIA_HA *info, LSN lsn, LSN rec_lsn,
|
||||
const uchar *header);
|
||||
uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
const uchar *header);
|
||||
|
|
|
@ -100,6 +100,9 @@ static my_bool _ma_flush_table_files_before_swap(HA_CHECK *param,
|
|||
static TrID max_trid_in_system(void);
|
||||
static void _ma_check_print_not_visible_error(HA_CHECK *param, TrID used_trid);
|
||||
void retry_if_quick(MARIA_SORT_PARAM *param, int error);
|
||||
static void print_bitmap_description(MARIA_SHARE *share,
|
||||
pgcache_page_no_t page,
|
||||
uchar *buff);
|
||||
|
||||
|
||||
/* Initialize check param with default values */
|
||||
|
@ -1842,6 +1845,8 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
|
|||
}
|
||||
param->used+= block_size;
|
||||
param->link_used+= block_size;
|
||||
if (param->verbose > 2)
|
||||
print_bitmap_description(share, page, bitmap_buff);
|
||||
continue;
|
||||
}
|
||||
/* Skip pages marked as empty in bitmap */
|
||||
|
@ -2177,12 +2182,17 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
|
|||
llstr(param->del_length, llbuff2));
|
||||
printf("Empty space: %12s Linkdata: %10s\n",
|
||||
llstr(param->empty, llbuff),llstr(param->link_used, llbuff2));
|
||||
if (param->lost)
|
||||
printf("Lost space: %12s", llstr(param->lost, llbuff));
|
||||
if (param->max_found_trid)
|
||||
if (share->data_file_type == BLOCK_RECORD)
|
||||
{
|
||||
printf("Max trans. id: %11s\n",
|
||||
llstr(param->max_found_trid, llbuff));
|
||||
printf("Full pages: %12s Tail count: %12s\n",
|
||||
llstr(param->full_page_count, llbuff),
|
||||
llstr(param->tail_count, llbuff2));
|
||||
printf("Lost space: %12s\n", llstr(param->lost, llbuff));
|
||||
if (param->max_found_trid)
|
||||
{
|
||||
printf("Max trans. id: %11s\n",
|
||||
llstr(param->max_found_trid, llbuff));
|
||||
}
|
||||
}
|
||||
}
|
||||
my_free(record,MYF(0));
|
||||
|
@ -6799,3 +6809,46 @@ void retry_if_quick(MARIA_SORT_PARAM *sort_param, int error)
|
|||
param->testflag|=T_RETRY_WITHOUT_QUICK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print information about bitmap page */
|
||||
|
||||
static void print_bitmap_description(MARIA_SHARE *share,
|
||||
pgcache_page_no_t page,
|
||||
uchar *bitmap_data)
|
||||
{
|
||||
uchar *pos, *end;
|
||||
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
|
||||
uint count=0, dot_printed= 0;
|
||||
char buff[80], last[80];
|
||||
|
||||
printf("Bitmap page %lu\n", (ulong) page);
|
||||
page++;
|
||||
last[0]=0;
|
||||
for (pos= bitmap_data, end= pos+ bitmap->used_size ; pos < end ; pos+= 6)
|
||||
{
|
||||
ulonglong bits= uint6korr(pos); /* 6 bytes = 6*8/3= 16 patterns */
|
||||
uint i;
|
||||
|
||||
for (i= 0; i < 16 ; i++, bits>>= 3)
|
||||
{
|
||||
if (count > 60)
|
||||
{
|
||||
buff[count]= 0;
|
||||
if (strcmp(buff, last))
|
||||
{
|
||||
memcpy(last, buff, count+1);
|
||||
printf("%8lu: %s\n", (ulong) page - count, buff);
|
||||
dot_printed= 0;
|
||||
}
|
||||
else if (!(dot_printed++))
|
||||
printf("...\n");
|
||||
count= 0;
|
||||
}
|
||||
buff[count++]= '0' + (uint) (bits & 7);
|
||||
page++;
|
||||
}
|
||||
}
|
||||
buff[count]= 0;
|
||||
printf("%8lu: %s\n", (ulong) page - count, buff);
|
||||
fputs("\n", stdout);
|
||||
}
|
||||
|
|
|
@ -1643,8 +1643,8 @@ prototype_redo_exec_hook(REDO_FREE_BLOCKS)
|
|||
}
|
||||
|
||||
buff= log_record_buffer.str;
|
||||
if (_ma_apply_redo_free_blocks(info, current_group_end_lsn,
|
||||
buff + FILEID_STORE_SIZE))
|
||||
if (_ma_apply_redo_free_blocks(info, current_group_end_lsn, rec->lsn,
|
||||
buff))
|
||||
goto end;
|
||||
error= 0;
|
||||
end:
|
||||
|
@ -3015,10 +3015,11 @@ static MARIA_HA *get_MARIA_HA_from_REDO_record(const
|
|||
page= page_korr(rec->header + FILEID_STORE_SIZE);
|
||||
llstr(page, llbuf);
|
||||
break;
|
||||
case LOGREC_REDO_FREE_BLOCKS:
|
||||
/*
|
||||
For REDO_FREE_BLOCKS, no need to look at dirty pages list: it does not
|
||||
read data pages, only reads/modifies bitmap page(s) which is cheap.
|
||||
We are checking against the dirty pages in _ma_apply_redo_free_blocks()
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue