mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 10:14:19 +01:00
Merge desktop.sanja.is.com.ua:/home/bell/mysql/bk/mysql-maria
into desktop.sanja.is.com.ua:/home/bell/mysql/bk/work-maria-logpurge storage/maria/ma_checkpoint.c: Auto merged storage/maria/ma_loghandler.c: Auto merged storage/maria/ma_loghandler.h: Auto merged storage/maria/ma_recovery.c: Auto merged
This commit is contained in:
commit
b5b0d94dc0
9 changed files with 508 additions and 25 deletions
82
mysql-test/r/maria-purge.result
Normal file
82
mysql-test/r/maria-purge.result
Normal file
|
@ -0,0 +1,82 @@
|
|||
set global storage_engine=maria;
|
||||
set session storage_engine=maria;
|
||||
drop table if exists t1,t2;
|
||||
SET SQL_WARNINGS=1;
|
||||
CREATE TABLE t1 (
|
||||
STRING_DATA char(255) default NULL
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
STRING_DATA char(255) default NULL
|
||||
);
|
||||
INSERT INTO t1 VALUES ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
|
||||
INSERT INTO t1 VALUES ('DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD');
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
set global maria_checkpoint_interval=2;
|
||||
SHOW ENGINE maria logs;
|
||||
Type Name Status
|
||||
maria master-data/maria_log.00000001 in use
|
||||
set global maria_log_file_size=16777216;
|
||||
select @@global.maria_log_file_size;
|
||||
@@global.maria_log_file_size
|
||||
16777216
|
||||
SHOW ENGINE maria logs;
|
||||
Type Name Status
|
||||
maria master-data/maria_log.00000002 in use
|
||||
set global maria_log_file_size=8388608;
|
||||
select @@global.maria_log_file_size;
|
||||
@@global.maria_log_file_size
|
||||
8388608
|
||||
set global maria_log_purge_type=at_flush;
|
||||
insert into t1 select * from t2;
|
||||
SHOW ENGINE maria logs;
|
||||
Type Name Status
|
||||
maria master-data/maria_log.00000002 free
|
||||
maria master-data/maria_log.00000003 free
|
||||
maria master-data/maria_log.00000004 free
|
||||
maria master-data/maria_log.00000005 in use
|
||||
flush logs;
|
||||
SHOW ENGINE maria logs;
|
||||
Type Name Status
|
||||
maria master-data/maria_log.00000005 in use
|
||||
set global maria_log_file_size=16777216;
|
||||
set global maria_log_purge_type=external;
|
||||
insert into t1 select * from t2;
|
||||
SHOW ENGINE maria logs;
|
||||
Type Name Status
|
||||
maria master-data/maria_log.00000005 free
|
||||
maria master-data/maria_log.00000006 in use
|
||||
flush logs;
|
||||
SHOW ENGINE maria logs;
|
||||
Type Name Status
|
||||
maria master-data/maria_log.00000005 free
|
||||
maria master-data/maria_log.00000006 in use
|
||||
set global maria_log_purge_type=immediate;
|
||||
insert into t1 select * from t2;
|
||||
SHOW ENGINE maria logs;
|
||||
Type Name Status
|
||||
maria master-data/maria_log.00000007 in use
|
||||
maria master-data/maria_log.00000008 in use
|
||||
drop table t1, t2;
|
|
@ -2048,6 +2048,8 @@ show variables like 'maria%';
|
|||
Variable_name Value
|
||||
maria_block_size 8192
|
||||
maria_checkpoint_interval 30
|
||||
maria_log_file_size 1073741824
|
||||
maria_log_purge_type immediate
|
||||
maria_max_sort_file_size 9223372036853727232
|
||||
maria_pagecache_age_threshold 300
|
||||
maria_pagecache_buffer_size 8384512
|
||||
|
|
95
mysql-test/t/maria-purge.test
Normal file
95
mysql-test/t/maria-purge.test
Normal file
|
@ -0,0 +1,95 @@
|
|||
-- source include/have_maria.inc
|
||||
-- source include/big_test.inc
|
||||
let $default=`select @@global.storage_engine`;
|
||||
set global storage_engine=maria;
|
||||
set session storage_engine=maria;
|
||||
let $def_logsize=`select @@global.maria_log_file_size`;
|
||||
let $def_checkinterval=`select @@global.maria_checkpoint_interval`;
|
||||
|
||||
# Initialise
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2;
|
||||
--enable_warnings
|
||||
SET SQL_WARNINGS=1;
|
||||
|
||||
CREATE TABLE t1 (
|
||||
STRING_DATA char(255) default NULL
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
STRING_DATA char(255) default NULL
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
|
||||
INSERT INTO t1 VALUES ('DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD');
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
|
||||
|
||||
set global maria_checkpoint_interval=2;
|
||||
--replace_regex /Size +[0-9]+ ; .+master-data/master-data/
|
||||
SHOW ENGINE maria logs;
|
||||
set global maria_log_file_size=16777216;
|
||||
select @@global.maria_log_file_size;
|
||||
sleep 7;
|
||||
--replace_regex /Size +[0-9]+ ; .+master-data/master-data/
|
||||
SHOW ENGINE maria logs;
|
||||
set global maria_log_file_size=8388608;
|
||||
select @@global.maria_log_file_size;
|
||||
|
||||
set global maria_log_purge_type=at_flush;
|
||||
insert into t1 select * from t2;
|
||||
sleep 7;
|
||||
--replace_regex /Size +[0-9]+ ; .+master-data/master-data/
|
||||
SHOW ENGINE maria logs;
|
||||
flush logs;
|
||||
--replace_regex /Size +[0-9]+ ; .+master-data/master-data/
|
||||
SHOW ENGINE maria logs;
|
||||
|
||||
set global maria_log_file_size=16777216;
|
||||
set global maria_log_purge_type=external;
|
||||
insert into t1 select * from t2;
|
||||
sleep 7;
|
||||
--replace_regex /Size +[0-9]+ ; .+master-data/master-data/
|
||||
SHOW ENGINE maria logs;
|
||||
flush logs;
|
||||
--replace_regex /Size +[0-9]+ ; .+master-data/master-data/
|
||||
SHOW ENGINE maria logs;
|
||||
|
||||
set global maria_log_purge_type=immediate;
|
||||
insert into t1 select * from t2;
|
||||
sleep 7;
|
||||
--replace_regex /Size +[0-9]+ ; .+master-data/master-data/
|
||||
SHOW ENGINE maria logs;
|
||||
|
||||
drop table t1, t2;
|
||||
|
||||
--disable_result_log
|
||||
--disable_query_log
|
||||
set global maria_log_purge_type=immediate;
|
||||
eval set global storage_engine=$default;
|
||||
eval set global maria_log_file_size=$def_logsize;
|
||||
eval set global maria_checkpoint_interval=$def_checkinterval;
|
||||
--enable_result_log
|
||||
--enable_query_log
|
|
@ -22,6 +22,7 @@
|
|||
#include "mysql_priv.h"
|
||||
#include <mysql/plugin.h>
|
||||
#include <m_ctype.h>
|
||||
#include <my_dir.h>
|
||||
#include <myisampack.h>
|
||||
#include <my_bit.h>
|
||||
#include "ha_maria.h"
|
||||
|
@ -81,6 +82,16 @@ TYPELIB maria_stats_method_typelib=
|
|||
maria_stats_method_names, NULL
|
||||
};
|
||||
|
||||
/* transactions log purge mode */
|
||||
const char *maria_translog_purge_type_names[]=
|
||||
{
|
||||
"immediate", "external", "at_flush", NullS
|
||||
};
|
||||
TYPELIB maria_translog_purge_type_typelib=
|
||||
{
|
||||
array_elements(maria_translog_purge_type_names) - 1, "",
|
||||
maria_translog_purge_type_names, NULL
|
||||
};
|
||||
const char *maria_sync_log_dir_names[]=
|
||||
{
|
||||
"NEVER", "NEWFILE", "ALWAYS", NullS
|
||||
|
@ -97,6 +108,9 @@ static ulong checkpoint_interval;
|
|||
static void update_checkpoint_interval(MYSQL_THD thd,
|
||||
struct st_mysql_sys_var *var,
|
||||
void *var_ptr, void *save);
|
||||
static void update_log_file_size(MYSQL_THD thd,
|
||||
struct st_mysql_sys_var *var,
|
||||
void *var_ptr, void *save);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(block_size, maria_block_size,
|
||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
||||
|
@ -110,6 +124,20 @@ 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_ULONG(log_file_size, log_file_size,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Limit for transaction log size",
|
||||
NULL, update_log_file_size, TRANSLOG_FILE_SIZE,
|
||||
TRANSLOG_MIN_FILE_SIZE, 0xffffffffL, TRANSLOG_PAGE_SIZE);
|
||||
|
||||
static MYSQL_SYSVAR_ENUM(log_purge_type, log_purge_type,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Specifies how maria transactional log will be purged. "
|
||||
"Possible values of name are \"immediate\", \"external\" "
|
||||
"and \"at_flush\"",
|
||||
NULL, NULL, TRANSLOG_PURGE_IMMIDIATE,
|
||||
&maria_translog_purge_type_typelib);
|
||||
|
||||
static MYSQL_SYSVAR_ULONGLONG(max_sort_file_size,
|
||||
maria_max_temp_length, PLUGIN_VAR_RQCMDARG,
|
||||
"Don't use the fast sort index method to created index if the "
|
||||
|
@ -2415,6 +2443,109 @@ static int maria_rollback(handlerton *hton __attribute__ ((unused)),
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@brief flush log handler
|
||||
|
||||
@param hton maria handlerton (unused)
|
||||
|
||||
@retval FALSE OK
|
||||
@retval TRUE Error
|
||||
*/
|
||||
|
||||
bool maria_flush_logs(handlerton *hton)
|
||||
{
|
||||
return test(translog_purge_at_flush());
|
||||
}
|
||||
|
||||
|
||||
#define SHOW_MSG_LEN (FN_REFLEN + 20)
|
||||
/**
|
||||
@brief show status handler
|
||||
|
||||
@param hton maria handlerton
|
||||
@param thd thread handler
|
||||
@param print print function
|
||||
@param stat type of status
|
||||
*/
|
||||
|
||||
bool maria_show_status(handlerton *hton,
|
||||
THD *thd,
|
||||
stat_print_fn *print,
|
||||
enum ha_stat_type stat)
|
||||
{
|
||||
char engine_name[]= "maria";
|
||||
switch (stat)
|
||||
{
|
||||
case HA_ENGINE_LOGS:
|
||||
{
|
||||
TRANSLOG_ADDRESS horizon= translog_get_horizon();
|
||||
uint32 last_file= LSN_FILE_NO(horizon);
|
||||
uint32 first_needed= translog_get_first_needed_file();
|
||||
uint32 first_file= translog_get_first_file(horizon);
|
||||
uint32 i;
|
||||
const char unknown[]= "unknown";
|
||||
const char needed[]= "in use";
|
||||
const char unneeded[]= "free";
|
||||
char path[FN_REFLEN];
|
||||
|
||||
if (first_file == 0)
|
||||
{
|
||||
const char error[]= "error";
|
||||
print(thd, engine_name, sizeof(engine_name),
|
||||
STRING_WITH_LEN(""), error, sizeof(error));
|
||||
break;
|
||||
}
|
||||
|
||||
for (i= first_file; i <= last_file; i++)
|
||||
{
|
||||
char *file;
|
||||
const char *status;
|
||||
uint length, status_len;
|
||||
MY_STAT stat_buff, *stat;
|
||||
const char error[]= "can't stat";
|
||||
char object[SHOW_MSG_LEN];
|
||||
file= translog_filename_by_fileno(i, path);
|
||||
if (!(stat= my_stat(file, &stat_buff, MYF(MY_WME))))
|
||||
{
|
||||
status= error;
|
||||
status_len= sizeof(error);
|
||||
length= snprintf(object, SHOW_MSG_LEN, "Size unknown ; %s", file);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (first_needed == 0)
|
||||
{
|
||||
status= unknown;
|
||||
status_len= sizeof(unknown);
|
||||
}
|
||||
else if (i < first_needed)
|
||||
{
|
||||
status= unneeded;
|
||||
status_len= sizeof(unneeded);
|
||||
}
|
||||
else
|
||||
{
|
||||
status= needed;
|
||||
status_len= sizeof(needed);
|
||||
}
|
||||
length= snprintf(object, SHOW_MSG_LEN, "Size %12lu ; %s",
|
||||
(ulong) stat->st_size, file);
|
||||
}
|
||||
|
||||
print(thd, engine_name, sizeof(engine_name),
|
||||
object, length, status, status_len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HA_ENGINE_STATUS:
|
||||
case HA_ENGINE_MUTEX:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ha_maria_init(void *p)
|
||||
{
|
||||
int res;
|
||||
|
@ -2425,6 +2556,8 @@ static int ha_maria_init(void *p)
|
|||
maria_hton->panic= maria_hton_panic;
|
||||
maria_hton->commit= maria_commit;
|
||||
maria_hton->rollback= maria_rollback;
|
||||
maria_hton->flush_logs= maria_flush_logs;
|
||||
maria_hton->show_status= maria_show_status;
|
||||
/* TODO: decide if we support Maria being used for log tables */
|
||||
maria_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
|
||||
bzero(maria_log_pagecache, sizeof(*maria_log_pagecache));
|
||||
|
@ -2437,7 +2570,7 @@ static int ha_maria_init(void *p)
|
|||
!init_pagecache(maria_log_pagecache,
|
||||
TRANSLOG_PAGECACHE_SIZE, 0, 0,
|
||||
TRANSLOG_PAGE_SIZE, 0) ||
|
||||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
|
||||
translog_init(maria_data_root, log_file_size,
|
||||
MYSQL_VERSION_ID, server_id, maria_log_pagecache,
|
||||
TRANSLOG_DEFAULT_FLAGS) ||
|
||||
maria_recover() ||
|
||||
|
@ -2525,6 +2658,8 @@ 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(log_file_size),
|
||||
MYSQL_SYSVAR(log_purge_type),
|
||||
MYSQL_SYSVAR(max_sort_file_size),
|
||||
MYSQL_SYSVAR(pagecache_age_threshold),
|
||||
MYSQL_SYSVAR(pagecache_buffer_size),
|
||||
|
@ -2549,6 +2684,19 @@ static void update_checkpoint_interval(MYSQL_THD thd,
|
|||
ma_checkpoint_init(*(ulong *)var_ptr= (ulong)(*(long *)save));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Updates the transaction log file limit.
|
||||
*/
|
||||
|
||||
static void update_log_file_size(MYSQL_THD thd,
|
||||
struct st_mysql_sys_var *var,
|
||||
void *var_ptr, void *save)
|
||||
{
|
||||
uint32 size= (uint32)((ulong)(*(long *)save));
|
||||
translog_set_file_size(size);
|
||||
*(ulong *)var_ptr= size;
|
||||
}
|
||||
|
||||
static SHOW_VAR status_variables[]= {
|
||||
{"Maria_pagecache_blocks_not_flushed", (char*) &maria_pagecache_var.global_blocks_changed, SHOW_LONG_NOFLUSH},
|
||||
{"Maria_pagecache_blocks_unused", (char*) &maria_pagecache_var.blocks_unused, SHOW_LONG_NOFLUSH},
|
||||
|
|
|
@ -278,10 +278,8 @@ static int really_execute_checkpoint(void)
|
|||
be robust against that: remember a few previous checkpoints in the
|
||||
control file, and not purge logs immediately... Think about it.
|
||||
*/
|
||||
#if 0 /* purging/keeping will be an option */
|
||||
if (translog_purge(log_low_water_mark))
|
||||
ma_message_no_user(0, "log purging failed");
|
||||
#endif
|
||||
|
||||
goto end;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
/* number of opened log files in the pagecache (should be at least 2) */
|
||||
#define OPENED_FILES_NUM 3
|
||||
|
||||
/* records buffer size (should be LOG_PAGE_SIZE * n) */
|
||||
/* records buffer size (should be TRANSLOG_PAGE_SIZE * n) */
|
||||
#define TRANSLOG_WRITE_BUFFER (1024*1024)
|
||||
/* min chunk length */
|
||||
#define TRANSLOG_MIN_CHUNK 3
|
||||
|
@ -214,6 +214,11 @@ struct st_translog_descriptor
|
|||
pthread_mutex_t unfinished_files_lock;
|
||||
DYNAMIC_ARRAY unfinished_files;
|
||||
|
||||
/*
|
||||
minimum number of still need file calculeted during last
|
||||
translog_purge call
|
||||
*/
|
||||
uint32 min_need_file;
|
||||
/* Purger data: minimum file in the log (or 0 if unknown) */
|
||||
uint32 min_file_number;
|
||||
/* Protect purger from many calls and it's data */
|
||||
|
@ -224,6 +229,8 @@ struct st_translog_descriptor
|
|||
|
||||
static struct st_translog_descriptor log_descriptor;
|
||||
|
||||
ulong log_purge_type= TRANSLOG_PURGE_IMMIDIATE;
|
||||
ulong log_file_size= TRANSLOG_FILE_SIZE;
|
||||
ulong sync_log_dir= TRANSLOG_SYNC_DIR_NEWFILE;
|
||||
|
||||
/* Marker for end of log */
|
||||
|
@ -661,18 +668,16 @@ static void translog_check_cursor(struct st_buffer_cursor *cursor)
|
|||
#endif
|
||||
|
||||
/*
|
||||
Get file name of the log by log number
|
||||
@brief Get file name of the log by log number
|
||||
|
||||
SYNOPSIS
|
||||
translog_filename_by_fileno()
|
||||
file_no Number of the log we want to open
|
||||
path Pointer to buffer where file name will be
|
||||
@param file_no Number of the log we want to open
|
||||
@param path Pointer to buffer where file name will be
|
||||
stored (must be FN_REFLEN bytes at least)
|
||||
RETURN
|
||||
pointer to path
|
||||
|
||||
@return pointer to path
|
||||
*/
|
||||
|
||||
static char *translog_filename_by_fileno(uint32 file_no, char *path)
|
||||
char *translog_filename_by_fileno(uint32 file_no, char *path)
|
||||
{
|
||||
char buff[11], *end;
|
||||
uint length;
|
||||
|
@ -682,7 +687,7 @@ static char *translog_filename_by_fileno(uint32 file_no, char *path)
|
|||
/* log_descriptor.directory is already formated */
|
||||
end= strxmov(path, log_descriptor.directory, "maria_log.0000000", NullS);
|
||||
length= (uint) (int10_to_str(file_no, buff, 10) - buff);
|
||||
strmov(end-length+1, buff);
|
||||
strmov(end - length +1, buff);
|
||||
|
||||
DBUG_PRINT("info", ("Path: '%s' path: 0x%lx", path, (ulong) path));
|
||||
DBUG_RETURN(path);
|
||||
|
@ -2822,6 +2827,9 @@ my_bool translog_init(const char *directory,
|
|||
my_bool version_changed= 0;
|
||||
DBUG_ENTER("translog_init");
|
||||
DBUG_ASSERT(translog_inited == 0);
|
||||
compile_time_assert(TRANSLOG_MIN_FILE_SIZE >
|
||||
TRANSLOG_WRITE_BUFFER * TRANSLOG_BUFFERS_NO);
|
||||
compile_time_assert(TRANSLOG_WRITE_BUFFER % TRANSLOG_PAGE_SIZE == 0);
|
||||
|
||||
loghandler_init(); /* Safe to do many times */
|
||||
|
||||
|
@ -2839,6 +2847,7 @@ my_bool translog_init(const char *directory,
|
|||
sizeof(struct st_file_counter),
|
||||
10, 10))
|
||||
DBUG_RETURN(1);
|
||||
log_descriptor.min_need_file= 0;
|
||||
log_descriptor.min_file_number= 0;
|
||||
log_descriptor.last_lsn_checked= LSN_IMPOSSIBLE;
|
||||
|
||||
|
@ -2854,9 +2863,12 @@ my_bool translog_init(const char *directory,
|
|||
}
|
||||
|
||||
log_descriptor.in_buffers_only= LSN_IMPOSSIBLE;
|
||||
DBUG_ASSERT(log_file_max_size % TRANSLOG_PAGE_SIZE == 0 &&
|
||||
log_file_max_size >= TRANSLOG_MIN_FILE_SIZE &&
|
||||
log_file_max_size <= 0xffffffffL);
|
||||
/* max size of one log size (for new logs creation) */
|
||||
log_descriptor.log_file_max_size=
|
||||
log_file_max_size - (log_file_max_size % TRANSLOG_PAGE_SIZE);
|
||||
log_file_size= log_descriptor.log_file_max_size=
|
||||
log_file_max_size;
|
||||
/* server version */
|
||||
log_descriptor.server_version= server_version;
|
||||
/* server ID */
|
||||
|
@ -6988,7 +7000,7 @@ LSN translog_first_lsn_in_log()
|
|||
|
||||
|
||||
/**
|
||||
@brief returns theoretical first LSN if first log is present
|
||||
@brief Returns theoretical first LSN if first log is present
|
||||
|
||||
@retval LSN_ERROR Error
|
||||
@retval LSN_IMPOSSIBLE no log
|
||||
|
@ -7024,7 +7036,7 @@ LSN translog_first_theoretical_lsn()
|
|||
|
||||
|
||||
/**
|
||||
@brief Check given low water mark and purge files if it is need
|
||||
@brief Checks given low water mark and purge files if it is need
|
||||
|
||||
@param low the last (minimum) address which is need
|
||||
|
||||
|
@ -7047,7 +7059,6 @@ my_bool translog_purge(TRANSLOG_ADDRESS low)
|
|||
uint32 i;
|
||||
uint32 min_file= translog_first_file(horizon, 1);
|
||||
DBUG_ASSERT(min_file != 0); /* log is already started */
|
||||
|
||||
for(i= min_file; i < last_need_file && rc == 0; i++)
|
||||
{
|
||||
LSN lsn= translog_get_file_max_lsn_stored(i);
|
||||
|
@ -7061,14 +7072,144 @@ my_bool translog_purge(TRANSLOG_ADDRESS low)
|
|||
if (cmp_translog_addr(lsn, low) >= 0)
|
||||
break;
|
||||
DBUG_PRINT("info", ("purge file %lu", (ulong) i));
|
||||
if (log_purge_type == TRANSLOG_PURGE_IMMIDIATE)
|
||||
{
|
||||
char path[FN_REFLEN], *file_name;
|
||||
file_name= translog_filename_by_fileno(i, path);
|
||||
rc= test(my_delete(file_name, MYF(MY_WME)));
|
||||
}
|
||||
}
|
||||
if (unlikely(rc == 1))
|
||||
log_descriptor.min_need_file= 0; /* impossible value */
|
||||
else
|
||||
log_descriptor.min_need_file= i;
|
||||
}
|
||||
|
||||
translog_mutex_unlock(&log_descriptor.purger_lock);
|
||||
DBUG_RETURN(rc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Purges files by stored min need file in case of
|
||||
"ondemend" purge type
|
||||
|
||||
@note This function do real work only if it is "ondemend" purge type
|
||||
and translog_purge() was called at least once and last time without
|
||||
errors
|
||||
|
||||
@retval 0 OK
|
||||
@retval 1 Error
|
||||
*/
|
||||
|
||||
my_bool translog_purge_at_flush()
|
||||
{
|
||||
uint32 i, min_file;
|
||||
int rc= 0;
|
||||
DBUG_ENTER("translog_purge_at_flush");
|
||||
DBUG_ASSERT(translog_inited == 1);
|
||||
|
||||
if (log_purge_type != TRANSLOG_PURGE_ONDEMAND)
|
||||
{
|
||||
DBUG_PRINT("info", ("It is not \"at_flush\" => exit"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
translog_mutex_lock(&log_descriptor.purger_lock);
|
||||
|
||||
if (unlikely(log_descriptor.min_need_file == 0))
|
||||
{
|
||||
DBUG_PRINT("info", ("No info about min need file => exit"));
|
||||
translog_mutex_unlock(&log_descriptor.purger_lock);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
min_file= translog_first_file(translog_get_horizon(), 1);
|
||||
DBUG_ASSERT(min_file != 0); /* log is already started */
|
||||
for(i= min_file; i < log_descriptor.min_need_file && rc == 0; i++)
|
||||
{
|
||||
char path[FN_REFLEN], *file_name;
|
||||
DBUG_PRINT("info", ("purge file %lu\n", (ulong) i));
|
||||
file_name= translog_filename_by_fileno(i, path);
|
||||
rc= test(my_delete(file_name, MYF(MY_WME)));
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&log_descriptor.purger_lock);
|
||||
DBUG_RETURN(rc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Gets min file number
|
||||
|
||||
@param horizon the end of the log
|
||||
|
||||
@retval minimum file number
|
||||
@retval 0 no files found
|
||||
*/
|
||||
|
||||
uint32 translog_get_first_file(TRANSLOG_ADDRESS horizon)
|
||||
{
|
||||
return translog_first_file(horizon, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Gets min file number which is needed
|
||||
|
||||
@retval minimum file number
|
||||
@retval 0 unknown
|
||||
*/
|
||||
|
||||
uint32 translog_get_first_needed_file()
|
||||
{
|
||||
uint32 file_no;
|
||||
translog_mutex_lock(&log_descriptor.purger_lock);
|
||||
file_no= log_descriptor.min_need_file;
|
||||
translog_mutex_unlock(&log_descriptor.purger_lock);
|
||||
return file_no;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Gets transaction log file size
|
||||
|
||||
@return transaction log file size
|
||||
*/
|
||||
|
||||
uint32 translog_get_file_size()
|
||||
{
|
||||
uint32 res;
|
||||
translog_lock();
|
||||
res= log_descriptor.log_file_max_size;
|
||||
translog_unlock();
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Sets transaction log file size
|
||||
|
||||
@return Returns actually set transaction log size
|
||||
*/
|
||||
|
||||
void translog_set_file_size(uint32 size)
|
||||
{
|
||||
DBUG_ENTER("translog_set_file_size");
|
||||
translog_lock();
|
||||
DBUG_PRINT("enter", ("Size: %lu", (ulong) size));
|
||||
DBUG_ASSERT(size % TRANSLOG_PAGE_SIZE == 0 &&
|
||||
size >= TRANSLOG_MIN_FILE_SIZE &&
|
||||
size <= 0xffffffffL);
|
||||
log_descriptor.log_file_max_size= size;
|
||||
/* if current file longer then finish it*/
|
||||
if (LSN_OFFSET(log_descriptor.horizon) >= log_descriptor.log_file_max_size)
|
||||
{
|
||||
struct st_translog_buffer *old_buffer= log_descriptor.bc.buffer;
|
||||
translog_buffer_next(&log_descriptor.horizon, &log_descriptor.bc, 1);
|
||||
translog_buffer_unlock(old_buffer);
|
||||
}
|
||||
translog_unlock();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
#define _ma_loghandler_h
|
||||
|
||||
/* transaction log default cache size (TODO: make it global variable) */
|
||||
#define TRANSLOG_PAGECACHE_SIZE 1024*1024*2
|
||||
/* transaction log default file size (TODO: make it global variable) */
|
||||
#define TRANSLOG_FILE_SIZE 1024*1024*1024
|
||||
#define TRANSLOG_PAGECACHE_SIZE (1024*1024*2)
|
||||
/* transaction log default file size */
|
||||
#define TRANSLOG_FILE_SIZE (1024*1024*1024)
|
||||
/* minimum possible transaction log size */
|
||||
#define TRANSLOG_MIN_FILE_SIZE (1024*1024*8)
|
||||
/* transaction log default flags (TODO: make it global variable) */
|
||||
#define TRANSLOG_DEFAULT_FLAGS 0
|
||||
|
||||
|
@ -308,6 +310,11 @@ extern my_bool translog_inited;
|
|||
extern LSN translog_first_lsn_in_log();
|
||||
extern LSN translog_first_theoretical_lsn();
|
||||
extern LSN translog_next_LSN(TRANSLOG_ADDRESS addr, TRANSLOG_ADDRESS horizon);
|
||||
extern my_bool translog_purge_at_flush();
|
||||
extern uint32 translog_get_first_file(TRANSLOG_ADDRESS horizon);
|
||||
extern uint32 translog_get_first_needed_file();
|
||||
extern char *translog_filename_by_fileno(uint32 file_no, char *path);
|
||||
extern void translog_set_file_size(uint32 size);
|
||||
|
||||
/* record parts descriptor */
|
||||
struct st_translog_parts
|
||||
|
@ -389,6 +396,15 @@ typedef struct st_log_record_type_descriptor
|
|||
|
||||
extern LOG_DESC log_record_type_descriptor[LOGREC_NUMBER_OF_TYPES];
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TRANSLOG_PURGE_IMMIDIATE,
|
||||
TRANSLOG_PURGE_EXTERNAL,
|
||||
TRANSLOG_PURGE_ONDEMAND
|
||||
} enum_maria_translog_purge_type;
|
||||
extern ulong log_purge_type;
|
||||
extern ulong log_file_size;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TRANSLOG_SYNC_DIR_NEVER,
|
||||
|
|
|
@ -2890,8 +2890,9 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
|
|||
cur_logno= LSN_FILE_NO(addr);
|
||||
cur_offset= LSN_OFFSET(addr);
|
||||
local_remainder= (cur_logno == end_logno) ? (end_offset - cur_offset) :
|
||||
(TRANSLOG_FILE_SIZE - cur_offset +
|
||||
max(end_logno - cur_logno - 1, 0) * TRANSLOG_FILE_SIZE + end_offset);
|
||||
(((longlong)log_file_size) - cur_offset +
|
||||
max(end_logno - cur_logno - 1, 0) * ((longlong)log_file_size) +
|
||||
end_offset);
|
||||
if (initial_remainder == (ulonglong)(-1))
|
||||
initial_remainder= local_remainder;
|
||||
percentage_done= ((initial_remainder - local_remainder) * ULL(100) /
|
||||
|
|
|
@ -18,12 +18,12 @@ static TRN *trn= &dummy_transaction_object;
|
|||
|
||||
#ifdef LONG_LOG_TEST
|
||||
#define LOG_FLAGS 0
|
||||
#define LOG_FILE_SIZE (1024L*1024L)
|
||||
#define LOG_FILE_SIZE (1024L*1024L*8)
|
||||
#define ITERATIONS (1600*4)
|
||||
|
||||
#else
|
||||
#define LOG_FLAGS (TRANSLOG_SECTOR_PROTECTION | TRANSLOG_PAGE_CRC)
|
||||
#define LOG_FILE_SIZE (1024L*1024L*3L)
|
||||
#define LOG_FILE_SIZE (1024L*1024L*8L)
|
||||
#define ITERATIONS 1600
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue