Commit 9f1aaeff authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-maria

into  mysql.com:/home/my/mysql-maria


include/my_sys.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
storage/maria/ma_checkpoint.c:
  Auto merged
storage/maria/ma_pagecache.c:
  Auto merged
storage/maria/ma_pagecache.h:
  Auto merged
storage/maria/maria_chk.c:
  Auto merged
storage/maria/ma_recovery.c:
  SCCS merged
parents 6b3743f0 fc0a25ec
...@@ -90,6 +90,8 @@ extern int NEAR my_errno; /* Last error in mysys */ ...@@ -90,6 +90,8 @@ extern int NEAR my_errno; /* Last error in mysys */
#define ME_COLOUR1 ((1 << ME_HIGHBYTE)) /* Possibly error-colours */ #define ME_COLOUR1 ((1 << ME_HIGHBYTE)) /* Possibly error-colours */
#define ME_COLOUR2 ((2 << ME_HIGHBYTE)) #define ME_COLOUR2 ((2 << ME_HIGHBYTE))
#define ME_COLOUR3 ((3 << ME_HIGHBYTE)) #define ME_COLOUR3 ((3 << ME_HIGHBYTE))
#define ME_JUST_INFO 1024 /**< not error but just info */
#define ME_JUST_WARNING 2048 /**< not error but just warning */
/* Bits in last argument to fn_format */ /* Bits in last argument to fn_format */
#define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */ #define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */
...@@ -208,6 +210,7 @@ extern int errno; /* declare errno */ ...@@ -208,6 +210,7 @@ extern int errno; /* declare errno */
extern char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE]; extern char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE];
extern char *home_dir; /* Home directory for user */ extern char *home_dir; /* Home directory for user */
extern const char *my_progname; /* program-name (printed in errors) */ extern const char *my_progname; /* program-name (printed in errors) */
extern const char *my_progname_short; /* like above but without directory */
extern char NEAR curr_dir[]; /* Current directory for user */ extern char NEAR curr_dir[]; /* Current directory for user */
extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags); extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
extern int (*fatal_error_handler_hook)(uint my_err, const char *str, extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
......
...@@ -4885,12 +4885,7 @@ sub gdb_arguments { ...@@ -4885,12 +4885,7 @@ sub gdb_arguments {
{ {
# write init file for mysqld # write init file for mysqld
mtr_tofile($gdb_init_file, mtr_tofile($gdb_init_file,
"set args $str\n" . "set args $str\n");
"break mysql_parse\n" .
"commands 1\n" .
"disable 1\n" .
"end\n" .
"run");
} }
if ( $opt_manual_gdb ) if ( $opt_manual_gdb )
...@@ -4950,11 +4945,7 @@ sub ddd_arguments { ...@@ -4950,11 +4945,7 @@ sub ddd_arguments {
# write init file for mysqld # write init file for mysqld
mtr_tofile($gdb_init_file, mtr_tofile($gdb_init_file,
"file $$exe\n" . "file $$exe\n" .
"set args $str\n" . "set args $str\n");
"break mysql_parse\n" .
"commands 1\n" .
"disable 1\n" .
"end");
} }
if ( $opt_manual_ddd ) if ( $opt_manual_ddd )
......
...@@ -78,6 +78,7 @@ my_bool my_init(void) ...@@ -78,6 +78,7 @@ my_bool my_init(void)
my_umask= 0660; /* Default umask for new files */ my_umask= 0660; /* Default umask for new files */
my_umask_dir= 0700; /* Default umask for new directories */ my_umask_dir= 0700; /* Default umask for new directories */
init_glob_errs(); init_glob_errs();
my_progname_short= my_progname + dirname_length(my_progname);
#if defined(THREAD) && defined(SAFE_MUTEX) #if defined(THREAD) && defined(SAFE_MUTEX)
safe_mutex_global_init(); /* Must be called early */ safe_mutex_global_init(); /* Must be called early */
#endif #endif
......
...@@ -26,7 +26,7 @@ my_bool timed_mutexes= 0; ...@@ -26,7 +26,7 @@ my_bool timed_mutexes= 0;
/* from my_init */ /* from my_init */
char * home_dir=0; char * home_dir=0;
const char *my_progname=0; const char *my_progname= NULL, *my_progname_short= NULL;
char NEAR curr_dir[FN_REFLEN]= {0}, char NEAR curr_dir[FN_REFLEN]= {0},
NEAR home_dir_buff[FN_REFLEN]= {0}; NEAR home_dir_buff[FN_REFLEN]= {0};
ulong my_stream_opened=0,my_file_opened=0, my_tmp_file_created=0; ulong my_stream_opened=0,my_file_opened=0, my_tmp_file_created=0;
......
...@@ -2558,6 +2558,8 @@ extern "C" int my_message_sql(uint error, const char *str, myf MyFlags); ...@@ -2558,6 +2558,8 @@ extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
int my_message_sql(uint error, const char *str, myf MyFlags) int my_message_sql(uint error, const char *str, myf MyFlags)
{ {
THD *thd; THD *thd;
MYSQL_ERROR::enum_warning_level level;
sql_print_message_func func;
DBUG_ENTER("my_message_sql"); DBUG_ENTER("my_message_sql");
DBUG_PRINT("error", ("error: %u message: '%s'", error, str)); DBUG_PRINT("error", ("error: %u message: '%s'", error, str));
/* /*
...@@ -2565,21 +2567,36 @@ int my_message_sql(uint error, const char *str, myf MyFlags) ...@@ -2565,21 +2567,36 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
will be fixed will be fixed
DBUG_ASSERT(error != 0); DBUG_ASSERT(error != 0);
*/ */
if (MyFlags & ME_JUST_INFO)
{
level= MYSQL_ERROR::WARN_LEVEL_NOTE;
func= sql_print_information;
}
else if (MyFlags & ME_JUST_WARNING)
{
level= MYSQL_ERROR::WARN_LEVEL_WARN;
func= sql_print_warning;
}
else
{
level= MYSQL_ERROR::WARN_LEVEL_ERROR;
func= sql_print_error;
}
if ((thd= current_thd)) if ((thd= current_thd))
{ {
/* /*
TODO: There are two exceptions mechanism (THD and sp_rcontext), TODO: There are two exceptions mechanism (THD and sp_rcontext),
this could be improved by having a common stack of handlers. this could be improved by having a common stack of handlers.
*/ */
if (thd->handle_error(error, if (thd->handle_error(error, level) ||
MYSQL_ERROR::WARN_LEVEL_ERROR)) (thd->spcont && thd->spcont->handle_error(error, level, thd)))
DBUG_RETURN(0); DBUG_RETURN(0);
if (thd->spcont && if (level == MYSQL_ERROR::WARN_LEVEL_WARN)
thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd)) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, error, str);
{ if (level != MYSQL_ERROR::WARN_LEVEL_ERROR)
DBUG_RETURN(0); goto to_error_log;
}
thd->query_error= 1; // needed to catch query errors during replication thd->query_error= 1; // needed to catch query errors during replication
...@@ -2611,8 +2628,9 @@ int my_message_sql(uint error, const char *str, myf MyFlags) ...@@ -2611,8 +2628,9 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
} }
} }
} }
to_error_log:
if (!thd || MyFlags & ME_NOREFRESH) if (!thd || MyFlags & ME_NOREFRESH)
sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */ (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -3262,6 +3280,9 @@ static int init_server_components() ...@@ -3262,6 +3280,9 @@ static int init_server_components()
} }
} }
/* set up the hook before initializing plugins which may use it */
error_handler_hook= my_message_sql;
if (xid_cache_init()) if (xid_cache_init())
{ {
sql_print_error("Out of memory"); sql_print_error("Out of memory");
...@@ -3872,7 +3893,6 @@ we force server id to 2, but this MySQL server will not act as a slave."); ...@@ -3872,7 +3893,6 @@ we force server id to 2, but this MySQL server will not act as a slave.");
init signals & alarm init signals & alarm
After this we can't quit by a simple unireg_abort After this we can't quit by a simple unireg_abort
*/ */
error_handler_hook= my_message_sql;
start_signal_handler(); // Creates pidfile start_signal_handler(); // Creates pidfile
if (mysql_rm_tmp_tables() || acl_init(opt_noacl) || if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
......
...@@ -66,21 +66,21 @@ struct st_filter_param ...@@ -66,21 +66,21 @@ struct st_filter_param
}; /**< information to determine which dirty pages should be flushed */ }; /**< information to determine which dirty pages should be flushed */
static enum pagecache_flush_filter_result static enum pagecache_flush_filter_result
filter_flush_data_file_medium(enum pagecache_page_type type, filter_flush_file_medium(enum pagecache_page_type type,
pgcache_page_no_t page, pgcache_page_no_t page,
LSN rec_lsn, void *arg); LSN rec_lsn, void *arg);
static enum pagecache_flush_filter_result static enum pagecache_flush_filter_result
filter_flush_data_file_full(enum pagecache_page_type type, filter_flush_file_full(enum pagecache_page_type type,
pgcache_page_no_t page, pgcache_page_no_t page,
LSN rec_lsn, void *arg); LSN rec_lsn, void *arg);
static enum pagecache_flush_filter_result static enum pagecache_flush_filter_result
filter_flush_data_file_indirect(enum pagecache_page_type type, filter_flush_file_indirect(enum pagecache_page_type type,
pgcache_page_no_t page, pgcache_page_no_t page,
LSN rec_lsn, void *arg); LSN rec_lsn, void *arg);
static enum pagecache_flush_filter_result static enum pagecache_flush_filter_result
filter_flush_data_file_evenly(enum pagecache_page_type type, filter_flush_file_evenly(enum pagecache_page_type type,
pgcache_page_no_t pageno, pgcache_page_no_t pageno,
LSN rec_lsn, void *arg); LSN rec_lsn, void *arg);
static int really_execute_checkpoint(void); static int really_execute_checkpoint(void);
pthread_handler_t ma_checkpoint_background(void *arg); pthread_handler_t ma_checkpoint_background(void *arg);
static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon); static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon);
...@@ -280,14 +280,14 @@ static int really_execute_checkpoint(void) ...@@ -280,14 +280,14 @@ static int really_execute_checkpoint(void)
*/ */
#if 0 /* purging/keeping will be an option */ #if 0 /* purging/keeping will be an option */
if (translog_purge(log_low_water_mark)) if (translog_purge(log_low_water_mark))
fprintf(stderr, "Maria engine: log purge failed\n"); /* not deadly */ ma_message_no_user(0, "log purging failed");
#endif #endif
goto end; goto end;
err: err:
error= 1; error= 1;
fprintf(stderr, "Maria engine: checkpoint failed\n"); /* TODO: improve ;) */ ma_message_no_user(0, "checkpoint failed");
/* we were possibly not able to determine what pages to flush */ /* we were possibly not able to determine what pages to flush */
pages_to_flush_before_next_checkpoint= 0; pages_to_flush_before_next_checkpoint= 0;
...@@ -459,9 +459,9 @@ void ma_checkpoint_end(void) ...@@ -459,9 +459,9 @@ void ma_checkpoint_end(void)
*/ */
static enum pagecache_flush_filter_result static enum pagecache_flush_filter_result
filter_flush_data_file_medium(enum pagecache_page_type type, filter_flush_file_medium(enum pagecache_page_type type,
pgcache_page_no_t pageno, pgcache_page_no_t pageno,
LSN rec_lsn, void *arg) LSN rec_lsn, void *arg)
{ {
struct st_filter_param *param= (struct st_filter_param *)arg; struct st_filter_param *param= (struct st_filter_param *)arg;
return ((type == PAGECACHE_LSN_PAGE) && return ((type == PAGECACHE_LSN_PAGE) &&
...@@ -483,10 +483,10 @@ filter_flush_data_file_medium(enum pagecache_page_type type, ...@@ -483,10 +483,10 @@ filter_flush_data_file_medium(enum pagecache_page_type type,
*/ */
static enum pagecache_flush_filter_result static enum pagecache_flush_filter_result
filter_flush_data_file_full(enum pagecache_page_type type, filter_flush_file_full(enum pagecache_page_type type,
pgcache_page_no_t pageno, pgcache_page_no_t pageno,
LSN rec_lsn __attribute__ ((unused)), LSN rec_lsn __attribute__ ((unused)),
void *arg) void *arg)
{ {
struct st_filter_param *param= (struct st_filter_param *)arg; struct st_filter_param *param= (struct st_filter_param *)arg;
return (type == PAGECACHE_LSN_PAGE) || return (type == PAGECACHE_LSN_PAGE) ||
...@@ -507,11 +507,11 @@ filter_flush_data_file_full(enum pagecache_page_type type, ...@@ -507,11 +507,11 @@ filter_flush_data_file_full(enum pagecache_page_type type,
*/ */
static enum pagecache_flush_filter_result static enum pagecache_flush_filter_result
filter_flush_data_file_indirect(enum pagecache_page_type type filter_flush_file_indirect(enum pagecache_page_type type
__attribute__ ((unused)), __attribute__ ((unused)),
pgcache_page_no_t pageno, pgcache_page_no_t pageno,
LSN rec_lsn __attribute__ ((unused)), LSN rec_lsn __attribute__ ((unused)),
void *arg) void *arg)
{ {
struct st_filter_param *param= (struct st_filter_param *)arg; struct st_filter_param *param= (struct st_filter_param *)arg;
return return
...@@ -523,11 +523,11 @@ filter_flush_data_file_indirect(enum pagecache_page_type type ...@@ -523,11 +523,11 @@ filter_flush_data_file_indirect(enum pagecache_page_type type
/** /**
@brief dirty-page filtering criteria for background flushing thread. @brief dirty-page filtering criteria for background flushing thread.
We flush data pages which have been dirty since the previous checkpoint We flush data/index pages which have been dirty since the previous
(this is the two-checkpoint rule: the REDO phase will not have to start checkpoint (this is the two-checkpoint rule: the REDO phase will not have
from earlier than the next-to-last checkpoint), and all dirty bitmap to start from earlier than the next-to-last checkpoint), and no
pages. But we flush no more than a certain number of pages (to have an bitmap pages. But we flush no more than a certain number of pages (to have
even flushing, no write burst). an even flushing, no write burst).
@param type Page's type @param type Page's type
@param pageno Page's number @param pageno Page's number
...@@ -536,9 +536,9 @@ filter_flush_data_file_indirect(enum pagecache_page_type type ...@@ -536,9 +536,9 @@ filter_flush_data_file_indirect(enum pagecache_page_type type
*/ */
static enum pagecache_flush_filter_result static enum pagecache_flush_filter_result
filter_flush_data_file_evenly(enum pagecache_page_type type, filter_flush_file_evenly(enum pagecache_page_type type,
pgcache_page_no_t pageno __attribute__ ((unused)), pgcache_page_no_t pageno __attribute__ ((unused)),
LSN rec_lsn, void *arg) LSN rec_lsn, void *arg)
{ {
struct st_filter_param *param= (struct st_filter_param *)arg; struct st_filter_param *param= (struct st_filter_param *)arg;
if (unlikely(param->max_pages == 0)) /* all flushed already */ if (unlikely(param->max_pages == 0)) /* all flushed already */
...@@ -670,12 +670,10 @@ pthread_handler_t ma_checkpoint_background(void *arg) ...@@ -670,12 +670,10 @@ pthread_handler_t ma_checkpoint_background(void *arg)
int res= int res=
flush_pagecache_blocks_with_filter(maria_pagecache, flush_pagecache_blocks_with_filter(maria_pagecache,
dfile, FLUSH_KEEP_LAZY, dfile, FLUSH_KEEP_LAZY,
filter_flush_data_file_evenly, filter_flush_file_evenly,
&filter_param); &filter_param);
/* note that it may just be a pinned page */ if (unlikely(res & PCFLUSH_ERROR))
if (unlikely(res)) ma_message_no_user(0, "background data page flush failed");
fprintf(stderr, "Maria engine: warning - background page flush"
" failed\n");
if (filter_param.max_pages == 0) /* bunch all flushed, sleep */ if (filter_param.max_pages == 0) /* bunch all flushed, sleep */
break; /* and we will continue with the same file */ break; /* and we will continue with the same file */
dfile++; /* otherwise all this file is flushed, move to next file */ dfile++; /* otherwise all this file is flushed, move to next file */
...@@ -692,12 +690,11 @@ pthread_handler_t ma_checkpoint_background(void *arg) ...@@ -692,12 +690,11 @@ pthread_handler_t ma_checkpoint_background(void *arg)
{ {
int res= int res=
flush_pagecache_blocks_with_filter(maria_pagecache, flush_pagecache_blocks_with_filter(maria_pagecache,
dfile, FLUSH_KEEP_LAZY, kfile, FLUSH_KEEP_LAZY,
filter_flush_data_file_evenly, filter_flush_file_evenly,
&filter_param); &filter_param);
if (unlikely(res)) if (unlikely(res & PCFLUSH_ERROR))
fprintf(stderr, "Maria engine: warning - background page flush" ma_message_no_user(0, "background index page flush failed");
" failed\n");
if (filter_param.max_pages == 0) /* bunch all flushed, sleep */ if (filter_param.max_pages == 0) /* bunch all flushed, sleep */
break; /* and we will continue with the same file */ break; /* and we will continue with the same file */
kfile++; /* otherwise all this file is flushed, move to next file */ kfile++; /* otherwise all this file is flushed, move to next file */
...@@ -854,13 +851,13 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) ...@@ -854,13 +851,13 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
switch(checkpoint_in_progress) switch(checkpoint_in_progress)
{ {
case CHECKPOINT_MEDIUM: case CHECKPOINT_MEDIUM:
filter= &filter_flush_data_file_medium; filter= &filter_flush_file_medium;
break; break;
case CHECKPOINT_FULL: case CHECKPOINT_FULL:
filter= &filter_flush_data_file_full; filter= &filter_flush_file_full;
break; break;
case CHECKPOINT_INDIRECT: case CHECKPOINT_INDIRECT:
filter= &filter_flush_data_file_indirect; filter= &filter_flush_file_indirect;
break; break;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
...@@ -1148,22 +1145,18 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) ...@@ -1148,22 +1145,18 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
flushed, as the REDOs about it will be skipped, it will wrongly not be flushed, as the REDOs about it will be skipped, it will wrongly not be
recovered. If bitmap pages had a rec_lsn it would be different. recovered. If bitmap pages had a rec_lsn it would be different.
*/ */
/** if ((filter_param.is_data_file= TRUE),
@todo we ignore the error because it may be just due a pinned page; (flush_pagecache_blocks_with_filter(maria_pagecache,
we should rather fix the function below to distinguish between
pinned page and write error. Then we can turn the warning into an
error.
*/
if (((filter_param.is_data_file= TRUE),
flush_pagecache_blocks_with_filter(maria_pagecache,
&dfile, FLUSH_KEEP, &dfile, FLUSH_KEEP,
filter, &filter_param)) || filter, &filter_param) &
((filter_param.is_data_file= FALSE), PCFLUSH_ERROR))
flush_pagecache_blocks_with_filter(maria_pagecache, ma_message_no_user(0, "checkpoint data page flush failed");
if ((filter_param.is_data_file= FALSE),
(flush_pagecache_blocks_with_filter(maria_pagecache,
&kfile, FLUSH_KEEP, &kfile, FLUSH_KEEP,
filter, &filter_param))) filter, &filter_param) &
fprintf(stderr, "Maria engine: warning - checkpoint page flush" PCFLUSH_ERROR))
" failed\n"); /** @todo improve */ ma_message_no_user(0, "checkpoint index page flush failed");
/* /*
fsyncs the fd, that's the loooong operation (e.g. max 150 fsync fsyncs the fd, that's the loooong operation (e.g. max 150 fsync
per second, so if you have touched 1000 files it's 7 seconds). per second, so if you have touched 1000 files it's 7 seconds).
......
...@@ -79,3 +79,14 @@ static inline LSN lsn_read_non_atomic_32(const volatile LSN *x) ...@@ -79,3 +79,14 @@ static inline LSN lsn_read_non_atomic_32(const volatile LSN *x)
} }
#define lsn_read_non_atomic(x) lsn_read_non_atomic_32(&x) #define lsn_read_non_atomic(x) lsn_read_non_atomic_32(&x)
#endif #endif
/**
prints a message from a task not connected to any user (checkpoint
and recovery for example).
@param level 0 if error, ME_JUST_WARNING if warning,
ME_JUST_INFO if info
@param sentence text to write
*/
#define ma_message_no_user(level, sentence) \
my_printf_error(HA_ERR_GENERIC, "Maria engine: %s", MYF(level), sentence)
...@@ -3577,21 +3577,37 @@ static int cmp_sec_link(PAGECACHE_BLOCK_LINK **a, PAGECACHE_BLOCK_LINK **b) ...@@ -3577,21 +3577,37 @@ static int cmp_sec_link(PAGECACHE_BLOCK_LINK **a, PAGECACHE_BLOCK_LINK **b)
} }
/* /**
Flush a portion of changed blocks to disk, @brief Flush a portion of changed blocks to disk, free used blocks
free used blocks if requested if requested
@param pagecache This page cache reference.
@param file File which should be flushed
@param cache Beginning of array of the block.
@param end Reference to the block after last in the array.
@param flush_type Type of the flush.
@param first_errno Where to store first errno of the flush.
@return Operation status
@retval PCFLUSH_OK OK
@retval PCFLUSH_ERROR There was errors during the flush process.
@retval PCFLUSH_PINNED Pinned blocks was met and skipped.
@retval PCFLUSH_PINNED_AND_ERROR PCFLUSH_ERROR and PCFLUSH_PINNED.
*/ */
static int flush_cached_blocks(PAGECACHE *pagecache, static int flush_cached_blocks(PAGECACHE *pagecache,
PAGECACHE_FILE *file, PAGECACHE_FILE *file,
PAGECACHE_BLOCK_LINK **cache, PAGECACHE_BLOCK_LINK **cache,
PAGECACHE_BLOCK_LINK **end, PAGECACHE_BLOCK_LINK **end,
enum flush_type type) enum flush_type type,
int *first_errno)
{ {
int rc= PCFLUSH_OK;
int error; int error;
int last_errno= 0;
uint count= (uint) (end-cache); uint count= (uint) (end-cache);
DBUG_ENTER("flush_cached_blocks"); DBUG_ENTER("flush_cached_blocks");
*first_errno= 0;
/* Don't lock the cache during the flush */ /* Don't lock the cache during the flush */
pagecache_pthread_mutex_unlock(&pagecache->cache_lock); pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
...@@ -3616,7 +3632,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache, ...@@ -3616,7 +3632,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
PCBLOCK_INFO(block); PCBLOCK_INFO(block);
/* undo the mark put by flush_pagecache_blocks_int(): */ /* undo the mark put by flush_pagecache_blocks_int(): */
block->status&= ~PCBLOCK_IN_FLUSH; block->status&= ~PCBLOCK_IN_FLUSH;
last_errno= -1; rc|= PCFLUSH_PINNED;
unreg_request(pagecache, block, 1); unreg_request(pagecache, block, 1);
continue; continue;
} }
...@@ -3657,8 +3673,8 @@ static int flush_cached_blocks(PAGECACHE *pagecache, ...@@ -3657,8 +3673,8 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
if (error) if (error)
{ {
block->status|= PCBLOCK_ERROR; block->status|= PCBLOCK_ERROR;
if (!last_errno) if (!*first_errno)
last_errno= errno ? errno : -1; *first_errno= errno ? errno : -1;
} }
#ifdef THREAD #ifdef THREAD
/* /*
...@@ -3683,7 +3699,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache, ...@@ -3683,7 +3699,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
unreg_request(pagecache, block, 1); unreg_request(pagecache, block, 1);
} }
} }
DBUG_RETURN(last_errno); DBUG_RETURN(rc);
} }
...@@ -3711,8 +3727,10 @@ static int flush_cached_blocks(PAGECACHE *pagecache, ...@@ -3711,8 +3727,10 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
this situation. this situation.
@return Operation status @return Operation status
@retval 0 OK @retval PCFLUSH_OK OK
@retval 1 Error @retval PCFLUSH_ERROR There was errors during the flush process.
@retval PCFLUSH_PINNED Pinned blocks was met and skipped.
@retval PCFLUSH_PINNED_AND_ERROR PCFLUSH_ERROR and PCFLUSH_PINNED.
*/ */
static int flush_pagecache_blocks_int(PAGECACHE *pagecache, static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
...@@ -3723,6 +3741,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, ...@@ -3723,6 +3741,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
{ {
PAGECACHE_BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache; PAGECACHE_BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache;
int last_errno= 0; int last_errno= 0;
int rc= PCFLUSH_OK;
DBUG_ENTER("flush_pagecache_blocks_int"); DBUG_ENTER("flush_pagecache_blocks_int");
DBUG_PRINT("enter", DBUG_PRINT("enter",
("file: %d blocks_used: %lu blocks_changed: %lu type: %d", ("file: %d blocks_used: %lu blocks_changed: %lu type: %d",
...@@ -3885,8 +3904,9 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, ...@@ -3885,8 +3904,9 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
This happens only if there is not enough This happens only if there is not enough
memory for the big block memory for the big block
*/ */
if ((error= flush_cached_blocks(pagecache, file, cache, if ((rc|= flush_cached_blocks(pagecache, file, cache,
end,type))) end, type, &error)) &
PCFLUSH_ERROR)
last_errno=error; last_errno=error;
DBUG_PRINT("info", ("restarting...")); DBUG_PRINT("info", ("restarting..."));
/* /*
...@@ -3920,7 +3940,8 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, ...@@ -3920,7 +3940,8 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
} }
if (pos != cache) if (pos != cache)
{ {
if ((error= flush_cached_blocks(pagecache, file, cache, pos, type))) if ((rc|= flush_cached_blocks(pagecache, file, cache, pos, type,
&error)) & PCFLUSH_ERROR)
last_errno= error; last_errno= error;
} }
/* Wait until list of blocks in switch is empty */ /* Wait until list of blocks in switch is empty */
...@@ -3998,8 +4019,8 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, ...@@ -3998,8 +4019,8 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
if (cache != cache_buff) if (cache != cache_buff)
my_free((uchar*) cache, MYF(0)); my_free((uchar*) cache, MYF(0));
if (last_errno) if (last_errno)
errno=last_errno; /* Return first error */ errno= last_errno; /* Return first error */
DBUG_RETURN(last_errno != 0); DBUG_RETURN(rc);
} }
...@@ -4016,8 +4037,10 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, ...@@ -4016,8 +4037,10 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
the block will be passed too. the block will be passed too.
@return Operation status @return Operation status
@retval 0 OK @retval PCFLUSH_OK OK
@retval 1 Error @retval PCFLUSH_ERROR There was errors during the flush process.
@retval PCFLUSH_PINNED Pinned blocks was met and skipped.
@retval PCFLUSH_PINNED_AND_ERROR PCFLUSH_ERROR and PCFLUSH_PINNED.
*/ */
int flush_pagecache_blocks_with_filter(PAGECACHE *pagecache, int flush_pagecache_blocks_with_filter(PAGECACHE *pagecache,
......
...@@ -246,6 +246,20 @@ extern void pagecache_unpin(PAGECACHE *pagecache, ...@@ -246,6 +246,20 @@ extern void pagecache_unpin(PAGECACHE *pagecache,
extern void pagecache_unpin_by_link(PAGECACHE *pagecache, extern void pagecache_unpin_by_link(PAGECACHE *pagecache,
PAGECACHE_BLOCK_LINK *link, PAGECACHE_BLOCK_LINK *link,
LSN lsn); LSN lsn);
/* Results of flush operation (bit field in fact) */
/* The flush is done. */
#define PCFLUSH_OK 0
/* There was errors during the flush process. */
#define PCFLUSH_ERROR 1
/* Pinned blocks was met and skipped. */
#define PCFLUSH_PINNED 2
/* PCFLUSH_ERROR and PCFLUSH_PINNED. */
#define PCFLUSH_PINNED_AND_ERROR (PCFLUSH_ERROR|PCFLUSH_PINNED)
#define flush_pagecache_blocks(A,B,C) \ #define flush_pagecache_blocks(A,B,C) \
flush_pagecache_blocks_with_filter(A,B,C,NULL,NULL) flush_pagecache_blocks_with_filter(A,B,C,NULL,NULL)
extern int flush_pagecache_blocks_with_filter(PAGECACHE *keycache, extern int flush_pagecache_blocks_with_filter(PAGECACHE *keycache,
......
...@@ -59,7 +59,6 @@ static my_bool skip_DDLs; /**< if REDO phase should skip DDL records */ ...@@ -59,7 +59,6 @@ static my_bool skip_DDLs; /**< if REDO phase should skip DDL records */
/** @brief to avoid writing a checkpoint if recovery did nothing. */ /** @brief to avoid writing a checkpoint if recovery did nothing. */
static my_bool checkpoint_useful; static my_bool checkpoint_useful;
static ulonglong now; /**< for tracking execution time of phases */ static ulonglong now; /**< for tracking execution time of phases */
static char preamble[]= "Maria engine: starting recovery; ";
uint warnings; /**< count of warnings */ uint warnings; /**< count of warnings */
#define prototype_redo_exec_hook(R) \ #define prototype_redo_exec_hook(R) \
...@@ -163,6 +162,11 @@ void tprint(FILE *trace_file __attribute__ ((unused)), ...@@ -163,6 +162,11 @@ void tprint(FILE *trace_file __attribute__ ((unused)),
#define ALERT_USER() DBUG_ASSERT(0) #define ALERT_USER() DBUG_ASSERT(0)
static void print_preamble()
{
ma_message_no_user(ME_JUST_INFO, "starting recovery");
}
/** /**
@brief Recovers from the last checkpoint. @brief Recovers from the last checkpoint.
...@@ -304,7 +308,10 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, ...@@ -304,7 +308,10 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
if (recovery_message_printed == REC_MSG_REDO) if (recovery_message_printed == REC_MSG_REDO)
{ {
float phase_took= (now - old_now)/10000000.0; float phase_took= (now - old_now)/10000000.0;
/** @todo RECOVERY BUG all prints to stderr should go to error log */ /*
Detailed progress info goes to stderr, because ma_message_no_user()
cannot put several messages on one line.
*/
fprintf(stderr, " (%.1f seconds); ", phase_took); fprintf(stderr, " (%.1f seconds); ", phase_took);
} }
...@@ -346,7 +353,6 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, ...@@ -346,7 +353,6 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
if (recovery_message_printed == REC_MSG_UNDO) if (recovery_message_printed == REC_MSG_UNDO)
{ {
float phase_took= (now - old_now)/10000000.0; float phase_took= (now - old_now)/10000000.0;
/** @todo RECOVERY BUG all prints to stderr should go to error log */
fprintf(stderr, " (%.1f seconds); ", phase_took); fprintf(stderr, " (%.1f seconds); ", phase_took);
} }
...@@ -362,7 +368,6 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, ...@@ -362,7 +368,6 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
if (recovery_message_printed == REC_MSG_FLUSH) if (recovery_message_printed == REC_MSG_FLUSH)
{ {
float phase_took= (now - old_now)/10000000.0; float phase_took= (now - old_now)/10000000.0;
/** @todo RECOVERY BUG all prints to stderr should go to error log */
fprintf(stderr, " (%.1f seconds); ", phase_took); fprintf(stderr, " (%.1f seconds); ", phase_took);
} }
...@@ -393,8 +398,11 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, ...@@ -393,8 +398,11 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
*warnings_count= warnings; *warnings_count= warnings;
if (recovery_message_printed != REC_MSG_NONE) if (recovery_message_printed != REC_MSG_NONE)
{ {
/** @todo RECOVERY BUG all prints to stderr should go to error log */ fprintf(stderr, "\n");
fprintf(stderr, "%s.\n", error ? " failed" : "done"); if (error)
ma_message_no_user(0, "recovery failed");
else
ma_message_no_user(ME_JUST_INFO, "recovery done");
} }
/* we don't cleanly close tables if we hit some error (may corrupt them) */ /* we don't cleanly close tables if we hit some error (may corrupt them) */
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -2180,10 +2188,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply) ...@@ -2180,10 +2188,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply)
translog_destroy_scanner(&scanner); translog_destroy_scanner(&scanner);
translog_free_record_header(&rec); translog_free_record_header(&rec);
if (recovery_message_printed == REC_MSG_REDO) if (recovery_message_printed == REC_MSG_REDO)
{
/** @todo RECOVERY BUG all prints to stderr should go to error log */
fprintf(stderr, " 100%%"); fprintf(stderr, " 100%%");
}
return 0; return 0;
err: err:
...@@ -2286,8 +2291,7 @@ static int run_undo_phase(uint unfinished) ...@@ -2286,8 +2291,7 @@ static int run_undo_phase(uint unfinished)
if (tracef != stdout) if (tracef != stdout)
{ {
if (recovery_message_printed == REC_MSG_NONE) if (recovery_message_printed == REC_MSG_NONE)
fprintf(stderr, preamble); print_preamble();
/** @todo RECOVERY BUG all prints to stderr should go to error log */
fprintf(stderr, "transactions to roll back:"); fprintf(stderr, "transactions to roll back:");
recovery_message_printed= REC_MSG_UNDO; recovery_message_printed= REC_MSG_UNDO;
} }
...@@ -2659,10 +2663,9 @@ static int close_all_tables(void) ...@@ -2659,10 +2663,9 @@ static int close_all_tables(void)
if (tracef != stdout) if (tracef != stdout)
{ {
if (recovery_message_printed == REC_MSG_NONE) if (recovery_message_printed == REC_MSG_NONE)
fprintf(stderr, preamble); print_preamble();
for (count= 0, list_element= maria_open_list ; for (count= 0, list_element= maria_open_list ;
list_element ; count++, (list_element= list_element->next)) list_element ; count++, (list_element= list_element->next))
/** @todo RECOVERY BUG all prints to stderr should go to error log */
fprintf(stderr, "tables to flush:"); fprintf(stderr, "tables to flush:");
recovery_message_printed= REC_MSG_FLUSH; recovery_message_printed= REC_MSG_FLUSH;
} }
...@@ -2772,8 +2775,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr) ...@@ -2772,8 +2775,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
return; return;
if (recovery_message_printed == REC_MSG_NONE) if (recovery_message_printed == REC_MSG_NONE)
{ {
/** @todo RECOVERY BUG all prints to stderr should go to error log */ print_preamble();
fprintf(stderr, preamble);
fprintf(stderr, "recovered pages: 0%%"); fprintf(stderr, "recovered pages: 0%%");
recovery_message_printed= REC_MSG_REDO; recovery_message_printed= REC_MSG_REDO;
} }
......
...@@ -39,7 +39,6 @@ static char **default_argv; ...@@ -39,7 +39,6 @@ static char **default_argv;
static const char *load_default_groups[]= { "maria_chk", 0 }; static const char *load_default_groups[]= { "maria_chk", 0 };
static const char *set_collation_name, *opt_tmpdir; static const char *set_collation_name, *opt_tmpdir;
static CHARSET_INFO *set_collation; static CHARSET_INFO *set_collation;
static const char *my_progname_short;
static int stopwords_inited= 0; static int stopwords_inited= 0;
static MY_TMPDIR maria_chk_tmpdir; static MY_TMPDIR maria_chk_tmpdir;
...@@ -93,7 +92,6 @@ int main(int argc, char **argv) ...@@ -93,7 +92,6 @@ int main(int argc, char **argv)
{ {
int error; int error;
MY_INIT(argv[0]); MY_INIT(argv[0]);
my_progname_short= my_progname+dirname_length(my_progname);
maria_chk_init(&check_param); maria_chk_init(&check_param);
check_param.opt_lock_memory= 1; /* Lock memory if possible */ check_param.opt_lock_memory= 1; /* Lock memory if possible */
......
...@@ -32,7 +32,6 @@ const char *default_dbug_option= "d:t:i:o,/tmp/maria_read_log.trace"; ...@@ -32,7 +32,6 @@ const char *default_dbug_option= "d:t:i:o,/tmp/maria_read_log.trace";
static my_bool opt_only_display, opt_apply, opt_apply_undo, opt_silent, static my_bool opt_only_display, opt_apply, opt_apply_undo, opt_silent,
opt_check; opt_check;
static ulong opt_page_buffer_size; static ulong opt_page_buffer_size;
static const char *my_progname_short;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
...@@ -40,7 +39,6 @@ int main(int argc, char **argv) ...@@ -40,7 +39,6 @@ int main(int argc, char **argv)
char **default_argv; char **default_argv;
uint warnings_count; uint warnings_count;
MY_INIT(argv[0]); MY_INIT(argv[0]);
my_progname_short= my_progname+dirname_length(my_progname);
load_defaults("my", load_default_groups, &argc, &argv); load_defaults("my", load_default_groups, &argc, &argv);
default_argv= argv; default_argv= argv;
......
...@@ -40,7 +40,6 @@ static const char *set_collation_name, *opt_tmpdir; ...@@ -40,7 +40,6 @@ static const char *set_collation_name, *opt_tmpdir;
static CHARSET_INFO *set_collation; static CHARSET_INFO *set_collation;
static long opt_myisam_block_size; static long opt_myisam_block_size;
static long opt_key_cache_block_size; static long opt_key_cache_block_size;
static const char *my_progname_short;
static int stopwords_inited= 0; static int stopwords_inited= 0;
static MY_TMPDIR myisamchk_tmpdir; static MY_TMPDIR myisamchk_tmpdir;
...@@ -85,7 +84,6 @@ int main(int argc, char **argv) ...@@ -85,7 +84,6 @@ int main(int argc, char **argv)
{ {
int error; int error;
MY_INIT(argv[0]); MY_INIT(argv[0]);
my_progname_short= my_progname+dirname_length(my_progname);
myisamchk_init(&check_param); myisamchk_init(&check_param);
check_param.opt_lock_memory=1; /* Lock memory if possible */ check_param.opt_lock_memory=1; /* Lock memory if possible */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment