mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge bk-internal.mysql.com:/home/bk/mysql-maria
into mysql.com:/home/my/mysql-maria include/maria.h: Auto merged sql/handler.h: Auto merged storage/maria/ha_maria.cc: Auto merged storage/maria/ma_close.c: Auto merged storage/maria/ma_loghandler.c: Auto merged storage/maria/ma_open.c: Auto merged storage/maria/ma_pagecache.c: Auto merged storage/maria/ma_pagecache.h: Auto merged storage/maria/maria_chk.c: Auto merged storage/maria/ma_blockrec.c: Manual merge (No changes) storage/maria/ma_check.c: Manual merge storage/maria/ma_create.c: Manual merge storage/maria/ma_delete_all.c: Manual merge storage/maria/ma_init.c: Manual merge (no changes) storage/maria/ma_test_all.sh: Manual merge storage/maria/maria_def.h: Manual merge
This commit is contained in:
commit
e2904e77f1
50 changed files with 958 additions and 345 deletions
|
@ -325,17 +325,18 @@ typedef struct st_maria_sort_info
|
|||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
#endif
|
||||
MARIA_HA *info;
|
||||
MARIA_HA *info, *new_info;
|
||||
HA_CHECK *param;
|
||||
char *buff;
|
||||
SORT_KEY_BLOCKS *key_block, *key_block_end;
|
||||
SORT_FT_BUF *ft_buf;
|
||||
my_off_t filelength, dupp, buff_length;
|
||||
ulonglong page;
|
||||
ha_rows max_records;
|
||||
uint current_key, total_keys;
|
||||
uint got_error, threads_running;
|
||||
myf myf_rw;
|
||||
enum data_file_type new_data_file_type;
|
||||
enum data_file_type new_data_file_type, org_data_file_type;
|
||||
} MARIA_SORT_INFO;
|
||||
|
||||
typedef struct st_maria_sort_param
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */
|
||||
#define HA_OPEN_FROM_SQL_LAYER 64
|
||||
#define HA_OPEN_MMAP 128 /* open memory mapped */
|
||||
#define HA_OPEN_COPY 256 /* Open copy (for repair) */
|
||||
|
||||
/* The following is parameter to ha_rkey() how to use key */
|
||||
|
||||
|
|
|
@ -110,7 +110,8 @@ extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|||
uint *diff_pos);
|
||||
|
||||
extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a);
|
||||
|
||||
extern void my_handler_error_register(void);
|
||||
extern void my_handler_error_unregister(void);
|
||||
/*
|
||||
Inside an in-memory data record, memory pointers to pieces of the
|
||||
record (like BLOBs) are stored in their native byte order and in
|
||||
|
|
|
@ -52,7 +52,7 @@ set @arg14= 'abc';
|
|||
set @arg14= NULL ;
|
||||
set @arg15= CAST('abc' as binary) ;
|
||||
set @arg15= NULL ;
|
||||
create table t5 as select
|
||||
eval create table t5 engine = MyISAM as select
|
||||
8 as const01, @arg01 as param01,
|
||||
8.0 as const02, @arg02 as param02,
|
||||
80.00000000000e-1 as const03, @arg03 as param03,
|
||||
|
|
23
mysql-test/r/maria-connect.result
Normal file
23
mysql-test/r/maria-connect.result
Normal file
|
@ -0,0 +1,23 @@
|
|||
set global storage_engine=maria;
|
||||
set session storage_engine=maria;
|
||||
drop table if exists t1;
|
||||
SET SQL_WARNINGS=1;
|
||||
RESET MASTER;
|
||||
set binlog_format=statement;
|
||||
CREATE TABLE t1 (a int primary key);
|
||||
insert t1 values (1),(2),(3);
|
||||
insert t1 values (4),(2),(5);
|
||||
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
SHOW BINLOG EVENTS FROM 102;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 102 Query 1 200 use `test`; CREATE TABLE t1 (a int primary key)
|
||||
master-bin.000001 200 Query 1 291 use `test`; insert t1 values (1),(2),(3)
|
||||
master-bin.000001 291 Query 1 382 use `test`; insert t1 values (4),(2),(5)
|
||||
drop table t1;
|
||||
set binlog_format=default;
|
|
@ -2,25 +2,6 @@ set global storage_engine=maria;
|
|||
set session storage_engine=maria;
|
||||
drop table if exists t1,t2;
|
||||
SET SQL_WARNINGS=1;
|
||||
RESET MASTER;
|
||||
set binlog_format=statement;
|
||||
CREATE TABLE t1 (a int primary key);
|
||||
insert t1 values (1),(2),(3);
|
||||
insert t1 values (4),(2),(5);
|
||||
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
SHOW BINLOG EVENTS FROM 102;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 102 Query 1 200 use `test`; CREATE TABLE t1 (a int primary key)
|
||||
master-bin.000001 200 Query 1 291 use `test`; insert t1 values (1),(2),(3)
|
||||
master-bin.000001 291 Query 1 382 use `test`; insert t1 values (4),(2),(5)
|
||||
drop table t1;
|
||||
set binlog_format=default;
|
||||
CREATE TABLE t1 (
|
||||
STRING_DATA char(255) default NULL,
|
||||
KEY string_data (STRING_DATA)
|
||||
|
@ -618,7 +599,7 @@ t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
|
|||
alter table t1 enable keys;
|
||||
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 NULL NULL NULL YES BTREE disabled
|
||||
t1 1 a 1 a A NULL NULL NULL YES BTREE
|
||||
alter table t1 engine=heap;
|
||||
alter table t1 disable keys;
|
||||
Warnings:
|
||||
|
@ -853,19 +834,19 @@ _id
|
|||
DELETE FROM t1 WHERE _id < 8;
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 MARIA 10 Paged 2 # # # # 0 # # # # # #
|
||||
t1 MARIA 10 Page 2 # # # # 0 # # # # # #
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize status Table is already up to date
|
||||
test.t1 optimize status OK
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 MARIA 10 Paged 2 # # # # 0 # # # # # #
|
||||
t1 MARIA 10 Page 2 # # # # 0 # # # # # #
|
||||
SELECT _id FROM t1;
|
||||
_id
|
||||
8
|
||||
|
@ -912,7 +893,7 @@ _id
|
|||
DELETE FROM t1 WHERE _id < 8;
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 MARIA 10 Paged 2 # # # # 0 # # # # # #
|
||||
t1 MARIA 10 Page 2 # # # # 0 # # # # # #
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
|
@ -924,7 +905,7 @@ Table Op Msg_type Msg_text
|
|||
test.t1 check status OK
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 MARIA 10 Paged 2 # # # # 0 # # # # # #
|
||||
t1 MARIA 10 Page 2 # # # # 0 # # # # # #
|
||||
SELECT _id FROM t1;
|
||||
_id
|
||||
8
|
||||
|
@ -1598,7 +1579,7 @@ alter table t1 disable keys;
|
|||
alter table t1 enable keys;
|
||||
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 disabled
|
||||
t1 1 a 1 a A 8 NULL NULL YES BTREE
|
||||
drop table t1;
|
||||
show create table t1;
|
||||
show create table t1;
|
||||
|
@ -1811,3 +1792,43 @@ CHECK TABLE t1;
|
|||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
DROP TABLE t1;
|
||||
create table t1 (a int) transactional=0;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 TRANSACTIONAL=0
|
||||
drop table t1;
|
||||
create table t1 (a int) row_format=dynamic transactional=0;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0
|
||||
drop table t1;
|
||||
create table t1 (a int) row_format=dynamic transactional=1;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC TRANSACTIONAL=1
|
||||
alter table t1 row_format=PAGE;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE TRANSACTIONAL=1
|
||||
alter table t1 transactional=0;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE TRANSACTIONAL=0
|
||||
drop table t1;
|
||||
create table t1 (a int) row_format=PAGE;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE
|
||||
drop table t1;
|
||||
|
|
|
@ -1756,7 +1756,7 @@ set @arg14= 'abc';
|
|||
set @arg14= NULL ;
|
||||
set @arg15= CAST('abc' as binary) ;
|
||||
set @arg15= NULL ;
|
||||
create table t5 as select
|
||||
create table t5 engine = MyISAM as select
|
||||
8 as const01, @arg01 as param01,
|
||||
8.0 as const02, @arg02 as param02,
|
||||
80.00000000000e-1 as const03, @arg03 as param03,
|
||||
|
|
|
@ -1739,7 +1739,7 @@ set @arg14= 'abc';
|
|||
set @arg14= NULL ;
|
||||
set @arg15= CAST('abc' as binary) ;
|
||||
set @arg15= NULL ;
|
||||
create table t5 as select
|
||||
create table t5 engine = MyISAM as select
|
||||
8 as const01, @arg01 as param01,
|
||||
8.0 as const02, @arg02 as param02,
|
||||
80.00000000000e-1 as const03, @arg03 as param03,
|
||||
|
|
|
@ -1740,7 +1740,7 @@ set @arg14= 'abc';
|
|||
set @arg14= NULL ;
|
||||
set @arg15= CAST('abc' as binary) ;
|
||||
set @arg15= NULL ;
|
||||
create table t5 as select
|
||||
create table t5 engine = MyISAM as select
|
||||
8 as const01, @arg01 as param01,
|
||||
8.0 as const02, @arg02 as param02,
|
||||
80.00000000000e-1 as const03, @arg03 as param03,
|
||||
|
|
|
@ -1676,7 +1676,7 @@ set @arg14= 'abc';
|
|||
set @arg14= NULL ;
|
||||
set @arg15= CAST('abc' as binary) ;
|
||||
set @arg15= NULL ;
|
||||
create table t5 as select
|
||||
create table t5 engine = MyISAM as select
|
||||
8 as const01, @arg01 as param01,
|
||||
8.0 as const02, @arg02 as param02,
|
||||
80.00000000000e-1 as const03, @arg03 as param03,
|
||||
|
@ -4690,7 +4690,7 @@ set @arg14= 'abc';
|
|||
set @arg14= NULL ;
|
||||
set @arg15= CAST('abc' as binary) ;
|
||||
set @arg15= NULL ;
|
||||
create table t5 as select
|
||||
create table t5 engine = MyISAM as select
|
||||
8 as const01, @arg01 as param01,
|
||||
8.0 as const02, @arg02 as param02,
|
||||
80.00000000000e-1 as const03, @arg03 as param03,
|
||||
|
|
|
@ -1739,7 +1739,7 @@ set @arg14= 'abc';
|
|||
set @arg14= NULL ;
|
||||
set @arg15= CAST('abc' as binary) ;
|
||||
set @arg15= NULL ;
|
||||
create table t5 as select
|
||||
create table t5 engine = MyISAM as select
|
||||
8 as const01, @arg01 as param01,
|
||||
8.0 as const02, @arg02 as param02,
|
||||
80.00000000000e-1 as const03, @arg03 as param03,
|
||||
|
|
|
@ -1756,7 +1756,7 @@ set @arg14= 'abc';
|
|||
set @arg14= NULL ;
|
||||
set @arg15= CAST('abc' as binary) ;
|
||||
set @arg15= NULL ;
|
||||
create table t5 as select
|
||||
create table t5 engine = MyISAM as select
|
||||
8 as const01, @arg01 as param01,
|
||||
8.0 as const02, @arg02 as param02,
|
||||
80.00000000000e-1 as const03, @arg03 as param03,
|
||||
|
|
39
mysql-test/t/maria-connect.test
Normal file
39
mysql-test/t/maria-connect.test
Normal file
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# Test that can't be run with --extern
|
||||
#
|
||||
|
||||
-- source include/have_maria.inc
|
||||
|
||||
let $default=`select @@global.storage_engine`;
|
||||
set global storage_engine=maria;
|
||||
set session storage_engine=maria;
|
||||
|
||||
# Initialise
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
SET SQL_WARNINGS=1;
|
||||
|
||||
#
|
||||
# UNIQUE key test
|
||||
#
|
||||
# as long as maria cannot rollback, binlog should contain both inserts
|
||||
#
|
||||
RESET MASTER;
|
||||
set binlog_format=statement;
|
||||
CREATE TABLE t1 (a int primary key);
|
||||
insert t1 values (1),(2),(3);
|
||||
--error 1582
|
||||
insert t1 values (4),(2),(5);
|
||||
select * from t1;
|
||||
SHOW BINLOG EVENTS FROM 102;
|
||||
drop table t1;
|
||||
set binlog_format=default;
|
||||
|
||||
# End of 5.2 tests
|
||||
|
||||
--disable_result_log
|
||||
--disable_query_log
|
||||
eval set global storage_engine=$default;
|
||||
--enable_result_log
|
||||
--enable_query_log
|
|
@ -15,22 +15,6 @@ drop table if exists t1,t2;
|
|||
--enable_warnings
|
||||
SET SQL_WARNINGS=1;
|
||||
|
||||
#
|
||||
# UNIQUE key test
|
||||
#
|
||||
# as long as maria cannot rollback, binlog should contain both inserts
|
||||
#
|
||||
RESET MASTER;
|
||||
set binlog_format=statement;
|
||||
CREATE TABLE t1 (a int primary key);
|
||||
insert t1 values (1),(2),(3);
|
||||
--error 1582
|
||||
insert t1 values (4),(2),(5);
|
||||
select * from t1;
|
||||
SHOW BINLOG EVENTS FROM 102;
|
||||
drop table t1;
|
||||
set binlog_format=default;
|
||||
|
||||
#
|
||||
# Test problem with CHECK TABLE;
|
||||
#
|
||||
|
@ -597,10 +581,7 @@ insert t1 select * from t2;
|
|||
show keys from t1;
|
||||
alter table t1 enable keys;
|
||||
show keys from t1;
|
||||
#TODO after we have repair: delete the following --disable-warnings
|
||||
--disable_warnings
|
||||
alter table t1 engine=heap;
|
||||
--enable_warnings
|
||||
alter table t1 disable keys;
|
||||
show keys from t1;
|
||||
drop table t1,t2;
|
||||
|
@ -1072,10 +1053,10 @@ create table t1 (a int not null, key key_block_size=1024 (a));
|
|||
--error 1064
|
||||
create table t1 (a int not null, key `a` key_block_size=1024 (a));
|
||||
|
||||
|
||||
#
|
||||
# Test of changing MI_KEY_BLOCK_LENGTH
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
c1 INT,
|
||||
c2 VARCHAR(300),
|
||||
|
@ -1116,6 +1097,27 @@ DELETE FROM t1 WHERE c1 >= 10;
|
|||
CHECK TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Test that TRANSACTIONAL is preserved
|
||||
#
|
||||
|
||||
create table t1 (a int) transactional=0;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
create table t1 (a int) row_format=dynamic transactional=0;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
create table t1 (a int) row_format=dynamic transactional=1;
|
||||
show create table t1;
|
||||
alter table t1 row_format=PAGE;
|
||||
show create table t1;
|
||||
alter table t1 transactional=0;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
create table t1 (a int) row_format=PAGE;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
# End of 5.2 tests
|
||||
|
||||
--disable_result_log
|
||||
|
|
|
@ -1696,6 +1696,7 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
|
|||
my_bool append_cache;
|
||||
my_off_t pos_in_file;
|
||||
DBUG_ENTER("my_b_flush_io_cache");
|
||||
DBUG_PRINT("enter", ("cache: 0x%lx", (long) info));
|
||||
|
||||
if (!(append_cache = (info->type == SEQ_READ_APPEND)))
|
||||
need_append_buffer_lock=0;
|
||||
|
|
|
@ -107,6 +107,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
|
|||
if (org_file >= 0 && file < 0)
|
||||
{
|
||||
int tmp=my_errno;
|
||||
close(org_file);
|
||||
(void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
|
||||
my_errno=tmp;
|
||||
}
|
||||
|
|
|
@ -84,11 +84,6 @@ int my_error(int nr, myf MyFlags, ...)
|
|||
if (nr <= meh_p->meh_last)
|
||||
break;
|
||||
|
||||
#ifdef SHARED_LIBRARY
|
||||
if ((meh_p == &my_errmsgs_globerrs) && ! globerrs[0])
|
||||
init_glob_errs();
|
||||
#endif
|
||||
|
||||
/* get the error message string. Default, if NULL or empty string (""). */
|
||||
if (! (format= (meh_p && (nr >= meh_p->meh_first)) ?
|
||||
meh_p->meh_errmsgs[nr - meh_p->meh_first] : NULL) || ! *format)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <m_ctype.h>
|
||||
#include <my_base.h>
|
||||
#include <my_handler.h>
|
||||
#include <my_sys.h>
|
||||
|
||||
int ha_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
|
||||
uchar *b, uint b_length, my_bool part_key,
|
||||
|
@ -563,3 +564,68 @@ HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a)
|
|||
return keyseg;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Errors a handler can give you
|
||||
*/
|
||||
|
||||
static const char *handler_error_messages[]=
|
||||
{
|
||||
"Didn't find key on read or update",
|
||||
"Duplicate key on write or update",
|
||||
"Undefined handler error 122",
|
||||
"Someone has changed the row since it was read (while the table was locked to prevent it)",
|
||||
"Wrong index given to function",
|
||||
"Undefined handler error 125",
|
||||
"Index file is crashed",
|
||||
"Record file is crashed",
|
||||
"Out of memory in engine",
|
||||
"Undefined handler error 129",
|
||||
"Incorrect file format",
|
||||
"Command not supported by database",
|
||||
"Old database file",
|
||||
"No record read before update",
|
||||
"Record was already deleted (or record file crashed)",
|
||||
"No more room in record file",
|
||||
"No more room in index file",
|
||||
"No more records (read after end of file)",
|
||||
"Unsupported extension used for table",
|
||||
"Too big row",
|
||||
"Wrong create options",
|
||||
"Duplicate unique key or constraint on write or update",
|
||||
"Unknown character set used in table",
|
||||
"Conflicting table definitions in sub-tables of MERGE table",
|
||||
"Table is crashed and last repair failed",
|
||||
"Table was marked as crashed and should be repaired",
|
||||
"Lock timed out; Retry transaction",
|
||||
"Lock table is full; Restart program with a larger locktable",
|
||||
"Updates are not allowed under a read only transactions",
|
||||
"Lock deadlock; Retry transaction",
|
||||
"Foreign key constraint is incorrectly formed",
|
||||
"Cannot add a child row",
|
||||
"Cannot delete a parent row",
|
||||
"Unknown handler error"
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Register handler error messages for usage with my_error()
|
||||
|
||||
NOTES
|
||||
This is safe to call multiple times as my_error_register()
|
||||
will ignore calls to register already registered error numbers.
|
||||
*/
|
||||
|
||||
|
||||
void my_handler_error_register(void)
|
||||
{
|
||||
my_error_register(handler_error_messages, HA_ERR_FIRST,
|
||||
HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
|
||||
}
|
||||
|
||||
|
||||
void my_handler_error_unregister(void)
|
||||
{
|
||||
my_error_unregister(HA_ERR_FIRST,
|
||||
HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ my_bool my_init(void)
|
|||
mysys_usage_id++;
|
||||
my_umask= 0660; /* Default umask for new files */
|
||||
my_umask_dir= 0700; /* Default umask for new directories */
|
||||
init_glob_errs();
|
||||
#if defined(THREAD) && defined(SAFE_MUTEX)
|
||||
safe_mutex_global_init(); /* Must be called early */
|
||||
#endif
|
||||
|
|
|
@ -71,6 +71,7 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
|
|||
#else
|
||||
fd = open((my_string) FileName, Flags);
|
||||
#endif
|
||||
|
||||
DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_OPEN,
|
||||
EE_FILENOTFOUND, MyFlags));
|
||||
} /* my_open */
|
||||
|
@ -124,61 +125,65 @@ int my_close(File fd, myf MyFlags)
|
|||
|
||||
SYNOPSIS
|
||||
my_register_filename()
|
||||
fd
|
||||
FileName
|
||||
type_file_type
|
||||
fd File number opened, -1 if error on open
|
||||
FileName File name
|
||||
type_file_type How file was created
|
||||
error_message_number Error message number if caller got error (fd == -1)
|
||||
MyFlags Flags for my_close()
|
||||
|
||||
RETURN
|
||||
-1 error
|
||||
# Filenumber
|
||||
|
||||
*/
|
||||
|
||||
File my_register_filename(File fd, const char *FileName, enum file_type
|
||||
type_of_file, uint error_message_number, myf MyFlags)
|
||||
{
|
||||
DBUG_ENTER("my_register_filename");
|
||||
if ((int) fd >= 0)
|
||||
{
|
||||
if ((uint) fd >= my_file_limit)
|
||||
{
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
(void) my_close(fd,MyFlags);
|
||||
my_errno=EMFILE;
|
||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
|
||||
my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
return(-1);
|
||||
#endif
|
||||
my_errno= EMFILE;
|
||||
#else
|
||||
thread_safe_increment(my_file_opened,&THR_LOCK_open);
|
||||
return(fd); /* safeguard */
|
||||
}
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
|
||||
{
|
||||
my_file_opened++;
|
||||
my_file_info[fd].type = type_of_file;
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST);
|
||||
DBUG_RETURN(fd); /* safeguard */
|
||||
#endif
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
DBUG_PRINT("exit",("fd: %d",fd));
|
||||
return(fd);
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
else
|
||||
{
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
|
||||
{
|
||||
my_file_opened++;
|
||||
my_file_info[fd].type = type_of_file;
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST);
|
||||
#endif
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
DBUG_PRINT("exit",("fd: %d",fd));
|
||||
DBUG_RETURN(fd);
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
my_errno= ENOMEM;
|
||||
}
|
||||
(void) my_close(fd, MyFlags);
|
||||
fd= -1;
|
||||
my_errno=ENOMEM;
|
||||
}
|
||||
else
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("error",("Got error %d on open",my_errno));
|
||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME)) {
|
||||
if (my_errno == EMFILE) {
|
||||
DBUG_PRINT("error",("print err: %d",EE_OUT_OF_FILERESOURCES));
|
||||
my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
} else {
|
||||
DBUG_PRINT("error",("print err: %d",error_message_number));
|
||||
my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
}
|
||||
my_errno= errno;
|
||||
|
||||
DBUG_PRINT("error",("Got error %d on open", my_errno));
|
||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
|
||||
{
|
||||
if (my_errno == EMFILE)
|
||||
error_message_number= EE_OUT_OF_FILERESOURCES;
|
||||
DBUG_PRINT("error",("print err: %d",error_message_number));
|
||||
my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
}
|
||||
return(fd);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
#ifdef __WIN__
|
||||
|
|
|
@ -33,7 +33,9 @@ File my_create_with_symlink(const char *linkname, const char *filename,
|
|||
int create_link;
|
||||
char abs_linkname[FN_REFLEN];
|
||||
DBUG_ENTER("my_create_with_symlink");
|
||||
DBUG_PRINT("enter", ("linkname: %s filename: %s", linkname, filename));
|
||||
DBUG_PRINT("enter",
|
||||
("linkname: %s filename: %s", linkname ? linkname : "NULL",
|
||||
filename));
|
||||
|
||||
if (my_disable_symlinks)
|
||||
{
|
||||
|
|
|
@ -6,15 +6,14 @@ machine="Linux-x64"
|
|||
|
||||
# InnoDB tests
|
||||
|
||||
./run-all-tests --suffix=-innodb --comments="Engine=InnoDB --innodb_log_file_size=100M" --create-options="ENGINE=InnoDB" --hw="$hw" --optimization="$optimization" --machine="$machine" --log
|
||||
|
||||
./run-all-tests --suffix=_fast-innodb --comments="Engine=InnoDB --innodb_log_file_size=100M" --create-options="ENGINE=InnoDB" --hw="$hw" --optimization="$optimization" --machine="$machine" --fast --log
|
||||
./run-all-tests --suffix=-innodb --comments="Engine=InnoDB --innodb_buffer_pool_size=256M --innodb_additional_mem_pool_size=20M --innodb_log_file_size=1000M --innodb_log_buffer_size=16M --innodb_lock_wait_timeout=50 --innodb_flush_log_at_trx_commit=1 --innodb_flush_method=O_DIRECT --innodb_log_files_in_group=2 --skip-innodb-doblewrite" --create-options="ENGINE=InnoDB" --hw="$hw" --optimization="$optimization" --machine="$machine" --log
|
||||
|
||||
./run-all-tests --suffix=_fast-innodb --comments="Engine=InnoDB --innodb_buffer_pool_size=256M --innodb_additional_mem_pool_size=20M --innodb_log_file_size=1000M --innodb_log_buffer_size=16M --innodb_lock_wait_timeout=50 --innodb_flush_log_at_trx_commit=1 --innodb_flush_method=O_DIRECT --innodb_log_files_in_group=2 --skip-innodb-doblewrite" --create-options="ENGINE=InnoDB" --hw="$hw" --optimization="$optimization" --machine="$machine" --fast --log
|
||||
|
||||
# MyISAM tests
|
||||
|
||||
./run-all-tests --suffix=-myisam --comments="Engine=MyISAM key_buffer_size=16M" --create-options="ENGINE=myisam" --hw="$hw" --optimization="$optimization" --machine="$machine" --log
|
||||
./run-all-tests --suffix=-myisam --comments="Engine=MyISAM key_buffer_size=256M" --create-options="ENGINE=myisam" --hw="$hw" --optimization="$optimization" --machine="$machine" --log
|
||||
|
||||
./run-all-tests --suffix=_fast-myisam --comments="Engine=MyISAM key_buffer_size=16M" --create-options="ENGINE=myisam" --hw="$hw" --optimization="$optimization" --machine="$machine" --fast --log
|
||||
./run-all-tests --suffix=_fast-myisam --comments="Engine=MyISAM key_buffer_size=256M" --create-options="ENGINE=myisam" --hw="$hw" --optimization="$optimization" --machine="$machine" --fast --log
|
||||
|
||||
compare-results --relative output/RUN-mysql-myisam-* output/RUN-mysql_fast-myisam* output/RUN-mysql*
|
||||
|
|
|
@ -68,7 +68,7 @@ static const LEX_STRING sys_table_aliases[]=
|
|||
};
|
||||
|
||||
const char *ha_row_type[] = {
|
||||
"", "FIXED", "DYNAMIC", "COMPRESSED", "REDUNDANT", "COMPACT", "?","?","?"
|
||||
"", "FIXED", "DYNAMIC", "COMPRESSED", "REDUNDANT", "COMPACT", "PAGE","?","?","?"
|
||||
};
|
||||
|
||||
const char *tx_isolation_names[] =
|
||||
|
@ -281,7 +281,8 @@ handler *get_ha_partition(partition_info *part_info)
|
|||
0 OK
|
||||
!= 0 Error
|
||||
*/
|
||||
static int ha_init_errors(void)
|
||||
|
||||
int ha_init_errors(void)
|
||||
{
|
||||
#define SETMSG(nr, msg) errmsgs[(nr) - HA_ERR_FIRST]= (msg)
|
||||
const char **errmsgs;
|
||||
|
@ -495,9 +496,6 @@ int ha_init()
|
|||
int error= 0;
|
||||
DBUG_ENTER("ha_init");
|
||||
|
||||
if (ha_init_errors())
|
||||
DBUG_RETURN(1);
|
||||
|
||||
DBUG_ASSERT(total_ha < MAX_HA);
|
||||
/*
|
||||
Check if there is a transaction-capable storage engine besides the
|
||||
|
|
|
@ -268,7 +268,7 @@ enum legacy_db_type
|
|||
|
||||
enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
|
||||
ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
|
||||
ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT, ROW_TYPE_PAGES };
|
||||
ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT, ROW_TYPE_PAGE };
|
||||
|
||||
enum enum_binlog_func {
|
||||
BFN_RESET_LOGS= 1,
|
||||
|
@ -311,6 +311,7 @@ enum enum_binlog_command {
|
|||
#define HA_CREATE_USED_PASSWORD (1L << 17)
|
||||
#define HA_CREATE_USED_CONNECTION (1L << 18)
|
||||
#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
|
||||
#define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
|
||||
|
||||
typedef ulonglong my_xid; // this line is the same as in log_event.h
|
||||
#define MYSQL_XID_PREFIX "MySQLXid"
|
||||
|
@ -741,6 +742,7 @@ class partition_info;
|
|||
struct st_partition_iter;
|
||||
#define NOT_A_PARTITION_ID ((uint32)-1)
|
||||
|
||||
enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
|
||||
|
||||
typedef struct st_ha_create_information
|
||||
{
|
||||
|
@ -763,6 +765,8 @@ typedef struct st_ha_create_information
|
|||
uint options; /* OR of HA_CREATE_ options */
|
||||
uint merge_insert_method;
|
||||
uint extra_size; /* length of extra data segment */
|
||||
/* 0 not used, 1 if not transactional, 2 if transactional */
|
||||
enum ha_choice transactional;
|
||||
bool table_existed; /* 1 in create if table existed */
|
||||
bool frm_only; /* 1 if no ha_create_table() */
|
||||
bool varchar; /* 1 if table has a VARCHAR */
|
||||
|
@ -1661,6 +1665,7 @@ static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
|
|||
}
|
||||
|
||||
/* basic stuff */
|
||||
int ha_init_errors(void);
|
||||
int ha_init(void);
|
||||
int ha_end(void);
|
||||
int ha_initialize_handlerton(st_plugin_int *plugin);
|
||||
|
|
|
@ -379,6 +379,7 @@ static SYMBOL symbols[] = {
|
|||
{ "OWNER", SYM(OWNER_SYM)},
|
||||
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
|
||||
{ "PARSER", SYM(PARSER_SYM)},
|
||||
{ "PAGE", SYM(PAGE_SYM)},
|
||||
{ "PARTIAL", SYM(PARTIAL)},
|
||||
{ "PARTITION", SYM(PARTITION_SYM)},
|
||||
{ "PARTITIONING", SYM(PARTITIONING_SYM)},
|
||||
|
@ -528,6 +529,7 @@ static SYMBOL symbols[] = {
|
|||
{ "TO", SYM(TO_SYM)},
|
||||
{ "TRAILING", SYM(TRAILING)},
|
||||
{ "TRANSACTION", SYM(TRANSACTION_SYM)},
|
||||
{ "TRANSACTIONAL", SYM(TRANSACTIONAL_SYM)},
|
||||
{ "TRIGGER", SYM(TRIGGER_SYM)},
|
||||
{ "TRIGGERS", SYM(TRIGGERS_SYM)},
|
||||
{ "TRUE", SYM(TRUE_SYM)},
|
||||
|
|
|
@ -3350,6 +3350,10 @@ server.");
|
|||
using_update_log=1;
|
||||
}
|
||||
|
||||
/* Allow storage engine to give real error messages */
|
||||
if (ha_init_errors())
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (plugin_init(opt_bootstrap))
|
||||
{
|
||||
sql_print_error("Failed to init plugins.");
|
||||
|
|
|
@ -1371,6 +1371,11 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
|
||||
packet->append(ha_row_type[(uint) share->row_type]);
|
||||
}
|
||||
if (share->transactional != HA_CHOICE_UNDEF)
|
||||
{
|
||||
packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
|
||||
packet->append(share->transactional == HA_CHOICE_YES ? "1" : "0", 1);
|
||||
}
|
||||
if (table->s->key_block_size)
|
||||
{
|
||||
char *end;
|
||||
|
@ -2910,8 +2915,8 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
|
|||
case ROW_TYPE_COMPACT:
|
||||
tmp_buff= "Compact";
|
||||
break;
|
||||
case ROW_TYPE_PAGES:
|
||||
tmp_buff= "Paged";
|
||||
case ROW_TYPE_PAGE:
|
||||
tmp_buff= "Page";
|
||||
break;
|
||||
}
|
||||
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
|
||||
|
|
|
@ -5653,6 +5653,8 @@ view_err:
|
|||
create_info->default_table_charset= table->s->table_charset;
|
||||
if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
|
||||
create_info->key_block_size= table->s->key_block_size;
|
||||
if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
|
||||
create_info->transactional= table->s->transactional;
|
||||
|
||||
if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY)
|
||||
{
|
||||
|
@ -6916,7 +6918,6 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
|
|||
lex->col_list.empty();
|
||||
lex->alter_info.reset();
|
||||
bzero((char*) &create_info,sizeof(create_info));
|
||||
create_info.db_type= 0;
|
||||
create_info.row_type=ROW_TYPE_NOT_USED;
|
||||
create_info.default_table_charset=default_charset_info;
|
||||
/* Force alter table to recreate table */
|
||||
|
|
|
@ -720,6 +720,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token OUT_SYM /* SQL-2003-R */
|
||||
%token OWNER_SYM
|
||||
%token PACK_KEYS_SYM
|
||||
%token PAGE_SYM
|
||||
%token PARAM_MARKER
|
||||
%token PARSER_SYM
|
||||
%token PARTIAL /* SQL-2003-N */
|
||||
|
@ -872,6 +873,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token TO_SYM /* SQL-2003-R */
|
||||
%token TRAILING /* SQL-2003-R */
|
||||
%token TRANSACTION_SYM
|
||||
%token TRANSACTIONAL_SYM
|
||||
%token TRIGGERS_SYM
|
||||
%token TRIGGER_SYM /* SQL-2003-R */
|
||||
%token TRIM /* SQL-2003-N */
|
||||
|
@ -4213,6 +4215,12 @@ create_table_option:
|
|||
Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
|
||||
Lex->create_info.key_block_size= $3;
|
||||
}
|
||||
| TRANSACTIONAL_SYM opt_equal ulong_num
|
||||
{
|
||||
Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
|
||||
Lex->create_info.transactional= ($3 != 0 ? HA_CHOICE_YES :
|
||||
HA_CHOICE_NO);
|
||||
}
|
||||
;
|
||||
|
||||
default_charset:
|
||||
|
@ -4273,6 +4281,7 @@ row_types:
|
|||
| COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
|
||||
| REDUNDANT_SYM { $$= ROW_TYPE_REDUNDANT; }
|
||||
| COMPACT_SYM { $$= ROW_TYPE_COMPACT; };
|
||||
| PAGE_SYM { $$= ROW_TYPE_PAGE; };
|
||||
|
||||
merge_insert_types:
|
||||
NO_SYM { $$= MERGE_INSERT_DISABLED; }
|
||||
|
@ -9786,6 +9795,7 @@ keyword_sp:
|
|||
| ONE_SHOT_SYM {}
|
||||
| ONE_SYM {}
|
||||
| PACK_KEYS_SYM {}
|
||||
| PAGE_SYM {}
|
||||
| PARTIAL {}
|
||||
| PARTITIONING_SYM {}
|
||||
| PARTITIONS_SYM {}
|
||||
|
@ -9855,6 +9865,7 @@ keyword_sp:
|
|||
| TEXT_SYM {}
|
||||
| THAN_SYM {}
|
||||
| TRANSACTION_SYM {}
|
||||
| TRANSACTIONAL_SYM {}
|
||||
| TRIGGERS_SYM {}
|
||||
| TIMESTAMP {}
|
||||
| TIMESTAMP_ADD {}
|
||||
|
|
|
@ -460,7 +460,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||
if (!head[32]) // New frm file in 3.23
|
||||
{
|
||||
share->avg_row_length= uint4korr(head+34);
|
||||
share-> row_type= (row_type) head[40];
|
||||
share->transactional= (ha_choice) head[39];
|
||||
share->row_type= (row_type) head[40];
|
||||
share->table_charset= get_charset((uint) head[38],MYF(0));
|
||||
share->null_field_first= 1;
|
||||
}
|
||||
|
@ -2111,7 +2112,9 @@ File create_frm(THD *thd, const char *name, const char *db,
|
|||
int2store(fileinfo+16,reclength);
|
||||
int4store(fileinfo+18,create_info->max_rows);
|
||||
int4store(fileinfo+22,create_info->min_rows);
|
||||
/* fileinfo[26] is set in mysql_create_frm() */
|
||||
fileinfo[27]=2; // Use long pack-fields
|
||||
/* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
|
||||
create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
|
||||
int2store(fileinfo+30,create_info->table_options);
|
||||
fileinfo[32]=0; // No filename anymore
|
||||
|
@ -2119,8 +2122,9 @@ File create_frm(THD *thd, const char *name, const char *db,
|
|||
int4store(fileinfo+34,create_info->avg_row_length);
|
||||
fileinfo[38]= (create_info->default_table_charset ?
|
||||
create_info->default_table_charset->number : 0);
|
||||
fileinfo[39]= (uchar) create_info->transactional;
|
||||
fileinfo[40]= (uchar) create_info->row_type;
|
||||
/* Next few bytes were for RAID support */
|
||||
/* Next few bytes where for RAID support */
|
||||
fileinfo[41]= 0;
|
||||
fileinfo[42]= 0;
|
||||
fileinfo[43]= 0;
|
||||
|
|
|
@ -175,6 +175,7 @@ typedef struct st_table_share
|
|||
handlerton *db_type; /* table_type for handler */
|
||||
enum row_type row_type; /* How rows are stored */
|
||||
enum tmp_table_type tmp_table;
|
||||
enum ha_choice transactional;
|
||||
|
||||
uint ref_count; /* How many TABLE objects uses this */
|
||||
uint open_count; /* Number of tables in open list */
|
||||
|
|
|
@ -437,32 +437,38 @@ volatile int *_ma_killed_ptr(HA_CHECK *param)
|
|||
|
||||
void _ma_check_print_error(HA_CHECK *param, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_error");
|
||||
param->error_printed |= 1;
|
||||
param->out_flag |= O_DATA_LOST;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
_ma_check_print_msg(param, "error", fmt, args);
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void _ma_check_print_info(HA_CHECK *param, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_info");
|
||||
va_start(args, fmt);
|
||||
_ma_check_print_msg(param, "info", fmt, args);
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void _ma_check_print_warning(HA_CHECK *param, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_warning");
|
||||
param->warning_printed= 1;
|
||||
param->out_flag |= O_DATA_LOST;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
_ma_check_print_msg(param, "warning", fmt, args);
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1067,16 +1073,6 @@ int ha_maria::repair(THD *thd, HA_CHECK ¶m, bool do_optimize)
|
|||
param.out_flag= 0;
|
||||
strmov(fixed_name, file->s->open_file_name);
|
||||
|
||||
#ifndef TO_BE_FIXED
|
||||
/* QQ: Until we have repair for block format, lie that it succeded */
|
||||
if (file->s->data_file_type == BLOCK_RECORD)
|
||||
{
|
||||
if (do_optimize)
|
||||
DBUG_RETURN(analyze(thd, (HA_CHECK_OPT*) 0));
|
||||
DBUG_RETURN(HA_ADMIN_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Don't lock tables if we have used LOCK TABLE
|
||||
if (!thd->locked_tables &&
|
||||
maria_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
|
||||
|
@ -1101,7 +1097,9 @@ int ha_maria::repair(THD *thd, HA_CHECK ¶m, bool do_optimize)
|
|||
local_testflag |= T_STATISTICS;
|
||||
param.testflag |= T_STATISTICS; // We get this for free
|
||||
statistics_done= 1;
|
||||
if (thd->variables.maria_repair_threads > 1)
|
||||
/* TODO: Remove BLOCK_RECORD test when parallel works with blocks */
|
||||
if (thd->variables.maria_repair_threads > 1 &&
|
||||
file->s->data_file_type != BLOCK_RECORD)
|
||||
{
|
||||
char buf[40];
|
||||
/* TODO: respect maria_repair_threads variable */
|
||||
|
@ -1979,7 +1977,7 @@ enum row_type ha_maria::get_row_type() const
|
|||
switch (file->s->data_file_type) {
|
||||
case STATIC_RECORD: return ROW_TYPE_FIXED;
|
||||
case DYNAMIC_RECORD: return ROW_TYPE_DYNAMIC;
|
||||
case BLOCK_RECORD: return ROW_TYPE_PAGES;
|
||||
case BLOCK_RECORD: return ROW_TYPE_PAGE;
|
||||
case COMPRESSED_RECORD: return ROW_TYPE_COMPRESSED;
|
||||
default: return ROW_TYPE_NOT_USED;
|
||||
}
|
||||
|
@ -1988,6 +1986,8 @@ enum row_type ha_maria::get_row_type() const
|
|||
|
||||
static enum data_file_type maria_row_type(HA_CREATE_INFO *info)
|
||||
{
|
||||
if (info->transactional == HA_CHOICE_YES)
|
||||
return BLOCK_RECORD;
|
||||
switch (info->row_type) {
|
||||
case ROW_TYPE_FIXED: return STATIC_RECORD;
|
||||
case ROW_TYPE_DYNAMIC: return DYNAMIC_RECORD;
|
||||
|
@ -2032,7 +2032,8 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||
share->avg_row_length);
|
||||
create_info.data_file_name= ha_create_info->data_file_name;
|
||||
create_info.index_file_name= ha_create_info->index_file_name;
|
||||
create_info.transactional= row_type == BLOCK_RECORD;
|
||||
create_info.transactional= (row_type == BLOCK_RECORD &&
|
||||
ha_create_info->transactional != HA_CHOICE_NO);
|
||||
|
||||
if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||
create_flags|= HA_CREATE_TMP_TABLE;
|
||||
|
|
|
@ -106,6 +106,19 @@
|
|||
put on disk even if they are not in the page cache).
|
||||
- When explicitely requested (for example on backup or after recvoery,
|
||||
to simplify things)
|
||||
|
||||
The flow of writing a row is that:
|
||||
- Lock the bitmap
|
||||
- Decide which data pages we will write to
|
||||
- Mark them full in the bitmap page so that other threads do not try to
|
||||
use the same data pages as us
|
||||
- We unlock the bitmap
|
||||
- Write the data pages
|
||||
- Lock the bitmap
|
||||
- Correct the bitmap page with the true final occupation of the data
|
||||
pages (that is, we marked pages full but when we are done we realize
|
||||
we didn't fill them)
|
||||
- Unlock the bitmap.
|
||||
*/
|
||||
|
||||
#include "maria_def.h"
|
||||
|
|
|
@ -1789,7 +1789,7 @@ static my_bool write_block_record(MARIA_HA *info,
|
|||
ulong length;
|
||||
ulong data_length= (tmp_data - info->rec_buff);
|
||||
|
||||
#ifdef SANITY_CHECK
|
||||
#ifdef SANITY_CHECKS
|
||||
if (cur_block->sub_blocks == 1)
|
||||
goto crashed; /* no reserved full or tails */
|
||||
#endif
|
||||
|
@ -1825,8 +1825,8 @@ static my_bool write_block_record(MARIA_HA *info,
|
|||
FULL_PAGE_SIZE(block_size))) &&
|
||||
cur_block->page_count)
|
||||
{
|
||||
#ifdef SANITY_CHECK
|
||||
if ((cur_block == end_block) || (cur_block->used & BLOCKUSED_BIT))
|
||||
#ifdef SANITY_CHECKS
|
||||
if ((cur_block == end_block) || (cur_block->used & BLOCKUSED_USED))
|
||||
goto crashed;
|
||||
#endif
|
||||
data_length-= length;
|
||||
|
@ -1840,7 +1840,7 @@ static my_bool write_block_record(MARIA_HA *info,
|
|||
/* Skip empty filler block */
|
||||
cur_block++;
|
||||
}
|
||||
#ifdef SANITY_CHECK
|
||||
#ifdef SANITY_CHECKS
|
||||
if ((cur_block >= end_block))
|
||||
goto crashed;
|
||||
#endif
|
||||
|
@ -2572,11 +2572,6 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
|
|||
PAGECACHE_PIN_LEFT_PINNED,
|
||||
PAGECACHE_WRITE_DELAY, &page_link.link))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/* Change the lock used when we read the page */
|
||||
page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK;
|
||||
set_dynamic(&info->pinned_pages, (void*) &page_link,
|
||||
info->pinned_pages.elements-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2595,8 +2590,24 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
|
|||
TRANSLOG_INTERNAL_PARTS + 1, log_array,
|
||||
log_data))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/* Write the empty page (needed only for REPAIR to work) */
|
||||
buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE;
|
||||
if (pagecache_write(share->pagecache,
|
||||
&info->dfile, page, 0,
|
||||
buff, share->page_type,
|
||||
PAGECACHE_LOCK_WRITE_TO_READ,
|
||||
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;
|
||||
set_dynamic(&info->pinned_pages, (void*) &page_link,
|
||||
info->pinned_pages.elements-1);
|
||||
|
||||
DBUG_PRINT("info", ("empty_space: %u", empty_space));
|
||||
DBUG_RETURN(_ma_bitmap_set(info, page, head, empty_space));
|
||||
}
|
||||
|
@ -2815,7 +2826,8 @@ static byte *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
|
|||
extent->extent+= ROW_EXTENT_SIZE;
|
||||
extent->page= uint5korr(extent->extent);
|
||||
page_count= uint2korr(extent->extent+ROW_EXTENT_PAGE_SIZE);
|
||||
DBUG_ASSERT(page_count != 0);
|
||||
if (!page_count)
|
||||
goto crashed;
|
||||
extent->tail= page_count & TAIL_BIT;
|
||||
extent->page_count= (page_count & ~TAIL_BIT);
|
||||
extent->first_extent= 0;
|
||||
|
@ -2838,7 +2850,8 @@ static byte *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
|
|||
if (!extent->tail)
|
||||
{
|
||||
/* Full data page */
|
||||
DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == BLOB_PAGE);
|
||||
if ((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != BLOB_PAGE)
|
||||
goto crashed;
|
||||
extent->page++; /* point to next page */
|
||||
extent->page_count--;
|
||||
*end_of_data= buff + share->block_size;
|
||||
|
@ -2847,7 +2860,8 @@ static byte *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
|
|||
}
|
||||
/* Found tail. page_count is in this case the position in the tail page */
|
||||
|
||||
DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == TAIL_PAGE);
|
||||
if ((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != TAIL_PAGE)
|
||||
goto crashed;
|
||||
*(extent->tail_positions++)= ma_recordpos(extent->page,
|
||||
extent->page_count);
|
||||
info->cur_row.tail_count++; /* For maria_chk */
|
||||
|
@ -2969,7 +2983,6 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||
MARIA_COLUMNDEF *column, *end_column;
|
||||
DBUG_ENTER("_ma_read_block_record2");
|
||||
|
||||
LINT_INIT(field_lengths);
|
||||
LINT_INIT(field_length_data);
|
||||
LINT_INIT(blob_buffer);
|
||||
|
||||
|
@ -3015,6 +3028,7 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||
}
|
||||
extent.first_extent= 1;
|
||||
|
||||
field_lengths= 0;
|
||||
if (share->base.max_field_lengths)
|
||||
{
|
||||
get_key_length(field_lengths, data);
|
||||
|
@ -3049,7 +3063,7 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||
Read row extents (note that first extent was already read into
|
||||
info->cur_row.extents above)
|
||||
*/
|
||||
if (row_extents)
|
||||
if (row_extents > 1)
|
||||
{
|
||||
if (read_long_data(info, info->cur_row.extents + ROW_EXTENT_SIZE,
|
||||
(row_extents - 1) * ROW_EXTENT_SIZE,
|
||||
|
@ -3074,7 +3088,7 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||
}
|
||||
|
||||
/* Read array of field lengths. This may be stored in several extents */
|
||||
if (share->base.max_field_lengths)
|
||||
if (field_lengths)
|
||||
{
|
||||
field_length_data= info->cur_row.field_lengths;
|
||||
if (read_long_data(info, field_length_data, field_lengths, &extent,
|
||||
|
@ -3480,6 +3494,8 @@ restart_bitmap_scan:
|
|||
DBUG_PRINT("error", ("Wrong page header"));
|
||||
DBUG_RETURN((my_errno= HA_ERR_WRONG_IN_RECORD));
|
||||
}
|
||||
DBUG_PRINT("info", ("Page %lu has %u rows",
|
||||
(ulong) page, info->scan.number_of_rows));
|
||||
info->scan.dir= (info->scan.page_buff + block_size -
|
||||
PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE);
|
||||
info->scan.dir_end= (info->scan.dir -
|
||||
|
@ -3505,8 +3521,11 @@ restart_bitmap_scan:
|
|||
filepos= (my_off_t) info->scan.bitmap_page * block_size;
|
||||
if (unlikely(filepos >= info->state->data_file_length))
|
||||
{
|
||||
DBUG_PRINT("info", ("Found end of file"));
|
||||
DBUG_RETURN((my_errno= HA_ERR_END_OF_FILE));
|
||||
}
|
||||
DBUG_PRINT("info", ("Reading bitmap at %lu",
|
||||
(ulong) info->scan.bitmap_page));
|
||||
if (!(pagecache_read(share->pagecache, &info->dfile,
|
||||
info->scan.bitmap_page,
|
||||
0, info->scan.bitmap_buff, PAGECACHE_PLAIN_PAGE,
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
#include "ma_ftdefs.h"
|
||||
#include <myisamchk.h>
|
||||
#include <m_ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <my_getopt.h>
|
||||
#ifdef HAVE_SYS_VADVISE_H
|
||||
|
@ -87,6 +86,12 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks,
|
|||
static ha_checksum maria_byte_checksum(const byte *buf, uint length);
|
||||
static void set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share);
|
||||
static void restore_data_file_type(MARIA_SHARE *share);
|
||||
static void change_data_file_descriptor(MARIA_HA *info, File new_file);
|
||||
static int _ma_safe_scan_block_record(MARIA_SORT_INFO *sort_info,
|
||||
MARIA_HA *info, byte *record);
|
||||
static void copy_data_file_state(MARIA_STATE_INFO *to,
|
||||
MARIA_STATE_INFO *from);
|
||||
|
||||
|
||||
void maria_chk_init(HA_CHECK *param)
|
||||
{
|
||||
|
@ -838,7 +843,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
}
|
||||
}
|
||||
(*key_checksum)+= maria_byte_checksum((byte*) key,
|
||||
key_length- info->s->rec_reflength);
|
||||
key_length- info->s->rec_reflength);
|
||||
record= _ma_dpos(info,0,key+key_length);
|
||||
if (keyinfo->flag & HA_FULLTEXT) /* special handling for ft2 */
|
||||
{
|
||||
|
@ -1263,18 +1268,21 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend,
|
|||
}
|
||||
else
|
||||
{
|
||||
info->cur_row.checksum= _ma_checksum(info,record);
|
||||
ha_checksum checksum= 0;
|
||||
if (info->s->calc_checksum)
|
||||
checksum= (*info->s->calc_checksum)(info, record);
|
||||
|
||||
if (param->testflag & (T_EXTEND | T_MEDIUM | T_VERBOSE))
|
||||
{
|
||||
if (_ma_rec_check(info,record, info->rec_buff,block_info.rec_len,
|
||||
test(info->s->calc_checksum)))
|
||||
test(info->s->calc_checksum), checksum))
|
||||
{
|
||||
_ma_check_print_error(param,"Found wrong packed record at %s",
|
||||
llstr(start_recpos,llbuff));
|
||||
got_error= 1;
|
||||
}
|
||||
}
|
||||
param->glob_crc+= info->cur_row.checksum;
|
||||
param->glob_crc+= checksum;
|
||||
}
|
||||
|
||||
if (! got_error)
|
||||
|
@ -1507,8 +1515,11 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, byte *record,
|
|||
}
|
||||
if (info->s->calc_checksum)
|
||||
{
|
||||
info->cur_row.checksum= _ma_checksum(info, record);
|
||||
param->glob_crc+= info->cur_row.checksum;
|
||||
ha_checksum checksum= (*info->s->calc_checksum)(info, record);
|
||||
if (info->cur_row.checksum != (checksum & 255))
|
||||
_ma_check_print_error(param, "Page %9s: Row %3d has wrong checksum",
|
||||
llstr(page_pos, llbuff), row);
|
||||
param->glob_crc+= checksum;
|
||||
}
|
||||
if (info->cur_row.extents_count)
|
||||
{
|
||||
|
@ -1572,6 +1583,8 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
|
|||
my_bool full_dir;
|
||||
uint offset_page, offset;
|
||||
|
||||
LINT_INIT(full_dir);
|
||||
|
||||
if (_ma_scan_init_block_record(info))
|
||||
{
|
||||
_ma_check_print_error(param, "got error %d when initializing scan",
|
||||
|
@ -1649,13 +1662,12 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
|
|||
llstr(pos, llbuff), page_type);
|
||||
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
|
||||
goto err;
|
||||
continue;
|
||||
}
|
||||
switch ((enum en_page_type) page_type) {
|
||||
case UNALLOCATED_PAGE:
|
||||
case MAX_PAGE_TYPE:
|
||||
DBUG_PRINT("warning",
|
||||
("Found page with wrong page type: %d", page_type));
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_ASSERT(0); /* Impossible */
|
||||
break;
|
||||
case HEAD_PAGE:
|
||||
row_count= ((uchar*) page_buff)[DIR_COUNT_OFFSET];
|
||||
|
@ -1908,13 +1920,28 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
|
|||
} /* maria_chk_data_link */
|
||||
|
||||
|
||||
/* Recover old table by reading each record and writing all keys */
|
||||
/* Save new datafile-name in temp_filename */
|
||||
/*
|
||||
Recover old table by reading each record and writing all keys
|
||||
|
||||
NOTES
|
||||
Save new datafile-name in temp_filename
|
||||
|
||||
IMPLEMENTATION (for hard repair with block format)
|
||||
- Create new, unrelated MARIA_HA of the table
|
||||
- Create new datafile and associate it with new handler
|
||||
- Reset all statistic information in new handler
|
||||
- Copy all data to new handler with normal write operations
|
||||
- Move state of new handler to old handler
|
||||
- Close new handler
|
||||
- Close data file in old handler
|
||||
- Rename old data file to new data file.
|
||||
- Reopen data file in old handler
|
||||
*/
|
||||
|
||||
int maria_repair(HA_CHECK *param, register MARIA_HA *info,
|
||||
my_string name, int rep_quick)
|
||||
{
|
||||
int error,got_error;
|
||||
int error, got_error= 1;
|
||||
uint i;
|
||||
ha_rows start_records,new_header_length;
|
||||
my_off_t del;
|
||||
|
@ -1923,6 +1950,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
|
|||
char llbuff[22],llbuff2[22];
|
||||
MARIA_SORT_INFO sort_info;
|
||||
MARIA_SORT_PARAM sort_param;
|
||||
my_bool block_record, scan_inited= 0;
|
||||
enum data_file_type org_data_file_type= info->s->data_file_type;
|
||||
DBUG_ENTER("maria_repair");
|
||||
|
||||
bzero((char *)&sort_info, sizeof(sort_info));
|
||||
|
@ -1930,9 +1959,11 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
|
|||
start_records=info->state->records;
|
||||
new_header_length=(param->testflag & T_UNPACK) ? 0L :
|
||||
share->pack.header_length;
|
||||
got_error=1;
|
||||
new_file= -1;
|
||||
sort_param.sort_info=&sort_info;
|
||||
block_record= org_data_file_type == BLOCK_RECORD;
|
||||
sort_info.info= sort_info.new_info= info;
|
||||
bzero(&info->rec_cache,sizeof(info->rec_cache));
|
||||
|
||||
if (!(param->testflag & T_SILENT))
|
||||
{
|
||||
|
@ -1944,28 +1975,6 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
|
|||
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
|
||||
param->testflag|=T_CALC_CHECKSUM;
|
||||
|
||||
if (init_io_cache(¶m->read_cache, info->dfile.file,
|
||||
(uint) param->read_buffer_length,
|
||||
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
|
||||
{
|
||||
bzero(&info->rec_cache,sizeof(info->rec_cache));
|
||||
goto err;
|
||||
}
|
||||
if (!rep_quick)
|
||||
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
|
||||
WRITE_CACHE, new_header_length, 1,
|
||||
MYF(MY_WME | MY_WAIT_IF_FULL)))
|
||||
goto err;
|
||||
info->opt_flag|=WRITE_CACHE_USED;
|
||||
if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
|
||||
MYF(0))) ||
|
||||
_ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
|
||||
info->s->base.default_rec_buff_size))
|
||||
{
|
||||
_ma_check_print_error(param, "Not enough memory for extra record");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!rep_quick)
|
||||
{
|
||||
/* Get real path for data file */
|
||||
|
@ -1984,11 +1993,71 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
|
|||
new_header_length, "datafile-header"))
|
||||
goto err;
|
||||
info->s->state.dellink= HA_OFFSET_ERROR;
|
||||
info->rec_cache.file=new_file;
|
||||
if (param->testflag & T_UNPACK)
|
||||
restore_data_file_type(share);
|
||||
info->rec_cache.file= new_file;
|
||||
if (share->data_file_type == BLOCK_RECORD ||
|
||||
((param->testflag & T_UNPACK) &&
|
||||
share->state.header.org_data_file_type == BLOCK_RECORD))
|
||||
{
|
||||
MARIA_HA *new_info;
|
||||
if (!(sort_info.new_info= maria_open(info->s->unique_file_name, O_RDWR,
|
||||
HA_OPEN_COPY | HA_OPEN_FOR_REPAIR)))
|
||||
goto err;
|
||||
new_info= sort_info.new_info;
|
||||
change_data_file_descriptor(new_info, new_file);
|
||||
maria_lock_database(new_info, F_EXTRA_LCK);
|
||||
if ((param->testflag & T_UNPACK) &&
|
||||
share->data_file_type == COMPRESSED_RECORD)
|
||||
{
|
||||
(*new_info->s->once_end)(new_info->s);
|
||||
(*new_info->s->end)(new_info);
|
||||
restore_data_file_type(new_info->s);
|
||||
_ma_setup_functions(new_info->s);
|
||||
if ((*new_info->s->once_init)(new_info->s, new_file) ||
|
||||
(*new_info->s->init)(new_info))
|
||||
goto err;
|
||||
}
|
||||
_ma_reset_status(sort_info.new_info);
|
||||
if (_ma_initialize_data_file(sort_info.new_info->s, new_file))
|
||||
goto err;
|
||||
block_record= 1;
|
||||
}
|
||||
}
|
||||
sort_info.info=info;
|
||||
|
||||
if (org_data_file_type != BLOCK_RECORD)
|
||||
{
|
||||
/* We need a read buffer to read rows in big blocks */
|
||||
if (init_io_cache(¶m->read_cache, info->dfile.file,
|
||||
(uint) param->read_buffer_length,
|
||||
READ_CACHE, share->pack.header_length, 1, MYF(MY_WME)))
|
||||
goto err;
|
||||
}
|
||||
if (sort_info.new_info->s->data_file_type != BLOCK_RECORD)
|
||||
{
|
||||
/* When writing to not block records, we need a write buffer */
|
||||
if (!rep_quick)
|
||||
if (init_io_cache(&info->rec_cache, new_file,
|
||||
(uint) param->write_buffer_length,
|
||||
WRITE_CACHE, new_header_length, 1,
|
||||
MYF(MY_WME | MY_WAIT_IF_FULL)))
|
||||
goto err;
|
||||
info->opt_flag|=WRITE_CACHE_USED;
|
||||
}
|
||||
else
|
||||
{
|
||||
scan_inited= 1;
|
||||
if (maria_scan_init(sort_info.info))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
|
||||
MYF(0))) ||
|
||||
_ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
|
||||
info->s->base.default_rec_buff_size))
|
||||
{
|
||||
_ma_check_print_error(param, "Not enough memory for extra record");
|
||||
goto err;
|
||||
}
|
||||
|
||||
sort_info.param = param;
|
||||
sort_param.read_cache=param->read_cache;
|
||||
sort_param.pos=sort_param.max_pos=share->pack.header_length;
|
||||
|
@ -2031,9 +2100,14 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
|
|||
|
||||
maria_lock_memory(param); /* Everything is alloced */
|
||||
|
||||
sort_info.org_data_file_type= info->s->data_file_type;
|
||||
|
||||
/* Re-create all keys, which are set in key_map. */
|
||||
while (!(error=sort_get_next_record(&sort_param)))
|
||||
{
|
||||
if (block_record && _ma_sort_write_record(&sort_param))
|
||||
goto err;
|
||||
|
||||
if (writekeys(&sort_param))
|
||||
{
|
||||
if (my_errno != HA_ERR_FOUND_DUPP_KEY)
|
||||
|
@ -2059,7 +2133,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (_ma_sort_write_record(&sort_param))
|
||||
|
||||
if (!block_record && _ma_sort_write_record(&sort_param))
|
||||
goto err;
|
||||
}
|
||||
if (error > 0 || maria_write_data_suffix(&sort_info, (my_bool)!rep_quick) ||
|
||||
|
@ -2082,35 +2157,61 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
|
|||
{
|
||||
_ma_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
|
||||
_ma_check_print_error(param,"Run recovery again without -q");
|
||||
got_error=1;
|
||||
param->retry_repair=1;
|
||||
param->testflag|=T_RETRY_WITHOUT_QUICK;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (param->testflag & T_SAFE_REPAIR)
|
||||
{
|
||||
/* Don't repair if we loosed more than one row */
|
||||
if (info->state->records+1 < start_records)
|
||||
if (sort_info.new_info->state->records+1 < start_records)
|
||||
{
|
||||
info->state->records=start_records;
|
||||
got_error=1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rep_quick)
|
||||
{
|
||||
my_close(info->dfile.file, MYF(0));
|
||||
info->dfile.file= new_file;
|
||||
info->state->data_file_length=sort_param.filepos;
|
||||
myf sync_dir= ((share->base.transactional && !share->temporary) ?
|
||||
MY_SYNC_DIR : 0);
|
||||
if (sort_info.new_info != sort_info.info)
|
||||
{
|
||||
MARIA_STATE_INFO save_state= sort_info.new_info->s->state;
|
||||
if (maria_close(sort_info.new_info))
|
||||
{
|
||||
_ma_check_print_error(param, "Got error %d on close", my_errno);
|
||||
goto err;
|
||||
}
|
||||
copy_data_file_state(&info->s->state, &save_state);
|
||||
new_file= -1;
|
||||
}
|
||||
else
|
||||
info->state->data_file_length= sort_param.filepos;
|
||||
share->state.version=(ulong) time((time_t*) 0); /* Force reopen */
|
||||
|
||||
/* Replace the actual file with the temporary file */
|
||||
if (new_file >= 0)
|
||||
my_close(new_file, MYF(MY_WME));
|
||||
my_close(info->dfile.file, MYF(MY_WME));
|
||||
info->dfile.file= new_file= -1;
|
||||
if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
|
||||
DATA_TMP_EXT,
|
||||
(param->testflag & T_BACKUP_DATA ?
|
||||
MYF(MY_REDEL_MAKE_BACKUP): MYF(0)) |
|
||||
sync_dir) ||
|
||||
_ma_open_datafile(info, share, -1))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info->state->data_file_length=sort_param.max_pos;
|
||||
info->state->data_file_length= sort_param.max_pos;
|
||||
}
|
||||
if (param->testflag & T_CALC_CHECKSUM)
|
||||
info->state->checksum=param->glob_crc;
|
||||
info->state->checksum= param->glob_crc;
|
||||
|
||||
if (!(param->testflag & T_SILENT))
|
||||
{
|
||||
|
@ -2128,29 +2229,19 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
|
|||
memcpy( &share->state.state, info->state, sizeof(*info->state));
|
||||
|
||||
err:
|
||||
if (!got_error)
|
||||
{
|
||||
/* Replace the actual file with the temporary file */
|
||||
if (new_file >= 0)
|
||||
{
|
||||
myf sync_dir= (share->base.transactional && !share->temporary) ?
|
||||
MY_SYNC_DIR : 0;
|
||||
my_close(new_file,MYF(0));
|
||||
info->dfile.file= new_file= -1;
|
||||
if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
|
||||
DATA_TMP_EXT,
|
||||
MYF((param->testflag & T_BACKUP_DATA ?
|
||||
MY_REDEL_MAKE_BACKUP : 0) |
|
||||
sync_dir)) ||
|
||||
_ma_open_datafile(info,share,-1))
|
||||
got_error=1;
|
||||
}
|
||||
}
|
||||
if (scan_inited)
|
||||
maria_scan_end(sort_info.info);
|
||||
|
||||
if (got_error)
|
||||
{
|
||||
if (! param->error_printed)
|
||||
_ma_check_print_error(param,"%d for record at pos %s",my_errno,
|
||||
llstr(sort_param.start_recpos,llbuff));
|
||||
if (sort_info.new_info && sort_info.new_info != sort_info.info)
|
||||
{
|
||||
sort_info.new_info->dfile.file= -1;
|
||||
maria_close(sort_info.new_info);
|
||||
}
|
||||
if (new_file >= 0)
|
||||
{
|
||||
VOID(my_close(new_file,MYF(0)));
|
||||
|
@ -2602,7 +2693,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
uint i;
|
||||
ulong length;
|
||||
ha_rows start_records;
|
||||
my_off_t new_header_length,del;
|
||||
my_off_t new_header_length, org_header_length, del;
|
||||
File new_file;
|
||||
MARIA_SORT_PARAM sort_param;
|
||||
MARIA_SHARE *share=info->s;
|
||||
|
@ -2611,15 +2702,19 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
char llbuff[22];
|
||||
MARIA_SORT_INFO sort_info;
|
||||
ulonglong key_map=share->state.key_map;
|
||||
myf sync_dir= (share->base.transactional && !share->temporary) ?
|
||||
MY_SYNC_DIR : 0;
|
||||
myf sync_dir= ((share->base.transactional && !share->temporary) ?
|
||||
MY_SYNC_DIR : 0);
|
||||
DBUG_ENTER("maria_repair_by_sort");
|
||||
|
||||
bzero((char*)&sort_info,sizeof(sort_info));
|
||||
bzero((char *)&sort_param, sizeof(sort_param));
|
||||
|
||||
start_records=info->state->records;
|
||||
got_error=1;
|
||||
new_file= -1;
|
||||
new_header_length=(param->testflag & T_UNPACK) ? 0 :
|
||||
share->pack.header_length;
|
||||
org_header_length= share->pack.header_length;
|
||||
new_header_length= (param->testflag & T_UNPACK) ? 0 : org_header_length;
|
||||
|
||||
if (!(param->testflag & T_SILENT))
|
||||
{
|
||||
printf("- recovering (with sort) MARIA-table '%s'\n",name);
|
||||
|
@ -2630,15 +2725,13 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
|
||||
param->testflag|=T_CALC_CHECKSUM;
|
||||
|
||||
bzero((char*)&sort_info,sizeof(sort_info));
|
||||
bzero((char *)&sort_param, sizeof(sort_param));
|
||||
if (!(sort_info.key_block=
|
||||
alloc_key_blocks(param,
|
||||
(uint) param->sort_key_blocks,
|
||||
share->base.max_key_block_length))
|
||||
|| init_io_cache(¶m->read_cache, info->dfile.file,
|
||||
(uint) param->read_buffer_length,
|
||||
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)) ||
|
||||
share->base.max_key_block_length)) ||
|
||||
init_io_cache(¶m->read_cache, info->dfile.file,
|
||||
(uint) param->read_buffer_length,
|
||||
READ_CACHE, org_header_length, 1, MYF(MY_WME)) ||
|
||||
(! rep_quick &&
|
||||
init_io_cache(&info->rec_cache, info->dfile.file,
|
||||
(uint) param->write_buffer_length,
|
||||
|
@ -2648,6 +2741,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
|
||||
info->opt_flag|=WRITE_CACHE_USED;
|
||||
info->rec_cache.file= info->dfile.file; /* for sort_delete_record */
|
||||
sort_info.org_data_file_type= info->s->data_file_type;
|
||||
|
||||
if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
|
||||
MYF(0))) ||
|
||||
|
@ -2703,8 +2797,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
key_map= ~key_map; /* Create the missing keys */
|
||||
}
|
||||
|
||||
sort_info.info=info;
|
||||
sort_info.param = param;
|
||||
sort_info.info= sort_info.new_info= info;
|
||||
sort_info.param= param;
|
||||
|
||||
set_data_file_type(&sort_info, share);
|
||||
sort_param.filepos=new_header_length;
|
||||
|
@ -2716,9 +2810,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
sort_param.wordlist=NULL;
|
||||
init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
|
||||
|
||||
if (share->data_file_type == DYNAMIC_RECORD)
|
||||
if (sort_info.org_data_file_type == DYNAMIC_RECORD)
|
||||
length=max(share->base.min_pack_length+1,share->base.min_block_length);
|
||||
else if (share->data_file_type == COMPRESSED_RECORD)
|
||||
else if (sort_info.org_data_file_type == COMPRESSED_RECORD)
|
||||
length=share->base.min_block_length;
|
||||
else
|
||||
length=share->base.pack_reclength;
|
||||
|
@ -2756,7 +2850,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
|
||||
if ((!(param->testflag & T_SILENT)))
|
||||
printf ("- Fixing index %d\n",sort_param.key+1);
|
||||
sort_param.max_pos=sort_param.pos=share->pack.header_length;
|
||||
sort_param.max_pos= sort_param.pos= org_header_length;
|
||||
keyseg=sort_param.seg;
|
||||
bzero((char*) sort_param.unique,sizeof(sort_param.unique));
|
||||
sort_param.key_length=share->rec_reflength;
|
||||
|
@ -2854,8 +2948,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
share->state.version=(ulong) time((time_t*) 0);
|
||||
my_close(info->dfile.file, MYF(0));
|
||||
info->dfile.file= new_file;
|
||||
share->data_file_type=sort_info.new_data_file_type;
|
||||
share->pack.header_length=(ulong) new_header_length;
|
||||
share->data_file_type= sort_info.new_data_file_type;
|
||||
org_header_length= (ulong) new_header_length;
|
||||
sort_info.org_data_file_type= info->s->data_file_type;
|
||||
sort_param.fix_datafile=0;
|
||||
}
|
||||
else
|
||||
|
@ -2883,11 +2978,11 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
|
||||
if (rep_quick & T_FORCE_UNIQUENESS)
|
||||
{
|
||||
my_off_t skr=info->state->data_file_length+
|
||||
(share->options & HA_OPTION_COMPRESS_RECORD ?
|
||||
MEMMAP_EXTRA_MARGIN : 0);
|
||||
my_off_t skr= (info->state->data_file_length +
|
||||
(sort_info.org_data_file_type == COMPRESSED_RECORD) ?
|
||||
MEMMAP_EXTRA_MARGIN : 0);
|
||||
#ifdef USE_RELOC
|
||||
if (share->data_file_type == STATIC_RECORD &&
|
||||
if (sort_info.org_data_file_type == STATIC_RECORD &&
|
||||
skr < share->base.reloc*share->base.min_pack_length)
|
||||
skr=share->base.reloc*share->base.min_pack_length;
|
||||
#endif
|
||||
|
@ -3085,6 +3180,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&sort_info.cond, 0);
|
||||
|
||||
sort_info.org_data_file_type= info->s->data_file_type;
|
||||
|
||||
if (!(sort_info.key_block=
|
||||
alloc_key_blocks(param, (uint) param->sort_key_blocks,
|
||||
share->base.max_key_block_length)) ||
|
||||
|
@ -3152,8 +3249,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||
key_map= ~key_map; /* Create the missing keys */
|
||||
}
|
||||
|
||||
sort_info.info=info;
|
||||
sort_info.param = param;
|
||||
sort_info.info= sort_info.new_info= info;
|
||||
sort_info.param= param;
|
||||
|
||||
set_data_file_type(&sort_info, share);
|
||||
sort_info.dupp=0;
|
||||
|
@ -3161,9 +3258,9 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||
param->read_cache.end_of_file=sort_info.filelength=
|
||||
my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
|
||||
|
||||
if (share->data_file_type == DYNAMIC_RECORD)
|
||||
if (sort_info.org_data_file_type == DYNAMIC_RECORD)
|
||||
rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
|
||||
else if (share->data_file_type == COMPRESSED_RECORD)
|
||||
else if (sort_info.org_data_file_type == COMPRESSED_RECORD)
|
||||
rec_length=share->base.min_block_length;
|
||||
else
|
||||
rec_length=share->base.pack_reclength;
|
||||
|
@ -3379,8 +3476,6 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||
*/
|
||||
my_close(info->dfile.file, MYF(0));
|
||||
info->dfile.file= new_file;
|
||||
|
||||
share->data_file_type=sort_info.new_data_file_type;
|
||||
share->pack.header_length=(ulong) new_header_length;
|
||||
}
|
||||
else
|
||||
|
@ -3397,11 +3492,11 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||
|
||||
if (rep_quick & T_FORCE_UNIQUENESS)
|
||||
{
|
||||
my_off_t skr=info->state->data_file_length+
|
||||
(share->options & HA_OPTION_COMPRESS_RECORD ?
|
||||
MEMMAP_EXTRA_MARGIN : 0);
|
||||
my_off_t skr= (info->state->data_file_length +
|
||||
(sort_info.org_data_file_type == COMPRESSED_RECORD) ?
|
||||
MEMMAP_EXTRA_MARGIN : 0);
|
||||
#ifdef USE_RELOC
|
||||
if (share->data_file_type == STATIC_RECORD &&
|
||||
if (sort_info.org_data_file_type == STATIC_RECORD &&
|
||||
skr < share->base.reloc*share->base.min_pack_length)
|
||||
skr=share->base.reloc*share->base.min_pack_length;
|
||||
#endif
|
||||
|
@ -3587,27 +3682,28 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, byte *key)
|
|||
sort_get_next_record()
|
||||
sort_param Information about and for the sort process
|
||||
|
||||
NOTE
|
||||
|
||||
NOTES
|
||||
Dynamic Records With Non-Quick Parallel Repair
|
||||
|
||||
For non-quick parallel repair we use a synchronized read/write
|
||||
cache. This means that one thread is the master who fixes the data
|
||||
file by reading each record from the old data file and writing it
|
||||
to the new data file. By doing this the records in the new data
|
||||
file are written contiguously. Whenever the write buffer is full,
|
||||
it is copied to the read buffer. The slaves read from the read
|
||||
buffer, which is not associated with a file. Thus read_cache.file
|
||||
is -1. When using _mi_read_cache(), the slaves must always set
|
||||
flag to READING_NEXT so that the function never tries to read from
|
||||
file. This is safe because the records are contiguous. There is no
|
||||
need to read outside the cache. This condition is evaluated in the
|
||||
variable 'parallel_flag' for quick reference. read_cache.file must
|
||||
be >= 0 in every other case.
|
||||
For non-quick parallel repair we use a synchronized read/write
|
||||
cache. This means that one thread is the master who fixes the data
|
||||
file by reading each record from the old data file and writing it
|
||||
to the new data file. By doing this the records in the new data
|
||||
file are written contiguously. Whenever the write buffer is full,
|
||||
it is copied to the read buffer. The slaves read from the read
|
||||
buffer, which is not associated with a file. Thus read_cache.file
|
||||
is -1. When using _mi_read_cache(), the slaves must always set
|
||||
flag to READING_NEXT so that the function never tries to read from
|
||||
file. This is safe because the records are contiguous. There is no
|
||||
need to read outside the cache. This condition is evaluated in the
|
||||
variable 'parallel_flag' for quick reference. read_cache.file must
|
||||
be >= 0 in every other case.
|
||||
|
||||
RETURN
|
||||
-1 end of file
|
||||
0 ok
|
||||
sort_param->filepos points to record position.
|
||||
sort_param->record contains record
|
||||
> 0 error
|
||||
*/
|
||||
|
||||
|
@ -3628,10 +3724,61 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
|
|||
if (*_ma_killed_ptr(param))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
switch (share->data_file_type) {
|
||||
switch (sort_info->org_data_file_type) {
|
||||
case BLOCK_RECORD:
|
||||
DBUG_ASSERT(0);
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int flag;
|
||||
|
||||
if (info != sort_info->new_info)
|
||||
{
|
||||
/* Safe scanning */
|
||||
flag= _ma_safe_scan_block_record(sort_info, info,
|
||||
sort_param->record);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Scan on clean table */
|
||||
flag= _ma_scan_block_record(info, sort_param->record,
|
||||
info->cur_row.nextpos, 1);
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
if (sort_param->calc_checksum)
|
||||
{
|
||||
ha_checksum checksum;
|
||||
checksum= (*info->s->calc_check_checksum)(info, sort_param->record);
|
||||
if (info->s->calc_checksum &&
|
||||
info->cur_row.checksum != (checksum & 255))
|
||||
{
|
||||
if (param->testflag & T_VERBOSE)
|
||||
{
|
||||
char llbuff[22];
|
||||
record_pos_to_txt(info, sort_param->filepos, llbuff);
|
||||
_ma_check_print_info(param,
|
||||
"Found record with wrong checksum at %s",
|
||||
llbuff);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
info->cur_row.checksum= checksum;
|
||||
param->glob_crc+= checksum;
|
||||
}
|
||||
sort_param->filepos= info->cur_row.lastpos;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (flag == HA_ERR_END_OF_FILE)
|
||||
{
|
||||
sort_param->max_pos= sort_info->filelength;
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
/* Retry only if wrong record, not if disk error */
|
||||
if (flag != HA_ERR_WRONG_IN_RECORD)
|
||||
DBUG_RETURN(flag);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STATIC_RECORD:
|
||||
for (;;)
|
||||
{
|
||||
|
@ -3669,6 +3816,8 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
|
|||
{
|
||||
byte *to;
|
||||
LINT_INIT(to);
|
||||
ha_checksum checksum= 0;
|
||||
|
||||
pos=sort_param->pos;
|
||||
searching=(sort_param->fix_datafile && (param->testflag & T_EXTEND));
|
||||
parallel_flag= (sort_param->read_cache.file < 0) ? READING_NEXT : 0;
|
||||
|
@ -3938,14 +4087,14 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
|
|||
if (sort_param->read_cache.error < 0)
|
||||
DBUG_RETURN(1);
|
||||
if (sort_param->calc_checksum)
|
||||
info->cur_row.checksum= _ma_checksum(info, sort_param->record);
|
||||
checksum= (info->s->calc_check_checksum)(info, sort_param->record);
|
||||
if ((param->testflag & (T_EXTEND | T_REP)) || searching)
|
||||
{
|
||||
if (_ma_rec_check(info, sort_param->record, sort_param->rec_buff,
|
||||
sort_param->find_length,
|
||||
(param->testflag & T_QUICK) &&
|
||||
sort_param->calc_checksum &&
|
||||
test(info->s->calc_checksum)))
|
||||
test(info->s->calc_checksum), checksum))
|
||||
{
|
||||
_ma_check_print_info(param,"Found wrong packed record at %s",
|
||||
llstr(sort_param->start_recpos,llbuff));
|
||||
|
@ -3953,7 +4102,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
|
|||
}
|
||||
}
|
||||
if (sort_param->calc_checksum)
|
||||
param->glob_crc+= info->cur_row.checksum;
|
||||
param->glob_crc+= checksum;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (!searching)
|
||||
|
@ -4027,8 +4176,9 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
|
|||
|
||||
if (sort_param->calc_checksum)
|
||||
{
|
||||
info->cur_row.checksum= (*info->s->calc_checksum)(info,
|
||||
sort_param->record);
|
||||
info->cur_row.checksum= (*info->s->calc_check_checksum)(info,
|
||||
sort_param->
|
||||
record);
|
||||
param->glob_crc+= info->cur_row.checksum;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
@ -4061,8 +4211,8 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
|
|||
byte *from;
|
||||
byte block_buff[8];
|
||||
MARIA_SORT_INFO *sort_info=sort_param->sort_info;
|
||||
HA_CHECK *param=sort_info->param;
|
||||
MARIA_HA *info=sort_info->info;
|
||||
HA_CHECK *param= sort_info->param;
|
||||
MARIA_HA *info= sort_info->new_info;
|
||||
MARIA_SHARE *share=info->s;
|
||||
DBUG_ENTER("_ma_sort_write_record");
|
||||
|
||||
|
@ -4070,7 +4220,11 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
|
|||
{
|
||||
switch (sort_info->new_data_file_type) {
|
||||
case BLOCK_RECORD:
|
||||
DBUG_ASSERT(0);
|
||||
if ((sort_param->filepos= (*share->write_record_init)(info,
|
||||
sort_param->
|
||||
record)) ==
|
||||
HA_OFFSET_ERROR)
|
||||
DBUG_RETURN(1);
|
||||
break;
|
||||
case STATIC_RECORD:
|
||||
if (my_b_write(&info->rec_cache,sort_param->record,
|
||||
|
@ -4103,7 +4257,9 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
|
|||
from=sort_info->buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER);
|
||||
}
|
||||
/* We can use info->checksum here as only one thread calls this */
|
||||
info->cur_row.checksum= _ma_checksum(info,sort_param->record);
|
||||
info->cur_row.checksum= (*info->s->calc_check_checksum)(info,
|
||||
sort_param->
|
||||
record);
|
||||
reclength= _ma_rec_pack(info,from,sort_param->record);
|
||||
flag=0;
|
||||
|
||||
|
@ -4160,7 +4316,7 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
|
|||
} /* _ma_sort_write_record */
|
||||
|
||||
|
||||
/* Compare two keys from _ma_create_index_by_sort */
|
||||
/* Compare two keys from _ma_create_index_by_sort */
|
||||
|
||||
static int sort_key_cmp(MARIA_SORT_PARAM *sort_param, const void *a,
|
||||
const void *b)
|
||||
|
@ -4518,7 +4674,8 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
|
|||
}
|
||||
}
|
||||
if (sort_param->calc_checksum)
|
||||
param->glob_crc-=(*info->s->calc_checksum)(info, sort_param->record);
|
||||
param->glob_crc-=(*info->s->calc_check_checksum)(info,
|
||||
sort_param->record);
|
||||
}
|
||||
error= (flush_io_cache(&info->rec_cache) ||
|
||||
(*info->s->delete_record)(info, sort_param->record));
|
||||
|
@ -4527,7 +4684,8 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
|
|||
DBUG_RETURN(error);
|
||||
} /* sort_delete_record */
|
||||
|
||||
/* Fix all pending blocks and flush everything to disk */
|
||||
|
||||
/* Fix all pending blocks and flush everything to disk */
|
||||
|
||||
int _ma_flush_pending_blocks(MARIA_SORT_PARAM *sort_param)
|
||||
{
|
||||
|
@ -4799,9 +4957,9 @@ end:
|
|||
|
||||
int maria_write_data_suffix(MARIA_SORT_INFO *sort_info, my_bool fix_datafile)
|
||||
{
|
||||
MARIA_HA *info=sort_info->info;
|
||||
MARIA_HA *info=sort_info->new_info;
|
||||
|
||||
if (info->s->options & HA_OPTION_COMPRESS_RECORD && fix_datafile)
|
||||
if (info->s->data_file_type == COMPRESSED_RECORD && fix_datafile)
|
||||
{
|
||||
char buff[MEMMAP_EXTRA_MARGIN];
|
||||
bzero(buff,sizeof(buff));
|
||||
|
@ -5114,6 +5272,9 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows,
|
|||
*/
|
||||
if (! maria_is_any_key_active(key_map))
|
||||
return FALSE; /* Can't use sort */
|
||||
/* QQ: Remove this when maria_repair_by_sort() works with block format */
|
||||
if (info->s->data_file_type == BLOCK_RECORD)
|
||||
return FALSE;
|
||||
for (i=0 ; i < share->base.keys ; i++,key++)
|
||||
{
|
||||
if (!force && maria_too_big_key_for_sort(key,rows))
|
||||
|
@ -5132,7 +5293,8 @@ set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share)
|
|||
MARIA_SHARE tmp;
|
||||
sort_info->new_data_file_type= share->state.header.org_data_file_type;
|
||||
/* Set delete_function for sort_delete_record() */
|
||||
memcpy((char*) &tmp, share, sizeof(*share));
|
||||
tmp= *share;
|
||||
tmp.state.header.data_file_type= tmp.state.header.org_data_file_type;
|
||||
tmp.options= ~HA_OPTION_COMPRESS_RECORD;
|
||||
_ma_setup_functions(&tmp);
|
||||
share->delete_record=tmp.delete_record;
|
||||
|
@ -5145,11 +5307,166 @@ static void restore_data_file_type(MARIA_SHARE *share)
|
|||
mi_int2store(share->state.header.options,share->options);
|
||||
share->state.header.data_file_type=
|
||||
share->state.header.org_data_file_type;
|
||||
share->data_file_type= share->state.header.data_file_type=
|
||||
share->data_file_type= share->state.header.data_file_type;
|
||||
share->pack.header_length= 0;
|
||||
}
|
||||
|
||||
|
||||
static void change_data_file_descriptor(MARIA_HA *info, File new_file)
|
||||
{
|
||||
my_close(info->dfile.file, MYF(0));
|
||||
info->dfile.file= info->s->bitmap.file.file= new_file;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Copy all states that has to do with the data file
|
||||
|
||||
NOTES
|
||||
This is done to copy the state from the data file generated from
|
||||
repair to the original handler
|
||||
*/
|
||||
|
||||
static void copy_data_file_state(MARIA_STATE_INFO *to,
|
||||
MARIA_STATE_INFO *from)
|
||||
{
|
||||
to->state.records= from->state.records;
|
||||
to->state.del= from->state.del;
|
||||
to->state.empty= from->state.empty;
|
||||
to->state.data_file_length= from->state.data_file_length;
|
||||
to->split= from->split;
|
||||
to->dellink= from->dellink;
|
||||
to->first_bitmap_with_space= from->first_bitmap_with_space;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Read 'safely' next record while scanning table.
|
||||
|
||||
SYNOPSIS
|
||||
_ma_safe_scan_block_record()
|
||||
info Maria handler
|
||||
record Store found here
|
||||
|
||||
NOTES
|
||||
- One must have called mi_scan() before this
|
||||
|
||||
Differences compared to _ma_scan_block_records() are:
|
||||
- We read all blocks, not only blocks marked by the bitmap to be safe
|
||||
- In case of errors, next read will read next record.
|
||||
- More sanity checks
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
HA_ERR_END_OF_FILE End of file
|
||||
# error number
|
||||
*/
|
||||
|
||||
|
||||
static int _ma_safe_scan_block_record(MARIA_SORT_INFO *sort_info,
|
||||
MARIA_HA *info, byte *record)
|
||||
{
|
||||
uint record_pos= info->cur_row.nextpos;
|
||||
ulonglong page= sort_info->page;
|
||||
DBUG_ENTER("_ma_safe_scan_block_record");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Find next row in current page */
|
||||
if (likely(record_pos < info->scan.number_of_rows))
|
||||
{
|
||||
uint length, offset;
|
||||
byte *data, *end_of_data;
|
||||
char llbuff[22];
|
||||
|
||||
while (!(offset= uint2korr(info->scan.dir)))
|
||||
{
|
||||
info->scan.dir-= DIR_ENTRY_SIZE;
|
||||
record_pos++;
|
||||
if (info->scan.dir < info->scan.dir_end)
|
||||
{
|
||||
_ma_check_print_info(sort_info->param,
|
||||
"Wrong directory on page: %s",
|
||||
llstr(page, llbuff));
|
||||
goto read_next_page;
|
||||
}
|
||||
}
|
||||
/* found row */
|
||||
info->cur_row.lastpos= info->scan.row_base_page + record_pos;
|
||||
info->cur_row.nextpos= record_pos + 1;
|
||||
data= info->scan.page_buff + offset;
|
||||
length= uint2korr(info->scan.dir + 2);
|
||||
end_of_data= data + length;
|
||||
info->scan.dir-= DIR_ENTRY_SIZE; /* Point to previous row */
|
||||
|
||||
if (end_of_data > info->scan.dir_end ||
|
||||
offset < PAGE_HEADER_SIZE || length < info->s->base.min_block_length)
|
||||
{
|
||||
_ma_check_print_info(sort_info->param,
|
||||
"Wrong directory entry %3u at page %s",
|
||||
record_pos, llstr(page, llbuff));
|
||||
record_pos++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("info", ("rowid: %lu", (ulong) info->cur_row.lastpos));
|
||||
DBUG_RETURN(_ma_read_block_record2(info, record, data, end_of_data));
|
||||
}
|
||||
}
|
||||
|
||||
read_next_page:
|
||||
/* Read until we find next head page */
|
||||
for (;;)
|
||||
{
|
||||
uint page_type;
|
||||
char llbuff[22];
|
||||
|
||||
sort_info->page++; /* In case of errors */
|
||||
page++;
|
||||
if (!(page % info->s->bitmap.pages_covered))
|
||||
page++; /* Skip bitmap */
|
||||
if ((page + 1) * info->s->block_size > sort_info->filelength)
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||
if (!(pagecache_read(info->s->pagecache,
|
||||
&info->dfile,
|
||||
page, 0, info->scan.page_buff,
|
||||
PAGECACHE_READ_UNKNOWN_PAGE,
|
||||
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
|
||||
DBUG_RETURN(my_errno);
|
||||
|
||||
page_type= (info->scan.page_buff[PAGE_TYPE_OFFSET] &
|
||||
PAGE_TYPE_MASK);
|
||||
if (page_type == HEAD_PAGE)
|
||||
{
|
||||
if ((info->scan.number_of_rows=
|
||||
(uint) (uchar) info->scan.page_buff[DIR_COUNT_OFFSET]) != 0)
|
||||
break;
|
||||
_ma_check_print_info(sort_info->param,
|
||||
"Wrong head page at %s",
|
||||
llstr(page * info->s->block_size, llbuff));
|
||||
}
|
||||
else if (page_type >= MAX_PAGE_TYPE)
|
||||
{
|
||||
_ma_check_print_info(sort_info->param,
|
||||
"Found wrong page type: %d at %s",
|
||||
page_type, llstr(page * info->s->block_size,
|
||||
llbuff));
|
||||
}
|
||||
}
|
||||
|
||||
/* New head page */
|
||||
info->scan.dir= (info->scan.page_buff + info->s->block_size -
|
||||
PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE);
|
||||
info->scan.dir_end= (info->scan.dir -
|
||||
(info->scan.number_of_rows - 1) *
|
||||
DIR_ENTRY_SIZE);
|
||||
info->scan.row_base_page= ma_recordpos(page, 0);
|
||||
record_pos= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Writes a LOGREC_REPAIR_TABLE record and updates create_rename_lsn
|
||||
|
||||
|
@ -5218,8 +5535,8 @@ int _ma_repair_write_log_record(const HA_CHECK *param, MARIA_HA *info)
|
|||
made durable earlier (MY_SYNC_DIR passed to maria_change_to_newfile()).
|
||||
*/
|
||||
DBUG_ASSERT(info->dfile.file >= 0);
|
||||
return _ma_update_create_rename_lsn_on_disk(share, FALSE) ||
|
||||
_ma_sync_table_files(info);
|
||||
return (_ma_update_create_rename_lsn_on_disk(share, FALSE) ||
|
||||
_ma_sync_table_files(info));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -122,8 +122,6 @@ int maria_close(register MARIA_HA *info)
|
|||
my_free((gptr) info,MYF(0));
|
||||
|
||||
if (error)
|
||||
{
|
||||
DBUG_RETURN(my_errno=error);
|
||||
}
|
||||
DBUG_RETURN(my_errno= error);
|
||||
DBUG_RETURN(0);
|
||||
} /* maria_close */
|
||||
|
|
|
@ -738,7 +738,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
(MY_UNPACK_FILENAME |
|
||||
(flags & HA_DONT_TOUCH_DATA) ? MY_RETURN_REAL_PATH : 0) |
|
||||
MY_APPEND_EXT);
|
||||
linkname_ptr= NULL;
|
||||
linkname_ptr= NullS;
|
||||
/*
|
||||
Replace the current file.
|
||||
Don't sync dir now if the data file has the same path.
|
||||
|
@ -1007,7 +1007,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
{
|
||||
fn_format(filename,name,"", MARIA_NAME_DEXT,
|
||||
MY_UNPACK_FILENAME | MY_APPEND_EXT);
|
||||
linkname_ptr= NULL;
|
||||
linkname_ptr= NullS;
|
||||
create_flag=MY_DELETE_OLD;
|
||||
}
|
||||
if ((dfile=
|
||||
|
@ -1016,7 +1016,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
goto err;
|
||||
errpos=3;
|
||||
|
||||
if (_ma_initialize_data_file(dfile, &share))
|
||||
if (_ma_initialize_data_file(&share, dfile))
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -1155,7 +1155,7 @@ static int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
|
|||
|
||||
/* Initialize data file */
|
||||
|
||||
int _ma_initialize_data_file(File dfile, MARIA_SHARE *share)
|
||||
int _ma_initialize_data_file(MARIA_SHARE *share, File dfile)
|
||||
{
|
||||
if (share->data_file_type == BLOCK_RECORD)
|
||||
{
|
||||
|
|
|
@ -31,9 +31,7 @@
|
|||
|
||||
int maria_delete_all_rows(MARIA_HA *info)
|
||||
{
|
||||
uint i;
|
||||
MARIA_SHARE *share=info->s;
|
||||
MARIA_STATE_INFO *state=&share->state;
|
||||
my_bool log_record;
|
||||
DBUG_ENTER("maria_delete_all_rows");
|
||||
|
||||
|
@ -71,18 +69,7 @@ int maria_delete_all_rows(MARIA_HA *info)
|
|||
goto err;
|
||||
}
|
||||
|
||||
info->state->records=info->state->del=state->split=0;
|
||||
state->changed= 0; /* File is optimized */
|
||||
state->dellink = HA_OFFSET_ERROR;
|
||||
state->sortkey= (ushort) ~0;
|
||||
info->state->key_file_length=share->base.keystart;
|
||||
info->state->data_file_length=0;
|
||||
info->state->empty=info->state->key_empty=0;
|
||||
info->state->checksum=0;
|
||||
|
||||
state->key_del= HA_OFFSET_ERROR;
|
||||
for (i=0 ; i < share->base.keys ; i++)
|
||||
state->key_root[i]= HA_OFFSET_ERROR;
|
||||
_ma_reset_status(info);
|
||||
|
||||
/*
|
||||
If we are using delayed keys or if the user has done changes to the tables
|
||||
|
@ -94,7 +81,7 @@ int maria_delete_all_rows(MARIA_HA *info)
|
|||
my_chsize(share->kfile.file, share->base.keystart, 0, MYF(MY_WME)) )
|
||||
goto err;
|
||||
|
||||
if (_ma_initialize_data_file(info->dfile.file, share))
|
||||
if (_ma_initialize_data_file(share, info->dfile.file))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
|
@ -126,4 +113,39 @@ err:
|
|||
allow_break(); /* Allow SIGHUP & SIGINT */
|
||||
DBUG_RETURN(my_errno=save_errno);
|
||||
}
|
||||
} /* maria_delete */
|
||||
} /* maria_delete_all_rows */
|
||||
|
||||
|
||||
/*
|
||||
Reset status information
|
||||
|
||||
SYNOPSIS
|
||||
_ma_reset_status()
|
||||
maria Maria handler
|
||||
|
||||
DESCRIPTION
|
||||
Resets data and index file information as if the file would be empty
|
||||
Files are not touched.
|
||||
*/
|
||||
|
||||
void _ma_reset_status(MARIA_HA *info)
|
||||
{
|
||||
MARIA_SHARE *share= info->s;
|
||||
MARIA_STATE_INFO *state= &share->state;
|
||||
uint i;
|
||||
|
||||
info->state->records= info->state->del= state->split= 0;
|
||||
state->changed= 0; /* File is optimized */
|
||||
state->dellink= HA_OFFSET_ERROR;
|
||||
state->sortkey= (ushort) ~0;
|
||||
info->state->key_file_length= share->base.keystart;
|
||||
info->state->data_file_length= 0;
|
||||
info->state->empty= info->state->key_empty= 0;
|
||||
info->state->checksum= 0;
|
||||
|
||||
/* Drop the delete key chain. */
|
||||
state->key_del= HA_OFFSET_ERROR;
|
||||
/* Clear all keys */
|
||||
for (i=0 ; i < share->base.keys ; i++)
|
||||
state->key_root[i]= HA_OFFSET_ERROR;
|
||||
}
|
||||
|
|
|
@ -1018,7 +1018,8 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
|
|||
*/
|
||||
|
||||
my_bool _ma_rec_check(MARIA_HA *info,const char *record, byte *rec_buff,
|
||||
ulong packed_length, my_bool with_checksum)
|
||||
ulong packed_length, my_bool with_checksum,
|
||||
ha_checksum checksum)
|
||||
{
|
||||
uint length,new_length,flag,bit,i;
|
||||
char *pos,*end,*packpos,*to;
|
||||
|
@ -1124,7 +1125,7 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, byte *rec_buff,
|
|||
if (packed_length != (uint) (to - rec_buff) + test(info->s->calc_checksum) ||
|
||||
(bit != 1 && (flag & ~(bit - 1))))
|
||||
goto err;
|
||||
if (with_checksum && ((uchar) info->cur_row.checksum != (uchar) *to))
|
||||
if (with_checksum && ((uchar) checksum != (uchar) *to))
|
||||
{
|
||||
DBUG_PRINT("error",("wrong checksum for row"));
|
||||
goto err;
|
||||
|
|
|
@ -135,6 +135,7 @@ void _ma_report_error(int errcode, const char *file_name)
|
|||
file_name+= length - 64;
|
||||
}
|
||||
}
|
||||
|
||||
my_error(errcode, MYF(ME_NOREFRESH), file_name);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ int maria_init(void)
|
|||
maria_inited= TRUE;
|
||||
pthread_mutex_init(&THR_LOCK_maria,MY_MUTEX_INIT_SLOW);
|
||||
_ma_init_block_record_data();
|
||||
my_handler_error_register();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4331,12 +4331,12 @@ my_bool translog_write_record(LSN *lsn,
|
|||
{
|
||||
uint i;
|
||||
uint len= 0;
|
||||
#ifdef HAVE_PURIFY
|
||||
#ifdef HAVE_purify
|
||||
ha_checksum checksum= 0;
|
||||
#endif
|
||||
for (i= TRANSLOG_INTERNAL_PARTS; i < part_no; i++)
|
||||
{
|
||||
#ifdef HAVE_PURIFY
|
||||
#ifdef HAVE_purify
|
||||
/* Find unitialized bytes early */
|
||||
checksum+= my_checksum(checksum, parts_data[i].str,
|
||||
parts_data[i].length);
|
||||
|
|
|
@ -260,7 +260,9 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
my_realpath(name_buff, fn_format(org_name,name,"",MARIA_NAME_IEXT,
|
||||
MY_UNPACK_FILENAME),MYF(0));
|
||||
pthread_mutex_lock(&THR_LOCK_maria);
|
||||
if (!(old_info=_ma_test_if_reopen(name_buff)))
|
||||
old_info= 0;
|
||||
if ((open_flags & HA_OPEN_COPY) ||
|
||||
!(old_info=_ma_test_if_reopen(name_buff)))
|
||||
{
|
||||
share= &share_buff;
|
||||
bzero((gptr) &share_buff,sizeof(share_buff));
|
||||
|
@ -586,6 +588,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
share->base.null_bytes +
|
||||
share->base.pack_bytes +
|
||||
test(share->options & HA_OPTION_CHECKSUM));
|
||||
if (open_flags & HA_OPEN_COPY)
|
||||
share->base.transactional= 0; /* Repair: no logging */
|
||||
if (share->base.transactional)
|
||||
{
|
||||
share->base_length+= TRANS_ROW_EXTRA_HEADER_SIZE;
|
||||
|
@ -870,6 +874,8 @@ void _ma_setup_functions(register MARIA_SHARE *share)
|
|||
}
|
||||
share->file_read= _ma_nommap_pread;
|
||||
share->file_write= _ma_nommap_pwrite;
|
||||
share->calc_check_checksum= share->calc_checksum;
|
||||
|
||||
if (!(share->options & HA_OPTION_CHECKSUM) &&
|
||||
share->data_file_type != COMPRESSED_RECORD)
|
||||
share->calc_checksum= share->calc_write_checksum= 0;
|
||||
|
|
|
@ -320,7 +320,8 @@ struct st_pagecache_block_link
|
|||
#ifndef DBUG_OFF
|
||||
/* debug checks */
|
||||
static my_bool info_check_pin(PAGECACHE_BLOCK_LINK *block,
|
||||
enum pagecache_page_pin mode)
|
||||
enum pagecache_page_pin mode
|
||||
__attribute__((unused)))
|
||||
{
|
||||
struct st_my_thread_var *thread= my_thread_var;
|
||||
PAGECACHE_PIN_INFO *info= info_find(block->pin_list, thread);
|
||||
|
@ -378,6 +379,7 @@ static my_bool info_check_pin(PAGECACHE_BLOCK_LINK *block,
|
|||
1 - Error
|
||||
*/
|
||||
|
||||
#ifdef NOT_USED
|
||||
static my_bool info_check_lock(PAGECACHE_BLOCK_LINK *block,
|
||||
enum pagecache_page_lock lock,
|
||||
enum pagecache_page_pin pin)
|
||||
|
@ -445,7 +447,8 @@ error:
|
|||
page_cache_page_pin_str[pin]));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
#endif
|
||||
#endif /* NOT_USED */
|
||||
#endif /* !DBUG_OFF */
|
||||
|
||||
#define FLUSH_CACHE 2000 /* sort this many blocks at once */
|
||||
|
||||
|
@ -2858,8 +2861,10 @@ restart:
|
|||
(pin == PAGECACHE_PIN)),
|
||||
&page_st);
|
||||
DBUG_ASSERT(block->type == PAGECACHE_EMPTY_PAGE ||
|
||||
block->type == type);
|
||||
block->type= type;
|
||||
block->type == type || type == PAGECACHE_READ_UNKNOWN_PAGE);
|
||||
if (type != PAGECACHE_READ_UNKNOWN_PAGE ||
|
||||
block->type == PAGECACHE_EMPTY_PAGE)
|
||||
block->type= type;
|
||||
if (((block->status & PCBLOCK_ERROR) == 0) && (page_st != PAGE_READ))
|
||||
{
|
||||
DBUG_PRINT("info", ("read block 0x%lx", (ulong)block));
|
||||
|
@ -3223,6 +3228,7 @@ restart:
|
|||
}
|
||||
|
||||
DBUG_ASSERT(block->type == PAGECACHE_EMPTY_PAGE ||
|
||||
block->type == PAGECACHE_READ_UNKNOWN_PAGE ||
|
||||
block->type == type);
|
||||
block->type= type;
|
||||
|
||||
|
|
|
@ -34,7 +34,9 @@ enum pagecache_page_type
|
|||
/* the page does not contain LSN */
|
||||
PAGECACHE_PLAIN_PAGE,
|
||||
/* the page contain LSN (maria tablespace page) */
|
||||
PAGECACHE_LSN_PAGE
|
||||
PAGECACHE_LSN_PAGE,
|
||||
/* Page type used when scanning file and we don't care about the type */
|
||||
PAGECACHE_READ_UNKNOWN_PAGE
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -5,15 +5,21 @@
|
|||
|
||||
# If you want to run this in Valgrind, you should use --trace-children=yes,
|
||||
# so that it detects problems in ma_test* and not in the shell script
|
||||
|
||||
# Remove # from following line if you need some more information
|
||||
#set -x -v -e
|
||||
|
||||
valgrind="valgrind --alignment=8 --leak-check=yes"
|
||||
silent="-s"
|
||||
suffix=""
|
||||
#set -x -v -e
|
||||
if [ -z "$maria_path" ]
|
||||
then
|
||||
maria_path="."
|
||||
fi
|
||||
|
||||
# Delete temporary files
|
||||
rm -f *.TMD
|
||||
|
||||
run_tests()
|
||||
{
|
||||
row_type=$1
|
||||
|
@ -126,6 +132,11 @@ run_repair_tests()
|
|||
$maria_path/maria_chk$suffix -se test1
|
||||
$maria_path/maria_chk$suffix -rqos --correct-checksum test1
|
||||
$maria_path/maria_chk$suffix -se test1
|
||||
$maria_path/ma_test2$suffix $silent -c -d1 $row_type
|
||||
$maria_path/maria_chk$suffix -s --parallel-recover test2
|
||||
$maria_path/maria_chk$suffix -se test2
|
||||
$maria_path/maria_chk$suffix -s --parallel-recover --quick test2
|
||||
$maria_path/maria_chk$suffix -se test2
|
||||
}
|
||||
|
||||
run_pack_tests()
|
||||
|
@ -153,6 +164,15 @@ run_pack_tests()
|
|||
$maria_path/maria_chk$suffix -es test1
|
||||
$maria_path/maria_chk$suffix -rus test1
|
||||
$maria_path/maria_chk$suffix -es test1
|
||||
|
||||
$maria_path/ma_test2$suffix $silent -c -d1 $row_type
|
||||
$maria_path/maria_chk$suffix -s --parallel-recover test2
|
||||
$maria_path/maria_chk$suffix -se test2
|
||||
$maria_path/maria_chk$suffix -s --parallel-recover --unpack test2
|
||||
$maria_path/maria_chk$suffix -se test2
|
||||
$maria_path/maria_pack$suffix --force -s test1
|
||||
$maria_path/maria_chk$suffix -s --parallel-recover --unpack test2
|
||||
$maria_path/maria_chk$suffix -se test2
|
||||
}
|
||||
|
||||
echo "Running tests with dynamic row format"
|
||||
|
@ -167,9 +187,13 @@ run_pack_tests -S
|
|||
|
||||
echo "Running tests with block row format"
|
||||
run_tests -M
|
||||
run_repair_tests -M
|
||||
run_pack_tests -M
|
||||
|
||||
echo "Running tests with block row format and transactions"
|
||||
run_tests "-M -T"
|
||||
run_repair_tests "-M -T"
|
||||
run_pack_tests "-M -T"
|
||||
|
||||
#
|
||||
# Tests that gives warnings
|
||||
|
|
|
@ -147,6 +147,7 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
|
|||
if (share->calc_checksum)
|
||||
{
|
||||
info->cur_row.checksum= (*share->calc_checksum)(info,newrec);
|
||||
info->state->checksum+= (info->cur_row.checksum - old_checksum);
|
||||
/* Store new checksum in index file header */
|
||||
key_changed|= HA_STATE_CHANGED;
|
||||
}
|
||||
|
@ -173,8 +174,6 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
|
|||
if (auto_key_changed)
|
||||
set_if_bigger(info->s->state.auto_increment,
|
||||
ma_retrieve_auto_increment(info, newrec));
|
||||
if (share->calc_checksum)
|
||||
info->state->checksum+= (info->cur_row.checksum - old_checksum);
|
||||
|
||||
/*
|
||||
We can't yet have HA_STATE_AKTIV here, as block_record dosn't support
|
||||
|
|
|
@ -676,14 +676,7 @@ get_one_option(int optid,
|
|||
check_param.testflag|= T_UPDATE_STATE;
|
||||
break;
|
||||
case '#':
|
||||
if (argument == disabled_my_option)
|
||||
{
|
||||
DBUG_POP();
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_PUSH(argument ? argument : "d:t:o,/tmp/maria_chk.trace");
|
||||
}
|
||||
DBUG_SET_INITIAL(argument ? argument : "d:t:o,/tmp/maria_chk.trace");
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
|
@ -862,16 +855,25 @@ static int maria_chk(HA_CHECK *param, my_string filename)
|
|||
share->r_locks=0;
|
||||
maria_block_size= share->base.block_size;
|
||||
|
||||
if (share->data_file_type == BLOCK_RECORD &&
|
||||
(param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_FAST | T_STATISTICS |
|
||||
T_CHECK | T_CHECK_ONLY_CHANGED)))
|
||||
if (share->data_file_type == BLOCK_RECORD ||
|
||||
((param->testflag & T_UNPACK) &&
|
||||
share->state.header.org_data_file_type == BLOCK_RECORD))
|
||||
{
|
||||
_ma_check_print_error(param,
|
||||
"Record format used by '%s' is is not yet supported with repair/check",
|
||||
filename);
|
||||
param->error_printed= 0;
|
||||
error= 1;
|
||||
goto end2;
|
||||
if (param->testflag & T_SORT_RECORDS)
|
||||
{
|
||||
_ma_check_print_error(param,
|
||||
"Record format used by '%s' is is not yet supported with repair/check",
|
||||
filename);
|
||||
param->error_printed= 0;
|
||||
error= 1;
|
||||
goto end2;
|
||||
}
|
||||
/* We can't do parallell repair with BLOCK_RECORD yet */
|
||||
if (param->testflag & (T_REP_BY_SORT | T_REP_PARALLEL))
|
||||
{
|
||||
param->testflag&= ~(T_REP_BY_SORT | T_REP_PARALLEL);
|
||||
param->testflag|= T_REP;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1764,11 +1766,14 @@ void _ma_check_print_info(HA_CHECK *param __attribute__((unused)),
|
|||
const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_info");
|
||||
DBUG_PRINT("enter", ("format: %s", fmt));
|
||||
|
||||
va_start(args,fmt);
|
||||
VOID(vfprintf(stdout, fmt, args));
|
||||
VOID(fputc('\n',stdout));
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
|
@ -1777,6 +1782,7 @@ void _ma_check_print_warning(HA_CHECK *param, const char *fmt,...)
|
|||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_warning");
|
||||
DBUG_PRINT("enter", ("format: %s", fmt));
|
||||
|
||||
fflush(stdout);
|
||||
if (!param->warning_printed && !param->error_printed)
|
||||
|
@ -1802,7 +1808,7 @@ void _ma_check_print_error(HA_CHECK *param, const char *fmt,...)
|
|||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_error");
|
||||
DBUG_PRINT("enter",("format: %s",fmt));
|
||||
DBUG_PRINT("enter", ("format: %s", fmt));
|
||||
|
||||
fflush(stdout);
|
||||
if (!param->warning_printed && !param->error_printed)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#define MAX_NONMAPPED_INSERTS 1000
|
||||
#define MARIA_MAX_TREE_LEVELS 32
|
||||
#define SANITY_CHECKS
|
||||
|
||||
struct st_transaction;
|
||||
|
||||
|
@ -264,7 +265,9 @@ typedef struct st_maria_share
|
|||
Calculate checksum for a row during write. May be 0 if we calculate
|
||||
the checksum in write_record_init()
|
||||
*/
|
||||
ha_checksum(*calc_write_checksum) (struct st_maria_info *, const byte *);
|
||||
ha_checksum(*calc_write_checksum)(struct st_maria_info *, const byte *);
|
||||
/* calculate checksum for a row during check table */
|
||||
ha_checksum(*calc_check_checksum)(struct st_maria_info *, const byte *);
|
||||
/* Compare a row in memory with a row on disk */
|
||||
my_bool (*compare_unique)(struct st_maria_info *, MARIA_UNIQUEDEF *,
|
||||
const byte *record, MARIA_RECORD_POS pos);
|
||||
|
@ -749,7 +752,7 @@ extern ulong _ma_rec_unpack(MARIA_HA *info, byte *to, byte *from,
|
|||
ulong reclength);
|
||||
extern my_bool _ma_rec_check(MARIA_HA *info, const char *record,
|
||||
byte *packpos, ulong packed_length,
|
||||
my_bool with_checkum);
|
||||
my_bool with_checkum, ha_checksum checksum);
|
||||
extern int _ma_write_part_record(MARIA_HA *info, my_off_t filepos,
|
||||
ulong length, my_off_t next_filepos,
|
||||
byte ** record, ulong *reclength,
|
||||
|
@ -874,6 +877,7 @@ void _ma_update_status(void *param);
|
|||
void _ma_restore_status(void *param);
|
||||
void _ma_copy_status(void *to, void *from);
|
||||
my_bool _ma_check_status(void *param);
|
||||
void _ma_reset_status(MARIA_HA *maria);
|
||||
|
||||
extern MARIA_HA *_ma_test_if_reopen(char *filename);
|
||||
my_bool _ma_check_table_is_closed(const char *name, const char *where);
|
||||
|
@ -908,10 +912,9 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param);
|
|||
int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
|
||||
ulong);
|
||||
int _ma_sync_table_files(const MARIA_HA *info);
|
||||
int _ma_initialize_data_file(File dfile, MARIA_SHARE *share);
|
||||
int _ma_initialize_data_file(MARIA_SHARE *share, File dfile);
|
||||
int _ma_update_create_rename_lsn_on_disk(MARIA_SHARE *share, my_bool do_sync);
|
||||
|
||||
void _ma_unpin_all_pages(MARIA_HA *info, LSN undo_lsn);
|
||||
|
||||
extern PAGECACHE *maria_log_pagecache;
|
||||
|
||||
|
|
|
@ -51,10 +51,11 @@ static int ft_add_stopword(const char *w)
|
|||
|
||||
int ft_init_stopwords()
|
||||
{
|
||||
DBUG_ENTER("ft_init_stopwords");
|
||||
if (!stopwords3)
|
||||
{
|
||||
if (!(stopwords3=(TREE *)my_malloc(sizeof(TREE),MYF(0))))
|
||||
return -1;
|
||||
DBUG_RETURN(-1);
|
||||
init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp,
|
||||
0,
|
||||
(ft_stopword_file ? (tree_element_free)&FT_STOPWORD_free : 0),
|
||||
|
@ -70,10 +71,10 @@ int ft_init_stopwords()
|
|||
int error=-1;
|
||||
|
||||
if (!*ft_stopword_file)
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
if ((fd=my_open(ft_stopword_file, O_RDONLY, MYF(MY_WME))) == -1)
|
||||
return -1;
|
||||
DBUG_RETURN(-1);
|
||||
len=(uint)my_seek(fd, 0L, MY_SEEK_END, MYF(0));
|
||||
my_seek(fd, 0L, MY_SEEK_SET, MYF(0));
|
||||
if (!(start=buffer=my_malloc(len+1, MYF(MY_WME))))
|
||||
|
@ -90,7 +91,7 @@ err1:
|
|||
my_free(buffer, MYF(0));
|
||||
err0:
|
||||
my_close(fd, MYF(MY_WME));
|
||||
return error;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -100,13 +101,14 @@ err0:
|
|||
for (;*sws;sws++)
|
||||
{
|
||||
if (ft_add_stopword(*sws))
|
||||
return -1;
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
ft_stopword_file="(built-in)"; /* for SHOW VARIABLES */
|
||||
}
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int is_stopword(char *word, uint len)
|
||||
{
|
||||
FT_STOPWORD sw;
|
||||
|
@ -118,6 +120,8 @@ int is_stopword(char *word, uint len)
|
|||
|
||||
void ft_free_stopwords()
|
||||
{
|
||||
DBUG_ENTER("ft_free_stopwords");
|
||||
|
||||
if (stopwords3)
|
||||
{
|
||||
delete_tree(stopwords3); /* purecov: inspected */
|
||||
|
@ -125,4 +129,5 @@ void ft_free_stopwords()
|
|||
stopwords3=0;
|
||||
}
|
||||
ft_stopword_file= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue