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:
commit
765caec21a
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 ;
|
||||
|
@ -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
|
||||
|
@ -14,5 +14,4 @@ INSERT INTO t1 SELECT UUID();
|
||||
query_vertical SHOW WARNINGS;
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
|
||||
DROP VIEW v1;
|
||||
|
@ -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
|
||||
|
@ -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 ;
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 &&
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1678,7 +1678,7 @@ bool multi_update::send_data(List<Item> ¬_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;
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user