mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Fixed REPAIR/CHECK/ANALYZE TABLE for tables with new BLOCK-ROW format.
Fixed maria_chk to repair BLOCK-ROW tables. Added CREATE options ROW_FORMAT=PAGE & TRANSACTIONAL= 0|1 More DBUG information in a lot of functions Some minor code cleanups Enable handler errors earlier for better clear text error messages at handler startup / standalone usage. Don't print NULL strings in my_create_with_symlink(); Fixes core dump when used with --debug include/maria.h: Added extra variables needed for REPAIR with BLOCK records include/my_base.h: Added argument for opening copy of maria table without a shared object include/my_handler.h: Prototypes for my_handler_error_register() & my_handler_error_unregister() include/pagecache.h: Added PAGECACHE_READ_UNKNOWN_PAGE mysql-test/include/ps_conv.inc: Enforce creation of table as MyISAM (to allow one to use --default-storage-engine) mysql-test/r/maria.result: Moved some things to maria-connect.test Updared results as REPAIR now works Added tests for creation option TRANSACTIONAL mysql-test/r/ps_2myisam.result: Enforce creation of table as MyISAM (to allow one to use --default-storage-engine) mysql-test/r/ps_3innodb.result: Enforce creation of table as MyISAM (to allow one to use --default-storage-engine) mysql-test/r/ps_4heap.result: Enforce creation of table as MyISAM (to allow one to use --default-storage-engine) mysql-test/r/ps_5merge.result: Enforce creation of table as MyISAM (to allow one to use --default-storage-engine) mysql-test/r/ps_7ndb.result: Enforce creation of table as MyISAM (to allow one to use --default-storage-engine) mysql-test/r/ps_maria.result: Enforce creation of table as MyISAM (to allow one to use --default-storage-engine) mysql-test/t/maria.test: Moved some things to maria-connect.test Updared results as REPAIR now works Added tests for creation option TRANSACTIONAL mysys/mf_iocache.c: More debugging mysys/mf_tempfile.c: Added missing close() mysys/my_error.c: init_glob_errs() is now done in my_init() mysys/my_handler.c: Added functions to initialize handler error messages mysys/my_init.c: Moevd init_glob_errs() here. mysys/my_open.c: More comments More debugging Code cleanup (join multiple code paths) and indentation fixes. No change in logic. mysys/my_symlink2.c: Don't print NULL strings sql/handler.cc: Added printing of PAGE row type Moved out initializing of handler errors to allow handler to give better error messages at startup sql/handler.h: ROW_TYPE_PAGES -> ROW_TYPE_PAGE sql/lex.h: Added 'PAGE' and 'TRANSACTIONAL' sql/mysqld.cc: Initialize handler error messages early to get better error messages from handler startup sql/sql_show.cc: ROW_TYPE_PAGES -> ROW_TYPE_PAGE sql/sql_table.cc: Removed not needed initializer sql/sql_yacc.yy: Added CREATE options ROW_FORMAT=PAGE and TRANSACTIONAL=[0|1] sql/table.cc: Store transactional flag in .frm More comments sql-bench/example: Better example sql/table.h: Added transactional table option storage/maria/ha_maria.cc: More debug information Enable REPAIR Detect usage of TRANSACTIONAL table option storage/maria/ma_bitmap.c: More comments (from Guilhem) storage/maria/ma_blockrec.c: SANITY_CHECK -> SANITY_CHECKS (fixed typo) Write out pages on delete even if there is no rows. (Fixed problem with REPAIR) Removed some ASSERTS to runtime checks (for better REPAIR) Fixed bug when scanning rows More DBUG information storage/maria/ma_check.c: Partial rewrite to allow REPAIR of BLOCK/PAGE format. Repair of BLOCK format rows is for now only done with 'maria_repair()' (= repair through key cache) The new logic to repair rows with BLOCK format is: - 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 storage/maria/ma_close.c: REmoved not needed block storage/maria/ma_create.c: Swap arguments to _ma_initialize_data_file() storage/maria/ma_delete_all.c: Split maria_delete_all_rows() to two functions to allow REPAIR to easily reset all status information. storage/maria/ma_dynrec.c: Added checksum argument to _ma_rec_check (multi-thread fix) storage/maria/ma_info.c: Indentation fix storage/maria/ma_init.c: Register error message to get better error message on init and when using as standalone module. storage/maria/ma_loghandler.c: Fixed typo that disabled some error detection by valgrind storage/maria/ma_open.c: Added 'calc_check_checksum()' Don't log things during repair Added option HA_OPEN_COPY to allow one to open a Maria table with an independent share (required by REPAIR) storage/maria/ma_pagecache.c: Fixed some compiler warnings Added support for PAGECACHE_READ_UNKNOWN_PAGE (used for scanning file without knowing page types) storage/maria/ma_test_all.sh: More test of REPAIR storage/maria/ma_update.c: Optimized checksum code storage/maria/maria_chk.c: Use DBUG_SET_INITIAL() to get DBUG to work with --parallel-repair Ensure we always use maria_repair() for BLOCK format (for now) More DBUG information storage/maria/maria_def.h: For now, always run with more checkings (SANITY_CHECKS) Added share->calc_check_checksum to be used with REPAIR / CHECK table. Swaped arguments to _ma_initialize_data_file() storage/myisam/ft_stopwords.c: Added DBUG information mysql-test/r/maria-connect.result: New BitKeeper file ``mysql-test/r/maria-connect.result'' mysql-test/t/maria-connect.test: New BitKeeper file ``mysql-test/t/maria-connect.test''
This commit is contained in:
parent
fdfb51484c
commit
d6f2fda680
50 changed files with 948 additions and 336 deletions
|
@ -327,17 +327,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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -436,32 +436,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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1065,16 +1071,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))
|
||||
|
@ -1099,7 +1095,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 */
|
||||
|
@ -1954,7 +1952,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;
|
||||
}
|
||||
|
@ -1963,6 +1961,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;
|
||||
|
@ -2007,7 +2007,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"
|
||||
|
|
|
@ -1778,7 +1778,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
|
||||
|
@ -1814,8 +1814,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;
|
||||
|
@ -1829,7 +1829,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
|
||||
|
@ -2548,11 +2548,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
|
||||
{
|
||||
|
@ -2564,7 +2559,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
|
|||
pagerange_store(log_data + FILEID_STORE_SIZE, 1);
|
||||
page_store(log_data+ FILEID_STORE_SIZE + PAGERANGE_STORE_SIZE, page);
|
||||
pagerange_store(log_data + FILEID_STORE_SIZE + PAGERANGE_STORE_SIZE +
|
||||
PAGERANGE_STORE_SIZE, 1);
|
||||
PAGE_STORE_SIZE, 1);
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
|
||||
if (translog_write_record(!info->trn->rec_lsn ? &info->trn->rec_lsn : &lsn,
|
||||
|
@ -2573,8 +2568,24 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
|
|||
sizeof(log_data), TRANSLOG_INTERNAL_PARTS + 1,
|
||||
log_array))
|
||||
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));
|
||||
}
|
||||
|
@ -2794,7 +2805,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;
|
||||
|
@ -2817,7 +2829,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;
|
||||
|
@ -2826,7 +2839,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 */
|
||||
|
@ -2948,7 +2962,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);
|
||||
|
||||
|
@ -2994,6 +3007,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);
|
||||
|
@ -3028,7 +3042,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,
|
||||
|
@ -3053,7 +3067,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,
|
||||
|
@ -3459,6 +3473,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 -
|
||||
|
@ -3471,7 +3487,8 @@ restart_bitmap_scan:
|
|||
for (data+= 6; data < info->scan.bitmap_end; data+= 6)
|
||||
{
|
||||
bits= uint6korr(data);
|
||||
if (bits && ((bits & LL(04444444444444444)) != LL(04444444444444444)))
|
||||
/* Skip not allocated pages and blob / full tail pages */
|
||||
if (bits && bits != LL(07777777777777777))
|
||||
break;
|
||||
}
|
||||
bit_pos= 0;
|
||||
|
@ -3483,8 +3500,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
|
||||
|
@ -86,6 +85,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)
|
||||
{
|
||||
|
@ -837,7 +842,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 */
|
||||
{
|
||||
|
@ -1262,18 +1267,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)
|
||||
|
@ -1506,8 +1514,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)
|
||||
{
|
||||
|
@ -1571,6 +1582,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",
|
||||
|
@ -1648,13 +1661,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];
|
||||
|
@ -1907,13 +1919,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;
|
||||
|
@ -1922,6 +1949,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));
|
||||
|
@ -1929,9 +1958,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))
|
||||
{
|
||||
|
@ -1943,28 +1974,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 */
|
||||
|
@ -1983,11 +1992,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;
|
||||
|
@ -2030,9 +2099,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)
|
||||
|
@ -2058,7 +2132,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) ||
|
||||
|
@ -2081,35 +2156,58 @@ 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;
|
||||
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))) ||
|
||||
_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))
|
||||
{
|
||||
|
@ -2127,25 +2225,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)
|
||||
{
|
||||
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, (param->testflag & T_BACKUP_DATA ?
|
||||
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
|
||||
_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)));
|
||||
|
@ -2595,7 +2687,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;
|
||||
|
@ -2606,11 +2698,15 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
ulonglong key_map=share->state.key_map;
|
||||
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);
|
||||
|
@ -2621,15 +2717,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,
|
||||
|
@ -2639,6 +2733,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))) ||
|
||||
|
@ -2694,8 +2789,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;
|
||||
|
@ -2707,9 +2802,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;
|
||||
|
@ -2747,7 +2842,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;
|
||||
|
@ -2845,8 +2940,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
|
||||
|
@ -2874,11 +2970,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
|
||||
|
@ -3073,6 +3169,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)) ||
|
||||
|
@ -3140,8 +3238,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;
|
||||
|
@ -3149,9 +3247,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;
|
||||
|
@ -3367,8 +3465,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
|
||||
|
@ -3385,11 +3481,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
|
||||
|
@ -3574,27 +3670,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
|
||||
*/
|
||||
|
||||
|
@ -3615,10 +3712,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 (;;)
|
||||
{
|
||||
|
@ -3656,6 +3804,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;
|
||||
|
@ -3925,14 +4075,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));
|
||||
|
@ -3940,7 +4090,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)
|
||||
|
@ -4014,8 +4164,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);
|
||||
|
@ -4048,8 +4199,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");
|
||||
|
||||
|
@ -4057,7 +4208,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,
|
||||
|
@ -4090,7 +4245,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;
|
||||
|
||||
|
@ -4147,7 +4304,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)
|
||||
|
@ -4505,7 +4662,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));
|
||||
|
@ -4514,7 +4672,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)
|
||||
{
|
||||
|
@ -4786,9 +4945,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));
|
||||
|
@ -5101,6 +5260,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))
|
||||
|
@ -5119,7 +5281,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;
|
||||
|
@ -5132,6 +5295,161 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,8 +124,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 */
|
||||
|
|
|
@ -798,7 +798,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;
|
||||
}
|
||||
DBUG_PRINT("info", ("write state info and base info"));
|
||||
|
@ -1082,7 +1082,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)
|
||||
{
|
||||
|
|
|
@ -20,9 +20,7 @@
|
|||
|
||||
int maria_delete_all_rows(MARIA_HA *info)
|
||||
{
|
||||
uint i;
|
||||
MARIA_SHARE *share=info->s;
|
||||
MARIA_STATE_INFO *state=&share->state;
|
||||
DBUG_ENTER("maria_delete_all_rows");
|
||||
|
||||
if (share->options & HA_OPTION_READ_ONLY_DATA)
|
||||
|
@ -35,18 +33,7 @@ int maria_delete_all_rows(MARIA_HA *info)
|
|||
if (_ma_mark_file_changed(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
|
||||
|
@ -67,7 +54,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, info->s))
|
||||
if (_ma_initialize_data_file(info->s, info->dfile.file))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
|
@ -104,4 +91,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;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ int maria_init(void)
|
|||
pthread_mutex_init(&THR_LOCK_maria,MY_MUTEX_INIT_SLOW);
|
||||
_ma_init_block_record_data();
|
||||
loghandler_init();
|
||||
my_handler_error_register();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4143,12 +4143,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;
|
||||
share->base.default_rec_buff_size= max(share->base.pack_reclength,
|
||||
|
@ -858,6 +862,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;
|
||||
|
|
|
@ -315,7 +315,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);
|
||||
|
@ -373,6 +374,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)
|
||||
|
@ -440,7 +442,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;
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ silent="-s"
|
|||
suffix=""
|
||||
#set -x -v -e
|
||||
|
||||
# Delete temporary files
|
||||
rm -f *.TMD
|
||||
|
||||
run_tests()
|
||||
{
|
||||
row_type=$1
|
||||
|
@ -120,6 +123,11 @@ run_repair_tests()
|
|||
./maria_chk$suffix -se test1
|
||||
./maria_chk$suffix -rqos --correct-checksum test1
|
||||
./maria_chk$suffix -se test1
|
||||
./ma_test2$suffix $silent -c -d1 $row_type
|
||||
./maria_chk$suffix -s --parallel-recover test2
|
||||
./maria_chk$suffix -se test2
|
||||
./maria_chk$suffix -s --parallel-recover --quick test2
|
||||
./maria_chk$suffix -se test2
|
||||
}
|
||||
|
||||
run_pack_tests()
|
||||
|
@ -147,6 +155,15 @@ run_pack_tests()
|
|||
./maria_chk$suffix -es test1
|
||||
./maria_chk$suffix -rus test1
|
||||
./maria_chk$suffix -es test1
|
||||
|
||||
./ma_test2$suffix $silent -c -d1 $row_type
|
||||
./maria_chk$suffix -s --parallel-recover test2
|
||||
./maria_chk$suffix -se test2
|
||||
./maria_chk$suffix -s --parallel-recover --unpack test2
|
||||
./maria_chk$suffix -se test2
|
||||
./maria_pack$suffix --force -s test1
|
||||
./maria_chk$suffix -s --parallel-recover --unpack test2
|
||||
./maria_chk$suffix -se test2
|
||||
}
|
||||
|
||||
echo "Running tests with dynamic row format"
|
||||
|
@ -161,9 +178,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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1757,11 +1759,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 */
|
||||
|
@ -1770,6 +1775,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)
|
||||
|
@ -1795,7 +1801,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;
|
||||
|
||||
|
@ -261,7 +262,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);
|
||||
|
@ -746,7 +749,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,
|
||||
|
@ -871,6 +874,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);
|
||||
|
@ -904,9 +908,8 @@ 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);
|
||||
|
||||
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…
Add table
Reference in a new issue