Merge jani@marvel:/my/bk/mysql-maria.new

into  hynda.mysql.fi:/home/my/mysql-maria


include/my_sys.h:
  Auto merged
include/myisam.h:
  Auto merged
mysql-test/mysql-test-run.pl:
  Auto merged
mysql-test/r/binlog_unsafe.result:
  Auto merged
mysql-test/suite/rpl/t/rpl_innodb_bug28430.test:
  Auto merged
mysys/my_write.c:
  Auto merged
sql/handler.cc:
  Auto merged
sql/handler.h:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_plugin.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_select.h:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/sql_union.cc:
  Auto merged
sql/sql_update.cc:
  Auto merged
storage/myisam/ha_myisam.cc:
  Auto merged
storage/myisam/ha_myisam.h:
  Auto merged
storage/myisam/mi_check.c:
  Auto merged
storage/myisam/mi_open.c:
  Auto merged
include/my_base.h:
  Manual merge. New error code.
This commit is contained in:
unknown 2007-12-18 16:23:15 +02:00
commit 765caec21a
66 changed files with 1166 additions and 546 deletions

View File

@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using maria_funktions */
/* This file should be included when using maria functions */
#ifndef _maria_h
#define _maria_h
@ -250,7 +250,7 @@ typedef struct st_maria_columndef /* column information */
extern ulong maria_block_size, maria_checkpoint_frequency;
extern ulong maria_concurrent_insert;
extern my_bool maria_flush, maria_single_user;
extern my_bool maria_flush, maria_single_user, maria_page_checksums;
extern my_bool maria_delay_key_write;
extern my_off_t maria_max_temp_length;
extern ulong maria_bulk_insert_tree_size, maria_data_pointer_size;

View File

@ -304,8 +304,10 @@ enum ha_base_keytype {
#define HA_OPTION_RELIES_ON_SQL_LAYER 512
#define HA_OPTION_NULL_FIELDS 1024
#define HA_OPTION_PAGE_CHECKSUM 2048
#define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */
#define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */
#define HA_OPTION_TEMP_COMPRESS_RECORD (1L << 15) /* set by isamchk */
#define HA_OPTION_READ_ONLY_DATA (1L << 16) /* Set by isamchk */
#define HA_OPTION_NO_CHECKSUM (1L << 17)
#define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
/* Bits in flag to create() */
@ -372,6 +374,7 @@ enum ha_base_keytype {
#define HA_ERR_KEY_NOT_FOUND 120 /* Didn't find key on read or update */
#define HA_ERR_FOUND_DUPP_KEY 121 /* Dupplicate key on write */
#define HA_ERR_INTERNAL_ERROR 122 /* Internal error */
#define HA_ERR_RECORD_CHANGED 123 /* Uppdate with is recoverable */
#define HA_ERR_WRONG_INDEX 124 /* Wrong index given to function */
#define HA_ERR_CRASHED 126 /* Indexfile is crashed */
@ -433,7 +436,8 @@ enum ha_base_keytype {
#define HA_ERR_NEW_FILE 172 /* New file format */
#define HA_ERR_INITIALIZATION 173 /* Error during initialization */
#define HA_ERR_FILE_TOO_SHORT 174 /* File too short */
#define HA_ERR_LAST 174 /* Copy of last error nr */
#define HA_ERR_WRONG_CRC 175 /* Wrong CRC on page */
#define HA_ERR_LAST 175 /* Copy of last error nr */
/* Number of different errors */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)

View File

@ -62,12 +62,14 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */
#define MY_REDEL_MAKE_BACKUP 256
#define MY_SEEK_NOT_DONE 32 /* my_lock may have to do a seek */
#define MY_DONT_WAIT 64 /* my_lock() don't wait if can't lock */
#define MY_SHORT_WAIT 64 /* my_lock() don't wait if can't lock */
#define MY_FORCE_LOCK 128 /* use my_lock() even if disable_locking */
#define MY_NO_WAIT 256 /* my_lock() don't wait at all */
#define MY_ZEROFILL 32 /* my_malloc(), fill array with zero */
#define MY_ALLOW_ZERO_PTR 64 /* my_realloc() ; zero ptr -> malloc */
#define MY_FREE_ON_ERROR 128 /* my_realloc() ; Free old ptr on error */
#define MY_HOLD_ON_ERROR 256 /* my_realloc() ; Return old ptr on error */
#define MY_DONT_OVERWRITE_FILE 1024 /* my_copy: Don't overwrite file */
#define MY_DONT_OVERWRITE_FILE 2048 /* my_copy: Don't overwrite file */
#define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */
#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */

View File

@ -225,7 +225,7 @@ struct st_mi_bit_buff;
typedef struct st_columndef /* column information */
{
int16 type; /* en_fieldtype */
enum en_fieldtype type;
uint16 length; /* length of field */
uint32 offset; /* Offset to position in row */
uint8 null_bit; /* If column may be 0 */

View File

@ -474,12 +474,6 @@ sub mtr_kill_leftovers () {
}
}
}
else
{
mtr_warning("Found non pid file $elem in $rundir")
if -f "$rundir/$elem";
next;
}
}
closedir(RUNDIR);

View File

@ -3097,6 +3097,7 @@ sub install_db ($$) {
mtr_add_arg($args, "--datadir=%s", $data_dir);
mtr_add_arg($args, "--loose-skip-innodb");
mtr_add_arg($args, "--loose-skip-ndbcluster");
mtr_add_arg($args, "--sync-frm=0");
mtr_add_arg($args, "--tmpdir=.");
mtr_add_arg($args, "--core-file");
@ -3852,6 +3853,7 @@ sub mysqld_arguments ($$$$) {
mtr_add_arg($args, "%s--datadir=%s", $prefix,
$mysqld->{'path_myddir'});
mtr_add_arg($args, "--sync-frm=0"); # Faster test
if ( $mysql_version_id >= 50106 )
{

View File

@ -11,3 +11,4 @@ Level Warning
Code 1592
Message Statement is not safe to log in statement format.
DROP TABLE t1,t2,t3;
DROP VIEW v1;

View File

@ -325,7 +325,7 @@ KEY `ip` (`ip`),
KEY `poster_login` (`poster_login`),
KEY `topic_id` (`topic_id`),
FULLTEXT KEY `post_text` (`post_text`)
);
) TRANSACTIONAL=0;
INSERT INTO t1 (post_text) VALUES ('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test');
REPAIR TABLE t1;
Table Op Msg_type Msg_text
@ -2052,6 +2052,7 @@ maria_checkpoint_interval 30
maria_log_file_size 4294959104
maria_log_purge_type immediate
maria_max_sort_file_size 9223372036853727232
maria_page_checksum ON
maria_pagecache_age_threshold 300
maria_pagecache_buffer_size 8384512
maria_pagecache_division_limit 100
@ -2068,3 +2069,10 @@ Maria_pagecache_read_requests #
Maria_pagecache_reads #
Maria_pagecache_write_requests #
Maria_pagecache_writes #
create table t1 (s varchar(25), fulltext(s)) TRANSACTIONAL= 1;
ERROR HY000: Maria can't yet handle SPATIAL or FULLTEXT keys in transactional mode. For now use TRANSACTIONAL=0
drop table if exists t1;
create table t1 ( fid int not null auto_increment primary key,
g geometry not null, spatial key(g));
ERROR HY000: Maria can't yet handle SPATIAL or FULLTEXT keys in transactional mode. For now use TRANSACTIONAL=0
drop table if exists t1;

View File

@ -1166,7 +1166,7 @@ def Extra 253 255 0 N 1 31 8
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t9 ALL NULL NULL NULL NULL 2
drop table if exists t2 ;
create table t2 (s varchar(25), fulltext(s))
create table t2 (s varchar(25), fulltext(s)) TRANSACTIONAL= 0
ENGINE = 'MARIA' ;
insert into t2 values ('Gravedigger'), ('Greed'),('Hollow Dogs') ;
commit ;

View File

@ -1,3 +1,4 @@
--source include/big_test.inc
--source include/have_innodb.inc
--source include/have_partition.inc
--source include/have_binlog_format_mixed_or_row.inc

View File

@ -14,5 +14,4 @@ INSERT INTO t1 SELECT UUID();
query_vertical SHOW WARNINGS;
DROP TABLE t1,t2,t3;
DROP VIEW v1;

View File

@ -342,7 +342,7 @@ CREATE TABLE `t1` (
KEY `poster_login` (`poster_login`),
KEY `topic_id` (`topic_id`),
FULLTEXT KEY `post_text` (`post_text`)
);
) TRANSACTIONAL=0;
INSERT INTO t1 (post_text) VALUES ('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test');
@ -1306,6 +1306,18 @@ show variables like 'maria%';
--replace_column 2 #
show status like 'maria%';
#
# Show that we can't yet create fulltext or spatial index with Maria
#
--error 138
create table t1 (s varchar(25), fulltext(s)) TRANSACTIONAL= 1;
drop table if exists t1;
--error 138
create table t1 ( fid int not null auto_increment primary key,
g geometry not null, spatial key(g));
drop table if exists t1;
# End of 5.2 tests
--disable_result_log

View File

@ -24,7 +24,7 @@ let $type= 'MARIA' ;
--disable_warnings
drop table if exists t2 ;
--enable_warnings
eval create table t2 (s varchar(25), fulltext(s))
eval create table t2 (s varchar(25), fulltext(s)) TRANSACTIONAL= 0
ENGINE = $type ;
insert into t2 values ('Gravedigger'), ('Greed'),('Hollow Dogs') ;
commit ;

View File

@ -134,7 +134,7 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
FILE *fd;
char type[5];
DBUG_ENTER("my_fdopen");
DBUG_PRINT("my",("Fd: %d Flags: %d MyFlags: %d",
DBUG_PRINT("my",("fd: %d Flags: %d MyFlags: %d",
Filedes, Flags, MyFlags));
make_ftype(type,Flags);

View File

@ -575,7 +575,7 @@ static const char *handler_error_messages[]=
{
"Didn't find key on read or update",
"Duplicate key on write or update",
"Undefined handler error 122",
"Internal (unspecified) error in handler",
"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",
@ -627,7 +627,8 @@ static const char *handler_error_messages[]=
"It is not possible to log this statement",
"The table is of a new format not supported by this version",
"Got a fatal error during initialzaction of handler",
"File to short; Expected more data in file"
"File to short; Expected more data in file",
"Read page with wrong checksum"
};

View File

@ -49,12 +49,12 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
int nxErrno;
#endif
DBUG_ENTER("my_lock");
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
DBUG_PRINT("my",("fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
fd,locktype,(long) start,(long) length,MyFlags));
#ifdef VMS
DBUG_RETURN(0);
#else
if (my_disable_locking)
if (my_disable_locking && ! (MyFlags & MY_FORCE_LOCK))
DBUG_RETURN(0);
#if defined(__NETWARE__)
@ -131,10 +131,16 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
lock.l_start= (off_t) start;
lock.l_len= (off_t) length;
if (MyFlags & MY_DONT_WAIT)
if (MyFlags & (MY_NO_WAIT | MY_SHORT_WAIT))
{
if (fcntl(fd,F_SETLK,&lock) != -1) /* Check if we can lock */
DBUG_RETURN(0); /* Ok, file locked */
DBUG_RETURN(0); /* Ok, file locked */
if (MyFlags & MY_NO_WAIT)
{
my_errno= (errno == EACCES) ? EAGAIN : errno ? errno : -1;
DBUG_RETURN(-1);
}
DBUG_PRINT("info",("Was locked, trying with alarm"));
ALARM_INIT;
while ((value=fcntl(fd,F_SETLKW,&lock)) && ! ALARM_TEST &&

View File

@ -48,7 +48,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
size_t readbytes;
int error= 0;
DBUG_ENTER("my_pread");
DBUG_PRINT("my",("Fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d",
DBUG_PRINT("my",("fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d",
Filedes, (ulong) offset, (long) Buffer, (uint) Count,
MyFlags));
for (;;)
@ -128,7 +128,7 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
size_t writenbytes, written;
uint errors;
DBUG_ENTER("my_pwrite");
DBUG_PRINT("my",("Fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d",
DBUG_PRINT("my",("fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d",
Filedes, (ulong) offset, (long) Buffer, (uint) Count,
MyFlags));
errors= 0;

View File

@ -37,7 +37,7 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
{
size_t readbytes, save_count;
DBUG_ENTER("my_read");
DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
Filedes, (long) Buffer, (ulong) Count, MyFlags));
save_count= Count;

View File

@ -47,7 +47,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
{
reg1 os_off_t newpos= -1;
DBUG_ENTER("my_seek");
DBUG_PRINT("my",("Fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d",
DBUG_PRINT("my",("fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d",
fd, (ulong) (((ulonglong) pos) >> 32), (ulong) pos,
whence, MyFlags));
DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */
@ -87,7 +87,7 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
{
os_off_t pos;
DBUG_ENTER("my_tell");
DBUG_PRINT("my",("Fd: %d MyFlags: %d",fd, MyFlags));
DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
DBUG_ASSERT(fd >= 0);
#ifdef HAVE_TELL
pos=tell(fd);

View File

@ -44,7 +44,7 @@ int my_sync(File fd, myf my_flags)
{
int res;
DBUG_ENTER("my_sync");
DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags));
DBUG_PRINT("my",("fd: %d my_flags: %d", fd, my_flags));
do
{

View File

@ -289,12 +289,12 @@ my_bool my_thread_init(void)
#endif
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&tmp->suspend, NULL);
tmp->init= 1;
pthread_mutex_lock(&THR_LOCK_threads);
tmp->id= ++thread_id;
++THR_thread_count;
pthread_mutex_unlock(&THR_LOCK_threads);
tmp->init= 1;
#ifndef DBUG_OFF
/* Generate unique name for thread */
(void) my_thread_name();
@ -392,7 +392,7 @@ extern void **my_thread_var_dbug()
{
struct st_my_thread_var *tmp=
my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
return tmp ? &tmp->dbug : 0;
return tmp && tmp->init ? &tmp->dbug : 0;
}
#endif

View File

@ -25,7 +25,7 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
size_t writenbytes, written;
uint errors;
DBUG_ENTER("my_write");
DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
Filedes, (long) Buffer, (ulong) Count, MyFlags));
errors=0; written=0;

View File

@ -26,7 +26,7 @@
#include "mysql_priv.h"
#include "rpl_filter.h"
#include <myisampack.h>
#include <errno.h>
#include "myisam.h"
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"

View File

@ -237,8 +237,6 @@
#define HA_LEX_CREATE_TMP_TABLE 1
#define HA_LEX_CREATE_IF_NOT_EXISTS 2
#define HA_LEX_CREATE_TABLE_LIKE 4
#define HA_OPTION_NO_CHECKSUM (1L << 17)
#define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
#define HA_MAX_REC_LENGTH 65535
/* Table caching type */
@ -1359,14 +1357,18 @@ public:
}
virtual int read_first_row(uchar *buf, uint primary_key);
/*
The following function is only needed for tables that may be temporary
tables during joins
The following 3 function is only needed for tables that may be
internal temporary tables during joins
*/
virtual int restart_rnd_next(uchar *buf, uchar *pos)
virtual int remember_rnd_pos()
{ return HA_ERR_WRONG_COMMAND; }
virtual int restart_rnd_next(uchar *buf)
{ return HA_ERR_WRONG_COMMAND; }
virtual int rnd_same(uchar *buf, uint inx)
{ return HA_ERR_WRONG_COMMAND; }
virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
virtual ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key)
{ return (ha_rows) 10; }
virtual void position(const uchar *record)=0;
virtual int info(uint)=0; // see my_base.h for full description

View File

@ -25,7 +25,15 @@
#include <thr_alarm.h>
#include <errno.h>
/* Lock a part of a file */
/**
@breif Lock a part of a file
@note
This works like mysys/my_lock.c, with the exception that this function
uses the thr_alarm() to break long lock statements.
(mysys can't use thr_alarm() as by default the alarm handling doesn't
exists)
*/
int my_lock(File fd,int locktype,my_off_t start,my_off_t length,myf MyFlags)
{
@ -36,29 +44,34 @@ int my_lock(File fd,int locktype,my_off_t start,my_off_t length,myf MyFlags)
DBUG_ENTER("my_lock");
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
fd,locktype,(ulong) start,(ulong) length,MyFlags));
if (my_disable_locking)
if (my_disable_locking && ! (MyFlags & MY_FORCE_LOCK))
DBUG_RETURN(0); /* purecov: inspected */
m_lock.l_type=(short) locktype;
m_lock.l_whence=0L;
m_lock.l_start=(long) start;
m_lock.l_len=(long) length;
wait_for_alarm=(MyFlags & MY_DONT_WAIT ? MY_HOW_OFTEN_TO_ALARM :
(uint) 12*60*60);
if (fcntl(fd,F_SETLK,&m_lock) != -1) /* Check if we can lock */
DBUG_RETURN(0); /* Ok, file locked */
DBUG_PRINT("info",("Was locked, trying with alarm"));
if (!thr_alarm(&alarmed,wait_for_alarm,&alarm_buff))
if (!(MyFlags & MY_NO_WAIT))
{
int value;
while ((value=fcntl(fd,F_SETLKW,&m_lock)) && !thr_got_alarm(&alarmed) &&
errno == EINTR) ;
thr_end_alarm(&alarmed);
if (value != -1)
DBUG_RETURN(0);
}
else
{
errno=EINTR;
wait_for_alarm= (MyFlags & MY_SHORT_WAIT ? MY_HOW_OFTEN_TO_ALARM :
(uint) 12*60*60);
DBUG_PRINT("info",("Was locked, trying with alarm"));
if (!thr_alarm(&alarmed,wait_for_alarm,&alarm_buff))
{
int value;
while ((value=fcntl(fd,F_SETLKW,&m_lock)) && !thr_got_alarm(&alarmed) &&
errno == EINTR) ;
thr_end_alarm(&alarmed);
if (value != -1)
DBUG_RETURN(0);
}
else
{
errno=EINTR;
}
}
if (errno == EINTR || errno == EACCES)
my_errno=EAGAIN; /* Easier to check for this */

View File

@ -1945,6 +1945,7 @@ extern TYPELIB log_output_typelib;
extern SHOW_COMP_OPTION have_maria_db;
extern handlerton *partition_hton;
extern handlerton *myisam_hton;
extern handlerton *maria_hton;
extern handlerton *heap_hton;
extern SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen;

View File

@ -3284,7 +3284,7 @@ static int init_server_components()
my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
set_proper_floating_point_mode();
init_thr_lock();
my_uuid_init(my_rnd(&sql_rand),12345);
my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345);
#ifdef HAVE_REPLICATION
init_slave_list();
#endif

View File

@ -2214,7 +2214,14 @@ public:
int prepare2(void) { return 0; }
};
#ifdef WITH_MARIA_STORAGE_ENGINE
#include <maria.h>
#define ENGINE_COLUMNDEF MARIA_COLUMNDEF
#else
#include <myisam.h>
#define ENGINE_COLUMNDEF MI_COLUMNDEF
#endif
/*
Param to create temporary tables when doing SELECT:s
@ -2236,7 +2243,7 @@ public:
Copy_field *save_copy_field, *save_copy_field_end;
uchar *group_buff;
Item **items_to_copy; /* Fields in tmp table */
MI_COLUMNDEF *recinfo,*start_recinfo;
ENGINE_COLUMNDEF *recinfo, *start_recinfo;
KEY *keyinfo;
ha_rows end_write_records;
uint field_count,sum_func_count,func_count;

View File

@ -633,7 +633,7 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
*plugin= pi;
#endif
pi->ref_count++;
DBUG_PRINT("info",("thd: 0x%lx, plugin: \"%s\", ref_count: %d",
DBUG_PRINT("info",("thd: 0x%lx plugin: \"%s\" ref_count: %d",
(long) current_thd, pi->name.str, pi->ref_count));
if (lex)

View File

@ -27,11 +27,16 @@
#include "mysql_priv.h"
#include "sql_select.h"
#include "sql_cursor.h"
#include <m_ctype.h>
#include <my_bit.h>
#include <hash.h>
#include <ft_global.h>
#ifdef WITH_MARIA_STORAGE_ENGINE
#include "../storage/maria/ha_maria.h"
#define TMP_ENGINE_HTON maria_hton
#else
#define TMP_ENGINE_HTON myisam_hton
#endif
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
"MAYBE_REF","ALL","range","index","fulltext",
@ -116,8 +121,14 @@ static COND *optimize_cond(JOIN *join, COND *conds,
Item::cond_result *cond_value);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulonglong options);
static bool create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
int error,
bool ignore_last_dupp,
handlerton *hton,
const char *proc_info);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
@ -9565,7 +9576,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
KEY *keyinfo;
KEY_PART_INFO *key_part_info;
Item **copy_func;
MI_COLUMNDEF *recinfo;
ENGINE_COLUMNDEF *recinfo;
uint total_uneven_bit_length= 0;
bool force_copy_fields= param->force_copy_fields;
DBUG_ENTER("create_tmp_table");
@ -9591,11 +9602,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/*
No need to change table name to lower case as we are only creating
MyISAM or HEAP tables here
MyISAM, Maria or HEAP tables here
*/
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
if (group)
{
if (!param->quick_group)
@ -9687,7 +9697,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
share->blob_field= blob_field;
share->blob_ptr_size= portable_sizeof_char_ptr;
share->db_low_byte_first=1; // True for HEAP and MyISAM
share->db_low_byte_first=1; // True for HEAP, MyISAM and Maria
share->table_charset= param->table_charset;
share->primary_key= MAX_KEY; // Indicate no primary key
share->keys_for_keyread.init();
@ -9819,6 +9829,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*blob_field++= fieldnr;
blob_count++;
}
if (new_field->real_type() == MYSQL_TYPE_STRING ||
new_field->real_type() == MYSQL_TYPE_VARCHAR)
{
string_count++;
string_total_length+= new_field->pack_length();
}
if (item->marker == 4 && item->maybe_null)
{
group_null_items++;
@ -9855,7 +9871,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
{
share->db_plugin= ha_lock_engine(0, myisam_hton);
share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
table->file= get_new_handler(share, &table->mem_root,
share->db_type());
if (group &&
@ -9872,7 +9888,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!table->file)
goto err;
if (!using_unique_constraint)
reclength+= group_null_items; // null flag is stored separately
@ -10008,13 +10023,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/* Make entry for create table */
recinfo->length=length;
if (field->flags & BLOB_FLAG)
recinfo->type= (int) FIELD_BLOB;
recinfo->type= FIELD_BLOB;
else if (use_packed_rows &&
field->real_type() == MYSQL_TYPE_STRING &&
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
recinfo->type=FIELD_SKIP_ENDSPACE;
recinfo->type= FIELD_SKIP_ENDSPACE;
else if (field->real_type() == MYSQL_TYPE_VARCHAR)
recinfo->type= FIELD_VARCHAR;
else
recinfo->type=FIELD_NORMAL;
recinfo->type= FIELD_NORMAL;
if (!--hidden_field_count)
null_count=(null_count+7) & ~7; // move to next byte
@ -10177,9 +10195,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
share->db_record_offset= 1;
if (share->db_type() == myisam_hton)
if (share->db_type() == TMP_ENGINE_HTON)
{
if (create_myisam_tmp_table(table,param,select_options))
if (create_internal_tmp_table(table,param,select_options))
goto err;
}
if (open_tmp_table(table))
@ -10344,15 +10362,149 @@ static bool open_tmp_table(TABLE *table)
}
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulonglong options)
#ifdef WITH_MARIA_STORAGE_ENGINE
/* Create internal Maria temporary table */
static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulonglong options)
{
int error;
MARIA_KEYDEF keydef;
MARIA_UNIQUEDEF uniquedef;
KEY *keyinfo=param->keyinfo;
TABLE_SHARE *share= table->s;
MARIA_CREATE_INFO create_info;
DBUG_ENTER("create_internal_tmp_table");
if (share->keys)
{ // Get keys for ni_create
bool using_unique_constraint=0;
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
sizeof(*seg) * keyinfo->key_parts);
if (!seg)
goto err;
bzero(seg, sizeof(*seg) * keyinfo->key_parts);
if (keyinfo->key_length >= table->file->max_key_length() ||
keyinfo->key_parts > table->file->max_key_parts() ||
share->uniques)
{
/* Can't create a key; Make a unique constraint instead of a key */
share->keys= 0;
share->uniques= 1;
using_unique_constraint=1;
bzero((char*) &uniquedef,sizeof(uniquedef));
uniquedef.keysegs=keyinfo->key_parts;
uniquedef.seg=seg;
uniquedef.null_are_equal=1;
/* Create extra column for hash value */
bzero((uchar*) param->recinfo,sizeof(*param->recinfo));
param->recinfo->type= FIELD_CHECK;
param->recinfo->length= MARIA_UNIQUE_HASH_LENGTH;
param->recinfo++;
share->reclength+= MARIA_UNIQUE_HASH_LENGTH;
}
else
{
/* Create an unique key */
bzero((char*) &keydef,sizeof(keydef));
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
keydef.keysegs= keyinfo->key_parts;
keydef.seg= seg;
}
for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
{
Field *field=keyinfo->key_part[i].field;
seg->flag= 0;
seg->language= field->charset()->number;
seg->length= keyinfo->key_part[i].length;
seg->start= keyinfo->key_part[i].offset;
if (field->flags & BLOB_FLAG)
{
seg->type=
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size);
seg->flag= HA_BLOB_PART;
seg->length=0; // Whole blob in unique constraint
}
else
{
seg->type= keyinfo->key_part[i].type;
/* Tell handler if it can do suffic space compression */
if (field->real_type() == MYSQL_TYPE_STRING &&
keyinfo->key_part[i].length > 4)
seg->flag|= HA_SPACE_PACK;
}
if (!(field->flags & NOT_NULL_FLAG))
{
seg->null_bit= field->null_bit;
seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
/*
We are using a GROUP BY on something that contains NULL
In this case we have to tell Maria that two NULL should
on INSERT be regarded at the same value
*/
if (!using_unique_constraint)
keydef.flag|= HA_NULL_ARE_EQUAL;
}
}
}
bzero((char*) &create_info,sizeof(create_info));
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
OPTION_BIG_TABLES)
create_info.data_file_length= ~(ulonglong) 0;
if ((error= maria_create(share->table_name.str,
share->reclength < 64 &&
!share->blob_fields ? STATIC_RECORD :
BLOCK_RECORD,
share->keys, &keydef,
(uint) (param->recinfo-param->start_recinfo),
param->start_recinfo,
share->uniques, &uniquedef,
&create_info,
HA_CREATE_TMP_TABLE)))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
table->db_stat=0;
goto err;
}
status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
share->db_record_offset= 1;
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
}
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
int error,
bool ignore_last_dupp_key_error)
{
return create_internal_tmp_table_from_heap2(thd, table, param, error,
ignore_last_dupp_key_error,
maria_hton,
"converting HEAP to Maria");
}
#else
/* Create internal MyISAM temporary table */
static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulonglong options)
{
int error;
MI_KEYDEF keydef;
MI_UNIQUEDEF uniquedef;
KEY *keyinfo=param->keyinfo;
TABLE_SHARE *share= table->s;
DBUG_ENTER("create_myisam_tmp_table");
DBUG_ENTER("create_internal_tmp_table");
if (share->keys)
{ // Get keys for ni_create
@ -10455,54 +10607,43 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
}
void
free_tmp_table(THD *thd, TABLE *entry)
{
MEM_ROOT own_root= entry->mem_root;
const char *save_proc_info;
DBUG_ENTER("free_tmp_table");
DBUG_PRINT("enter",("table: %s",entry->alias));
save_proc_info=thd->proc_info;
thd->proc_info="removing tmp table";
if (entry->file)
{
if (entry->db_stat)
entry->file->drop_table(entry->s->table_name.str);
else
entry->file->delete_table(entry->s->table_name.str);
delete entry->file;
}
/* free blobs */
for (Field **ptr=entry->field ; *ptr ; ptr++)
(*ptr)->free();
free_io_cache(entry);
if (entry->temp_pool_slot != MY_BIT_NONE)
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
plugin_unlock(0, entry->s->db_plugin);
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
thd->proc_info=save_proc_info;
DBUG_VOID_RETURN;
}
/*
* If a HEAP table gets full, create a MyISAM table and copy all rows to this
If a HEAP table gets full, create a MyISAM table and copy all rows to this
*/
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
int error, bool ignore_last_dupp_key_error)
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
int error,
bool ignore_last_dupp_key_error)
{
return create_internal_tmp_table_from_heap2(thd, table, param, error,
ignore_last_dupp_key_error,
myisam_hton,
"converting HEAP to MyISAM");
}
#endif /* WITH_MARIA_STORAGE_ENGINE */
/*
If a HEAP table gets full, create a internal table in MyISAM or Maria
and copy all rows to this
*/
static bool
create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
int error,
bool ignore_last_dupp_key_error,
handlerton *hton,
const char *proc_info)
{
TABLE new_table;
TABLE_SHARE share;
const char *save_proc_info;
int write_err;
DBUG_ENTER("create_myisam_from_heap");
DBUG_ENTER("create_internal_tmp_table_from_heap2");
if (table->s->db_type() != heap_hton ||
error != HA_ERR_RECORD_FILE_FULL)
@ -10513,15 +10654,15 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
new_table= *table;
share= *table->s;
new_table.s= &share;
new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
new_table.s->db_plugin= ha_lock_engine(thd, hton);
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
new_table.s->db_type())))
DBUG_RETURN(1); // End of memory
save_proc_info=thd->proc_info;
thd->proc_info="converting HEAP to MyISAM";
thd->proc_info= proc_info;
if (create_myisam_tmp_table(&new_table, param,
if (create_internal_tmp_table(&new_table, param,
thd->lex->select_lex.options | thd->options))
goto err2;
if (open_tmp_table(&new_table))
@ -10602,6 +10743,43 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
}
void
free_tmp_table(THD *thd, TABLE *entry)
{
MEM_ROOT own_root= entry->mem_root;
const char *save_proc_info;
DBUG_ENTER("free_tmp_table");
DBUG_PRINT("enter",("table: %s",entry->alias));
save_proc_info=thd->proc_info;
thd->proc_info="removing tmp table";
if (entry->file)
{
if (entry->db_stat)
entry->file->drop_table(entry->s->table_name.str);
else
entry->file->delete_table(entry->s->table_name.str);
delete entry->file;
}
/* free blobs */
for (Field **ptr=entry->field ; *ptr ; ptr++)
(*ptr)->free();
free_io_cache(entry);
if (entry->temp_pool_slot != MY_BIT_NONE)
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
plugin_unlock(0, entry->s->db_plugin);
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
thd->proc_info=save_proc_info;
DBUG_VOID_RETURN;
}
/*
SYNOPSIS
setup_end_select_func()
@ -12029,7 +12207,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
goto end;
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param,
error,1))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
table->s->uniques=0; // To ensure rows are the same
@ -12113,7 +12291,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
copy_funcs(join->tmp_table_param.items_to_copy);
if ((error=table->file->write_row(table->record[0])))
{
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param,
error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
/* Change method to update rows */
@ -12208,7 +12386,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->having || join->having->val_int())
{
int error= table->file->write_row(table->record[0]);
if (error && create_myisam_from_heap(join->thd, table,
if (error && create_internal_tmp_table_from_heap(join->thd, table,
&join->tmp_table_param,
error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR);
@ -13468,13 +13646,14 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
else if (!found)
{
found=1;
file->position(record); // Remember position
if ((error= file->remember_rnd_pos()))
goto err;
}
}
if (!found)
break; // End of file
/* Restart search on next row */
error=file->restart_rnd_next(record,file->ref);
/* Restart search on saved row */
error=file->restart_rnd_next(record);
}
file->extra(HA_EXTRA_NO_CACHE);
@ -15585,7 +15764,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
if ((write_error= table_arg->file->write_row(table_arg->record[0])))
{
if (create_myisam_from_heap(thd, table_arg, &tmp_table_param,
if (create_internal_tmp_table_from_heap(thd, table_arg, &tmp_table_param,
write_error, 0))
return 1;
}

View File

@ -542,7 +542,7 @@ bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
uint elements, List<Item> &fields);
void copy_fields(TMP_TABLE_PARAM *param);
void copy_funcs(Item **func_ptr);
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
int error, bool ignore_last_dupp_error);
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
Field* create_tmp_field_from_field(THD *thd, Field* org_field,

View File

@ -2248,7 +2248,7 @@ bool schema_table_store_record(THD *thd, TABLE *table)
int error;
if ((error= table->file->ha_write_row(table->record[0])))
{
if (create_myisam_from_heap(thd, table,
if (create_internal_tmp_table_from_heap(thd, table,
table->pos_in_table_list->schema_table_param,
error, 0))
return 1;

View File

@ -3195,8 +3195,9 @@ bool mysql_create_table_no_lock(THD *thd,
if (check_engine(thd, table_name, create_info))
DBUG_RETURN(TRUE);
db_options= create_info->table_options;
if (create_info->row_type == ROW_TYPE_DYNAMIC)
db_options|=HA_OPTION_PACK_RECORD;
if (create_info->row_type != ROW_TYPE_FIXED &&
create_info->row_type != ROW_TYPE_DEFAULT)
db_options|= HA_OPTION_PACK_RECORD;
alias= table_case_name(create_info, table_name);
if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
create_info->db_type)))
@ -5162,8 +5163,7 @@ compare_tables(TABLE *table,
}
/* Don't pack rows in old tables if the user has requested this. */
if (create_info->row_type == ROW_TYPE_DYNAMIC ||
(new_field->flags & BLOB_FLAG) ||
if ((new_field->flags & BLOB_FLAG) ||
new_field->sql_type == MYSQL_TYPE_VARCHAR &&
create_info->row_type != ROW_TYPE_FIXED)
create_info->table_options|= HA_OPTION_PACK_RECORD;

View File

@ -63,9 +63,9 @@ bool select_union::send_data(List<Item> &values)
if ((error= table->file->ha_write_row(table->record[0])))
{
/* create_myisam_from_heap will generate error if needed */
/* create_internal_tmp_table_from_heap will generate error if needed */
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
create_myisam_from_heap(thd, table, &tmp_table_param, error, 1))
create_internal_tmp_table_from_heap(thd, table, &tmp_table_param, error, 1))
return 1;
}
return 0;

View File

@ -1678,7 +1678,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
{
if (error &&
create_myisam_from_heap(thd, tmp_table,
create_internal_tmp_table_from_heap(thd, tmp_table,
tmp_table_param + offset, error, 1))
{
do_update= 0;

View File

@ -124,6 +124,10 @@ static MYSQL_SYSVAR_ULONG(checkpoint_interval, checkpoint_interval,
" 0 means 'no automatic checkpoints'.",
NULL, update_checkpoint_interval, 30, 0, UINT_MAX, 1);
static MYSQL_SYSVAR_BOOL(page_checksum, maria_page_checksums, 0,
"Maintain page checksums (can be overridden per table "
"with PAGE_CHECKSUM clause in CREATE TABLE)", 0, 0, 1);
static MYSQL_SYSVAR_ULONG(log_file_size, log_file_size,
PLUGIN_VAR_RQCMDARG,
"Limit for transaction log size",
@ -267,8 +271,10 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type,
# error code
*/
int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
MARIA_COLUMNDEF **recinfo_out, uint *records_out)
static int table2maria(TABLE *table_arg, data_file_type row_type,
MARIA_KEYDEF **keydef_out,
MARIA_COLUMNDEF **recinfo_out, uint *records_out,
MARIA_CREATE_INFO *create_info)
{
uint i, j, recpos, minpos, fieldpos, temp_length, length;
enum ha_base_keytype type= HA_KEYTYPE_BINARY;
@ -281,6 +287,9 @@ int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
uint options= share->db_options_in_use;
DBUG_ENTER("table2maria");
if (row_type == BLOCK_RECORD)
options|= HA_OPTION_PACK_RECORD;
if (!(my_multi_malloc(MYF(MY_WME),
recinfo_out, (share->fields * 2 + 2) * sizeof(MARIA_COLUMNDEF),
keydef_out, share->keys * sizeof(MARIA_KEYDEF),
@ -369,6 +378,8 @@ int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
record= table_arg->record[0];
recpos= 0;
recinfo_pos= recinfo;
create_info->null_bytes= table_arg->s->null_bytes;
while (recpos < (uint) share->reclength)
{
Field **field, *found= 0;
@ -394,13 +405,6 @@ int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
}
DBUG_PRINT("loop", ("found: 0x%lx recpos: %d minpos: %d length: %d",
(long) found, recpos, minpos, length));
if (recpos != minpos)
{
/* reserve space for null bits */
bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
recinfo_pos->type= FIELD_NORMAL;
recinfo_pos++->length= (uint16) (minpos - recpos);
}
if (!found)
break;
@ -561,6 +565,7 @@ int maria_check_definition(MARIA_KEYDEF *t1_keyinfo,
}
}
}
for (i= 0; i < t1_recs; i++)
{
MARIA_COLUMNDEF *t1_rec= &t1_recinfo[i];
@ -1900,13 +1905,20 @@ int ha_maria::rnd_next(uchar *buf)
}
int ha_maria::restart_rnd_next(uchar *buf, uchar *pos)
int ha_maria::remember_rnd_pos()
{
return rnd_pos(buf, pos);
return (*file->s->scan_remember_pos)(file, &remember_pos);
}
int ha_maria::rnd_pos(uchar * buf, uchar *pos)
int ha_maria::restart_rnd_next(uchar *buf)
{
(*file->s->scan_restore_pos)(file, remember_pos);
return rnd_next(buf);
}
int ha_maria::rnd_pos(uchar *buf, uchar *pos)
{
ha_statistic_increment(&SSV::ha_read_rnd_count);
int error= maria_rrnd(file, buf, my_get_ptr(pos, ref_length));
@ -1915,7 +1927,7 @@ int ha_maria::rnd_pos(uchar * buf, uchar *pos)
}
void ha_maria::position(const uchar * record)
void ha_maria::position(const uchar *record)
{
my_off_t row_position= maria_position(file);
my_store_ptr(ref, ref_length, row_position);
@ -2172,9 +2184,10 @@ enum row_type ha_maria::get_row_type() const
}
static enum data_file_type maria_row_type(HA_CREATE_INFO *info)
static enum data_file_type maria_row_type(HA_CREATE_INFO *info,
my_bool ignore_transactional)
{
if (info->transactional == HA_CHOICE_YES)
if (info->transactional == HA_CHOICE_YES && ! ignore_transactional)
return BLOCK_RECORD;
switch (info->row_type) {
case ROW_TYPE_FIXED: return STATIC_RECORD;
@ -2207,7 +2220,7 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
}
}
/* Note: BLOCK_RECORD is used if table is transactional */
row_type= maria_row_type(ha_create_info);
row_type= maria_row_type(ha_create_info, 0);
if (ha_create_info->transactional == HA_CHOICE_YES &&
ha_create_info->row_type != ROW_TYPE_PAGE &&
ha_create_info->row_type != ROW_TYPE_NOT_USED &&
@ -2216,9 +2229,10 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
ER_ILLEGAL_HA_CREATE_OPTION,
"Row format set to PAGE because of TRANSACTIONAL=1 option");
if ((error= table2maria(table_arg, &keydef, &recinfo, &record_count)))
DBUG_RETURN(error); /* purecov: inspected */
bzero((char*) &create_info, sizeof(create_info));
if ((error= table2maria(table_arg, row_type, &keydef, &recinfo,
&record_count, &create_info)))
DBUG_RETURN(error); /* purecov: inspected */
create_info.max_rows= share->max_rows;
create_info.reloc_rows= share->min_rows;
create_info.with_auto_increment= share->next_number_key_offset == 0;
@ -2253,7 +2267,8 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
create_flags|= HA_CREATE_CHECKSUM;
if (options & HA_OPTION_DELAY_KEY_WRITE)
create_flags|= HA_CREATE_DELAY_KEY_WRITE;
if (ha_create_info->page_checksum != HA_CHOICE_NO)
if ((ha_create_info->page_checksum == HA_CHOICE_UNDEF && maria_page_checksums) ||
ha_create_info->page_checksum == HA_CHOICE_YES)
create_flags|= HA_CREATE_PAGE_CHECKSUM;
/* TODO: Check that the following fn_format is really needed */
@ -2387,7 +2402,8 @@ bool ha_maria::check_if_incompatible_data(HA_CREATE_INFO *create_info,
if (create_info->auto_increment_value != stats.auto_increment_value ||
create_info->data_file_name != data_file_name ||
create_info->index_file_name != index_file_name ||
maria_row_type(create_info) != data_file_type ||
(maria_row_type(create_info, 1) != data_file_type &&
create_info->row_type != ROW_TYPE_DEFAULT) ||
table_changes == IS_EQUAL_NO ||
table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
return COMPATIBLE_DATA_NO;
@ -2658,6 +2674,7 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name,
static struct st_mysql_sys_var* system_variables[]= {
MYSQL_SYSVAR(block_size),
MYSQL_SYSVAR(checkpoint_interval),
MYSQL_SYSVAR(page_checksum),
MYSQL_SYSVAR(log_file_size),
MYSQL_SYSVAR(log_purge_type),
MYSQL_SYSVAR(max_sort_file_size),

View File

@ -36,6 +36,7 @@ class ha_maria :public handler
{
MARIA_HA *file;
ulonglong int_table_flags;
MARIA_RECORD_POS remember_pos;
char *data_file_name, *index_file_name;
enum data_file_type data_file_type;
bool can_enable_indexes;
@ -101,7 +102,8 @@ public:
int rnd_end(void);
int rnd_next(uchar * buf);
int rnd_pos(uchar * buf, uchar * pos);
int restart_rnd_next(uchar * buf, uchar * pos);
int remember_rnd_pos();
int restart_rnd_next(uchar * buf);
void position(const uchar * record);
int info(uint);
int extra(enum ha_extra_function operation);

View File

@ -144,6 +144,7 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_size);
DBUG_ASSERT(bitmap->file.write_callback != 0);
DBUG_PRINT("info", ("bitmap->non_flushable: %u", bitmap->non_flushable));
if ((bitmap->non_flushable == 0)
#ifdef WRONG_BITMAP_FLUSH
|| 1
@ -176,10 +177,11 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
int res= pagecache_write(share->pagecache,
&bitmap->file, bitmap->page, 0,
(uchar*) bitmap->map, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_READ, PAGECACHE_PIN,
PAGECACHE_LOCK_WRITE, PAGECACHE_PIN,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE);
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
page_link.changed= 1;
push_dynamic(&bitmap->pinned_pages, (void*) &page_link);
DBUG_RETURN(res);
}
@ -217,12 +219,23 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
sizeof(MARIA_PINNED_PAGE), 1, 1))
return 1;
bitmap->file.file= file;
bitmap->block_size= share->block_size;
pagecache_file_init(bitmap->file, &maria_page_crc_check_bitmap,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_bitmap), share);
bitmap->file.file= file;
bitmap->file.callback_data= (uchar*) share;
if (share->temporary)
{
bitmap->file.read_callback= &maria_page_crc_check_none;
bitmap->file.write_callback= &maria_page_filler_set_none;
}
else
{
bitmap->file.read_callback= &maria_page_crc_check_bitmap;
if (share->options & HA_OPTION_PAGE_CHECKSUM)
bitmap->file.write_callback= &maria_page_crc_set_normal;
else
bitmap->file.write_callback= &maria_page_filler_set_bitmap;
}
/* Size needs to be aligned on 6 */
aligned_bit_blocks= (share->block_size - PAGE_SUFFIX_SIZE) / 6;
bitmap->total_size= aligned_bit_blocks * 6;
@ -2119,7 +2132,18 @@ my_bool _ma_bitmap_set_full_page_bits(MARIA_HA *info,
void _ma_bitmap_flushable(MARIA_SHARE *share, int non_flushable_inc)
{
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
MARIA_FILE_BITMAP *bitmap;
/*
Not transactional tables are never automaticly flushed and needs no
protection
*/
#ifndef EXTRA_DEBUG
if (!share->now_transactional)
return;
#endif
bitmap= &share->bitmap;
if (non_flushable_inc == -1)
{
pthread_mutex_lock(&bitmap->bitmap_lock);

View File

@ -502,7 +502,8 @@ my_bool _ma_init_block_record(MARIA_HA *info)
sizeof(MARIA_BITMAP_BLOCK), default_extents,
64))
goto err;
if (!(info->cur_row.extents= my_malloc(default_extents * ROW_EXTENT_SIZE,
info->cur_row.extents_buffer_length= default_extents * ROW_EXTENT_SIZE;
if (!(info->cur_row.extents= my_malloc(info->cur_row.extents_buffer_length,
MYF(MY_WME))))
goto err;
@ -1915,7 +1916,7 @@ static my_bool write_block_record(MARIA_HA *info,
row_extents_first_part= data;
data+= ROW_EXTENT_SIZE;
}
if (share->base.pack_fields)
if (share->base.max_field_lengths)
store_key_length_inc(data, row->field_lengths_length);
if (share->calc_checksum)
{
@ -3287,7 +3288,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record)
delete_tails(info, info->cur_row.tail_positions))
goto err;
if (info->cur_row.extents && free_full_pages(info, &info->cur_row))
if (info->cur_row.extents_count && free_full_pages(info, &info->cur_row))
goto err;
if (share->now_transactional)
@ -4152,6 +4153,81 @@ void _ma_scan_end_block_record(MARIA_HA *info)
DBUG_ENTER("_ma_scan_end_block_record");
my_free(info->scan.bitmap_buff, MYF(MY_ALLOW_ZERO_PTR));
info->scan.bitmap_buff= 0;
if (info->scan_save)
{
my_free(info->scan_save, MYF(0));
info->scan_save= 0;
}
DBUG_VOID_RETURN;
}
/**
@brief Save current scan position
@note
For the moment we can only remember one position, but this is
good enough for MySQL usage
@Warning
When this function is called, we assume that the thread is not deleting
or updating the current row before ma_scan_restore_block_record()
is called!
@return
@retval 0 ok
@retval HA_ERR_WRONG_IN_RECORD Could not allocate memory to hold position
*/
int _ma_scan_remember_block_record(MARIA_HA *info,
MARIA_RECORD_POS *lastpos)
{
uchar *bitmap_buff;
DBUG_ENTER("_ma_scan_remember_block_record");
if (!(info->scan_save))
{
if (!(info->scan_save= my_malloc(ALIGN_SIZE(sizeof(*info->scan_save)) +
info->s->block_size * 2,
MYF(MY_WME))))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
info->scan_save->bitmap_buff= ((uchar*) info->scan_save +
ALIGN_SIZE(sizeof(*info->scan_save)));
}
/* Point to the last read row */
*lastpos= info->cur_row.nextpos - 1;
info->scan.dir+= DIR_ENTRY_SIZE;
/* Remember used bitmap and used head page */
bitmap_buff= info->scan_save->bitmap_buff;
memcpy(info->scan_save, &info->scan, sizeof(*info->scan_save));
info->scan_save->bitmap_buff= bitmap_buff;
memcpy(bitmap_buff, info->scan.bitmap_buff, info->s->block_size * 2);
DBUG_RETURN(0);
}
/**
@brief restore scan block it's original values
@note
In theory we could swap bitmap buffers instead of copy them.
For the moment we don't do that because there are variables pointing
inside the buffers and it's a bit of hassle to either make them relative
or repoint them.
*/
void _ma_scan_restore_block_record(MARIA_HA *info,
MARIA_RECORD_POS lastpos)
{
uchar *bitmap_buff;
DBUG_ENTER("_ma_scan_restore_block_record");
info->cur_row.nextpos= lastpos;
bitmap_buff= info->scan.bitmap_buff;
memcpy(&info->scan, info->scan_save, sizeof(*info->scan_save));
info->scan.bitmap_buff= bitmap_buff;
memcpy(bitmap_buff, info->scan_save->bitmap_buff, info->s->block_size * 2);
DBUG_VOID_RETURN;
}
@ -4204,7 +4280,10 @@ restart_record_read:
record_pos++;
#ifdef SANITY_CHECKS
if (info->scan.dir < info->scan.dir_end)
{
DBUG_ASSERT(0);
goto err;
}
#endif
}
/* found row */
@ -4217,7 +4296,10 @@ restart_record_read:
#ifdef SANITY_CHECKS
if (end_of_data > info->scan.dir_end ||
offset < PAGE_HEADER_SIZE || length < share->base.min_block_length)
{
DBUG_ASSERT(0);
goto err;
}
#endif
DBUG_PRINT("info", ("rowid: %lu", (ulong) info->cur_row.lastpos));
DBUG_RETURN(_ma_read_block_record2(info, record, data, end_of_data));
@ -4256,8 +4338,20 @@ restart_bitmap_scan:
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
DBUG_RETURN(my_errno);
if (((info->scan.page_buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) !=
HEAD_PAGE) ||
(info->scan.number_of_rows=
HEAD_PAGE))
{
/*
This may happen if someone has been deleting all rows
from a page since we read the bitmap, so it may be ok.
Print warning in debug log and continue.
*/
DBUG_PRINT("warning",
("Found page of type %d when expecting head page",
(info->scan.page_buff[PAGE_TYPE_OFFSET] &
PAGE_TYPE_MASK)));
continue;
}
if ((info->scan.number_of_rows=
(uint) (uchar) info->scan.page_buff[DIR_COUNT_OFFSET]) == 0)
{
DBUG_PRINT("error", ("Wrong page header"));
@ -4295,7 +4389,7 @@ restart_bitmap_scan:
}
DBUG_PRINT("info", ("Reading bitmap at %lu",
(ulong) info->scan.bitmap_page));
if (!(pagecache_read(share->pagecache, &info->dfile,
if (!(pagecache_read(share->pagecache, &info->s->bitmap.file,
info->scan.bitmap_page,
0, info->scan.bitmap_buff, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
@ -5081,9 +5175,11 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
share->pagecache->readwrite_flags= share->pagecache->org_readwrite_flags;
if (!buff)
{
if (my_errno != HA_ERR_FILE_TOO_SHORT)
/* Skip errors when reading outside of file and uninitialized pages */
if (my_errno != HA_ERR_FILE_TOO_SHORT &&
my_errno != HA_ERR_WRONG_CRC)
{
/* If not read outside of file */
/* Fatal disk error when reading page */
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
@ -5091,8 +5187,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
DBUG_RETURN(my_errno);
}
/* Create new page */
buff= info->keyread_buff;
info->keyread_buff_used= 1;
buff= pagecache_block_link_to_buffer(page_link.link);
buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE;
}
else if (lsn_korr(buff) >= lsn) /* Test if already applied */
@ -5532,7 +5627,8 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
org_readwrite_flags;
if (!buff)
{
if (my_errno != HA_ERR_FILE_TOO_SHORT)
if (my_errno != HA_ERR_FILE_TOO_SHORT &&
my_errno != HA_ERR_WRONG_CRC)
{
/* If not read outside of file */
pagecache_unlock_by_link(share->pagecache, page_link.link,
@ -5547,8 +5643,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
pagecache (increased data_file_length but not physical file
length), now reads page N+1: the read fails.
*/
buff= info->keyread_buff;
info->keyread_buff_used= 1;
buff= pagecache_block_link_to_buffer(page_link.link);
make_empty_page(info, buff, BLOB_PAGE);
}
else
@ -5648,7 +5743,7 @@ my_bool _ma_apply_undo_row_insert(MARIA_HA *info, LSN undo_lsn,
delete_tails(info, info->cur_row.tail_positions))
goto err;
if (info->cur_row.extents && free_full_pages(info, &info->cur_row))
if (info->cur_row.extents_count && free_full_pages(info, &info->cur_row))
goto err;
checksum= 0;
@ -5844,6 +5939,7 @@ my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn,
/* Row is now up to date. Time to insert the record */
res= allocate_and_write_block_record(info, record, &row, undo_lsn);
info->cur_row.lastpos= row.lastpos;
my_free(record, MYF(0));
DBUG_RETURN(res);
}
@ -5879,6 +5975,7 @@ my_bool _ma_apply_undo_row_update(MARIA_HA *info, LSN undo_lsn,
rownr= dirpos_korr(header);
header+= DIRPOS_STORE_SIZE;
record_pos= ma_recordpos(page, rownr);
info->cur_row.lastpos= record_pos; /* For key insert */
DBUG_PRINT("enter", ("Page: %lu rownr: %u", (ulong) page, rownr));
if (share->calc_checksum)

View File

@ -159,6 +159,10 @@ my_bool _ma_cmp_block_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
const uchar *record, MARIA_RECORD_POS pos);
my_bool _ma_scan_init_block_record(MARIA_HA *info);
void _ma_scan_end_block_record(MARIA_HA *info);
int _ma_scan_remember_block_record(MARIA_HA *info,
MARIA_RECORD_POS *lastpos);
void _ma_scan_restore_block_record(MARIA_HA *info,
MARIA_RECORD_POS lastpos);
MARIA_RECORD_POS _ma_write_init_block_record(MARIA_HA *info,
const uchar *record);

View File

@ -922,8 +922,11 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
}
if (keypos != endpos)
{
_ma_check_print_error(param,"Keyblock size at page %s is not correct. Block length: %d key length: %d",
llstr(page,llbuff), used_length, (keypos - buff));
_ma_check_print_error(param,
"Keyblock size at page %s is not correct. "
"Block length: %u key length: %u",
llstr(page, llbuff), used_length,
(uint) (keypos - buff));
goto err;
}
my_afree((uchar*) temp_buff);
@ -1376,7 +1379,7 @@ static int check_compressed_record(HA_CHECK *param, MARIA_HA *info, int extend,
block_info.rec_len > (uint) share->max_pack_length)
{
_ma_check_print_error(param,
"Found block with wrong recordlength: %d at %s",
"Found block with wrong recordlength: %lu at %s",
block_info.rec_len, llstr(start_recpos,llbuff));
got_error=1;
goto end;
@ -1709,7 +1712,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
{
/* Bitmap page */
if (pagecache_read(share->pagecache,
&info->dfile,
&info->s->bitmap.file,
(pos / block_size), 1,
bitmap_buff,
PAGECACHE_PLAIN_PAGE,
@ -1717,7 +1720,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
{
_ma_check_print_error(param,
"Page %9s: Got error: %d when reading datafile",
my_errno, llstr(pos, llbuff));
llstr(pos, llbuff), my_errno);
goto err;
}
param->used+= block_size;
@ -1746,7 +1749,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
{
_ma_check_print_error(param,
"Page %9s: Got error: %d when reading datafile",
my_errno, llstr(pos, llbuff));
llstr(pos, llbuff), my_errno);
goto err;
}
page_type= page_buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK;
@ -4154,8 +4157,9 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
{
if (!searching)
_ma_check_print_info(param,
"Deleted block with impossible length %u at %s",
block_info.block_len,llstr(pos,llbuff));
"Deleted block with impossible length %lu "
"at %s",
block_info.block_len,llstr(pos,llbuff));
error=1;
}
else
@ -4193,10 +4197,11 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
{
if (!searching)
_ma_check_print_info(param,
"Found block with impossible length %u at %s; Skipped",
block_info.block_len+
"Found block with impossible length %lu "
"at %s; Skipped",
block_info.block_len+
(uint) (block_info.filepos-pos),
llstr(pos,llbuff));
llstr(pos,llbuff));
if (found_record)
goto try_next;
searching=1;
@ -4393,9 +4398,11 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
block_info.rec_len > (uint) share->max_pack_length)
{
if (! searching)
_ma_check_print_info(param,"Found block with wrong recordlength: %d at %s\n",
block_info.rec_len,
llstr(sort_param->pos,llbuff));
_ma_check_print_info(param,
"Found block with wrong recordlength: %lu "
"at %s\n",
block_info.rec_len,
llstr(sort_param->pos,llbuff));
continue;
}
if (_ma_read_cache(&sort_param->read_cache,(uchar*) sort_param->rec_buff,
@ -4918,9 +4925,9 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
if (key_info->s->options & HA_OPTION_COMPRESS_RECORD)
{
_ma_check_print_error(param,
"Recover aborted; Can't run standard recovery on compressed tables "
"with errors in data-file. Use 'maria_chk --safe-recover' "
"to fix it",stderr);;
"Recover aborted; Can't run standard recovery on "
"compressed tables with errors in data-file. "
"Use 'maria_chk --safe-recover' to fix it");
DBUG_RETURN(1);
}
@ -5801,8 +5808,16 @@ read_next_page:
page, 0, info->scan.page_buff,
PAGECACHE_READ_UNKNOWN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
{
if (my_errno == HA_ERR_WRONG_CRC)
{
_ma_check_print_info(sort_info->param,
"Wrong CRC on page at %s",
llstr(page * share->block_size, llbuff));
continue;
}
DBUG_RETURN(my_errno);
}
page_type= (info->scan.page_buff[PAGE_TYPE_OFFSET] &
PAGE_TYPE_MASK);
if (page_type == HEAD_PAGE)

View File

@ -100,7 +100,7 @@ int maria_close(register MARIA_HA *info)
File must be synced as it is going out of the maria_open_list and so
becoming unknown to future Checkpoints.
*/
if (my_sync(share->kfile.file, MYF(MY_WME)))
if (!share->temporary && my_sync(share->kfile.file, MYF(MY_WME)))
error= my_errno;
if (my_close(share->kfile.file, MYF(0)))
error= my_errno;
@ -145,13 +145,16 @@ int maria_close(register MARIA_HA *info)
Checkpoint. Fortunately in BLOCK_RECORD we close earlier under mutex.
*/
if (my_close(info->dfile.file, MYF(0)))
error = my_errno;
error= my_errno;
}
delete_dynamic(&info->pinned_pages);
my_free(info, MYF(0));
if (error)
{
DBUG_PRINT("error", ("Got error on close: %d", my_errno));
DBUG_RETURN(my_errno= error);
}
DBUG_RETURN(0);
} /* maria_close */

View File

@ -214,6 +214,7 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
const char *errmsg;
MY_STAT stat_buff;
uint new_cf_create_time_size, new_cf_changeable_size, new_block_size;
uint retry;
int open_flags= O_BINARY | /*O_DIRECT |*/ O_RDWR;
int error= CONTROL_FILE_UNKNOWN_ERROR;
DBUG_ENTER("ma_control_file_create_or_open");
@ -347,6 +348,29 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
CF_LSN_OFFSET);
last_logno= uint4korr(buffer + new_cf_create_time_size + CF_FILENO_OFFSET);
retry= 0;
/*
We can't here use the automatic wait in my_lock() as the alarm thread
may not yet exists.
*/
while (my_lock(control_file_fd, F_WRLCK, 0L, F_TO_EOF,
MYF(MY_SEEK_NOT_DONE | MY_FORCE_LOCK | MY_NO_WAIT)))
{
if (retry == 0)
my_printf_error(HA_ERR_INITIALIZATION,
"Can't lock maria control file '%s' for exclusive use, "
"error: %d. Will retry for %d seconds", 0,
name, my_errno, MARIA_MAX_CONTROL_FILE_LOCK_RETRY);
if (retry++ > MARIA_MAX_CONTROL_FILE_LOCK_RETRY)
{
errmsg= "Could not get an exclusive lock; File is probably in use by another process";
goto err;
}
sleep(1);
}
DBUG_RETURN(0);
err:
@ -463,6 +487,9 @@ int ma_control_file_end()
if (control_file_fd < 0) /* already closed */
DBUG_RETURN(0);
(void) my_lock(control_file_fd, F_UNLCK, 0L, F_TO_EOF,
MYF(MY_SEEK_NOT_DONE | MY_FORCE_LOCK));
close_error= my_close(control_file_fd, MYF(MY_WME));
/*
As my_close() frees structures even if close() fails, we do the same,

View File

@ -124,7 +124,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
(keys + uniques) * HA_MAX_KEY_SEG);
/* Start by checking fields and field-types used */
/* Start by checking fields and field-types used */
varchar_length=long_varchar_count=packed= not_block_record_extra_length=
pack_reclength= max_field_lengths= 0;
@ -147,8 +147,17 @@ int maria_create(const char *name, enum data_file_type datafile_type,
reclength+= column->length;
type= column->type;
if (type == FIELD_SKIP_PRESPACE && datafile_type == BLOCK_RECORD)
type= FIELD_NORMAL; /* SKIP_PRESPACE not supported */
if (datafile_type == BLOCK_RECORD)
{
if (type == FIELD_SKIP_PRESPACE)
type= FIELD_NORMAL; /* SKIP_PRESPACE not supported */
if (type == FIELD_NORMAL &&
column->length > FULL_PAGE_SIZE(maria_block_size))
{
/* FIELD_NORMAL can't be split over many blocks, convert to a CHAR */
type= column->type= FIELD_SKIP_ENDSPACE;
}
}
if (type != FIELD_NORMAL && type != FIELD_CHECK)
{
@ -403,6 +412,17 @@ int maria_create(const char *name, enum data_file_type datafile_type,
share.state.key_root[i]= HA_OFFSET_ERROR;
length= real_length_diff= 0;
min_key_length= key_length= pointer;
if ((keydef->flag & (HA_SPATIAL | HA_FULLTEXT) &&
ci->transactional))
{
my_errno= HA_ERR_UNSUPPORTED;
my_message(HA_ERR_UNSUPPORTED,
"Maria can't yet handle SPATIAL or FULLTEXT keys in "
"transactional mode. For now use TRANSACTIONAL=0", MYF(0));
goto err_no_lock;
}
if (keydef->flag & HA_SPATIAL)
{
#ifdef HAVE_SPATIAL
@ -623,7 +643,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
}
unique_key_parts=0;
offset=reclength-uniques*MARIA_UNIQUE_HASH_LENGTH;
for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++)
{
uniquedef->key=keys+i;
@ -869,7 +888,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
#endif
}
/* Create extra keys for unique definitions */
offset=reclength-uniques*MARIA_UNIQUE_HASH_LENGTH;
offset= real_reclength - uniques*MARIA_UNIQUE_HASH_LENGTH;
bzero((char*) &tmp_keydef,sizeof(tmp_keydef));
bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg));
for (i=0; i < uniques ; i++)
@ -1049,10 +1068,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
DROP+CREATE happened (applying REDOs to the wrong table).
*/
share.kfile.file= file;
pagecache_file_init(share.kfile, &maria_page_crc_check_index,
(share.options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_index :
&maria_page_filler_set_normal), &share);
if (_ma_update_create_rename_lsn_sub(&share, lsn, FALSE))
goto err;
my_free(log_data, MYF(0));
@ -1199,7 +1214,7 @@ uint maria_get_pointer_length(ulonglong file_length, uint def)
For same kind of fields, keep fields in original order
*/
static inline int sign(longlong a)
static inline int sign(long a)
{
return a < 0 ? -1 : (a > 0 ? 1 : 0);
}
@ -1219,12 +1234,12 @@ static int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
{
if (b_type != FIELD_NORMAL || b->null_bit)
return -1;
return sign((long) (a->offset - b->offset));
return sign((long) a->offset - (long) b->offset);
}
if (b_type == FIELD_NORMAL && !b->null_bit)
return 1;
if (a_type == b_type)
return sign((long) (a->offset - b->offset));
return sign((long) a->offset - (long) b->offset);
if (a_type == FIELD_NORMAL)
return -1;
if (b_type == FIELD_NORMAL)
@ -1233,11 +1248,17 @@ static int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
return 1;
if (b_type == FIELD_BLOB)
return -1;
return sign((long) (a->offset - b->offset));
return sign((long) a->offset - (long) b->offset);
}
/* Initialize data file */
/**
@brief Initialize data file
@note
In BLOCK_RECORD, a freshly created datafile is one page long; while in
other formats it is 0-byte long.
*/
int _ma_initialize_data_file(MARIA_SHARE *share, File dfile)
{
@ -1245,16 +1266,8 @@ int _ma_initialize_data_file(MARIA_SHARE *share, File dfile)
{
share->bitmap.block_size= share->base.block_size;
share->bitmap.file.file = dfile;
pagecache_file_init(share->bitmap.file, &maria_page_crc_check_bitmap,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_bitmap), share);
return _ma_bitmap_create_first(share);
}
/*
So, in BLOCK_RECORD, a freshly created datafile is one page long; while in
other formats it is 0-byte long.
*/
return 0;
}

View File

@ -192,7 +192,11 @@ int _ma_ck_delete(register MARIA_HA *info, uint keynr, uchar *key,
log_type= LOGREC_UNDO_KEY_DELETE_WITH_ROOT;
}
key_length+= share->rec_reflength;
/*
Note that for delete key, we don't log the reference to the record.
This is because the row may be inserted at a different place when
we exceute the undo
*/
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data);
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= (char*) key_buff;

View File

@ -1501,7 +1501,10 @@ my_bool _ma_cmp_dynamic_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
old_rec_buff_size= info->rec_buff_size;
if (info->s->base.blobs)
{
info->rec_buff= 0;
info->rec_buff_size= 0;
}
error= _ma_read_dynamic_record(info, old_record, pos) != 0;
if (!error)
error=_ma_unique_comp(def, record, old_record, def->null_are_equal) != 0;

View File

@ -224,7 +224,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
info->lock_wait= 0;
break;
case HA_EXTRA_NO_WAIT_LOCK:
info->lock_wait= MY_DONT_WAIT;
info->lock_wait= MY_SHORT_WAIT;
break;
case HA_EXTRA_NO_KEYS:
/* we're going to modify pieces of the state, stall Checkpoint */
@ -273,11 +273,12 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
break;
case HA_EXTRA_FORCE_REOPEN:
/*
Normally MySQL uses this case when it is going to close all open
instances of the table, thus going to flush all data/index/state.
MySQL uses this case after it has closed all other instances
of this table.
We however do a flush here for additional safety.
*/
/** @todo consider porting these flush-es to MyISAM */
DBUG_ASSERT(share->reopen == 1);
error= _ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
FLUSH_FORCE_WRITE, FLUSH_FORCE_WRITE);
if (!error && share->changed)
@ -287,19 +288,6 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
share->changed= 0;
pthread_mutex_unlock(&share->intern_lock);
}
/**
@todo RECOVERY BUG
Though we flushed the state, IF some other thread may have the same
table (same MARIA_SHARE) open at this time then it may have a
more recent state to flush when it closes, thus we don't set
share->changed to 0 here. On the other hand, this means that when our
thread closes its table, it will flush the state again, then it would
overwrite any state written by yet another thread which may have opened
the table (new MARIA_SHARE) and done some updates.
ASK_MONTY about the IF above. See also same tag in
HA_EXTRA_PREPARE_FOR_DROP|RENAME.
*/
pthread_mutex_lock(&THR_LOCK_maria);
pthread_mutex_lock(&share->intern_lock); /* protect against Checkpoint */
/* this makes the share not be re-used next time the table is opened */

View File

@ -109,6 +109,20 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
page_store(log_pos + KEY_NR_STORE_SIZE, page);
log_pos+= KEY_NR_STORE_SIZE + PAGE_STORE_SIZE;
}
if (undo_type == LOGREC_UNDO_ROW_DELETE ||
undo_type == LOGREC_UNDO_ROW_UPDATE)
{
/*
We need to store position to the row that was inserted to be
able to regenerate keys
*/
MARIA_RECORD_POS rowid= info->cur_row.lastpos;
ulonglong page= ma_recordpos_to_page(rowid);
uint dir_entry= ma_recordpos_to_dir_entry(rowid);
page_store(log_pos, page);
dirpos_store(log_pos+ PAGE_STORE_SIZE, dir_entry);
log_pos+= PAGE_STORE_SIZE + DIRPOS_STORE_SIZE;
}
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data);
@ -570,10 +584,15 @@ uint _ma_apply_redo_index_new_page(MARIA_HA *info, LSN lsn,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
{
result= (uint) my_errno;
goto err;
if (my_errno != HA_ERR_FILE_TOO_SHORT &&
my_errno != HA_ERR_WRONG_CRC)
{
result= 1;
goto err;
}
buff= pagecache_block_link_to_buffer(page_link.link);
}
if (lsn_korr(buff) >= lsn)
else if (lsn_korr(buff) >= lsn)
{
/* Already applied */
result= 0;
@ -648,7 +667,7 @@ uint _ma_apply_redo_index_free_page(MARIA_HA *info,
old_link= ((free_page != IMPOSSIBLE_PAGE_NO) ?
(my_off_t) free_page * share->block_size :
HA_OFFSET_ERROR);
if (!(buff= pagecache_read(share->pagecache, &info->s->kfile,
if (!(buff= pagecache_read(share->pagecache, &share->kfile,
page, 0, 0,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
@ -664,7 +683,8 @@ uint _ma_apply_redo_index_free_page(MARIA_HA *info,
}
/* Free page */
bzero(buff + LSN_STORE_SIZE, share->keypage_header - LSN_STORE_SIZE);
_ma_store_keynr(info->s, buff, (uchar) MARIA_DELETE_KEY_NR);
_ma_store_keynr(share, buff, (uchar) MARIA_DELETE_KEY_NR);
_ma_store_page_used(share, buff, share->keypage_header + 8);
mi_sizestore(buff + share->keypage_header, old_link);
share->state.changed|= STATE_NOT_SORTED_PAGES;
@ -741,7 +761,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
/* Set header to point at key data */
header+= PAGE_STORE_SIZE;
if (!(buff= pagecache_read(share->pagecache, &info->s->kfile,
if (!(buff= pagecache_read(share->pagecache, &share->kfile,
page, 0, 0,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
@ -920,7 +940,7 @@ my_bool _ma_apply_undo_key_insert(MARIA_HA *info, LSN undo_lsn,
new_root= share->state.key_root[keynr];
res= _ma_ck_real_delete(info, share->keyinfo+keynr, key,
length - info->s->rec_reflength, &new_root);
length - share->rec_reflength, &new_root);
msg.root= &share->state.key_root[keynr];
msg.value= new_root;
@ -937,7 +957,7 @@ my_bool _ma_apply_undo_key_insert(MARIA_HA *info, LSN undo_lsn,
/**
@brief Undo of insert of key (ie, delete the inserted key)
@brief Undo of delete of key (ie, insert the deleted key)
*/
my_bool _ma_apply_undo_key_delete(MARIA_HA *info, LSN undo_lsn,
@ -959,11 +979,12 @@ my_bool _ma_apply_undo_key_delete(MARIA_HA *info, LSN undo_lsn,
/* We have to copy key as _ma_ck_real_write_btree() may change it */
memcpy(key, header + KEY_NR_STORE_SIZE, length);
DBUG_DUMP("key", key, length);
_ma_dpointer(info, key + length, info->cur_row.lastpos);
DBUG_DUMP("key", key, length + share->rec_reflength);
new_root= share->state.key_root[keynr];
res= _ma_ck_real_write_btree(info, share->keyinfo+keynr, key,
length - info->s->rec_reflength,
length,
&new_root,
share->keyinfo[keynr].write_comp_flag);
@ -1035,13 +1056,13 @@ my_bool _ma_lock_key_del(MARIA_HA *info, my_bool insert_at_end)
void _ma_unlock_key_del(MARIA_HA *info)
{
MARIA_SHARE *share= info->s;
DBUG_ASSERT(info->used_key_del);
if (info->used_key_del == 1) /* Ignore insert-with-append */
{
MARIA_SHARE *share= info->s;
pthread_mutex_lock(&share->intern_lock);
share->used_key_del= 0;
info->s->state.key_del= info->s->current_key_del;
share->state.key_del= info->s->current_key_del;
pthread_mutex_unlock(&share->intern_lock);
pthread_cond_signal(&share->intern_cond);
}

View File

@ -2729,7 +2729,7 @@ static uchar *translog_get_page(TRANSLOG_VALIDATOR_DATA *data, uchar *buffer,
supposed to be correct.
*/
if (translog_page_validator((uchar*) buffer,
LSN_OFFSET(addr),
LSN_OFFSET(addr) / TRANSLOG_PAGE_SIZE,
(uchar*) &file_copy))
{
DBUG_ASSERT(0);

View File

@ -28,9 +28,6 @@
#include <process.h> /* Prototype for getpid */
#endif
#endif
#ifdef VMS
#include "static.c"
#endif
static void setup_key_functions(MARIA_KEYDEF *keyinfo);
static my_bool maria_scan_init_dummy(MARIA_HA *info);
@ -39,6 +36,11 @@ static my_bool maria_once_init_dummy(MARIA_SHARE *, File);
static my_bool maria_once_end_dummy(MARIA_SHARE *);
static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base);
static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state);
static void set_data_pagecache_callbacks(PAGECACHE_FILE *file,
MARIA_SHARE *share);
static void set_index_pagecache_callbacks(PAGECACHE_FILE *file,
MARIA_SHARE *share);
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
pos+=size;}
@ -144,17 +146,18 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, int mode,
info.this_loop=0; /* Update counter */
info.last_unique= share->state.unique;
info.last_loop= share->state.update_count;
info.lock_type=F_UNLCK;
info.quick_mode=0;
info.bulk_insert=0;
info.ft1_to_ft2=0;
info.errkey= -1;
info.page_changed=1;
info.keyread_buff= info.buff + share->base.max_key_block_length;
pagecache_file_init(info.dfile, &maria_page_crc_check_data,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_normal), share);
info.lock_type= F_UNLCK;
if (share->options & HA_OPTION_TMP_TABLE)
info.lock_type= F_WRLCK;
set_data_pagecache_callbacks(&info.dfile, share);
bitmap_init(&info.changed_fields, changed_fields_bitmap,
share->base.fields, 0);
if ((*share->init)(&info))
@ -178,15 +181,6 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, int mode,
share->r_locks++;
share->tot_locks++;
}
if (share->options & HA_OPTION_TMP_TABLE)
{
share->temporary= share->delay_key_write= 1;
share->write_flag=MYF(MY_NABP);
share->w_locks++; /* We don't have to update status */
share->tot_locks++;
info.lock_type=F_WRLCK;
}
if ((share->options & HA_OPTION_DELAY_KEY_WRITE) &&
maria_delay_key_write)
share->delay_key_write=1;
@ -717,11 +711,23 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
}
errpos= 5;
if (open_flags & HA_OPEN_DELAY_KEY_WRITE)
share->options|= HA_OPTION_DELAY_KEY_WRITE;
if (mode == O_RDONLY)
share->options|= HA_OPTION_READ_ONLY_DATA;
share->is_log_table= FALSE;
if (open_flags & HA_OPEN_TMP_TABLE)
{
share->options|= HA_OPTION_TMP_TABLE;
share->temporary= share->delay_key_write= 1;
share->write_flag=MYF(MY_NABP);
share->w_locks++; /* We don't have to update status */
share->tot_locks++;
}
share->kfile.file= kfile;
pagecache_file_init(share->kfile, &maria_page_crc_check_index,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_index :
&maria_page_filler_set_normal), share);
set_index_pagecache_callbacks(&share->kfile, share);
share->this_process=(ulong) getpid();
share->last_process= share->state.process;
share->base.key_parts=key_parts;
@ -737,13 +743,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
_ma_setup_functions(share);
if ((*share->once_init)(share, info.dfile.file))
goto err;
share->is_log_table= FALSE;
if (open_flags & HA_OPEN_TMP_TABLE)
share->options|= HA_OPTION_TMP_TABLE;
if (open_flags & HA_OPEN_DELAY_KEY_WRITE)
share->options|= HA_OPTION_DELAY_KEY_WRITE;
if (mode == O_RDONLY)
share->options|= HA_OPTION_READ_ONLY_DATA;
#ifdef THREAD
thr_lock_init(&share->lock);
@ -879,6 +878,9 @@ void _ma_setup_functions(register MARIA_SHARE *share)
share->end= maria_scan_end_dummy;
share->scan_init= maria_scan_init_dummy;/* Compat. dummy function */
share->scan_end= maria_scan_end_dummy;/* Compat. dummy function */
share->scan_remember_pos= _ma_def_scan_remember_pos;
share->scan_restore_pos= _ma_def_scan_restore_pos;
share->write_record_init= _ma_write_init_default;
share->write_record_abort= _ma_write_abort_default;
share->keypos_to_recpos= _ma_transparent_recpos;
@ -944,8 +946,10 @@ void _ma_setup_functions(register MARIA_SHARE *share)
share->write_record_abort= _ma_write_abort_block_record;
share->scan_init= _ma_scan_init_block_record;
share->scan_end= _ma_scan_end_block_record;
share->read_record= _ma_read_block_record;
share->scan= _ma_scan_block_record;
share->scan_remember_pos= _ma_scan_remember_block_record;
share->scan_restore_pos= _ma_scan_restore_block_record;
share->read_record= _ma_read_block_record;
share->delete_record= _ma_delete_block_record;
share->compare_record= _ma_compare_block_record;
share->update_record= _ma_update_block_record;
@ -1002,7 +1006,8 @@ static void setup_key_functions(register MARIA_KEYDEF *keyinfo)
if (keyinfo->seg[0].flag & HA_PACK_KEY)
{ /* Prefix compression */
if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) ||
(keyinfo->seg->flag & HA_NULL_PART))
(keyinfo->seg->flag & HA_NULL_PART) ||
keyinfo->seg->charset->mbminlen > 1)
keyinfo->bin_search= _ma_seq_search;
else
keyinfo->bin_search= _ma_prefix_search;
@ -1474,12 +1479,14 @@ my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
uchar buff[MARIA_COLUMNDEF_SIZE];
uchar *ptr=buff;
mi_int2store(ptr,(ulong) columndef->offset); ptr+= 2;
mi_int2store(ptr,columndef->type); ptr+= 2;
mi_int2store(ptr,columndef->length); ptr+= 2;
mi_int2store(ptr,columndef->fill_length); ptr+= 2;
mi_int2store(ptr,columndef->null_pos); ptr+= 2;
mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
mi_int2store(ptr,(ulong) columndef->column_nr); ptr+= 2;
mi_int2store(ptr,(ulong) columndef->offset); ptr+= 2;
mi_int2store(ptr,columndef->type); ptr+= 2;
mi_int2store(ptr,columndef->length); ptr+= 2;
mi_int2store(ptr,columndef->fill_length); ptr+= 2;
mi_int2store(ptr,columndef->null_pos); ptr+= 2;
mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
(*ptr++)= columndef->null_bit;
(*ptr++)= columndef->empty_bit;
ptr[0]= ptr[1]= ptr[2]= ptr[3]= 0; ptr+= 4; /* For future */
@ -1488,6 +1495,7 @@ my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
uchar *_ma_columndef_read(uchar *ptr, MARIA_COLUMNDEF *columndef)
{
columndef->column_nr= mi_uint2korr(ptr); ptr+= 2;
columndef->offset= mi_uint2korr(ptr); ptr+= 2;
columndef->type= mi_sint2korr(ptr); ptr+= 2;
columndef->length= mi_uint2korr(ptr); ptr+= 2;
@ -1526,6 +1534,46 @@ uchar *_ma_column_nr_read(uchar *ptr, uint16 *offsets, uint columns)
}
static void set_data_pagecache_callbacks(PAGECACHE_FILE *file,
MARIA_SHARE *share)
{
file->callback_data= (uchar*) share;
if (share->temporary)
{
file->read_callback= &maria_page_crc_check_none;
file->write_callback= &maria_page_filler_set_none;
}
else
{
file->read_callback= &maria_page_crc_check_data;
if (share->options & HA_OPTION_PAGE_CHECKSUM)
file->write_callback= &maria_page_crc_set_normal;
else
file->write_callback= &maria_page_filler_set_normal;
}
}
static void set_index_pagecache_callbacks(PAGECACHE_FILE *file,
MARIA_SHARE *share)
{
file->callback_data= (uchar*) share;
if (share->temporary)
{
file->read_callback= &maria_page_crc_check_none;
file->write_callback= &maria_page_filler_set_none;
}
else
{
file->read_callback= &maria_page_crc_check_index;
if (share->options & HA_OPTION_PAGE_CHECKSUM)
file->write_callback= &maria_page_crc_set_index;
else
file->write_callback= &maria_page_filler_set_normal;
}
}
/**************************************************************************
Open data file
We can't use dup() here as the data file descriptors need to have different
@ -1541,14 +1589,6 @@ int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share,
info->dfile.file= share->bitmap.file.file=
my_open(share->data_file_name, share->mode | O_SHARE,
MYF(MY_WME));
pagecache_file_init(share->bitmap.file, &maria_page_crc_check_bitmap,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_bitmap), share);
pagecache_file_init(info->dfile, &maria_page_crc_check_data,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_normal), share);
return info->dfile.file >= 0 ? 0 : 1;
}
@ -1563,10 +1603,6 @@ int _ma_open_keyfile(MARIA_SHARE *share)
share->kfile.file= my_open(share->unique_file_name,
share->mode | O_SHARE,
MYF(MY_WME));
pagecache_file_init(share->kfile, &maria_page_crc_check_index,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_index :
&maria_page_filler_set_normal), share);
pthread_mutex_unlock(&share->intern_lock);
return (share->kfile.file < 0);
}

View File

@ -199,6 +199,7 @@ int _ma_dispose(register MARIA_HA *info, my_off_t pos, my_bool page_not_read)
page_no= pos / block_size;
bzero(buff, share->keypage_header);
_ma_store_keynr(share, buff, (uchar) MARIA_DELETE_KEY_NR);
_ma_store_page_used(share, buff, share->keypage_header + 8);
mi_sizestore(buff + share->keypage_header, old_link);
share->state.changed|= STATE_NOT_SORTED_PAGES;

View File

@ -318,7 +318,7 @@ struct st_pagecache_block_link
/** @brief information describing a run of flush_pagecache_blocks_int() */
struct st_file_in_flush
{
PAGECACHE_FILE file;
File file;
/**
@brief threads waiting for the thread currently flushing this file to be
done
@ -2421,6 +2421,8 @@ retry:
or waits until another thread reads it. What page to read is determined
by a block parameter - reference to a hash link for this page.
If an error occurs THE PCBLOCK_ERROR bit is set in the block status.
On entry cache_lock is locked
*/
static void read_block(PAGECACHE *pagecache,
@ -2428,8 +2430,6 @@ static void read_block(PAGECACHE *pagecache,
my_bool primary)
{
/* On entry cache_lock is locked */
DBUG_ENTER("read_block");
if (primary)
{
@ -2456,21 +2456,17 @@ static void read_block(PAGECACHE *pagecache,
if (error)
block->status|= PCBLOCK_ERROR;
else
block->status= PCBLOCK_READ;
DBUG_PRINT("info", ("read_callback: 0x%lx data: 0x%lx",
(ulong) block->hash_link->file.read_callback,
(ulong) block->hash_link->file.callback_data));
if ((*block->hash_link->file.read_callback)(block->buffer,
block->hash_link->pageno,
block->hash_link->
file.callback_data))
{
DBUG_PRINT("error", ("read callback problem"));
block->status|= PCBLOCK_ERROR;
block->status|= PCBLOCK_READ;
if ((*block->hash_link->file.read_callback)(block->buffer,
block->hash_link->pageno,
block->hash_link->
file.callback_data))
{
DBUG_PRINT("error", ("read callback problem"));
block->status|= PCBLOCK_ERROR;
}
}
DBUG_PRINT("read_block",
("primary request: new page in cache"));
/* Signal that all pending requests for this page now can be processed */
@ -2796,6 +2792,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
}
if (lsn != LSN_IMPOSSIBLE)
check_and_set_lsn(pagecache, lsn, block);
block->status&= ~PCBLOCK_ERROR;
}
/* if we lock for write we must link the block to changed blocks */
@ -3066,7 +3063,11 @@ restart:
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
if (status & PCBLOCK_ERROR)
{
DBUG_ASSERT(my_errno != 0);
DBUG_PRINT("error", ("Got error %d when doing page read", my_errno));
DBUG_RETURN((uchar *) 0);
}
DBUG_RETURN(buff);
}
@ -3412,7 +3413,11 @@ restart:
if (write_mode == PAGECACHE_WRITE_DONE)
{
if (!(block->status & PCBLOCK_ERROR))
if (block->status & PCBLOCK_ERROR)
{
DBUG_PRINT("warning", ("Writing on page with error"));
}
else
{
/* Copy data from buff */
if (!(size & 511))
@ -3646,7 +3651,10 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
/* undo the mark put by flush_pagecache_blocks_int(): */
block->status&= ~PCBLOCK_IN_FLUSH;
rc|= PCFLUSH_PINNED;
DBUG_PRINT("warning", ("Page pinned"));
unreg_request(pagecache, block, 1);
if (!*first_errno)
*first_errno= HA_ERR_INTERNAL_ERROR;
continue;
}
/* if the block is not pinned then it is not write locked */
@ -3671,7 +3679,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
@todo If page is contiguous with next page to flush, group flushes in
one single my_pwrite().
*/
error= pagecache_fwrite(pagecache, file,
error= pagecache_fwrite(pagecache, &block->hash_link->file,
block->buffer,
block->hash_link->pageno,
block->type,
@ -3687,7 +3695,8 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
{
block->status|= PCBLOCK_ERROR;
if (!*first_errno)
*first_errno= errno ? errno : -1;
*first_errno= my_errno ? my_errno : -1;
rc|= PCFLUSH_ERROR;
}
#ifdef THREAD
/*
@ -3789,12 +3798,12 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
#ifdef THREAD
struct st_file_in_flush us_flusher, *other_flusher;
us_flusher.file= *file;
us_flusher.file= file->file;
us_flusher.flush_queue.last_thread= NULL;
us_flusher.first_in_switch= FALSE;
while ((other_flusher= (struct st_file_in_flush *)
hash_search(&pagecache->files_in_flush, (uchar *)file,
sizeof(*file))))
hash_search(&pagecache->files_in_flush, (uchar *)&file->file,
sizeof(file->file))))
{
/*
File is in flush already: wait, unless FLUSH_KEEP_LAZY. "Flusher"
@ -4031,8 +4040,12 @@ restart:
#endif
if (cache != cache_buff)
my_free((uchar*) cache, MYF(0));
if (last_errno)
errno= last_errno; /* Return first error */
if (rc != 0)
{
if (last_errno)
my_errno= last_errno; /* Return first error */
DBUG_PRINT("error", ("Got error: %d", my_errno));
}
DBUG_RETURN(rc);
}

View File

@ -41,11 +41,11 @@ static uint32 maria_page_crc(ulong start, uchar *data, uint length)
@retval 1 Error
*/
static inline my_bool maria_page_crc_check(uchar *page,
pgcache_page_no_t page_no,
MARIA_SHARE *share,
uint32 no_crc_val,
int data_length)
static my_bool maria_page_crc_check(uchar *page,
pgcache_page_no_t page_no,
MARIA_SHARE *share,
uint32 no_crc_val,
int data_length)
{
uint32 crc= uint4korr(page + share->block_size - CRC_SIZE), new_crc;
my_bool res;
@ -63,22 +63,24 @@ static inline my_bool maria_page_crc_check(uchar *page,
*/
if (crc >= MARIA_NO_CRC_BITMAP_PAGE)
{
DBUG_PRINT("info", ("No crc: (0x%lx) crc: (0x%lx) page: %lu ",
DBUG_PRINT("info", ("No crc: %lu crc: %lu page: %lu ",
(ulong) no_crc_val, (ulong) crc, (ulong) page_no));
#ifndef DBUG_OFF
if (crc != no_crc_val)
DBUG_PRINT("CRCerror", ("Wrong no CRC value"));
#endif
DBUG_RETURN(test(crc != no_crc_val));
{
my_errno= HA_ERR_WRONG_CRC;
DBUG_PRINT("error", ("Wrong no CRC value"));
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
new_crc= maria_page_crc(page_no, page, data_length);
DBUG_ASSERT(new_crc != no_crc_val);
res= test(new_crc != crc);
if (res)
{
DBUG_PRINT("CRCerror", ("Page: %lu crc: 0x%lx calculated crc: 0x%lx",
(ulong) page_no, (ulong) crc, (ulong) new_crc));
maria_mark_crashed_share(share);
DBUG_PRINT("error", ("Page: %lu crc: %lu calculated crc: %lu",
(ulong) page_no, (ulong) crc, (ulong) new_crc));
my_errno= HA_ERR_WRONG_CRC;
}
DBUG_RETURN(res);
}
@ -97,15 +99,13 @@ static inline my_bool maria_page_crc_check(uchar *page,
my_bool maria_page_crc_set_normal(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
int data_length= share->block_size - CRC_SIZE;
uint32 crc= maria_page_crc(page_no, page, data_length);
DBUG_ENTER("maria_page_crc_set");
DBUG_PRINT("info", ("Page %u crc: 0x%lx",
(uint)page_no, (ulong)crc));
DBUG_PRINT("info", ("Page %lu crc: %lu", (ulong) page_no, (ulong)crc));
/* crc is on the stack so it is aligned, pagecache buffer is aligned, too */
int4store_aligned(page + data_length, crc);
@ -125,15 +125,15 @@ my_bool maria_page_crc_set_normal(uchar *page,
my_bool maria_page_crc_set_index(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
int data_length= _ma_get_page_used(share, page);
uint32 crc= maria_page_crc(page_no, page, data_length);
DBUG_ENTER("maria_page_crc_set");
DBUG_PRINT("info", ("Page %u crc: 0x%lx",
(uint)page_no, (ulong)crc));
DBUG_PRINT("info", ("Page %lu crc: %lu",
(ulong) page_no, (ulong) crc));
DBUG_ASSERT((uint)data_length <= share->block_size - CRC_SIZE);
/* crc is on the stack so it is aligned, pagecache buffer is aligned, too */
int4store_aligned(page + share->block_size - CRC_SIZE, crc);
@ -157,7 +157,7 @@ my_bool maria_page_crc_set_index(uchar *page,
my_bool maria_page_crc_check_data(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
return (maria_page_crc_check(page, page_no, share,
@ -179,7 +179,7 @@ my_bool maria_page_crc_check_data(uchar *page,
my_bool maria_page_crc_check_bitmap(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
return (maria_page_crc_check(page, page_no, share,
@ -201,12 +201,34 @@ my_bool maria_page_crc_check_bitmap(uchar *page,
my_bool maria_page_crc_check_index(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
return (maria_page_crc_check(page, page_no, share,
uint length= _ma_get_page_used(share, page);
if (length > share->block_size - CRC_SIZE)
{
DBUG_PRINT("error", ("Wrong page length: %u", length));
return (my_errno= HA_ERR_WRONG_CRC);
}
return maria_page_crc_check(page, page_no, share,
MARIA_NO_CRC_NORMAL_PAGE,
_ma_get_page_used(share, page)));
length);
}
/**
@brief Maria pages dumme read callback for temporary tables
@retval 0 OK
@retval 1 Error
*/
my_bool maria_page_crc_check_none(uchar *page __attribute__((unused)),
pgcache_page_no_t page_no
__attribute__((unused)),
uchar *data_ptr __attribute__((unused)))
{
return 0;
}
@ -221,16 +243,18 @@ my_bool maria_page_crc_check_index(uchar *page,
*/
my_bool maria_page_filler_set_normal(uchar *page,
__attribute__((unused))
pgcache_page_no_t page_no,
uchar* data_ptr)
pgcache_page_no_t page_no
__attribute__((unused)),
uchar *data_ptr)
{
DBUG_ENTER("maria_page_filler_set_normal");
DBUG_ASSERT(page_no != 0); /* Catches some simple bugs */
int4store_aligned(page + ((MARIA_SHARE *)data_ptr)->block_size - CRC_SIZE,
MARIA_NO_CRC_NORMAL_PAGE);
DBUG_RETURN(0);
}
/**
@brief Maria pages write callback (sets the page filler for bitmap)
@ -242,12 +266,27 @@ my_bool maria_page_filler_set_normal(uchar *page,
*/
my_bool maria_page_filler_set_bitmap(uchar *page,
__attribute__((unused))
pgcache_page_no_t page_no,
uchar* data_ptr)
pgcache_page_no_t page_no
__attribute__((unused)),
uchar *data_ptr)
{
DBUG_ENTER("maria_page_filler_set_bitmap");
int4store_aligned(page + ((MARIA_SHARE *)data_ptr)->block_size - CRC_SIZE,
MARIA_NO_CRC_BITMAP_PAGE);
DBUG_RETURN(0);
}
/**
@brief Maria pages dummy write callback for temporary tables
@retval 0 OK
*/
my_bool maria_page_filler_set_none(uchar *page __attribute__((unused)),
pgcache_page_no_t page_no
__attribute__((unused)),
uchar *data_ptr __attribute__((unused)))
{
return 0;
}

View File

@ -161,6 +161,7 @@ void tprint(FILE *trace_file __attribute__ ((unused)),
{
va_list args;
va_start(args, format);
DBUG_PRINT("info", ("%s", format));
if (trace_file != NULL)
{
if (procent_printed)
@ -181,6 +182,7 @@ void eprint(FILE *trace_file __attribute__ ((unused)),
{
va_list args;
va_start(args, format);
DBUG_PRINT("error", ("%s", format));
if (procent_printed)
{
/* In silent mode, print on another line than the 0% 10% 20% line */
@ -329,11 +331,17 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
now= my_getsystime();
if (run_redo_phase(from_lsn, apply))
{
ma_message_no_user(0, "Redo phase failed");
goto err;
}
if ((uncommitted_trans=
end_of_redo_phase(should_run_undo_phase)) == (uint)-1)
{
ma_message_no_user(0, "End of redo phase failed");
goto err;
}
old_now= now;
now= my_getsystime();
@ -375,7 +383,10 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
if (should_run_undo_phase)
{
if (run_undo_phase(uncommitted_trans))
{
ma_message_no_user(0, "Undo phase failed");
goto err;
}
}
else if (uncommitted_trans > 0)
{
@ -398,7 +409,10 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
not want that (we want to keep some modules initialized for runtime).
*/
if (close_all_tables())
{
ma_message_no_user(0, "closing of tables failed");
goto err;
}
old_now= now;
now= my_getsystime();
@ -437,11 +451,13 @@ end:
if (recovery_message_printed != REC_MSG_NONE)
{
fprintf(stderr, "\n");
if (error)
ma_message_no_user(0, "recovery failed");
else
if (!error)
ma_message_no_user(ME_JUST_INFO, "recovery done");
}
if (error)
my_message(HA_ERR_INITIALIZATION,
"Maria recovery failed. Please run maria_chk -r on all maria "
"tables and delete all maria_log.######## files", MYF(0));
procent_printed= 0;
/* we don't cleanly close tables if we hit some error (may corrupt them) */
DBUG_RETURN(error);
@ -1765,6 +1781,24 @@ prototype_redo_exec_hook(COMMIT)
}
/*
Set position for next active record that will have key inserted
*/
static void set_lastpos(MARIA_HA *info, uchar *pos)
{
ulonglong page;
uint dir_entry;
/* If we have checksum, it's before rowid */
if (info->s->calc_checksum)
pos+= HA_CHECKSUM_STORE_SIZE;
page= page_korr(pos);
dir_entry= dirpos_korr(pos + PAGE_STORE_SIZE);
info->cur_row.lastpos= ma_recordpos(page, dir_entry);
}
prototype_redo_exec_hook(CLR_END)
{
MARIA_HA *info= get_MARIA_HA_from_UNDO_record(rec);
@ -1773,6 +1807,7 @@ prototype_redo_exec_hook(CLR_END)
enum translog_record_type undone_record_type;
const LOG_DESC *log_desc;
my_bool row_entry= 0;
uchar *logpos;
DBUG_ENTER("exec_REDO_LOGREC_CLR_END");
if (info == NULL)
@ -1786,6 +1821,19 @@ prototype_redo_exec_hook(CLR_END)
set_undo_lsn_for_active_trans(rec->short_trid, previous_undo_lsn);
tprint(tracef, " CLR_END was about %s, undo_lsn now LSN (%lu,0x%lx)\n",
log_desc->name, LSN_IN_PARTS(previous_undo_lsn));
enlarge_buffer(rec);
if (log_record_buffer.str == NULL ||
translog_read_record(rec->lsn, 0, rec->record_length,
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
return 1;
}
logpos= (log_record_buffer.str + LSN_STORE_SIZE + FILEID_STORE_SIZE +
CLR_TYPE_STORE_SIZE);
if (cmp_translog_addr(rec->lsn, share->state.is_of_horizon) >= 0)
{
tprint(tracef, " state older than record\n");
@ -1793,6 +1841,7 @@ prototype_redo_exec_hook(CLR_END)
case LOGREC_UNDO_ROW_DELETE:
row_entry= 1;
share->state.state.records++;
set_lastpos(info, logpos);
break;
case LOGREC_UNDO_ROW_INSERT:
share->state.state.records--;
@ -1801,6 +1850,7 @@ prototype_redo_exec_hook(CLR_END)
break;
case LOGREC_UNDO_ROW_UPDATE:
row_entry= 1;
set_lastpos(info, logpos);
break;
case LOGREC_UNDO_KEY_INSERT:
case LOGREC_UNDO_KEY_DELETE:
@ -1810,18 +1860,8 @@ prototype_redo_exec_hook(CLR_END)
{
uint key_nr;
my_off_t page;
uchar buff[KEY_NR_STORE_SIZE + PAGE_STORE_SIZE];
if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
CLR_TYPE_STORE_SIZE,
KEY_NR_STORE_SIZE + PAGE_STORE_SIZE,
buff, NULL) !=
KEY_NR_STORE_SIZE + PAGE_STORE_SIZE)
{
eprint(tracef, "Failed to read record\n");
DBUG_RETURN(1);
}
key_nr= key_nr_korr(buff);
page= page_korr(buff + KEY_NR_STORE_SIZE);
key_nr= key_nr_korr(logpos);
page= page_korr(logpos + KEY_NR_STORE_SIZE);
share->state.key_root[key_nr]= (page == IMPOSSIBLE_PAGE_NO ?
HA_OFFSET_ERROR :
page * share->block_size);
@ -1831,19 +1871,21 @@ prototype_redo_exec_hook(CLR_END)
DBUG_ASSERT(0);
}
if (row_entry && share->calc_checksum)
{
uchar buff[HA_CHECKSUM_STORE_SIZE];
if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
CLR_TYPE_STORE_SIZE, HA_CHECKSUM_STORE_SIZE,
buff, NULL) != HA_CHECKSUM_STORE_SIZE)
{
eprint(tracef, "Failed to read record\n");
DBUG_RETURN(1);
}
share->state.state.checksum+= ha_checksum_korr(buff);
}
share->state.state.checksum+= ha_checksum_korr(logpos);
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
}
else
{
/* We must set lastpos for upcoming undo delete keys */
switch (undone_record_type) {
case LOGREC_UNDO_ROW_DELETE:
case LOGREC_UNDO_ROW_UPDATE:
set_lastpos(info, logpos);
break;
default:
break;
}
}
if (row_entry)
tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records);
_ma_unpin_all_pages(info, rec->lsn);
@ -2436,6 +2478,8 @@ static uint end_of_redo_phase(my_bool prepare_for_undo_phase)
static int run_undo_phase(uint uncommitted)
{
DBUG_ENTER("run_undo_phase");
if (uncommitted > 0)
{
checkpoint_useful= TRUE;
@ -2467,23 +2511,23 @@ static int run_undo_phase(uint uncommitted)
LOG_DESC *log_desc;
if (translog_read_record_header(trn->undo_lsn, &rec) ==
RECHEADER_READ_ERROR)
return 1;
DBUG_RETURN(1);
log_desc= &log_record_type_descriptor[rec.type];
display_record_position(log_desc, &rec, 0);
if (log_desc->record_execute_in_undo_phase(&rec, trn))
{
tprint(tracef, "Got error %d when executing undo\n", my_errno);
return 1;
DBUG_RETURN(1);
}
}
if (trnman_rollback_trn(trn))
return 1;
DBUG_RETURN(1);
/* We could want to span a few threads (4?) instead of 1 */
/* In the future, we want to have this phase *online* */
}
}
return 0;
DBUG_RETURN(0);
}
@ -2783,7 +2827,7 @@ static LSN parse_checkpoint_record(LSN lsn)
*/
if (ptr != (log_record_buffer.str + log_record_buffer.length))
{
tprint(tracef, "checkpoint record corrupted\n");
eprint(tracef, "checkpoint record corrupted\n");
return LSN_ERROR;
}
set_if_smaller(start_address, minimum_rec_lsn_of_dirty_pages);
@ -2821,6 +2865,8 @@ static int close_all_tables(void)
LIST *list_element, *next_open;
MARIA_HA *info;
TRANSLOG_ADDRESS addr;
DBUG_ENTER("close_all_tables");
pthread_mutex_lock(&THR_LOCK_maria);
if (maria_open_list == NULL)
goto end;
@ -2862,7 +2908,7 @@ static int close_all_tables(void)
}
end:
pthread_mutex_unlock(&THR_LOCK_maria);
return error;
DBUG_RETURN(error);
}

View File

@ -58,3 +58,16 @@ void maria_scan_end(MARIA_HA *info)
{
(*info->s->scan_end)(info);
}
int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos)
{
*lastpos= info->cur_row.lastpos;
return 0;
}
void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos)
{
info->cur_row.nextpos= lastpos;
}

View File

@ -33,7 +33,7 @@ uchar maria_uuid[MY_UUID_SIZE];
uint maria_quick_table_bits=9;
ulong maria_block_size= MARIA_KEY_BLOCK_LENGTH;
my_bool maria_flush= 0, maria_single_user= 0;
my_bool maria_delay_key_write= 0;
my_bool maria_delay_key_write= 0, maria_page_checksums= 1;
#if defined(THREAD) && !defined(DONT_USE_RW_LOCKS)
ulong maria_concurrent_insert= 2;
#else

View File

@ -788,7 +788,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
key_type= HA_KEYTYPE_TEXT;
break;
case 'c':
create_flag|= HA_CREATE_CHECKSUM;
create_flag|= HA_CREATE_CHECKSUM | HA_CREATE_PAGE_CHECKSUM;
break;
case 'R': /* Length of record pointer */
if (rec_pointer_size > 3)

View File

@ -1105,7 +1105,7 @@ static void get_options(int argc, char **argv)
opt_quick_mode=1;
break;
case 'c':
create_flag|= HA_CREATE_CHECKSUM;
create_flag|= HA_CREATE_CHECKSUM | HA_CREATE_PAGE_CHECKSUM;
break;
case 'D':
create_flag|=HA_CREATE_DELAY_KEY_WRITE;

View File

@ -1636,8 +1636,8 @@ static int maria_sort_records(HA_CHECK *param,
share->state.key_root[sort_key],
MYF(MY_NABP+MY_WME)))
{
_ma_check_print_error(param,"Can't read indexpage from filepos: %s",
(ulong) share->state.key_root[sort_key]);
_ma_check_print_error(param, "Can't read indexpage from filepos: %s",
llstr(share->state.key_root[sort_key], llbuff));
goto err;
}

View File

@ -40,6 +40,7 @@
#define MAX_NONMAPPED_INSERTS 1000
#define MARIA_MAX_TREE_LEVELS 32
#define MARIA_MAX_CONTROL_FILE_LOCK_RETRY 30 /* Retry this many times */
struct st_transaction;
@ -126,7 +127,7 @@ typedef struct st_maria_state_info
#define MARIA_KEYDEF_SIZE (2+ 5*2)
#define MARIA_UNIQUEDEF_SIZE (2+1+1)
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
#define MARIA_COLUMNDEF_SIZE (2*7+1+1+4)
#define MARIA_BASE_INFO_SIZE (MY_UUID_SIZE + 5*8 + 6*4 + 11*2 + 6 + 5*2 + 1 + 16)
#define MARIA_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */
/* Internal management bytes needed to store 2 keys on an index page */
@ -277,6 +278,8 @@ typedef struct st_maria_share
int (*scan)(MARIA_HA *, uchar *, MARIA_RECORD_POS, my_bool);
/* End scan */
void (*scan_end)(MARIA_HA *);
int (*scan_remember_pos)(MARIA_HA *, MARIA_RECORD_POS*);
void (*scan_restore_pos)(MARIA_HA *, MARIA_RECORD_POS);
/* Pre-write of row (some handlers may do the actual write here) */
MARIA_RECORD_POS (*write_record_init)(MARIA_HA *, const uchar *);
/* Write record (or accept write_record_init) */
@ -430,7 +433,7 @@ struct st_maria_handler
MARIA_STATUS_INFO *state, save_state;
MARIA_ROW cur_row; /* The active row that we just read */
MARIA_ROW new_row; /* Storage for a row during update */
MARIA_BLOCK_SCAN scan;
MARIA_BLOCK_SCAN scan, *scan_save;
MARIA_BLOB *blobs; /* Pointer to blobs */
MARIA_BIT_BUFF bit_buff;
DYNAMIC_ARRAY bitmap_blocks;
@ -483,7 +486,7 @@ struct st_maria_handler
enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */
uint save_lastkey_length;
uint pack_key_length; /* For MARIAMRG */
myf lock_wait; /* is 0 or MY_DONT_WAIT */
myf lock_wait; /* is 0 or MY_SHORT_WAIT */
int errkey; /* Got last error on this key */
int lock_type; /* How database was locked */
int tmp_lock_type; /* When locked by readinfo */
@ -999,6 +1002,9 @@ 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);
int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos);
void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos);
#include "ma_commit.h"
extern MARIA_HA *_ma_test_if_reopen(const char *filename);
@ -1023,9 +1029,12 @@ int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
See ma_check_standalone.h .
*/
volatile int *_ma_killed_ptr(HA_CHECK *param);
void _ma_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...));
void _ma_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...));
void _ma_check_print_info _VARARGS((HA_CHECK *param, const char *fmt, ...));
void _ma_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...))
ATTRIBUTE_FORMAT(printf, 2, 3);
void _ma_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...))
ATTRIBUTE_FORMAT(printf, 2, 3);
void _ma_check_print_info _VARARGS((HA_CHECK *param, const char *fmt, ...))
ATTRIBUTE_FORMAT(printf, 2, 3);
C_MODE_END
int _ma_flush_pending_blocks(MARIA_SORT_PARAM *param);
@ -1056,23 +1065,29 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
#define MARIA_NO_CRC_BITMAP_PAGE 0xfffffffe
extern my_bool maria_page_crc_set_index(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_set_normal(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_check_bitmap(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_check_data(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_check_index(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_check_none(uchar *page,
pgcache_page_no_t page_no,
uchar *data_ptr);
extern my_bool maria_page_filler_set_bitmap(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_filler_set_normal(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_filler_set_none(uchar *page,
pgcache_page_no_t page_no,
uchar *data_ptr);
extern PAGECACHE *maria_log_pagecache;

View File

@ -259,28 +259,28 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
{
/* reserve space for null bits */
bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
recinfo_pos->type= (int) FIELD_NORMAL;
recinfo_pos->type= FIELD_NORMAL;
recinfo_pos++->length= (uint16) (minpos - recpos);
}
if (!found)
break;
if (found->flags & BLOB_FLAG)
recinfo_pos->type= (int) FIELD_BLOB;
recinfo_pos->type= FIELD_BLOB;
else if (found->type() == MYSQL_TYPE_VARCHAR)
recinfo_pos->type= FIELD_VARCHAR;
else if (!(options & HA_OPTION_PACK_RECORD))
recinfo_pos->type= (int) FIELD_NORMAL;
recinfo_pos->type= FIELD_NORMAL;
else if (found->zero_pack())
recinfo_pos->type= (int) FIELD_SKIP_ZERO;
recinfo_pos->type= FIELD_SKIP_ZERO;
else
recinfo_pos->type= (int) ((length <= 3 ||
(found->flags & ZEROFILL_FLAG)) ?
FIELD_NORMAL :
found->type() == MYSQL_TYPE_STRING ||
found->type() == MYSQL_TYPE_VAR_STRING ?
FIELD_SKIP_ENDSPACE :
FIELD_SKIP_PRESPACE);
recinfo_pos->type= ((length <= 3 ||
(found->flags & ZEROFILL_FLAG)) ?
FIELD_NORMAL :
found->type() == MYSQL_TYPE_STRING ||
found->type() == MYSQL_TYPE_VAR_STRING ?
FIELD_SKIP_ENDSPACE :
FIELD_SKIP_PRESPACE);
if (found->null_ptr)
{
recinfo_pos->null_bit= found->null_bit;
@ -1683,9 +1683,15 @@ int ha_myisam::rnd_next(uchar *buf)
return error;
}
int ha_myisam::restart_rnd_next(uchar *buf, uchar *pos)
int ha_myisam::remember_rnd_pos()
{
return rnd_pos(buf,pos);
position((uchar*) 0);
return 0;
}
int ha_myisam::restart_rnd_next(uchar *buf)
{
return rnd_pos(buf, ref);
}
int ha_myisam::rnd_pos(uchar *buf, uchar *pos)

View File

@ -94,7 +94,8 @@ class ha_myisam: public handler
int rnd_init(bool scan);
int rnd_next(uchar *buf);
int rnd_pos(uchar * buf, uchar *pos);
int restart_rnd_next(uchar *buf, uchar *pos);
int remember_rnd_pos();
int restart_rnd_next(uchar *buf);
void position(const uchar *record);
int info(uint);
int extra(enum ha_extra_function operation);

View File

@ -2145,7 +2145,7 @@ int lock_file(HA_CHECK *param, File file, my_off_t start, int lock_type,
{
if (my_lock(file,lock_type,start,F_TO_EOF,
param->testflag & T_WAIT_FOREVER ? MYF(MY_SEEK_NOT_DONE) :
MYF(MY_SEEK_NOT_DONE | MY_DONT_WAIT)))
MYF(MY_SEEK_NOT_DONE | MY_SHORT_WAIT)))
{
mi_check_print_error(param," %d when locking %s '%s'",my_errno,filetype,filename);
param->error_printed=2; /* Don't give that data is crashed */

View File

@ -216,7 +216,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
info->lock_wait=0;
break;
case HA_EXTRA_NO_WAIT_LOCK:
info->lock_wait=MY_DONT_WAIT;
info->lock_wait= MY_SHORT_WAIT;
break;
case HA_EXTRA_NO_KEYS:
if (info->lock_type == F_UNLCK)

View File

@ -180,7 +180,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
0 : MY_DONT_WAIT))) &&
0 : MY_SHORT_WAIT))) &&
!(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
goto err;
}

View File

@ -284,7 +284,7 @@ struct st_myisam_info
LIST open_list;
IO_CACHE rec_cache; /* When cacheing records */
uint preload_buff_size; /* When preloading indexes */
myf lock_wait; /* is 0 or MY_DONT_WAIT */
myf lock_wait; /* is 0 or MY_SHORT_WAIT */
my_bool was_locked; /* Was locked in panic */
my_bool append_insert_at_end; /* Set if concurrent insert */
my_bool quick_mode;