diff options
author | Monty <monty@mariadb.org> | 2018-11-16 16:50:12 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2018-12-09 22:12:25 +0200 |
commit | 2aff2f2f34a7843c402512219c76bf8dd81eeec8 (patch) | |
tree | 10046189f4e8bc596f61ea9990e648fb7a8d46f6 /storage/maria | |
parent | 1077f320e42323528c02757ba5dd17275cf47617 (diff) | |
download | mariadb-git-2aff2f2f34a7843c402512219c76bf8dd81eeec8.tar.gz |
Added --print-log-control-file option to aria_read_log
Diffstat (limited to 'storage/maria')
-rw-r--r-- | storage/maria/ma_control_file.c | 120 | ||||
-rw-r--r-- | storage/maria/ma_control_file.h | 1 | ||||
-rw-r--r-- | storage/maria/maria_read_log.c | 24 |
3 files changed, 141 insertions, 4 deletions
diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c index 3c536d2c46f..d55b12bbd9f 100644 --- a/storage/maria/ma_control_file.c +++ b/storage/maria/ma_control_file.c @@ -608,4 +608,124 @@ my_bool ma_control_file_inited(void) return (control_file_fd >= 0); } +/** + Print content of aria_log_control file +*/ + +my_bool print_aria_log_control() +{ + uchar buffer[CF_MAX_SIZE]; + char name[FN_REFLEN], uuid_str[MY_UUID_STRING_LENGTH+1]; + const char *errmsg; + uint new_cf_create_time_size, new_cf_changeable_size; + my_off_t file_size; + ulong logno; + ulonglong trid,checkpoint_lsn; + int open_flags= O_BINARY | /*O_DIRECT |*/ O_RDWR | O_CLOEXEC; + int error= CONTROL_FILE_UNKNOWN_ERROR; + uint recovery_fails; + File file; + DBUG_ENTER("ma_control_file_open"); + + if (fn_format(name, CONTROL_FILE_BASE_NAME, + maria_data_root, "", MYF(MY_WME)) == NullS) + DBUG_RETURN(CONTROL_FILE_UNKNOWN_ERROR); + + if ((file= mysql_file_open(key_file_control, name, + open_flags, MYF(MY_WME))) < 0) + { + errmsg= "Can't open file"; + goto err; + } + + file_size= mysql_file_seek(file, 0, SEEK_END, MYF(MY_WME)); + if (file_size == MY_FILEPOS_ERROR) + { + errmsg= "Can't read size"; + goto err; + } + if (file_size < CF_MIN_SIZE) + { + /* + Given that normally we write only a sector and it's atomic, the only + possibility for a file to be of too short size is if we crashed at the + very first startup, between file creation and file write. Quite unlikely + (and can be made even more unlikely by doing this: create a temp file, + write it, and then rename it to be the control file). + What's more likely is if someone forgot to restore the control file, + just did a "touch control" to try to get Maria to start, or if the + disk/filesystem has a problem. + So let's be rigid. + */ + error= CONTROL_FILE_TOO_SMALL; + errmsg= "Size of control file is smaller than expected"; + goto err; + } + + /* Check if control file is unexpectedly big */ + if (file_size > CF_MAX_SIZE) + { + error= CONTROL_FILE_TOO_BIG; + errmsg= "File size bigger than expected"; + goto err; + } + + if (mysql_file_pread(file, buffer, (size_t)file_size, 0, MYF(MY_FNABP))) + { + errmsg= "Can't read file"; + goto err; + } + + if (memcmp(buffer + CF_MAGIC_STRING_OFFSET, + CF_MAGIC_STRING, CF_MAGIC_STRING_SIZE)) + { + error= CONTROL_FILE_BAD_MAGIC_STRING; + errmsg= "Missing valid id at start of file. File is not a valid aria control file"; + goto err; + } + + printf("Aria file version: %u\n", buffer[CF_VERSION_OFFSET]); + + new_cf_create_time_size= uint2korr(buffer + CF_CREATE_TIME_SIZE_OFFSET); + new_cf_changeable_size= uint2korr(buffer + CF_CHANGEABLE_SIZE_OFFSET); + + if (new_cf_create_time_size < CF_MIN_CREATE_TIME_TOTAL_SIZE || + new_cf_changeable_size < CF_MIN_CHANGEABLE_TOTAL_SIZE || + new_cf_create_time_size + new_cf_changeable_size != file_size) + { + error= CONTROL_FILE_INCONSISTENT_INFORMATION; + errmsg= "Sizes stored in control file are inconsistent"; + goto err; + } + checkpoint_lsn= lsn_korr(buffer + new_cf_create_time_size + + CF_LSN_OFFSET); + logno= uint4korr(buffer + new_cf_create_time_size + CF_FILENO_OFFSET); + my_uuid2str(buffer + CF_UUID_OFFSET, uuid_str); + uuid_str[MY_UUID_STRING_LENGTH]= 0; + + printf("Block size: %u\n", uint2korr(buffer + CF_BLOCKSIZE_OFFSET)); + printf("maria_uuid: %s\n", uuid_str); + printf("last_checkpoint_lsn: " LSN_FMT "\n", LSN_IN_PARTS(checkpoint_lsn)); + printf("last_log_number: %lu\n", (ulong) logno); + if (new_cf_changeable_size >= (CF_MAX_TRID_OFFSET + CF_MAX_TRID_SIZE)) + { + trid= transid_korr(buffer + new_cf_create_time_size + CF_MAX_TRID_OFFSET); + printf("trid: %llu\n", (ulonglong) trid); + } + if (new_cf_changeable_size >= (CF_RECOV_FAIL_OFFSET + CF_RECOV_FAIL_SIZE)) + { + recovery_fails= + (buffer + new_cf_create_time_size + CF_RECOV_FAIL_OFFSET)[0]; + printf("recovery_failuers: %u\n", recovery_fails); + } + + DBUG_RETURN(0); + +err: + my_printf_error(HA_ERR_INITIALIZATION, + "Got error '%s' when trying to use aria control file " + "'%s'", 0, errmsg, name); + DBUG_RETURN(error); +} + #endif /* EXTRACT_DEFINITIONS */ diff --git a/storage/maria/ma_control_file.h b/storage/maria/ma_control_file.h index 85e8f2c899d..51599f0abfc 100644 --- a/storage/maria/ma_control_file.h +++ b/storage/maria/ma_control_file.h @@ -70,5 +70,6 @@ int ma_control_file_write_and_force(LSN last_checkpoint_lsn_arg, uint8 recovery_failures_arg); int ma_control_file_end(void); my_bool ma_control_file_inited(void); +my_bool print_aria_log_control(void); C_MODE_END #endif diff --git a/storage/maria/maria_read_log.c b/storage/maria/maria_read_log.c index 9a9c78f66d4..f3338714846 100644 --- a/storage/maria/maria_read_log.c +++ b/storage/maria/maria_read_log.c @@ -31,6 +31,7 @@ const char *default_dbug_option= "d:t:o,/tmp/aria_read_log.trace"; #endif /* DBUG_OFF */ static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent; static my_bool opt_check; +static my_bool opt_print_aria_log_control; static const char *opt_tmpdir; static ulong opt_translog_buffer_size; static ulonglong opt_page_buffer_size; @@ -59,6 +60,12 @@ int main(int argc, char **argv) goto err; } maria_block_size= 0; /* Use block size from file */ + if (opt_print_aria_log_control) + { + if (print_aria_log_control()) + goto err; + goto end; + } /* we don't want to create a control file, it MUST exist */ if (ma_control_file_open(FALSE, TRUE)) { @@ -209,6 +216,10 @@ static struct my_option my_long_options[] = &opt_page_buffer_size, &opt_page_buffer_size, 0, GET_ULL, REQUIRED_ARG, PAGE_BUFFER_INIT, PAGE_BUFFER_INIT, SIZE_T_MAX, MALLOC_OVERHEAD, (long) IO_SIZE, 0}, + { "print-log-control-file", 'l', + "Print the content of the aria_log_control_file", + &opt_print_aria_log_control, &opt_print_aria_log_control, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, { "start-from-lsn", 'o', "Start reading log from this lsn", &opt_start_from_lsn, &opt_start_from_lsn, 0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 }, @@ -249,7 +260,7 @@ static struct my_option my_long_options[] = static void print_version(void) { - printf("%s Ver 1.3 for %s on %s\n", + printf("%s Ver 1.4 for %s on %s\n", my_progname_short, SYSTEM_TYPE, MACHINE_TYPE); } @@ -271,6 +282,11 @@ static void usage(void) #endif printf("\nUsage: %s OPTIONS [-d | -a] -h `aria_log_directory`\n", my_progname_short); + printf("or\n"); + printf("Usage: %s OPTIONS -h `aria_log_directory` " + "--print-aria-log-control\n\n", + my_progname_short); + my_print_help(my_long_options); print_defaults("my", load_default_groups); my_print_variables(my_long_options); @@ -339,12 +355,12 @@ static void get_options(int *argc,char ***argv) need_help= 1; fprintf(stderr, "Too many arguments given\n"); } - if ((opt_display_only + opt_apply) != 1) + if ((opt_display_only + opt_apply + opt_print_aria_log_control) != 1) { need_help= 1; fprintf(stderr, - "You must use one and only one of the options 'display-only' or " - "'apply'\n"); + "You must use one and only one of the options 'display-only', \n" + "'print-log-control-file' and 'apply'\n"); } if (need_help) |