diff options
Diffstat (limited to 'extra')
44 files changed, 4670 insertions, 3033 deletions
diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt index c8e15dd4fb4..8c73e23d72b 100644 --- a/extra/CMakeLists.txt +++ b/extra/CMakeLists.txt @@ -82,13 +82,6 @@ IF(WITH_INNOBASE_STORAGE_ENGINE OR WITH_XTRADB_STORAGE_ENGINE) ../storage/innobase/fil/fil0crypt.cc ) - IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le") - enable_language(ASM) - LIST(APPEND INNOBASE_SOURCES - ../storage/innobase/ut/crc32_power8/crc32.S - ../storage/innobase/ut/crc32_power8/crc32_wrapper.c - ) - ENDIF() MYSQL_ADD_EXECUTABLE(innochecksum innochecksum.cc ${INNOBASE_SOURCES}) TARGET_LINK_LIBRARIES(innochecksum mysys mysys_ssl) diff --git a/extra/comp_err.c b/extra/comp_err.c index 3fc4b05fa61..5e3cec676bc 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -32,9 +32,11 @@ #include <my_getopt.h> #include <my_dir.h> -#define MAX_ROWS 2000 +#define MAX_ROWS 3000 +#define ERRORS_PER_RANGE 1000 +#define MAX_SECTIONS 4 #define HEADER_LENGTH 32 /* Length of header in errmsg.sys */ -#define ERRMSG_VERSION 3 /* Version number of errmsg.sys */ +#define ERRMSG_VERSION 4 /* Version number of errmsg.sys */ #define DEFAULT_CHARSET_DIR "../sql/share/charsets" #define ER_PREFIX "ER_" #define ER_PREFIX2 "MARIA_ER_" @@ -53,6 +55,8 @@ static char *default_dbug_option= (char*) "d:t:O,/tmp/comp_err.trace"; uchar file_head[]= { 254, 254, 2, ERRMSG_VERSION }; /* Store positions to each error message row to store in errmsg.sys header */ uint file_pos[MAX_ROWS+1]; +uint section_count,section_start; +uchar section_header[MAX_SECTIONS*2]; const char *empty_string= ""; /* For empty states */ /* @@ -131,7 +135,7 @@ static struct my_option my_long_options[]= }; -static struct errors *generate_empty_message(uint dcode); +static struct errors *generate_empty_message(uint dcode, my_bool skip); static struct languages *parse_charset_string(char *str); static struct errors *parse_error_string(char *ptr, int er_count); static struct message *parse_message_string(struct message *new_message, @@ -140,8 +144,9 @@ static struct message *find_message(struct errors *err, const char *lang, my_bool no_default); static int check_message_format(struct errors *err, const char* mess); -static int parse_input_file(const char *file_name, struct errors **top_error, - struct languages **top_language); +static uint parse_input_file(const char *file_name, struct errors **top_error, + struct languages **top_language, + uint *error_count); static int get_options(int *argc, char ***argv); static void print_version(void); static void usage(void); @@ -158,47 +163,55 @@ static char *find_end_of_word(char *str); static void clean_up(struct languages *lang_head, struct errors *error_head); static int create_header_files(struct errors *error_head); static int create_sys_files(struct languages *lang_head, - struct errors *error_head, uint row_count); + struct errors *error_head, uint max_error, + uint error_count); int main(int argc, char *argv[]) { MY_INIT(argv[0]); { - uint row_count; - struct errors *error_head; - struct languages *lang_head; + uint max_error, error_count; + struct errors *error_head= NULL; + struct languages *lang_head= NULL; DBUG_ENTER("main"); charsets_dir= DEFAULT_CHARSET_DIR; my_umask_dir= 0777; if (get_options(&argc, &argv)) - DBUG_RETURN(1); - if (!(row_count= parse_input_file(TXTFILE, &error_head, &lang_head))) + goto err; + if (!(max_error= parse_input_file(TXTFILE, &error_head, &lang_head, + &error_count))) { fprintf(stderr, "Failed to parse input file %s\n", TXTFILE); - DBUG_RETURN(1); + goto err; } if (lang_head == NULL || error_head == NULL) { fprintf(stderr, "Failed to parse input file %s\n", TXTFILE); - DBUG_RETURN(1); + goto err; } if (create_header_files(error_head)) { fprintf(stderr, "Failed to create header files\n"); - DBUG_RETURN(1); + goto err; } - if (create_sys_files(lang_head, error_head, row_count)) + if (create_sys_files(lang_head, error_head, max_error, error_count)) { fprintf(stderr, "Failed to create sys files\n"); - DBUG_RETURN(1); + goto err; } clean_up(lang_head, error_head); DBUG_LEAVE; /* Can't use dbug after my_end() */ my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); return 0; + +err: + clean_up(lang_head, error_head); + DBUG_LEAVE; /* Can't use dbug after my_end() */ + my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); + exit(1); } } @@ -226,6 +239,7 @@ static void print_escaped_string(FILE *f, const char *str) static int create_header_files(struct errors *error_head) { uint er_last= 0; + uint section= 1; FILE *er_definef, *sql_statef, *er_namef; struct errors *tmp_error; struct message *er_msg; @@ -253,6 +267,7 @@ static int create_header_files(struct errors *error_head) fprintf(sql_statef, "/* Autogenerated file, please don't edit */\n\n"); fprintf(er_namef, "/* Autogenerated file, please don't edit */\n\n"); + fprintf(er_definef, "#ifndef ER_ERROR_FIRST\n"); fprintf(er_definef, "#define ER_ERROR_FIRST %d\n", error_head->d_code); current_d_code= error_head->d_code -1; @@ -266,8 +281,19 @@ static int create_header_files(struct errors *error_head) if (!tmp_error->er_name) continue; /* Placeholder for gap */ - if (tmp_error->d_code > current_d_code + 1) + while (tmp_error->d_code > current_d_code + 1) + { + uint next_range= (((current_d_code + ERRORS_PER_RANGE) / + ERRORS_PER_RANGE) * ERRORS_PER_RANGE); + + fprintf(er_definef, "#define ER_ERROR_LAST_SECTION_%d %d\n", section, + current_d_code); fprintf(er_definef, "\n/* New section */\n\n"); + fprintf(er_definef, "#define ER_ERROR_FIRST_SECTION_%d %d\n", section+1, + MY_MIN(tmp_error->d_code, next_range)); + section++; + current_d_code= MY_MIN(tmp_error->d_code, next_range); + } current_d_code= tmp_error->d_code; fprintf(er_definef, "#define %s %u\n", tmp_error->er_name, @@ -289,6 +315,7 @@ static int create_header_files(struct errors *error_head) } /* finishing off with mysqld_error.h */ fprintf(er_definef, "#define ER_ERROR_LAST %d\n", er_last); + fprintf(er_definef, "#endif /* ER_ERROR_FIRST */\n"); my_fclose(er_definef, MYF(0)); my_fclose(sql_statef, MYF(0)); my_fclose(er_namef, MYF(0)); @@ -297,17 +324,19 @@ static int create_header_files(struct errors *error_head) static int create_sys_files(struct languages *lang_head, - struct errors *error_head, uint row_count) + struct errors *error_head, + uint max_error, + uint error_count) { FILE *to; - uint csnum= 0, length, i, row_nr; - uchar head[32]; + uint csnum= 0, i, row_nr; + ulong length; + uchar head[HEADER_LENGTH]; char outfile[FN_REFLEN], *outfile_end; long start_pos; struct message *tmp; struct languages *tmp_lang; struct errors *tmp_error; - MY_STAT stat_info; DBUG_ENTER("create_sys_files"); @@ -331,7 +360,7 @@ static int create_sys_files(struct languages *lang_head, { if (my_mkdir(outfile, 0777,MYF(0)) < 0) { - fprintf(stderr, "Can't create output directory for %s\n", + fprintf(stderr, "Can't creqate output directory for %s\n", outfile); DBUG_RETURN(1); } @@ -343,8 +372,8 @@ static int create_sys_files(struct languages *lang_head, DBUG_RETURN(1); /* 2 is for 2 bytes to store row position / error message */ - start_pos= (long) (HEADER_LENGTH + row_count * 2); - fseek(to, start_pos, 0); + start_pos= (long) (HEADER_LENGTH + (error_count + section_count) * 2); + my_fseek(to, start_pos, 0, MYF(0)); row_nr= 0; for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error) { @@ -358,29 +387,38 @@ static int create_sys_files(struct languages *lang_head, "language\n", tmp_error->er_name, tmp_lang->lang_short_name); goto err; } - if (copy_rows(to, tmp->text, row_nr, start_pos)) + if (tmp->text) /* If not skipped row */ { - fprintf(stderr, "Failed to copy rows to %s\n", outfile); - goto err; + if (copy_rows(to, tmp->text, row_nr, start_pos)) + { + fprintf(stderr, "Failed to copy rows to %s\n", outfile); + goto err; + } + row_nr++; } - row_nr++; } + DBUG_ASSERT(error_count == row_nr); /* continue with header of the errmsg.sys file */ - length= ftell(to) - HEADER_LENGTH - row_count * 2; + length= (ulong) (my_ftell(to, MYF(0)) - HEADER_LENGTH - + (error_count + section_count) * 2); bzero((uchar*) head, HEADER_LENGTH); - bmove((uchar *) head, (uchar *) file_head, 4); + bmove((uchar*) head, (uchar*) file_head, 4); head[4]= 1; int4store(head + 6, length); - int2store(head + 10, row_count); + int2store(head + 10, max_error); /* Max error */ + int2store(head + 12, row_nr); + int2store(head + 14, section_count); head[30]= csnum; my_fseek(to, 0l, MY_SEEK_SET, MYF(0)); - if (my_fwrite(to, (uchar*) head, HEADER_LENGTH, MYF(MY_WME | MY_FNABP))) + if (my_fwrite(to, (uchar*) head, HEADER_LENGTH, MYF(MY_WME | MY_FNABP)) || + my_fwrite(to, (uchar*) section_header, section_count*2, + MYF(MY_WME | MY_FNABP))) goto err; - file_pos[row_count]= (ftell(to) - start_pos); - for (i= 0; i < row_count; i++) + file_pos[row_nr]= (ftell(to) - start_pos); + for (i= 0; i < row_nr; i++) { /* Store length of each string */ int2store(head, file_pos[i+1] - file_pos[i]); @@ -437,24 +475,29 @@ static void clean_up(struct languages *lang_head, struct errors *error_head) } -static int parse_input_file(const char *file_name, struct errors **top_error, - struct languages **top_lang) +static uint parse_input_file(const char *file_name, struct errors **top_error, + struct languages **top_lang, uint *error_count) { FILE *file; char *str, buff[1000]; struct errors *current_error= 0, **tail_error= top_error; struct message current_message; - uint rcount= 0; + uint rcount= 0, skiped_errors= 0; my_bool er_offset_found= 0; DBUG_ENTER("parse_input_file"); *top_error= 0; *top_lang= 0; + *error_count= 0; + section_start= er_offset; + section_count= 0; + if (!(file= my_fopen(file_name, O_RDONLY | O_SHARE, MYF(MY_WME)))) DBUG_RETURN(0); while ((str= fgets(buff, sizeof(buff), file))) { + my_bool skip; if (is_prefix(str, "language")) { if (!(*top_lang= parse_charset_string(str))) @@ -464,18 +507,34 @@ static int parse_input_file(const char *file_name, struct errors **top_error, } continue; } - if (is_prefix(str, "start-error-number")) + skip= 0; + if (is_prefix(str, "start-error-number") || + (skip= is_prefix(str, "skip-to-error-number"))) { uint tmp_er_offset; + if (!(tmp_er_offset= parse_error_offset(str))) { fprintf(stderr, "Failed to parse the error offset string!\n"); DBUG_RETURN(0); } + if (skip) + { + if (section_count >= MAX_SECTIONS-1) + { + fprintf(stderr, "Found too many skip-to-error-number entries. " + "We only support %d entries\n", MAX_SECTIONS); + DBUG_RETURN(0); + } + int2store(section_header + section_count*2, + er_offset +rcount - section_start); + section_count++; + section_start= tmp_er_offset; + } if (!er_offset_found) { er_offset_found= 1; - er_offset= tmp_er_offset; + er_offset= section_start= tmp_er_offset; } else { @@ -487,7 +546,8 @@ static int parse_input_file(const char *file_name, struct errors **top_error, } for ( ; er_offset + rcount < tmp_er_offset ; rcount++) { - current_error= generate_empty_message(er_offset + rcount); + skiped_errors+= skip != 0; + current_error= generate_empty_message(er_offset + rcount, skip); *tail_error= current_error; tail_error= ¤t_error->next_error; } @@ -559,6 +619,11 @@ static int parse_input_file(const char *file_name, struct errors **top_error, fprintf(stderr, "Wrong input file format. Stop!\nLine: %s\n", str); DBUG_RETURN(0); } + int2store(section_header + section_count*2, + er_offset + rcount - section_start); + section_count++; + *error_count= rcount - skiped_errors; + *tail_error= 0; /* Mark end of list */ my_fclose(file, MYF(0)); @@ -887,7 +952,7 @@ static struct message *parse_message_string(struct message *new_message, } -static struct errors *generate_empty_message(uint d_code) +static struct errors *generate_empty_message(uint d_code, my_bool skip) { struct errors *new_error; struct message message; @@ -896,7 +961,8 @@ static struct errors *generate_empty_message(uint d_code) if (!(new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME)))) return(0); - if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 1, MYF(0))) + if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 1, + MYF(0))) return(0); /* OOM: Fatal error */ new_error->er_name= NULL; @@ -904,8 +970,10 @@ static struct errors *generate_empty_message(uint d_code) new_error->sql_code1= empty_string; new_error->sql_code2= empty_string; + message.text= 0; /* If skip set, don't generate a text */ + if (!(message.lang_short_name= my_strdup(default_language, MYF(MY_WME))) || - !(message.text= my_strdup("", MYF(MY_WME)))) + (!skip && !(message.text= my_strdup("", MYF(MY_WME))))) return(0); /* Can't fail as msg is preallocated */ @@ -1071,10 +1139,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__ ((unused)), switch (optid) { case 'V': print_version(); + my_end(0); exit(0); break; case '?': usage(); + my_end(0); exit(0); break; case '#': diff --git a/extra/crc32-vpmsum/CMakeLists.txt b/extra/crc32-vpmsum/CMakeLists.txt new file mode 100644 index 00000000000..0bb254bea6a --- /dev/null +++ b/extra/crc32-vpmsum/CMakeLists.txt @@ -0,0 +1,2 @@ +ENABLE_LANGUAGE(ASM) +ADD_CONVENIENCE_LIBRARY(${CRC32_VPMSUM_LIBRARY} crc32c.S crc32c_wrapper.c crc32ieee.S crc32ieee_wrapper.c) diff --git a/extra/crc32-vpmsum/crc32.iS b/extra/crc32-vpmsum/crc32.iS new file mode 100644 index 00000000000..4e7c18922da --- /dev/null +++ b/extra/crc32-vpmsum/crc32.iS @@ -0,0 +1,734 @@ +/* + * Calculate the checksum of data that is 16 byte aligned and a multiple of + * 16 bytes. + * + * The first step is to reduce it to 1024 bits. We do this in 8 parallel + * chunks in order to mask the latency of the vpmsum instructions. If we + * have more than 32 kB of data to checksum we repeat this step multiple + * times, passing in the previous 1024 bits. + * + * The next step is to reduce the 1024 bits to 64 bits. This step adds + * 32 bits of 0s to the end - this matches what a CRC does. We just + * calculate constants that land the data in this 32 bits. + * + * We then use fixed point Barrett reduction to compute a mod n over GF(2) + * for n = CRC using POWER8 instructions. We use x = 32. + * + * http://en.wikipedia.org/wiki/Barrett_reduction + * + * Copyright (C) 2015 Anton Blanchard <anton@au.ibm.com>, IBM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifdef __powerpc__ + +#include <ppc-asm.h> +#include "ppc-opcode.h" + +#undef toc + +#ifndef r1 +#define r1 1 +#endif + +#ifndef r2 +#define r2 2 +#endif + + .section .rodata +.balign 16 + +.byteswap_constant: + /* byte reverse permute constant */ + .octa 0x0F0E0D0C0B0A09080706050403020100 + + .text + +#define off16 r25 +#define off32 r26 +#define off48 r27 +#define off64 r28 +#define off80 r29 +#define off96 r30 +#define off112 r31 + +#define const1 v24 +#define const2 v25 + +#define byteswap v26 +#define mask_32bit v27 +#define mask_64bit v28 +#define zeroes v29 + +#ifdef BYTESWAP_DATA +#define VPERM(A, B, C, D) vperm A, B, C, D +#else +#define VPERM(A, B, C, D) +#endif + +/* unsigned int __crc32_vpmsum(unsigned int crc, void *p, unsigned long len) */ +FUNC_START(__F) + std r31,-8(r1) + std r30,-16(r1) + std r29,-24(r1) + std r28,-32(r1) + std r27,-40(r1) + std r26,-48(r1) + std r25,-56(r1) + + li off16,16 + li off32,32 + li off48,48 + li off64,64 + li off80,80 + li off96,96 + li off112,112 + li r0,0 + + /* Enough room for saving 10 non volatile VMX registers */ + subi r6,r1,56+10*16 + subi r7,r1,56+2*16 + + stvx v20,0,r6 + stvx v21,off16,r6 + stvx v22,off32,r6 + stvx v23,off48,r6 + stvx v24,off64,r6 + stvx v25,off80,r6 + stvx v26,off96,r6 + stvx v27,off112,r6 + stvx v28,0,r7 + stvx v29,off16,r7 + + mr r10,r3 + + vxor zeroes,zeroes,zeroes + vspltisw v0,-1 + + vsldoi mask_32bit,zeroes,v0,4 + vsldoi mask_64bit,zeroes,v0,8 + + /* Get the initial value into v8 */ + vxor v8,v8,v8 + MTVRD(v8, r3) + + vsldoi v8,zeroes,v8,8 /* shift into bottom 32 bits */ + + addis r3,r2,.byteswap_constant@toc@ha + addi r3,r3,.byteswap_constant@toc@l + + lvx byteswap,0,r3 + addi r3,r3,16 + + cmpdi r5,256 + blt .Lshort + + rldicr r6,r5,0,56 + + /* Checksum in blocks of MAX_SIZE */ +1: lis r7,MAX_SIZE@h + ori r7,r7,MAX_SIZE@l + mr r9,r7 + cmpd r6,r7 + bgt 2f + mr r7,r6 +2: subf r6,r7,r6 + + /* our main loop does 128 bytes at a time */ + srdi r7,r7,7 + + /* + * Work out the offset into the constants table to start at. Each + * constant is 16 bytes, and it is used against 128 bytes of input + * data - 128 / 16 = 8 + */ + sldi r8,r7,4 + srdi r9,r9,3 + subf r8,r8,r9 + + /* We reduce our final 128 bytes in a separate step */ + addi r7,r7,-1 + mtctr r7 + + addis r3,r2,CONSTANTS@toc@ha + addi r3,r3,CONSTANTS@toc@l + + /* Find the start of our constants */ + add r3,r3,r8 + + /* zero v0-v7 which will contain our checksums */ + vxor v0,v0,v0 + vxor v1,v1,v1 + vxor v2,v2,v2 + vxor v3,v3,v3 + vxor v4,v4,v4 + vxor v5,v5,v5 + vxor v6,v6,v6 + vxor v7,v7,v7 + + lvx const1,0,r3 + + /* + * If we are looping back to consume more data we use the values + * already in v16-v23. + */ + cmpdi r0,1 + beq 2f + + /* First warm up pass */ + lvx v16,0,r4 + lvx v17,off16,r4 + VPERM(v16,v16,v16,byteswap) + VPERM(v17,v17,v17,byteswap) + lvx v18,off32,r4 + lvx v19,off48,r4 + VPERM(v18,v18,v18,byteswap) + VPERM(v19,v19,v19,byteswap) + lvx v20,off64,r4 + lvx v21,off80,r4 + VPERM(v20,v20,v20,byteswap) + VPERM(v21,v21,v21,byteswap) + lvx v22,off96,r4 + lvx v23,off112,r4 + VPERM(v22,v22,v22,byteswap) + VPERM(v23,v23,v23,byteswap) + addi r4,r4,8*16 + + /* xor in initial value */ + vxor v16,v16,v8 + +2: bdz .Lfirst_warm_up_done + + addi r3,r3,16 + lvx const2,0,r3 + + /* Second warm up pass */ + VPMSUMD(v8,v16,const1) + lvx v16,0,r4 + VPERM(v16,v16,v16,byteswap) + ori r2,r2,0 + + VPMSUMD(v9,v17,const1) + lvx v17,off16,r4 + VPERM(v17,v17,v17,byteswap) + ori r2,r2,0 + + VPMSUMD(v10,v18,const1) + lvx v18,off32,r4 + VPERM(v18,v18,v18,byteswap) + ori r2,r2,0 + + VPMSUMD(v11,v19,const1) + lvx v19,off48,r4 + VPERM(v19,v19,v19,byteswap) + ori r2,r2,0 + + VPMSUMD(v12,v20,const1) + lvx v20,off64,r4 + VPERM(v20,v20,v20,byteswap) + ori r2,r2,0 + + VPMSUMD(v13,v21,const1) + lvx v21,off80,r4 + VPERM(v21,v21,v21,byteswap) + ori r2,r2,0 + + VPMSUMD(v14,v22,const1) + lvx v22,off96,r4 + VPERM(v22,v22,v22,byteswap) + ori r2,r2,0 + + VPMSUMD(v15,v23,const1) + lvx v23,off112,r4 + VPERM(v23,v23,v23,byteswap) + + addi r4,r4,8*16 + + bdz .Lfirst_cool_down + + /* + * main loop. We modulo schedule it such that it takes three iterations + * to complete - first iteration load, second iteration vpmsum, third + * iteration xor. + */ + .balign 16 +4: lvx const1,0,r3 + addi r3,r3,16 + ori r2,r2,0 + + vxor v0,v0,v8 + VPMSUMD(v8,v16,const2) + lvx v16,0,r4 + VPERM(v16,v16,v16,byteswap) + ori r2,r2,0 + + vxor v1,v1,v9 + VPMSUMD(v9,v17,const2) + lvx v17,off16,r4 + VPERM(v17,v17,v17,byteswap) + ori r2,r2,0 + + vxor v2,v2,v10 + VPMSUMD(v10,v18,const2) + lvx v18,off32,r4 + VPERM(v18,v18,v18,byteswap) + ori r2,r2,0 + + vxor v3,v3,v11 + VPMSUMD(v11,v19,const2) + lvx v19,off48,r4 + VPERM(v19,v19,v19,byteswap) + lvx const2,0,r3 + ori r2,r2,0 + + vxor v4,v4,v12 + VPMSUMD(v12,v20,const1) + lvx v20,off64,r4 + VPERM(v20,v20,v20,byteswap) + ori r2,r2,0 + + vxor v5,v5,v13 + VPMSUMD(v13,v21,const1) + lvx v21,off80,r4 + VPERM(v21,v21,v21,byteswap) + ori r2,r2,0 + + vxor v6,v6,v14 + VPMSUMD(v14,v22,const1) + lvx v22,off96,r4 + VPERM(v22,v22,v22,byteswap) + ori r2,r2,0 + + vxor v7,v7,v15 + VPMSUMD(v15,v23,const1) + lvx v23,off112,r4 + VPERM(v23,v23,v23,byteswap) + + addi r4,r4,8*16 + + bdnz 4b + +.Lfirst_cool_down: + /* First cool down pass */ + lvx const1,0,r3 + addi r3,r3,16 + + vxor v0,v0,v8 + VPMSUMD(v8,v16,const1) + ori r2,r2,0 + + vxor v1,v1,v9 + VPMSUMD(v9,v17,const1) + ori r2,r2,0 + + vxor v2,v2,v10 + VPMSUMD(v10,v18,const1) + ori r2,r2,0 + + vxor v3,v3,v11 + VPMSUMD(v11,v19,const1) + ori r2,r2,0 + + vxor v4,v4,v12 + VPMSUMD(v12,v20,const1) + ori r2,r2,0 + + vxor v5,v5,v13 + VPMSUMD(v13,v21,const1) + ori r2,r2,0 + + vxor v6,v6,v14 + VPMSUMD(v14,v22,const1) + ori r2,r2,0 + + vxor v7,v7,v15 + VPMSUMD(v15,v23,const1) + ori r2,r2,0 + +.Lsecond_cool_down: + /* Second cool down pass */ + vxor v0,v0,v8 + vxor v1,v1,v9 + vxor v2,v2,v10 + vxor v3,v3,v11 + vxor v4,v4,v12 + vxor v5,v5,v13 + vxor v6,v6,v14 + vxor v7,v7,v15 + + /* + * vpmsumd produces a 96 bit result in the least significant bits + * of the register. Since we are bit reflected we have to shift it + * left 32 bits so it occupies the least significant bits in the + * bit reflected domain. + */ + vsldoi v0,v0,zeroes,4 + vsldoi v1,v1,zeroes,4 + vsldoi v2,v2,zeroes,4 + vsldoi v3,v3,zeroes,4 + vsldoi v4,v4,zeroes,4 + vsldoi v5,v5,zeroes,4 + vsldoi v6,v6,zeroes,4 + vsldoi v7,v7,zeroes,4 + + /* xor with last 1024 bits */ + lvx v8,0,r4 + lvx v9,off16,r4 + VPERM(v8,v8,v8,byteswap) + VPERM(v9,v9,v9,byteswap) + lvx v10,off32,r4 + lvx v11,off48,r4 + VPERM(v10,v10,v10,byteswap) + VPERM(v11,v11,v11,byteswap) + lvx v12,off64,r4 + lvx v13,off80,r4 + VPERM(v12,v12,v12,byteswap) + VPERM(v13,v13,v13,byteswap) + lvx v14,off96,r4 + lvx v15,off112,r4 + VPERM(v14,v14,v14,byteswap) + VPERM(v15,v15,v15,byteswap) + + addi r4,r4,8*16 + + vxor v16,v0,v8 + vxor v17,v1,v9 + vxor v18,v2,v10 + vxor v19,v3,v11 + vxor v20,v4,v12 + vxor v21,v5,v13 + vxor v22,v6,v14 + vxor v23,v7,v15 + + li r0,1 + cmpdi r6,0 + addi r6,r6,128 + bne 1b + + /* Work out how many bytes we have left */ + andi. r5,r5,127 + + /* Calculate where in the constant table we need to start */ + subfic r6,r5,128 + add r3,r3,r6 + + /* How many 16 byte chunks are in the tail */ + srdi r7,r5,4 + mtctr r7 + + /* + * Reduce the previously calculated 1024 bits to 64 bits, shifting + * 32 bits to include the trailing 32 bits of zeros + */ + lvx v0,0,r3 + lvx v1,off16,r3 + lvx v2,off32,r3 + lvx v3,off48,r3 + lvx v4,off64,r3 + lvx v5,off80,r3 + lvx v6,off96,r3 + lvx v7,off112,r3 + addi r3,r3,8*16 + + VPMSUMW(v0,v16,v0) + VPMSUMW(v1,v17,v1) + VPMSUMW(v2,v18,v2) + VPMSUMW(v3,v19,v3) + VPMSUMW(v4,v20,v4) + VPMSUMW(v5,v21,v5) + VPMSUMW(v6,v22,v6) + VPMSUMW(v7,v23,v7) + + /* Now reduce the tail (0 - 112 bytes) */ + cmpdi r7,0 + beq 1f + + lvx v16,0,r4 + lvx v17,0,r3 + VPERM(v16,v16,v16,byteswap) + VPMSUMW(v16,v16,v17) + vxor v0,v0,v16 + bdz 1f + + lvx v16,off16,r4 + lvx v17,off16,r3 + VPERM(v16,v16,v16,byteswap) + VPMSUMW(v16,v16,v17) + vxor v0,v0,v16 + bdz 1f + + lvx v16,off32,r4 + lvx v17,off32,r3 + VPERM(v16,v16,v16,byteswap) + VPMSUMW(v16,v16,v17) + vxor v0,v0,v16 + bdz 1f + + lvx v16,off48,r4 + lvx v17,off48,r3 + VPERM(v16,v16,v16,byteswap) + VPMSUMW(v16,v16,v17) + vxor v0,v0,v16 + bdz 1f + + lvx v16,off64,r4 + lvx v17,off64,r3 + VPERM(v16,v16,v16,byteswap) + VPMSUMW(v16,v16,v17) + vxor v0,v0,v16 + bdz 1f + + lvx v16,off80,r4 + lvx v17,off80,r3 + VPERM(v16,v16,v16,byteswap) + VPMSUMW(v16,v16,v17) + vxor v0,v0,v16 + bdz 1f + + lvx v16,off96,r4 + lvx v17,off96,r3 + VPERM(v16,v16,v16,byteswap) + VPMSUMW(v16,v16,v17) + vxor v0,v0,v16 + + /* Now xor all the parallel chunks together */ +1: vxor v0,v0,v1 + vxor v2,v2,v3 + vxor v4,v4,v5 + vxor v6,v6,v7 + + vxor v0,v0,v2 + vxor v4,v4,v6 + + vxor v0,v0,v4 + +.Lbarrett_reduction: + /* Barrett constants */ + addis r3,r2,BARRETT_CONSTANTS@toc@ha + addi r3,r3,BARRETT_CONSTANTS@toc@l + + lvx const1,0,r3 + lvx const2,off16,r3 + + vsldoi v1,v0,v0,8 + vxor v0,v0,v1 /* xor two 64 bit results together */ + + /* shift left one bit */ + vspltisb v1,1 + vsl v0,v0,v1 + + vand v0,v0,mask_64bit + + /* + * The reflected version of Barrett reduction. Instead of bit + * reflecting our data (which is expensive to do), we bit reflect our + * constants and our algorithm, which means the intermediate data in + * our vector registers goes from 0-63 instead of 63-0. We can reflect + * the algorithm because we don't carry in mod 2 arithmetic. + */ + vand v1,v0,mask_32bit /* bottom 32 bits of a */ + VPMSUMD(v1,v1,const1) /* ma */ + vand v1,v1,mask_32bit /* bottom 32bits of ma */ + VPMSUMD(v1,v1,const2) /* qn */ + vxor v0,v0,v1 /* a - qn, subtraction is xor in GF(2) */ + + /* + * Since we are bit reflected, the result (ie the low 32 bits) is in + * the high 32 bits. We just need to shift it left 4 bytes + * V0 [ 0 1 X 3 ] + * V0 [ 0 X 2 3 ] + */ + vsldoi v0,v0,zeroes,4 /* shift result into top 64 bits of */ + +.Lout: + subi r6,r1,56+10*16 + subi r7,r1,56+2*16 + + lvx v20,0,r6 + lvx v21,off16,r6 + lvx v22,off32,r6 + lvx v23,off48,r6 + lvx v24,off64,r6 + lvx v25,off80,r6 + lvx v26,off96,r6 + lvx v27,off112,r6 + lvx v28,0,r7 + lvx v29,off16,r7 + + /* Get it into r3 */ + MFVRD(r3, v0) + + ld r31,-8(r1) + ld r30,-16(r1) + ld r29,-24(r1) + ld r28,-32(r1) + ld r27,-40(r1) + ld r26,-48(r1) + ld r25,-56(r1) + + blr + +.Lfirst_warm_up_done: + lvx const1,0,r3 + addi r3,r3,16 + + VPMSUMD(v8,v16,const1) + VPMSUMD(v9,v17,const1) + VPMSUMD(v10,v18,const1) + VPMSUMD(v11,v19,const1) + VPMSUMD(v12,v20,const1) + VPMSUMD(v13,v21,const1) + VPMSUMD(v14,v22,const1) + VPMSUMD(v15,v23,const1) + + b .Lsecond_cool_down + +.Lshort: + cmpdi r5,0 + beq .Lzero + + addis r3,r2,SHORT_CONSTANTS@toc@ha + addi r3,r3,SHORT_CONSTANTS@toc@l + + /* Calculate where in the constant table we need to start */ + subfic r6,r5,256 + add r3,r3,r6 + + /* How many 16 byte chunks? */ + srdi r7,r5,4 + mtctr r7 + + vxor v19,v19,v19 + vxor v20,v20,v20 + + lvx v0,0,r4 + lvx v16,0,r3 + VPERM(v0,v0,v16,byteswap) + vxor v0,v0,v8 /* xor in initial value */ + VPMSUMW(v0,v0,v16) + bdz .Lv0 + + lvx v1,off16,r4 + lvx v17,off16,r3 + VPERM(v1,v1,v17,byteswap) + VPMSUMW(v1,v1,v17) + bdz .Lv1 + + lvx v2,off32,r4 + lvx v16,off32,r3 + VPERM(v2,v2,v16,byteswap) + VPMSUMW(v2,v2,v16) + bdz .Lv2 + + lvx v3,off48,r4 + lvx v17,off48,r3 + VPERM(v3,v3,v17,byteswap) + VPMSUMW(v3,v3,v17) + bdz .Lv3 + + lvx v4,off64,r4 + lvx v16,off64,r3 + VPERM(v4,v4,v16,byteswap) + VPMSUMW(v4,v4,v16) + bdz .Lv4 + + lvx v5,off80,r4 + lvx v17,off80,r3 + VPERM(v5,v5,v17,byteswap) + VPMSUMW(v5,v5,v17) + bdz .Lv5 + + lvx v6,off96,r4 + lvx v16,off96,r3 + VPERM(v6,v6,v16,byteswap) + VPMSUMW(v6,v6,v16) + bdz .Lv6 + + lvx v7,off112,r4 + lvx v17,off112,r3 + VPERM(v7,v7,v17,byteswap) + VPMSUMW(v7,v7,v17) + bdz .Lv7 + + addi r3,r3,128 + addi r4,r4,128 + + lvx v8,0,r4 + lvx v16,0,r3 + VPERM(v8,v8,v16,byteswap) + VPMSUMW(v8,v8,v16) + bdz .Lv8 + + lvx v9,off16,r4 + lvx v17,off16,r3 + VPERM(v9,v9,v17,byteswap) + VPMSUMW(v9,v9,v17) + bdz .Lv9 + + lvx v10,off32,r4 + lvx v16,off32,r3 + VPERM(v10,v10,v16,byteswap) + VPMSUMW(v10,v10,v16) + bdz .Lv10 + + lvx v11,off48,r4 + lvx v17,off48,r3 + VPERM(v11,v11,v17,byteswap) + VPMSUMW(v11,v11,v17) + bdz .Lv11 + + lvx v12,off64,r4 + lvx v16,off64,r3 + VPERM(v12,v12,v16,byteswap) + VPMSUMW(v12,v12,v16) + bdz .Lv12 + + lvx v13,off80,r4 + lvx v17,off80,r3 + VPERM(v13,v13,v17,byteswap) + VPMSUMW(v13,v13,v17) + bdz .Lv13 + + lvx v14,off96,r4 + lvx v16,off96,r3 + VPERM(v14,v14,v16,byteswap) + VPMSUMW(v14,v14,v16) + bdz .Lv14 + + lvx v15,off112,r4 + lvx v17,off112,r3 + VPERM(v15,v15,v17,byteswap) + VPMSUMW(v15,v15,v17) + +.Lv15: vxor v19,v19,v15 +.Lv14: vxor v20,v20,v14 +.Lv13: vxor v19,v19,v13 +.Lv12: vxor v20,v20,v12 +.Lv11: vxor v19,v19,v11 +.Lv10: vxor v20,v20,v10 +.Lv9: vxor v19,v19,v9 +.Lv8: vxor v20,v20,v8 +.Lv7: vxor v19,v19,v7 +.Lv6: vxor v20,v20,v6 +.Lv5: vxor v19,v19,v5 +.Lv4: vxor v20,v20,v4 +.Lv3: vxor v19,v19,v3 +.Lv2: vxor v20,v20,v2 +.Lv1: vxor v19,v19,v1 +.Lv0: vxor v20,v20,v0 + + vxor v0,v19,v20 + + b .Lbarrett_reduction + +.Lzero: + mr r3,r10 + b .Lout + +FUNC_END(__F) + +#endif /* __powerpc__ */ diff --git a/extra/crc32-vpmsum/crc32_wrapper.ic b/extra/crc32-vpmsum/crc32_wrapper.ic new file mode 100644 index 00000000000..750e971f83e --- /dev/null +++ b/extra/crc32-vpmsum/crc32_wrapper.ic @@ -0,0 +1,52 @@ +#ifdef __powerpc__ + + +#define VMX_ALIGN 16 +#define VMX_ALIGN_MASK (VMX_ALIGN-1) + +static unsigned int crc32_align(unsigned int crc, unsigned char *p, + unsigned long len) +{ + while (len--) + crc = crc_table[(crc ^ *p++) & 0xff] ^ (crc >> 8); + return crc; +} + +unsigned int __F(unsigned int crc, unsigned char *p, + unsigned long len); + +unsigned int F(unsigned int crc, unsigned char *p, + unsigned long len) +{ + unsigned int prealign; + unsigned int tail; + + crc ^= 0xffffffff; + + if (len < VMX_ALIGN + VMX_ALIGN_MASK) { + crc = crc32_align(crc, p, len); + goto out; + } + + if ((unsigned long)p & VMX_ALIGN_MASK) { + prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK); + crc = crc32_align(crc, p, prealign); + len -= prealign; + p += prealign; + } + + crc = __F(crc, p, len & ~VMX_ALIGN_MASK); + + tail = len & VMX_ALIGN_MASK; + if (tail) { + p += len & ~VMX_ALIGN_MASK; + crc = crc32_align(crc, p, tail); + } + +out: + crc ^= 0xffffffff; + + return crc; +} + +#endif /* __powerpc__ */ diff --git a/extra/crc32-vpmsum/crc32c.S b/extra/crc32-vpmsum/crc32c.S new file mode 100644 index 00000000000..390c4bf0660 --- /dev/null +++ b/extra/crc32-vpmsum/crc32c.S @@ -0,0 +1,14 @@ +#ifdef __powerpc__ + +#define CONSTANTS .crc32c_constants +#define SHORT_CONSTANTS .crc32c_short_constants +#define BARRETT_CONSTANTS .crc32c_barrett_constants + +#include "crc32c_constants.h" + +#define __F __crc32c_vpmsum + +#include "crc32.iS" + +#endif + diff --git a/extra/crc32-vpmsum/crc32c_constants.h b/extra/crc32-vpmsum/crc32c_constants.h new file mode 100644 index 00000000000..555b785ce9f --- /dev/null +++ b/extra/crc32-vpmsum/crc32c_constants.h @@ -0,0 +1,837 @@ +#ifndef CRC32_CONSTANTS_H +#define CRC32_CONSTANTS_H + +#ifdef __powerpc__ + +#define CRC 0x1edc6f41 + +#define MAX_SIZE 32768 +CONSTANTS: + + /* Reduce 262144 kbits to 1024 bits */ + /* x^261120 mod p(x)` << 1, x^261184 mod p(x)` << 1 */ + .octa 0x00000000b6ca9e20000000009c37c408 + + /* x^260096 mod p(x)` << 1, x^260160 mod p(x)` << 1 */ + .octa 0x00000000350249a800000001b51df26c + + /* x^259072 mod p(x)` << 1, x^259136 mod p(x)` << 1 */ + .octa 0x00000001862dac54000000000724b9d0 + + /* x^258048 mod p(x)` << 1, x^258112 mod p(x)` << 1 */ + .octa 0x00000001d87fb48c00000001c00532fe + + /* x^257024 mod p(x)` << 1, x^257088 mod p(x)` << 1 */ + .octa 0x00000001f39b699e00000000f05a9362 + + /* x^256000 mod p(x)` << 1, x^256064 mod p(x)` << 1 */ + .octa 0x0000000101da11b400000001e1007970 + + /* x^254976 mod p(x)` << 1, x^255040 mod p(x)` << 1 */ + .octa 0x00000001cab571e000000000a57366ee + + /* x^253952 mod p(x)` << 1, x^254016 mod p(x)` << 1 */ + .octa 0x00000000c7020cfe0000000192011284 + + /* x^252928 mod p(x)` << 1, x^252992 mod p(x)` << 1 */ + .octa 0x00000000cdaed1ae0000000162716d9a + + /* x^251904 mod p(x)` << 1, x^251968 mod p(x)` << 1 */ + .octa 0x00000001e804effc00000000cd97ecde + + /* x^250880 mod p(x)` << 1, x^250944 mod p(x)` << 1 */ + .octa 0x0000000077c3ea3a0000000058812bc0 + + /* x^249856 mod p(x)` << 1, x^249920 mod p(x)` << 1 */ + .octa 0x0000000068df31b40000000088b8c12e + + /* x^248832 mod p(x)` << 1, x^248896 mod p(x)` << 1 */ + .octa 0x00000000b059b6c200000001230b234c + + /* x^247808 mod p(x)` << 1, x^247872 mod p(x)` << 1 */ + .octa 0x0000000145fb8ed800000001120b416e + + /* x^246784 mod p(x)` << 1, x^246848 mod p(x)` << 1 */ + .octa 0x00000000cbc0916800000001974aecb0 + + /* x^245760 mod p(x)` << 1, x^245824 mod p(x)` << 1 */ + .octa 0x000000005ceeedc2000000008ee3f226 + + /* x^244736 mod p(x)` << 1, x^244800 mod p(x)` << 1 */ + .octa 0x0000000047d74e8600000001089aba9a + + /* x^243712 mod p(x)` << 1, x^243776 mod p(x)` << 1 */ + .octa 0x00000001407e9e220000000065113872 + + /* x^242688 mod p(x)` << 1, x^242752 mod p(x)` << 1 */ + .octa 0x00000001da967bda000000005c07ec10 + + /* x^241664 mod p(x)` << 1, x^241728 mod p(x)` << 1 */ + .octa 0x000000006c8983680000000187590924 + + /* x^240640 mod p(x)` << 1, x^240704 mod p(x)` << 1 */ + .octa 0x00000000f2d14c9800000000e35da7c6 + + /* x^239616 mod p(x)` << 1, x^239680 mod p(x)` << 1 */ + .octa 0x00000001993c6ad4000000000415855a + + /* x^238592 mod p(x)` << 1, x^238656 mod p(x)` << 1 */ + .octa 0x000000014683d1ac0000000073617758 + + /* x^237568 mod p(x)` << 1, x^237632 mod p(x)` << 1 */ + .octa 0x00000001a7c93e6c0000000176021d28 + + /* x^236544 mod p(x)` << 1, x^236608 mod p(x)` << 1 */ + .octa 0x000000010211e90a00000001c358fd0a + + /* x^235520 mod p(x)` << 1, x^235584 mod p(x)` << 1 */ + .octa 0x000000001119403e00000001ff7a2c18 + + /* x^234496 mod p(x)` << 1, x^234560 mod p(x)` << 1 */ + .octa 0x000000001c3261aa00000000f2d9f7e4 + + /* x^233472 mod p(x)` << 1, x^233536 mod p(x)` << 1 */ + .octa 0x000000014e37a634000000016cf1f9c8 + + /* x^232448 mod p(x)` << 1, x^232512 mod p(x)` << 1 */ + .octa 0x0000000073786c0c000000010af9279a + + /* x^231424 mod p(x)` << 1, x^231488 mod p(x)` << 1 */ + .octa 0x000000011dc037f80000000004f101e8 + + /* x^230400 mod p(x)` << 1, x^230464 mod p(x)` << 1 */ + .octa 0x0000000031433dfc0000000070bcf184 + + /* x^229376 mod p(x)` << 1, x^229440 mod p(x)` << 1 */ + .octa 0x000000009cde8348000000000a8de642 + + /* x^228352 mod p(x)` << 1, x^228416 mod p(x)` << 1 */ + .octa 0x0000000038d3c2a60000000062ea130c + + /* x^227328 mod p(x)` << 1, x^227392 mod p(x)` << 1 */ + .octa 0x000000011b25f26000000001eb31cbb2 + + /* x^226304 mod p(x)` << 1, x^226368 mod p(x)` << 1 */ + .octa 0x000000001629e6f00000000170783448 + + /* x^225280 mod p(x)` << 1, x^225344 mod p(x)` << 1 */ + .octa 0x0000000160838b4c00000001a684b4c6 + + /* x^224256 mod p(x)` << 1, x^224320 mod p(x)` << 1 */ + .octa 0x000000007a44011c00000000253ca5b4 + + /* x^223232 mod p(x)` << 1, x^223296 mod p(x)` << 1 */ + .octa 0x00000000226f417a0000000057b4b1e2 + + /* x^222208 mod p(x)` << 1, x^222272 mod p(x)` << 1 */ + .octa 0x0000000045eb2eb400000000b6bd084c + + /* x^221184 mod p(x)` << 1, x^221248 mod p(x)` << 1 */ + .octa 0x000000014459d70c0000000123c2d592 + + /* x^220160 mod p(x)` << 1, x^220224 mod p(x)` << 1 */ + .octa 0x00000001d406ed8200000000159dafce + + /* x^219136 mod p(x)` << 1, x^219200 mod p(x)` << 1 */ + .octa 0x0000000160c8e1a80000000127e1a64e + + /* x^218112 mod p(x)` << 1, x^218176 mod p(x)` << 1 */ + .octa 0x0000000027ba80980000000056860754 + + /* x^217088 mod p(x)` << 1, x^217152 mod p(x)` << 1 */ + .octa 0x000000006d92d01800000001e661aae8 + + /* x^216064 mod p(x)` << 1, x^216128 mod p(x)` << 1 */ + .octa 0x000000012ed7e3f200000000f82c6166 + + /* x^215040 mod p(x)` << 1, x^215104 mod p(x)` << 1 */ + .octa 0x000000002dc8778800000000c4f9c7ae + + /* x^214016 mod p(x)` << 1, x^214080 mod p(x)` << 1 */ + .octa 0x0000000018240bb80000000074203d20 + + /* x^212992 mod p(x)` << 1, x^213056 mod p(x)` << 1 */ + .octa 0x000000001ad381580000000198173052 + + /* x^211968 mod p(x)` << 1, x^212032 mod p(x)` << 1 */ + .octa 0x00000001396b78f200000001ce8aba54 + + /* x^210944 mod p(x)` << 1, x^211008 mod p(x)` << 1 */ + .octa 0x000000011a68133400000001850d5d94 + + /* x^209920 mod p(x)` << 1, x^209984 mod p(x)` << 1 */ + .octa 0x000000012104732e00000001d609239c + + /* x^208896 mod p(x)` << 1, x^208960 mod p(x)` << 1 */ + .octa 0x00000000a140d90c000000001595f048 + + /* x^207872 mod p(x)` << 1, x^207936 mod p(x)` << 1 */ + .octa 0x00000001b7215eda0000000042ccee08 + + /* x^206848 mod p(x)` << 1, x^206912 mod p(x)` << 1 */ + .octa 0x00000001aaf1df3c000000010a389d74 + + /* x^205824 mod p(x)` << 1, x^205888 mod p(x)` << 1 */ + .octa 0x0000000029d15b8a000000012a840da6 + + /* x^204800 mod p(x)` << 1, x^204864 mod p(x)` << 1 */ + .octa 0x00000000f1a96922000000001d181c0c + + /* x^203776 mod p(x)` << 1, x^203840 mod p(x)` << 1 */ + .octa 0x00000001ac80d03c0000000068b7d1f6 + + /* x^202752 mod p(x)` << 1, x^202816 mod p(x)` << 1 */ + .octa 0x000000000f11d56a000000005b0f14fc + + /* x^201728 mod p(x)` << 1, x^201792 mod p(x)` << 1 */ + .octa 0x00000001f1c022a20000000179e9e730 + + /* x^200704 mod p(x)` << 1, x^200768 mod p(x)` << 1 */ + .octa 0x0000000173d00ae200000001ce1368d6 + + /* x^199680 mod p(x)` << 1, x^199744 mod p(x)` << 1 */ + .octa 0x00000001d4ffe4ac0000000112c3a84c + + /* x^198656 mod p(x)` << 1, x^198720 mod p(x)` << 1 */ + .octa 0x000000016edc5ae400000000de940fee + + /* x^197632 mod p(x)` << 1, x^197696 mod p(x)` << 1 */ + .octa 0x00000001f1a0214000000000fe896b7e + + /* x^196608 mod p(x)` << 1, x^196672 mod p(x)` << 1 */ + .octa 0x00000000ca0b28a000000001f797431c + + /* x^195584 mod p(x)` << 1, x^195648 mod p(x)` << 1 */ + .octa 0x00000001928e30a20000000053e989ba + + /* x^194560 mod p(x)` << 1, x^194624 mod p(x)` << 1 */ + .octa 0x0000000097b1b002000000003920cd16 + + /* x^193536 mod p(x)` << 1, x^193600 mod p(x)` << 1 */ + .octa 0x00000000b15bf90600000001e6f579b8 + + /* x^192512 mod p(x)` << 1, x^192576 mod p(x)` << 1 */ + .octa 0x00000000411c5d52000000007493cb0a + + /* x^191488 mod p(x)` << 1, x^191552 mod p(x)` << 1 */ + .octa 0x00000001c36f330000000001bdd376d8 + + /* x^190464 mod p(x)` << 1, x^190528 mod p(x)` << 1 */ + .octa 0x00000001119227e0000000016badfee6 + + /* x^189440 mod p(x)` << 1, x^189504 mod p(x)` << 1 */ + .octa 0x00000000114d47020000000071de5c58 + + /* x^188416 mod p(x)` << 1, x^188480 mod p(x)` << 1 */ + .octa 0x00000000458b5b9800000000453f317c + + /* x^187392 mod p(x)` << 1, x^187456 mod p(x)` << 1 */ + .octa 0x000000012e31fb8e0000000121675cce + + /* x^186368 mod p(x)` << 1, x^186432 mod p(x)` << 1 */ + .octa 0x000000005cf619d800000001f409ee92 + + /* x^185344 mod p(x)` << 1, x^185408 mod p(x)` << 1 */ + .octa 0x0000000063f4d8b200000000f36b9c88 + + /* x^184320 mod p(x)` << 1, x^184384 mod p(x)` << 1 */ + .octa 0x000000004138dc8a0000000036b398f4 + + /* x^183296 mod p(x)` << 1, x^183360 mod p(x)` << 1 */ + .octa 0x00000001d29ee8e000000001748f9adc + + /* x^182272 mod p(x)` << 1, x^182336 mod p(x)` << 1 */ + .octa 0x000000006a08ace800000001be94ec00 + + /* x^181248 mod p(x)` << 1, x^181312 mod p(x)` << 1 */ + .octa 0x0000000127d4201000000000b74370d6 + + /* x^180224 mod p(x)` << 1, x^180288 mod p(x)` << 1 */ + .octa 0x0000000019d76b6200000001174d0b98 + + /* x^179200 mod p(x)` << 1, x^179264 mod p(x)` << 1 */ + .octa 0x00000001b1471f6e00000000befc06a4 + + /* x^178176 mod p(x)` << 1, x^178240 mod p(x)` << 1 */ + .octa 0x00000001f64c19cc00000001ae125288 + + /* x^177152 mod p(x)` << 1, x^177216 mod p(x)` << 1 */ + .octa 0x00000000003c0ea00000000095c19b34 + + /* x^176128 mod p(x)` << 1, x^176192 mod p(x)` << 1 */ + .octa 0x000000014d73abf600000001a78496f2 + + /* x^175104 mod p(x)` << 1, x^175168 mod p(x)` << 1 */ + .octa 0x00000001620eb84400000001ac5390a0 + + /* x^174080 mod p(x)` << 1, x^174144 mod p(x)` << 1 */ + .octa 0x0000000147655048000000002a80ed6e + + /* x^173056 mod p(x)` << 1, x^173120 mod p(x)` << 1 */ + .octa 0x0000000067b5077e00000001fa9b0128 + + /* x^172032 mod p(x)` << 1, x^172096 mod p(x)` << 1 */ + .octa 0x0000000010ffe20600000001ea94929e + + /* x^171008 mod p(x)` << 1, x^171072 mod p(x)` << 1 */ + .octa 0x000000000fee8f1e0000000125f4305c + + /* x^169984 mod p(x)` << 1, x^170048 mod p(x)` << 1 */ + .octa 0x00000001da26fbae00000001471e2002 + + /* x^168960 mod p(x)` << 1, x^169024 mod p(x)` << 1 */ + .octa 0x00000001b3a8bd880000000132d2253a + + /* x^167936 mod p(x)` << 1, x^168000 mod p(x)` << 1 */ + .octa 0x00000000e8f3898e00000000f26b3592 + + /* x^166912 mod p(x)` << 1, x^166976 mod p(x)` << 1 */ + .octa 0x00000000b0d0d28c00000000bc8b67b0 + + /* x^165888 mod p(x)` << 1, x^165952 mod p(x)` << 1 */ + .octa 0x0000000030f2a798000000013a826ef2 + + /* x^164864 mod p(x)` << 1, x^164928 mod p(x)` << 1 */ + .octa 0x000000000fba10020000000081482c84 + + /* x^163840 mod p(x)` << 1, x^163904 mod p(x)` << 1 */ + .octa 0x00000000bdb9bd7200000000e77307c2 + + /* x^162816 mod p(x)` << 1, x^162880 mod p(x)` << 1 */ + .octa 0x0000000075d3bf5a00000000d4a07ec8 + + /* x^161792 mod p(x)` << 1, x^161856 mod p(x)` << 1 */ + .octa 0x00000000ef1f98a00000000017102100 + + /* x^160768 mod p(x)` << 1, x^160832 mod p(x)` << 1 */ + .octa 0x00000000689c760200000000db406486 + + /* x^159744 mod p(x)` << 1, x^159808 mod p(x)` << 1 */ + .octa 0x000000016d5fa5fe0000000192db7f88 + + /* x^158720 mod p(x)` << 1, x^158784 mod p(x)` << 1 */ + .octa 0x00000001d0d2b9ca000000018bf67b1e + + /* x^157696 mod p(x)` << 1, x^157760 mod p(x)` << 1 */ + .octa 0x0000000041e7b470000000007c09163e + + /* x^156672 mod p(x)` << 1, x^156736 mod p(x)` << 1 */ + .octa 0x00000001cbb6495e000000000adac060 + + /* x^155648 mod p(x)` << 1, x^155712 mod p(x)` << 1 */ + .octa 0x000000010052a0b000000000bd8316ae + + /* x^154624 mod p(x)` << 1, x^154688 mod p(x)` << 1 */ + .octa 0x00000001d8effb5c000000019f09ab54 + + /* x^153600 mod p(x)` << 1, x^153664 mod p(x)` << 1 */ + .octa 0x00000001d969853c0000000125155542 + + /* x^152576 mod p(x)` << 1, x^152640 mod p(x)` << 1 */ + .octa 0x00000000523ccce2000000018fdb5882 + + /* x^151552 mod p(x)` << 1, x^151616 mod p(x)` << 1 */ + .octa 0x000000001e2436bc00000000e794b3f4 + + /* x^150528 mod p(x)` << 1, x^150592 mod p(x)` << 1 */ + .octa 0x00000000ddd1c3a2000000016f9bb022 + + /* x^149504 mod p(x)` << 1, x^149568 mod p(x)` << 1 */ + .octa 0x0000000019fcfe3800000000290c9978 + + /* x^148480 mod p(x)` << 1, x^148544 mod p(x)` << 1 */ + .octa 0x00000001ce95db640000000083c0f350 + + /* x^147456 mod p(x)` << 1, x^147520 mod p(x)` << 1 */ + .octa 0x00000000af5828060000000173ea6628 + + /* x^146432 mod p(x)` << 1, x^146496 mod p(x)` << 1 */ + .octa 0x00000001006388f600000001c8b4e00a + + /* x^145408 mod p(x)` << 1, x^145472 mod p(x)` << 1 */ + .octa 0x0000000179eca00a00000000de95d6aa + + /* x^144384 mod p(x)` << 1, x^144448 mod p(x)` << 1 */ + .octa 0x0000000122410a6a000000010b7f7248 + + /* x^143360 mod p(x)` << 1, x^143424 mod p(x)` << 1 */ + .octa 0x000000004288e87c00000001326e3a06 + + /* x^142336 mod p(x)` << 1, x^142400 mod p(x)` << 1 */ + .octa 0x000000016c5490da00000000bb62c2e6 + + /* x^141312 mod p(x)` << 1, x^141376 mod p(x)` << 1 */ + .octa 0x00000000d1c71f6e0000000156a4b2c2 + + /* x^140288 mod p(x)` << 1, x^140352 mod p(x)` << 1 */ + .octa 0x00000001b4ce08a6000000011dfe763a + + /* x^139264 mod p(x)` << 1, x^139328 mod p(x)` << 1 */ + .octa 0x00000001466ba60c000000007bcca8e2 + + /* x^138240 mod p(x)` << 1, x^138304 mod p(x)` << 1 */ + .octa 0x00000001f6c488a40000000186118faa + + /* x^137216 mod p(x)` << 1, x^137280 mod p(x)` << 1 */ + .octa 0x000000013bfb06820000000111a65a88 + + /* x^136192 mod p(x)` << 1, x^136256 mod p(x)` << 1 */ + .octa 0x00000000690e9e54000000003565e1c4 + + /* x^135168 mod p(x)` << 1, x^135232 mod p(x)` << 1 */ + .octa 0x00000000281346b6000000012ed02a82 + + /* x^134144 mod p(x)` << 1, x^134208 mod p(x)` << 1 */ + .octa 0x000000015646402400000000c486ecfc + + /* x^133120 mod p(x)` << 1, x^133184 mod p(x)` << 1 */ + .octa 0x000000016063a8dc0000000001b951b2 + + /* x^132096 mod p(x)` << 1, x^132160 mod p(x)` << 1 */ + .octa 0x0000000116a663620000000048143916 + + /* x^131072 mod p(x)` << 1, x^131136 mod p(x)` << 1 */ + .octa 0x000000017e8aa4d200000001dc2ae124 + + /* x^130048 mod p(x)` << 1, x^130112 mod p(x)` << 1 */ + .octa 0x00000001728eb10c00000001416c58d6 + + /* x^129024 mod p(x)` << 1, x^129088 mod p(x)` << 1 */ + .octa 0x00000001b08fd7fa00000000a479744a + + /* x^128000 mod p(x)` << 1, x^128064 mod p(x)` << 1 */ + .octa 0x00000001092a16e80000000096ca3a26 + + /* x^126976 mod p(x)` << 1, x^127040 mod p(x)` << 1 */ + .octa 0x00000000a505637c00000000ff223d4e + + /* x^125952 mod p(x)` << 1, x^126016 mod p(x)` << 1 */ + .octa 0x00000000d94869b2000000010e84da42 + + /* x^124928 mod p(x)` << 1, x^124992 mod p(x)` << 1 */ + .octa 0x00000001c8b203ae00000001b61ba3d0 + + /* x^123904 mod p(x)` << 1, x^123968 mod p(x)` << 1 */ + .octa 0x000000005704aea000000000680f2de8 + + /* x^122880 mod p(x)` << 1, x^122944 mod p(x)` << 1 */ + .octa 0x000000012e295fa2000000008772a9a8 + + /* x^121856 mod p(x)` << 1, x^121920 mod p(x)` << 1 */ + .octa 0x000000011d0908bc0000000155f295bc + + /* x^120832 mod p(x)` << 1, x^120896 mod p(x)` << 1 */ + .octa 0x0000000193ed97ea00000000595f9282 + + /* x^119808 mod p(x)` << 1, x^119872 mod p(x)` << 1 */ + .octa 0x000000013a0f1c520000000164b1c25a + + /* x^118784 mod p(x)` << 1, x^118848 mod p(x)` << 1 */ + .octa 0x000000010c2c40c000000000fbd67c50 + + /* x^117760 mod p(x)` << 1, x^117824 mod p(x)` << 1 */ + .octa 0x00000000ff6fac3e0000000096076268 + + /* x^116736 mod p(x)` << 1, x^116800 mod p(x)` << 1 */ + .octa 0x000000017b3609c000000001d288e4cc + + /* x^115712 mod p(x)` << 1, x^115776 mod p(x)` << 1 */ + .octa 0x0000000088c8c92200000001eaac1bdc + + /* x^114688 mod p(x)` << 1, x^114752 mod p(x)` << 1 */ + .octa 0x00000001751baae600000001f1ea39e2 + + /* x^113664 mod p(x)` << 1, x^113728 mod p(x)` << 1 */ + .octa 0x000000010795297200000001eb6506fc + + /* x^112640 mod p(x)` << 1, x^112704 mod p(x)` << 1 */ + .octa 0x0000000162b00abe000000010f806ffe + + /* x^111616 mod p(x)` << 1, x^111680 mod p(x)` << 1 */ + .octa 0x000000000d7b404c000000010408481e + + /* x^110592 mod p(x)` << 1, x^110656 mod p(x)` << 1 */ + .octa 0x00000000763b13d40000000188260534 + + /* x^109568 mod p(x)` << 1, x^109632 mod p(x)` << 1 */ + .octa 0x00000000f6dc22d80000000058fc73e0 + + /* x^108544 mod p(x)` << 1, x^108608 mod p(x)` << 1 */ + .octa 0x000000007daae06000000000391c59b8 + + /* x^107520 mod p(x)` << 1, x^107584 mod p(x)` << 1 */ + .octa 0x000000013359ab7c000000018b638400 + + /* x^106496 mod p(x)` << 1, x^106560 mod p(x)` << 1 */ + .octa 0x000000008add438a000000011738f5c4 + + /* x^105472 mod p(x)` << 1, x^105536 mod p(x)` << 1 */ + .octa 0x00000001edbefdea000000008cf7c6da + + /* x^104448 mod p(x)` << 1, x^104512 mod p(x)` << 1 */ + .octa 0x000000004104e0f800000001ef97fb16 + + /* x^103424 mod p(x)` << 1, x^103488 mod p(x)` << 1 */ + .octa 0x00000000b48a82220000000102130e20 + + /* x^102400 mod p(x)` << 1, x^102464 mod p(x)` << 1 */ + .octa 0x00000001bcb4684400000000db968898 + + /* x^101376 mod p(x)` << 1, x^101440 mod p(x)` << 1 */ + .octa 0x000000013293ce0a00000000b5047b5e + + /* x^100352 mod p(x)` << 1, x^100416 mod p(x)` << 1 */ + .octa 0x00000001710d0844000000010b90fdb2 + + /* x^99328 mod p(x)` << 1, x^99392 mod p(x)` << 1 */ + .octa 0x0000000117907f6e000000004834a32e + + /* x^98304 mod p(x)` << 1, x^98368 mod p(x)` << 1 */ + .octa 0x0000000087ddf93e0000000059c8f2b0 + + /* x^97280 mod p(x)` << 1, x^97344 mod p(x)` << 1 */ + .octa 0x000000005970e9b00000000122cec508 + + /* x^96256 mod p(x)` << 1, x^96320 mod p(x)` << 1 */ + .octa 0x0000000185b2b7d0000000000a330cda + + /* x^95232 mod p(x)` << 1, x^95296 mod p(x)` << 1 */ + .octa 0x00000001dcee0efc000000014a47148c + + /* x^94208 mod p(x)` << 1, x^94272 mod p(x)` << 1 */ + .octa 0x0000000030da27220000000042c61cb8 + + /* x^93184 mod p(x)` << 1, x^93248 mod p(x)` << 1 */ + .octa 0x000000012f925a180000000012fe6960 + + /* x^92160 mod p(x)` << 1, x^92224 mod p(x)` << 1 */ + .octa 0x00000000dd2e357c00000000dbda2c20 + + /* x^91136 mod p(x)` << 1, x^91200 mod p(x)` << 1 */ + .octa 0x00000000071c80de000000011122410c + + /* x^90112 mod p(x)` << 1, x^90176 mod p(x)` << 1 */ + .octa 0x000000011513140a00000000977b2070 + + /* x^89088 mod p(x)` << 1, x^89152 mod p(x)` << 1 */ + .octa 0x00000001df876e8e000000014050438e + + /* x^88064 mod p(x)` << 1, x^88128 mod p(x)` << 1 */ + .octa 0x000000015f81d6ce0000000147c840e8 + + /* x^87040 mod p(x)` << 1, x^87104 mod p(x)` << 1 */ + .octa 0x000000019dd94dbe00000001cc7c88ce + + /* x^86016 mod p(x)` << 1, x^86080 mod p(x)` << 1 */ + .octa 0x00000001373d206e00000001476b35a4 + + /* x^84992 mod p(x)` << 1, x^85056 mod p(x)` << 1 */ + .octa 0x00000000668ccade000000013d52d508 + + /* x^83968 mod p(x)` << 1, x^84032 mod p(x)` << 1 */ + .octa 0x00000001b192d268000000008e4be32e + + /* x^82944 mod p(x)` << 1, x^83008 mod p(x)` << 1 */ + .octa 0x00000000e30f3a7800000000024120fe + + /* x^81920 mod p(x)` << 1, x^81984 mod p(x)` << 1 */ + .octa 0x000000010ef1f7bc00000000ddecddb4 + + /* x^80896 mod p(x)` << 1, x^80960 mod p(x)` << 1 */ + .octa 0x00000001f5ac738000000000d4d403bc + + /* x^79872 mod p(x)` << 1, x^79936 mod p(x)` << 1 */ + .octa 0x000000011822ea7000000001734b89aa + + /* x^78848 mod p(x)` << 1, x^78912 mod p(x)` << 1 */ + .octa 0x00000000c3a33848000000010e7a58d6 + + /* x^77824 mod p(x)` << 1, x^77888 mod p(x)` << 1 */ + .octa 0x00000001bd151c2400000001f9f04e9c + + /* x^76800 mod p(x)` << 1, x^76864 mod p(x)` << 1 */ + .octa 0x0000000056002d7600000000b692225e + + /* x^75776 mod p(x)` << 1, x^75840 mod p(x)` << 1 */ + .octa 0x000000014657c4f4000000019b8d3f3e + + /* x^74752 mod p(x)` << 1, x^74816 mod p(x)` << 1 */ + .octa 0x0000000113742d7c00000001a874f11e + + /* x^73728 mod p(x)` << 1, x^73792 mod p(x)` << 1 */ + .octa 0x000000019c5920ba000000010d5a4254 + + /* x^72704 mod p(x)` << 1, x^72768 mod p(x)` << 1 */ + .octa 0x000000005216d2d600000000bbb2f5d6 + + /* x^71680 mod p(x)` << 1, x^71744 mod p(x)` << 1 */ + .octa 0x0000000136f5ad8a0000000179cc0e36 + + /* x^70656 mod p(x)` << 1, x^70720 mod p(x)` << 1 */ + .octa 0x000000018b07beb600000001dca1da4a + + /* x^69632 mod p(x)` << 1, x^69696 mod p(x)` << 1 */ + .octa 0x00000000db1e93b000000000feb1a192 + + /* x^68608 mod p(x)` << 1, x^68672 mod p(x)` << 1 */ + .octa 0x000000000b96fa3a00000000d1eeedd6 + + /* x^67584 mod p(x)` << 1, x^67648 mod p(x)` << 1 */ + .octa 0x00000001d9968af0000000008fad9bb4 + + /* x^66560 mod p(x)` << 1, x^66624 mod p(x)` << 1 */ + .octa 0x000000000e4a77a200000001884938e4 + + /* x^65536 mod p(x)` << 1, x^65600 mod p(x)` << 1 */ + .octa 0x00000000508c2ac800000001bc2e9bc0 + + /* x^64512 mod p(x)` << 1, x^64576 mod p(x)` << 1 */ + .octa 0x0000000021572a8000000001f9658a68 + + /* x^63488 mod p(x)` << 1, x^63552 mod p(x)` << 1 */ + .octa 0x00000001b859daf2000000001b9224fc + + /* x^62464 mod p(x)` << 1, x^62528 mod p(x)` << 1 */ + .octa 0x000000016f7884740000000055b2fb84 + + /* x^61440 mod p(x)` << 1, x^61504 mod p(x)` << 1 */ + .octa 0x00000001b438810e000000018b090348 + + /* x^60416 mod p(x)` << 1, x^60480 mod p(x)` << 1 */ + .octa 0x0000000095ddc6f2000000011ccbd5ea + + /* x^59392 mod p(x)` << 1, x^59456 mod p(x)` << 1 */ + .octa 0x00000001d977c20c0000000007ae47f8 + + /* x^58368 mod p(x)` << 1, x^58432 mod p(x)` << 1 */ + .octa 0x00000000ebedb99a0000000172acbec0 + + /* x^57344 mod p(x)` << 1, x^57408 mod p(x)` << 1 */ + .octa 0x00000001df9e9e9200000001c6e3ff20 + + /* x^56320 mod p(x)` << 1, x^56384 mod p(x)` << 1 */ + .octa 0x00000001a4a3f95200000000e1b38744 + + /* x^55296 mod p(x)` << 1, x^55360 mod p(x)` << 1 */ + .octa 0x00000000e2f5122000000000791585b2 + + /* x^54272 mod p(x)` << 1, x^54336 mod p(x)` << 1 */ + .octa 0x000000004aa01f3e00000000ac53b894 + + /* x^53248 mod p(x)` << 1, x^53312 mod p(x)` << 1 */ + .octa 0x00000000b3e90a5800000001ed5f2cf4 + + /* x^52224 mod p(x)` << 1, x^52288 mod p(x)` << 1 */ + .octa 0x000000000c9ca2aa00000001df48b2e0 + + /* x^51200 mod p(x)` << 1, x^51264 mod p(x)` << 1 */ + .octa 0x000000015168231600000000049c1c62 + + /* x^50176 mod p(x)` << 1, x^50240 mod p(x)` << 1 */ + .octa 0x0000000036fce78c000000017c460c12 + + /* x^49152 mod p(x)` << 1, x^49216 mod p(x)` << 1 */ + .octa 0x000000009037dc10000000015be4da7e + + /* x^48128 mod p(x)` << 1, x^48192 mod p(x)` << 1 */ + .octa 0x00000000d3298582000000010f38f668 + + /* x^47104 mod p(x)` << 1, x^47168 mod p(x)` << 1 */ + .octa 0x00000001b42e8ad60000000039f40a00 + + /* x^46080 mod p(x)` << 1, x^46144 mod p(x)` << 1 */ + .octa 0x00000000142a983800000000bd4c10c4 + + /* x^45056 mod p(x)` << 1, x^45120 mod p(x)` << 1 */ + .octa 0x0000000109c7f1900000000042db1d98 + + /* x^44032 mod p(x)` << 1, x^44096 mod p(x)` << 1 */ + .octa 0x0000000056ff931000000001c905bae6 + + /* x^43008 mod p(x)` << 1, x^43072 mod p(x)` << 1 */ + .octa 0x00000001594513aa00000000069d40ea + + /* x^41984 mod p(x)` << 1, x^42048 mod p(x)` << 1 */ + .octa 0x00000001e3b5b1e8000000008e4fbad0 + + /* x^40960 mod p(x)` << 1, x^41024 mod p(x)` << 1 */ + .octa 0x000000011dd5fc080000000047bedd46 + + /* x^39936 mod p(x)` << 1, x^40000 mod p(x)` << 1 */ + .octa 0x00000001675f0cc20000000026396bf8 + + /* x^38912 mod p(x)` << 1, x^38976 mod p(x)` << 1 */ + .octa 0x00000000d1c8dd4400000000379beb92 + + /* x^37888 mod p(x)` << 1, x^37952 mod p(x)` << 1 */ + .octa 0x0000000115ebd3d8000000000abae54a + + /* x^36864 mod p(x)` << 1, x^36928 mod p(x)` << 1 */ + .octa 0x00000001ecbd0dac0000000007e6a128 + + /* x^35840 mod p(x)` << 1, x^35904 mod p(x)` << 1 */ + .octa 0x00000000cdf67af2000000000ade29d2 + + /* x^34816 mod p(x)` << 1, x^34880 mod p(x)` << 1 */ + .octa 0x000000004c01ff4c00000000f974c45c + + /* x^33792 mod p(x)` << 1, x^33856 mod p(x)` << 1 */ + .octa 0x00000000f2d8657e00000000e77ac60a + + /* x^32768 mod p(x)` << 1, x^32832 mod p(x)` << 1 */ + .octa 0x000000006bae74c40000000145895816 + + /* x^31744 mod p(x)` << 1, x^31808 mod p(x)` << 1 */ + .octa 0x0000000152af8aa00000000038e362be + + /* x^30720 mod p(x)` << 1, x^30784 mod p(x)` << 1 */ + .octa 0x0000000004663802000000007f991a64 + + /* x^29696 mod p(x)` << 1, x^29760 mod p(x)` << 1 */ + .octa 0x00000001ab2f5afc00000000fa366d3a + + /* x^28672 mod p(x)` << 1, x^28736 mod p(x)` << 1 */ + .octa 0x0000000074a4ebd400000001a2bb34f0 + + /* x^27648 mod p(x)` << 1, x^27712 mod p(x)` << 1 */ + .octa 0x00000001d7ab3a4c0000000028a9981e + + /* x^26624 mod p(x)` << 1, x^26688 mod p(x)` << 1 */ + .octa 0x00000001a8da60c600000001dbc672be + + /* x^25600 mod p(x)` << 1, x^25664 mod p(x)` << 1 */ + .octa 0x000000013cf6382000000000b04d77f6 + + /* x^24576 mod p(x)` << 1, x^24640 mod p(x)` << 1 */ + .octa 0x00000000bec12e1e0000000124400d96 + + /* x^23552 mod p(x)` << 1, x^23616 mod p(x)` << 1 */ + .octa 0x00000001c6368010000000014ca4b414 + + /* x^22528 mod p(x)` << 1, x^22592 mod p(x)` << 1 */ + .octa 0x00000001e6e78758000000012fe2c938 + + /* x^21504 mod p(x)` << 1, x^21568 mod p(x)` << 1 */ + .octa 0x000000008d7f2b3c00000001faed01e6 + + /* x^20480 mod p(x)` << 1, x^20544 mod p(x)` << 1 */ + .octa 0x000000016b4a156e000000007e80ecfe + + /* x^19456 mod p(x)` << 1, x^19520 mod p(x)` << 1 */ + .octa 0x00000001c63cfeb60000000098daee94 + + /* x^18432 mod p(x)` << 1, x^18496 mod p(x)` << 1 */ + .octa 0x000000015f902670000000010a04edea + + /* x^17408 mod p(x)` << 1, x^17472 mod p(x)` << 1 */ + .octa 0x00000001cd5de11e00000001c00b4524 + + /* x^16384 mod p(x)` << 1, x^16448 mod p(x)` << 1 */ + .octa 0x000000001acaec540000000170296550 + + /* x^15360 mod p(x)` << 1, x^15424 mod p(x)` << 1 */ + .octa 0x000000002bd0ca780000000181afaa48 + + /* x^14336 mod p(x)` << 1, x^14400 mod p(x)` << 1 */ + .octa 0x0000000032d63d5c0000000185a31ffa + + /* x^13312 mod p(x)` << 1, x^13376 mod p(x)` << 1 */ + .octa 0x000000001c6d4e4c000000002469f608 + + /* x^12288 mod p(x)` << 1, x^12352 mod p(x)` << 1 */ + .octa 0x0000000106a60b92000000006980102a + + /* x^11264 mod p(x)` << 1, x^11328 mod p(x)` << 1 */ + .octa 0x00000000d3855e120000000111ea9ca8 + + /* x^10240 mod p(x)` << 1, x^10304 mod p(x)` << 1 */ + .octa 0x00000000e312563600000001bd1d29ce + + /* x^9216 mod p(x)` << 1, x^9280 mod p(x)` << 1 */ + .octa 0x000000009e8f7ea400000001b34b9580 + + /* x^8192 mod p(x)` << 1, x^8256 mod p(x)` << 1 */ + .octa 0x00000001c82e562c000000003076054e + + /* x^7168 mod p(x)` << 1, x^7232 mod p(x)` << 1 */ + .octa 0x00000000ca9f09ce000000012a608ea4 + + /* x^6144 mod p(x)` << 1, x^6208 mod p(x)` << 1 */ + .octa 0x00000000c63764e600000000784d05fe + + /* x^5120 mod p(x)` << 1, x^5184 mod p(x)` << 1 */ + .octa 0x0000000168d2e49e000000016ef0d82a + + /* x^4096 mod p(x)` << 1, x^4160 mod p(x)` << 1 */ + .octa 0x00000000e986c1480000000075bda454 + + /* x^3072 mod p(x)` << 1, x^3136 mod p(x)` << 1 */ + .octa 0x00000000cfb65894000000003dc0a1c4 + + /* x^2048 mod p(x)` << 1, x^2112 mod p(x)` << 1 */ + .octa 0x0000000111cadee400000000e9a5d8be + + /* x^1024 mod p(x)` << 1, x^1088 mod p(x)` << 1 */ + .octa 0x0000000171fb63ce00000001609bc4b4 + +SHORT_CONSTANTS: + + /* Reduce final 1024-2048 bits to 64 bits, shifting 32 bits to include the trailing 32 bits of zeros */ + /* x^1952 mod p(x)`, x^1984 mod p(x)`, x^2016 mod p(x)`, x^2048 mod p(x)` */ + .octa 0x7fec2963e5bf80485cf015c388e56f72 + + /* x^1824 mod p(x)`, x^1856 mod p(x)`, x^1888 mod p(x)`, x^1920 mod p(x)` */ + .octa 0x38e888d4844752a9963a18920246e2e6 + + /* x^1696 mod p(x)`, x^1728 mod p(x)`, x^1760 mod p(x)`, x^1792 mod p(x)` */ + .octa 0x42316c00730206ad419a441956993a31 + + /* x^1568 mod p(x)`, x^1600 mod p(x)`, x^1632 mod p(x)`, x^1664 mod p(x)` */ + .octa 0x543d5c543e65ddf9924752ba2b830011 + + /* x^1440 mod p(x)`, x^1472 mod p(x)`, x^1504 mod p(x)`, x^1536 mod p(x)` */ + .octa 0x78e87aaf56767c9255bd7f9518e4a304 + + /* x^1312 mod p(x)`, x^1344 mod p(x)`, x^1376 mod p(x)`, x^1408 mod p(x)` */ + .octa 0x8f68fcec1903da7f6d76739fe0553f1e + + /* x^1184 mod p(x)`, x^1216 mod p(x)`, x^1248 mod p(x)`, x^1280 mod p(x)` */ + .octa 0x3f4840246791d588c133722b1fe0b5c3 + + /* x^1056 mod p(x)`, x^1088 mod p(x)`, x^1120 mod p(x)`, x^1152 mod p(x)` */ + .octa 0x34c96751b04de25a64b67ee0e55ef1f3 + + /* x^928 mod p(x)`, x^960 mod p(x)`, x^992 mod p(x)`, x^1024 mod p(x)` */ + .octa 0x156c8e180b4a395b069db049b8fdb1e7 + + /* x^800 mod p(x)`, x^832 mod p(x)`, x^864 mod p(x)`, x^896 mod p(x)` */ + .octa 0xe0b99ccbe661f7bea11bfaf3c9e90b9e + + /* x^672 mod p(x)`, x^704 mod p(x)`, x^736 mod p(x)`, x^768 mod p(x)` */ + .octa 0x041d37768cd75659817cdc5119b29a35 + + /* x^544 mod p(x)`, x^576 mod p(x)`, x^608 mod p(x)`, x^640 mod p(x)` */ + .octa 0x3a0777818cfaa9651ce9d94b36c41f1c + + /* x^416 mod p(x)`, x^448 mod p(x)`, x^480 mod p(x)`, x^512 mod p(x)` */ + .octa 0x0e148e8252377a554f256efcb82be955 + + /* x^288 mod p(x)`, x^320 mod p(x)`, x^352 mod p(x)`, x^384 mod p(x)` */ + .octa 0x9c25531d19e65ddeec1631edb2dea967 + + /* x^160 mod p(x)`, x^192 mod p(x)`, x^224 mod p(x)`, x^256 mod p(x)` */ + .octa 0x790606ff9957c0a65d27e147510ac59a + + /* x^32 mod p(x)`, x^64 mod p(x)`, x^96 mod p(x)`, x^128 mod p(x)` */ + .octa 0x82f63b786ea2d55ca66805eb18b8ea18 + + +BARRETT_CONSTANTS: + /* 33 bit reflected Barrett constant m - (4^32)/n */ + .octa 0x000000000000000000000000dea713f1 /* x^64 div p(x)` */ + /* 33 bit reflected Barrett constant n */ + .octa 0x00000000000000000000000105ec76f1 + +#endif /* __powerpc__ */ + +#endif diff --git a/extra/crc32-vpmsum/crc32c_wrapper.c b/extra/crc32-vpmsum/crc32c_wrapper.c new file mode 100644 index 00000000000..b121d3e8c41 --- /dev/null +++ b/extra/crc32-vpmsum/crc32c_wrapper.c @@ -0,0 +1,78 @@ +#ifdef __powerpc__ + +#define F crc32c_vpmsum +#define __F __crc32c_vpmsum + +#define CRC 0x1edc6f41 + +static const unsigned int crc_table[] = { + 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, + 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, + 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, + 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, + 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, + 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384, + 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, + 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b, + 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, + 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, + 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, + 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa, + 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, + 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a, + 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, + 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, + 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, + 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957, + 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, + 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198, + 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, + 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, + 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, + 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7, + 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, + 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789, + 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, + 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, + 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, + 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6, + 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, + 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829, + 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, + 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, + 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, + 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c, + 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, + 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc, + 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, + 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, + 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, + 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d, + 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, + 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982, + 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, + 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, + 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, + 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed, + 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, + 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f, + 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, + 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, + 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, + 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540, + 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, + 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f, + 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, + 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, + 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, + 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e, + 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, + 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e, + 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, + 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351,}; + + +#include "crc32_wrapper.ic" + +#endif + diff --git a/extra/crc32-vpmsum/crc32ieee.S b/extra/crc32-vpmsum/crc32ieee.S new file mode 100644 index 00000000000..42c4f77630f --- /dev/null +++ b/extra/crc32-vpmsum/crc32ieee.S @@ -0,0 +1,14 @@ +#ifdef __powerpc__ + +#define CONSTANTS .crc32_constants +#define SHORT_CONSTANTS .crc32_short_constants +#define BARRETT_CONSTANTS .crc32_barrett_constants + +#include "crc32ieee_constants.h" + +#define __F __crc32ieee_vpmsum + +#include "crc32.iS" + +#endif + diff --git a/extra/crc32-vpmsum/crc32ieee_constants.h b/extra/crc32-vpmsum/crc32ieee_constants.h new file mode 100644 index 00000000000..a99b1c0d859 --- /dev/null +++ b/extra/crc32-vpmsum/crc32ieee_constants.h @@ -0,0 +1,835 @@ +#ifndef CRC32_CONSTANTS_H +#define CRC32_CONSTANTS_H + +#ifdef __powerpc__ + +#define MAX_SIZE 32768 +CONSTANTS: + + /* Reduce 262144 kbits to 1024 bits */ + /* x^261120 mod p(x)` << 1, x^261184 mod p(x)` << 1 */ + .octa 0x00000001651797d20000000099ea94a8 + + /* x^260096 mod p(x)` << 1, x^260160 mod p(x)` << 1 */ + .octa 0x0000000021e0d56c00000000945a8420 + + /* x^259072 mod p(x)` << 1, x^259136 mod p(x)` << 1 */ + .octa 0x000000000f95ecaa0000000030762706 + + /* x^258048 mod p(x)` << 1, x^258112 mod p(x)` << 1 */ + .octa 0x00000001ebd224ac00000001a52fc582 + + /* x^257024 mod p(x)` << 1, x^257088 mod p(x)` << 1 */ + .octa 0x000000000ccb97ca00000001a4a7167a + + /* x^256000 mod p(x)` << 1, x^256064 mod p(x)` << 1 */ + .octa 0x00000001006ec8a8000000000c18249a + + /* x^254976 mod p(x)` << 1, x^255040 mod p(x)` << 1 */ + .octa 0x000000014f58f19600000000a924ae7c + + /* x^253952 mod p(x)` << 1, x^254016 mod p(x)` << 1 */ + .octa 0x00000001a7192ca600000001e12ccc12 + + /* x^252928 mod p(x)` << 1, x^252992 mod p(x)` << 1 */ + .octa 0x000000019a64bab200000000a0b9d4ac + + /* x^251904 mod p(x)` << 1, x^251968 mod p(x)` << 1 */ + .octa 0x0000000014f4ed2e0000000095e8ddfe + + /* x^250880 mod p(x)` << 1, x^250944 mod p(x)` << 1 */ + .octa 0x000000011092b6a200000000233fddc4 + + /* x^249856 mod p(x)` << 1, x^249920 mod p(x)` << 1 */ + .octa 0x00000000c8a1629c00000001b4529b62 + + /* x^248832 mod p(x)` << 1, x^248896 mod p(x)` << 1 */ + .octa 0x000000017bf32e8e00000001a7fa0e64 + + /* x^247808 mod p(x)` << 1, x^247872 mod p(x)` << 1 */ + .octa 0x00000001f8cc658200000001b5334592 + + /* x^246784 mod p(x)` << 1, x^246848 mod p(x)` << 1 */ + .octa 0x000000008631ddf0000000011f8ee1b4 + + /* x^245760 mod p(x)` << 1, x^245824 mod p(x)` << 1 */ + .octa 0x000000007e5a76d0000000006252e632 + + /* x^244736 mod p(x)` << 1, x^244800 mod p(x)` << 1 */ + .octa 0x000000002b09b31c00000000ab973e84 + + /* x^243712 mod p(x)` << 1, x^243776 mod p(x)` << 1 */ + .octa 0x00000001b2df1f84000000007734f5ec + + /* x^242688 mod p(x)` << 1, x^242752 mod p(x)` << 1 */ + .octa 0x00000001d6f56afc000000007c547798 + + /* x^241664 mod p(x)` << 1, x^241728 mod p(x)` << 1 */ + .octa 0x00000001b9b5e70c000000007ec40210 + + /* x^240640 mod p(x)` << 1, x^240704 mod p(x)` << 1 */ + .octa 0x0000000034b626d200000001ab1695a8 + + /* x^239616 mod p(x)` << 1, x^239680 mod p(x)` << 1 */ + .octa 0x000000014c53479a0000000090494bba + + /* x^238592 mod p(x)` << 1, x^238656 mod p(x)` << 1 */ + .octa 0x00000001a6d179a400000001123fb816 + + /* x^237568 mod p(x)` << 1, x^237632 mod p(x)` << 1 */ + .octa 0x000000015abd16b400000001e188c74c + + /* x^236544 mod p(x)` << 1, x^236608 mod p(x)` << 1 */ + .octa 0x00000000018f985200000001c2d3451c + + /* x^235520 mod p(x)` << 1, x^235584 mod p(x)` << 1 */ + .octa 0x000000001fb3084a00000000f55cf1ca + + /* x^234496 mod p(x)` << 1, x^234560 mod p(x)` << 1 */ + .octa 0x00000000c53dfb0400000001a0531540 + + /* x^233472 mod p(x)` << 1, x^233536 mod p(x)` << 1 */ + .octa 0x00000000e10c9ad60000000132cd7ebc + + /* x^232448 mod p(x)` << 1, x^232512 mod p(x)` << 1 */ + .octa 0x0000000025aa994a0000000073ab7f36 + + /* x^231424 mod p(x)` << 1, x^231488 mod p(x)` << 1 */ + .octa 0x00000000fa3a74c40000000041aed1c2 + + /* x^230400 mod p(x)` << 1, x^230464 mod p(x)` << 1 */ + .octa 0x0000000033eb3f400000000136c53800 + + /* x^229376 mod p(x)` << 1, x^229440 mod p(x)` << 1 */ + .octa 0x000000017193f2960000000126835a30 + + /* x^228352 mod p(x)` << 1, x^228416 mod p(x)` << 1 */ + .octa 0x0000000043f6c86a000000006241b502 + + /* x^227328 mod p(x)` << 1, x^227392 mod p(x)` << 1 */ + .octa 0x000000016b513ec600000000d5196ad4 + + /* x^226304 mod p(x)` << 1, x^226368 mod p(x)` << 1 */ + .octa 0x00000000c8f25b4e000000009cfa769a + + /* x^225280 mod p(x)` << 1, x^225344 mod p(x)` << 1 */ + .octa 0x00000001a45048ec00000000920e5df4 + + /* x^224256 mod p(x)` << 1, x^224320 mod p(x)` << 1 */ + .octa 0x000000000c4410040000000169dc310e + + /* x^223232 mod p(x)` << 1, x^223296 mod p(x)` << 1 */ + .octa 0x000000000e17cad60000000009fc331c + + /* x^222208 mod p(x)` << 1, x^222272 mod p(x)` << 1 */ + .octa 0x00000001253ae964000000010d94a81e + + /* x^221184 mod p(x)` << 1, x^221248 mod p(x)` << 1 */ + .octa 0x00000001d7c88ebc0000000027a20ab2 + + /* x^220160 mod p(x)` << 1, x^220224 mod p(x)` << 1 */ + .octa 0x00000001e7ca913a0000000114f87504 + + /* x^219136 mod p(x)` << 1, x^219200 mod p(x)` << 1 */ + .octa 0x0000000033ed078a000000004b076d96 + + /* x^218112 mod p(x)` << 1, x^218176 mod p(x)` << 1 */ + .octa 0x00000000e1839c7800000000da4d1e74 + + /* x^217088 mod p(x)` << 1, x^217152 mod p(x)` << 1 */ + .octa 0x00000001322b267e000000001b81f672 + + /* x^216064 mod p(x)` << 1, x^216128 mod p(x)` << 1 */ + .octa 0x00000000638231b6000000009367c988 + + /* x^215040 mod p(x)` << 1, x^215104 mod p(x)` << 1 */ + .octa 0x00000001ee7f16f400000001717214ca + + /* x^214016 mod p(x)` << 1, x^214080 mod p(x)` << 1 */ + .octa 0x0000000117d9924a000000009f47d820 + + /* x^212992 mod p(x)` << 1, x^213056 mod p(x)` << 1 */ + .octa 0x00000000e1a9e0c4000000010d9a47d2 + + /* x^211968 mod p(x)` << 1, x^212032 mod p(x)` << 1 */ + .octa 0x00000001403731dc00000000a696c58c + + /* x^210944 mod p(x)` << 1, x^211008 mod p(x)` << 1 */ + .octa 0x00000001a5ea9682000000002aa28ec6 + + /* x^209920 mod p(x)` << 1, x^209984 mod p(x)` << 1 */ + .octa 0x0000000101c5c57800000001fe18fd9a + + /* x^208896 mod p(x)` << 1, x^208960 mod p(x)` << 1 */ + .octa 0x00000000dddf6494000000019d4fc1ae + + /* x^207872 mod p(x)` << 1, x^207936 mod p(x)` << 1 */ + .octa 0x00000000f1c3db2800000001ba0e3dea + + /* x^206848 mod p(x)` << 1, x^206912 mod p(x)` << 1 */ + .octa 0x000000013112fb9c0000000074b59a5e + + /* x^205824 mod p(x)` << 1, x^205888 mod p(x)` << 1 */ + .octa 0x00000000b680b90600000000f2b5ea98 + + /* x^204800 mod p(x)` << 1, x^204864 mod p(x)` << 1 */ + .octa 0x000000001a2829320000000187132676 + + /* x^203776 mod p(x)` << 1, x^203840 mod p(x)` << 1 */ + .octa 0x0000000089406e7e000000010a8c6ad4 + + /* x^202752 mod p(x)` << 1, x^202816 mod p(x)` << 1 */ + .octa 0x00000001def6be8c00000001e21dfe70 + + /* x^201728 mod p(x)` << 1, x^201792 mod p(x)` << 1 */ + .octa 0x000000007525872800000001da0050e4 + + /* x^200704 mod p(x)` << 1, x^200768 mod p(x)` << 1 */ + .octa 0x000000019536090a00000000772172ae + + /* x^199680 mod p(x)` << 1, x^199744 mod p(x)` << 1 */ + .octa 0x00000000f2455bfc00000000e47724aa + + /* x^198656 mod p(x)` << 1, x^198720 mod p(x)` << 1 */ + .octa 0x000000018c40baf4000000003cd63ac4 + + /* x^197632 mod p(x)` << 1, x^197696 mod p(x)` << 1 */ + .octa 0x000000004cd390d400000001bf47d352 + + /* x^196608 mod p(x)` << 1, x^196672 mod p(x)` << 1 */ + .octa 0x00000001e4ece95a000000018dc1d708 + + /* x^195584 mod p(x)` << 1, x^195648 mod p(x)` << 1 */ + .octa 0x000000001a3ee918000000002d4620a4 + + /* x^194560 mod p(x)` << 1, x^194624 mod p(x)` << 1 */ + .octa 0x000000007c652fb80000000058fd1740 + + /* x^193536 mod p(x)` << 1, x^193600 mod p(x)` << 1 */ + .octa 0x000000011c67842c00000000dadd9bfc + + /* x^192512 mod p(x)` << 1, x^192576 mod p(x)` << 1 */ + .octa 0x00000000254f759c00000001ea2140be + + /* x^191488 mod p(x)` << 1, x^191552 mod p(x)` << 1 */ + .octa 0x000000007ece94ca000000009de128ba + + /* x^190464 mod p(x)` << 1, x^190528 mod p(x)` << 1 */ + .octa 0x0000000038f258c2000000013ac3aa8e + + /* x^189440 mod p(x)` << 1, x^189504 mod p(x)` << 1 */ + .octa 0x00000001cdf17b000000000099980562 + + /* x^188416 mod p(x)` << 1, x^188480 mod p(x)` << 1 */ + .octa 0x000000011f882c1600000001c1579c86 + + /* x^187392 mod p(x)` << 1, x^187456 mod p(x)` << 1 */ + .octa 0x0000000100093fc80000000068dbbf94 + + /* x^186368 mod p(x)` << 1, x^186432 mod p(x)` << 1 */ + .octa 0x00000001cd684f16000000004509fb04 + + /* x^185344 mod p(x)` << 1, x^185408 mod p(x)` << 1 */ + .octa 0x000000004bc6a70a00000001202f6398 + + /* x^184320 mod p(x)` << 1, x^184384 mod p(x)` << 1 */ + .octa 0x000000004fc7e8e4000000013aea243e + + /* x^183296 mod p(x)` << 1, x^183360 mod p(x)` << 1 */ + .octa 0x0000000130103f1c00000001b4052ae6 + + /* x^182272 mod p(x)` << 1, x^182336 mod p(x)` << 1 */ + .octa 0x0000000111b0024c00000001cd2a0ae8 + + /* x^181248 mod p(x)` << 1, x^181312 mod p(x)` << 1 */ + .octa 0x000000010b3079da00000001fe4aa8b4 + + /* x^180224 mod p(x)` << 1, x^180288 mod p(x)` << 1 */ + .octa 0x000000010192bcc200000001d1559a42 + + /* x^179200 mod p(x)` << 1, x^179264 mod p(x)` << 1 */ + .octa 0x0000000074838d5000000001f3e05ecc + + /* x^178176 mod p(x)` << 1, x^178240 mod p(x)` << 1 */ + .octa 0x000000001b20f5200000000104ddd2cc + + /* x^177152 mod p(x)` << 1, x^177216 mod p(x)` << 1 */ + .octa 0x0000000050c3590a000000015393153c + + /* x^176128 mod p(x)` << 1, x^176192 mod p(x)` << 1 */ + .octa 0x00000000b41cac8e0000000057e942c6 + + /* x^175104 mod p(x)` << 1, x^175168 mod p(x)` << 1 */ + .octa 0x000000000c72cc78000000012c633850 + + /* x^174080 mod p(x)` << 1, x^174144 mod p(x)` << 1 */ + .octa 0x0000000030cdb03200000000ebcaae4c + + /* x^173056 mod p(x)` << 1, x^173120 mod p(x)` << 1 */ + .octa 0x000000013e09fc32000000013ee532a6 + + /* x^172032 mod p(x)` << 1, x^172096 mod p(x)` << 1 */ + .octa 0x000000001ed624d200000001bf0cbc7e + + /* x^171008 mod p(x)` << 1, x^171072 mod p(x)` << 1 */ + .octa 0x00000000781aee1a00000000d50b7a5a + + /* x^169984 mod p(x)` << 1, x^170048 mod p(x)` << 1 */ + .octa 0x00000001c4d8348c0000000002fca6e8 + + /* x^168960 mod p(x)` << 1, x^169024 mod p(x)` << 1 */ + .octa 0x0000000057a40336000000007af40044 + + /* x^167936 mod p(x)` << 1, x^168000 mod p(x)` << 1 */ + .octa 0x00000000855449400000000016178744 + + /* x^166912 mod p(x)` << 1, x^166976 mod p(x)` << 1 */ + .octa 0x000000019cd21e80000000014c177458 + + /* x^165888 mod p(x)` << 1, x^165952 mod p(x)` << 1 */ + .octa 0x000000013eb95bc0000000011b6ddf04 + + /* x^164864 mod p(x)` << 1, x^164928 mod p(x)` << 1 */ + .octa 0x00000001dfc9fdfc00000001f3e29ccc + + /* x^163840 mod p(x)` << 1, x^163904 mod p(x)` << 1 */ + .octa 0x00000000cd028bc20000000135ae7562 + + /* x^162816 mod p(x)` << 1, x^162880 mod p(x)` << 1 */ + .octa 0x0000000090db8c440000000190ef812c + + /* x^161792 mod p(x)` << 1, x^161856 mod p(x)` << 1 */ + .octa 0x000000010010a4ce0000000067a2c786 + + /* x^160768 mod p(x)` << 1, x^160832 mod p(x)` << 1 */ + .octa 0x00000001c8f4c72c0000000048b9496c + + /* x^159744 mod p(x)` << 1, x^159808 mod p(x)` << 1 */ + .octa 0x000000001c26170c000000015a422de6 + + /* x^158720 mod p(x)` << 1, x^158784 mod p(x)` << 1 */ + .octa 0x00000000e3fccf6800000001ef0e3640 + + /* x^157696 mod p(x)` << 1, x^157760 mod p(x)` << 1 */ + .octa 0x00000000d513ed2400000001006d2d26 + + /* x^156672 mod p(x)` << 1, x^156736 mod p(x)` << 1 */ + .octa 0x00000000141beada00000001170d56d6 + + /* x^155648 mod p(x)` << 1, x^155712 mod p(x)` << 1 */ + .octa 0x000000011071aea000000000a5fb613c + + /* x^154624 mod p(x)` << 1, x^154688 mod p(x)` << 1 */ + .octa 0x000000012e19080a0000000040bbf7fc + + /* x^153600 mod p(x)` << 1, x^153664 mod p(x)` << 1 */ + .octa 0x0000000100ecf826000000016ac3a5b2 + + /* x^152576 mod p(x)` << 1, x^152640 mod p(x)` << 1 */ + .octa 0x0000000069b0941200000000abf16230 + + /* x^151552 mod p(x)` << 1, x^151616 mod p(x)` << 1 */ + .octa 0x0000000122297bac00000001ebe23fac + + /* x^150528 mod p(x)` << 1, x^150592 mod p(x)` << 1 */ + .octa 0x00000000e9e4b068000000008b6a0894 + + /* x^149504 mod p(x)` << 1, x^149568 mod p(x)` << 1 */ + .octa 0x000000004b38651a00000001288ea478 + + /* x^148480 mod p(x)` << 1, x^148544 mod p(x)` << 1 */ + .octa 0x00000001468360e2000000016619c442 + + /* x^147456 mod p(x)` << 1, x^147520 mod p(x)` << 1 */ + .octa 0x00000000121c24080000000086230038 + + /* x^146432 mod p(x)` << 1, x^146496 mod p(x)` << 1 */ + .octa 0x00000000da7e7d08000000017746a756 + + /* x^145408 mod p(x)` << 1, x^145472 mod p(x)` << 1 */ + .octa 0x00000001058d76520000000191b8f8f8 + + /* x^144384 mod p(x)` << 1, x^144448 mod p(x)` << 1 */ + .octa 0x000000014a098a90000000008e167708 + + /* x^143360 mod p(x)` << 1, x^143424 mod p(x)` << 1 */ + .octa 0x0000000020dbe72e0000000148b22d54 + + /* x^142336 mod p(x)` << 1, x^142400 mod p(x)` << 1 */ + .octa 0x000000011e7323e80000000044ba2c3c + + /* x^141312 mod p(x)` << 1, x^141376 mod p(x)` << 1 */ + .octa 0x00000000d5d4bf9400000000b54d2b52 + + /* x^140288 mod p(x)` << 1, x^140352 mod p(x)` << 1 */ + .octa 0x0000000199d8746c0000000005a4fd8a + + /* x^139264 mod p(x)` << 1, x^139328 mod p(x)` << 1 */ + .octa 0x00000000ce9ca8a00000000139f9fc46 + + /* x^138240 mod p(x)` << 1, x^138304 mod p(x)` << 1 */ + .octa 0x00000000136edece000000015a1fa824 + + /* x^137216 mod p(x)` << 1, x^137280 mod p(x)` << 1 */ + .octa 0x000000019b92a068000000000a61ae4c + + /* x^136192 mod p(x)` << 1, x^136256 mod p(x)` << 1 */ + .octa 0x0000000071d622060000000145e9113e + + /* x^135168 mod p(x)` << 1, x^135232 mod p(x)` << 1 */ + .octa 0x00000000dfc50158000000006a348448 + + /* x^134144 mod p(x)` << 1, x^134208 mod p(x)` << 1 */ + .octa 0x00000001517626bc000000004d80a08c + + /* x^133120 mod p(x)` << 1, x^133184 mod p(x)` << 1 */ + .octa 0x0000000148d1e4fa000000014b6837a0 + + /* x^132096 mod p(x)` << 1, x^132160 mod p(x)` << 1 */ + .octa 0x0000000094d8266e000000016896a7fc + + /* x^131072 mod p(x)` << 1, x^131136 mod p(x)` << 1 */ + .octa 0x00000000606c5e34000000014f187140 + + /* x^130048 mod p(x)` << 1, x^130112 mod p(x)` << 1 */ + .octa 0x000000019766beaa000000019581b9da + + /* x^129024 mod p(x)` << 1, x^129088 mod p(x)` << 1 */ + .octa 0x00000001d80c506c00000001091bc984 + + /* x^128000 mod p(x)` << 1, x^128064 mod p(x)` << 1 */ + .octa 0x000000001e73837c000000001067223c + + /* x^126976 mod p(x)` << 1, x^127040 mod p(x)` << 1 */ + .octa 0x0000000064d587de00000001ab16ea02 + + /* x^125952 mod p(x)` << 1, x^126016 mod p(x)` << 1 */ + .octa 0x00000000f4a507b0000000013c4598a8 + + /* x^124928 mod p(x)` << 1, x^124992 mod p(x)` << 1 */ + .octa 0x0000000040e342fc00000000b3735430 + + /* x^123904 mod p(x)` << 1, x^123968 mod p(x)` << 1 */ + .octa 0x00000001d5ad9c3a00000001bb3fc0c0 + + /* x^122880 mod p(x)` << 1, x^122944 mod p(x)` << 1 */ + .octa 0x0000000094a691a400000001570ae19c + + /* x^121856 mod p(x)` << 1, x^121920 mod p(x)` << 1 */ + .octa 0x00000001271ecdfa00000001ea910712 + + /* x^120832 mod p(x)` << 1, x^120896 mod p(x)` << 1 */ + .octa 0x000000009e54475a0000000167127128 + + /* x^119808 mod p(x)` << 1, x^119872 mod p(x)` << 1 */ + .octa 0x00000000c9c099ee0000000019e790a2 + + /* x^118784 mod p(x)` << 1, x^118848 mod p(x)` << 1 */ + .octa 0x000000009a2f736c000000003788f710 + + /* x^117760 mod p(x)` << 1, x^117824 mod p(x)` << 1 */ + .octa 0x00000000bb9f499600000001682a160e + + /* x^116736 mod p(x)` << 1, x^116800 mod p(x)` << 1 */ + .octa 0x00000001db688050000000007f0ebd2e + + /* x^115712 mod p(x)` << 1, x^115776 mod p(x)` << 1 */ + .octa 0x00000000e9b10af4000000002b032080 + + /* x^114688 mod p(x)` << 1, x^114752 mod p(x)` << 1 */ + .octa 0x000000012d4545e400000000cfd1664a + + /* x^113664 mod p(x)` << 1, x^113728 mod p(x)` << 1 */ + .octa 0x000000000361139c00000000aa1181c2 + + /* x^112640 mod p(x)` << 1, x^112704 mod p(x)` << 1 */ + .octa 0x00000001a5a1a3a800000000ddd08002 + + /* x^111616 mod p(x)` << 1, x^111680 mod p(x)` << 1 */ + .octa 0x000000006844e0b000000000e8dd0446 + + /* x^110592 mod p(x)` << 1, x^110656 mod p(x)` << 1 */ + .octa 0x00000000c3762f2800000001bbd94a00 + + /* x^109568 mod p(x)` << 1, x^109632 mod p(x)` << 1 */ + .octa 0x00000001d26287a200000000ab6cd180 + + /* x^108544 mod p(x)` << 1, x^108608 mod p(x)` << 1 */ + .octa 0x00000001f6f0bba80000000031803ce2 + + /* x^107520 mod p(x)` << 1, x^107584 mod p(x)` << 1 */ + .octa 0x000000002ffabd620000000024f40b0c + + /* x^106496 mod p(x)` << 1, x^106560 mod p(x)` << 1 */ + .octa 0x00000000fb4516b800000001ba1d9834 + + /* x^105472 mod p(x)` << 1, x^105536 mod p(x)` << 1 */ + .octa 0x000000018cfa961c0000000104de61aa + + /* x^104448 mod p(x)` << 1, x^104512 mod p(x)` << 1 */ + .octa 0x000000019e588d520000000113e40d46 + + /* x^103424 mod p(x)` << 1, x^103488 mod p(x)` << 1 */ + .octa 0x00000001180f0bbc00000001415598a0 + + /* x^102400 mod p(x)` << 1, x^102464 mod p(x)` << 1 */ + .octa 0x00000000e1d9177a00000000bf6c8c90 + + /* x^101376 mod p(x)` << 1, x^101440 mod p(x)` << 1 */ + .octa 0x0000000105abc27c00000001788b0504 + + /* x^100352 mod p(x)` << 1, x^100416 mod p(x)` << 1 */ + .octa 0x00000000972e4a580000000038385d02 + + /* x^99328 mod p(x)` << 1, x^99392 mod p(x)` << 1 */ + .octa 0x0000000183499a5e00000001b6c83844 + + /* x^98304 mod p(x)` << 1, x^98368 mod p(x)` << 1 */ + .octa 0x00000001c96a8cca0000000051061a8a + + /* x^97280 mod p(x)` << 1, x^97344 mod p(x)` << 1 */ + .octa 0x00000001a1a5b60c000000017351388a + + /* x^96256 mod p(x)` << 1, x^96320 mod p(x)` << 1 */ + .octa 0x00000000e4b6ac9c0000000132928f92 + + /* x^95232 mod p(x)` << 1, x^95296 mod p(x)` << 1 */ + .octa 0x00000001807e7f5a00000000e6b4f48a + + /* x^94208 mod p(x)` << 1, x^94272 mod p(x)` << 1 */ + .octa 0x000000017a7e3bc80000000039d15e90 + + /* x^93184 mod p(x)` << 1, x^93248 mod p(x)` << 1 */ + .octa 0x00000000d73975da00000000312d6074 + + /* x^92160 mod p(x)` << 1, x^92224 mod p(x)` << 1 */ + .octa 0x000000017375d038000000017bbb2cc4 + + /* x^91136 mod p(x)` << 1, x^91200 mod p(x)` << 1 */ + .octa 0x00000000193680bc000000016ded3e18 + + /* x^90112 mod p(x)` << 1, x^90176 mod p(x)` << 1 */ + .octa 0x00000000999b06f600000000f1638b16 + + /* x^89088 mod p(x)` << 1, x^89152 mod p(x)` << 1 */ + .octa 0x00000001f685d2b800000001d38b9ecc + + /* x^88064 mod p(x)` << 1, x^88128 mod p(x)` << 1 */ + .octa 0x00000001f4ecbed2000000018b8d09dc + + /* x^87040 mod p(x)` << 1, x^87104 mod p(x)` << 1 */ + .octa 0x00000000ba16f1a000000000e7bc27d2 + + /* x^86016 mod p(x)` << 1, x^86080 mod p(x)` << 1 */ + .octa 0x0000000115aceac400000000275e1e96 + + /* x^84992 mod p(x)` << 1, x^85056 mod p(x)` << 1 */ + .octa 0x00000001aeff629200000000e2e3031e + + /* x^83968 mod p(x)` << 1, x^84032 mod p(x)` << 1 */ + .octa 0x000000009640124c00000001041c84d8 + + /* x^82944 mod p(x)` << 1, x^83008 mod p(x)` << 1 */ + .octa 0x0000000114f41f0200000000706ce672 + + /* x^81920 mod p(x)` << 1, x^81984 mod p(x)` << 1 */ + .octa 0x000000009c5f3586000000015d5070da + + /* x^80896 mod p(x)` << 1, x^80960 mod p(x)` << 1 */ + .octa 0x00000001878275fa0000000038f9493a + + /* x^79872 mod p(x)` << 1, x^79936 mod p(x)` << 1 */ + .octa 0x00000000ddc42ce800000000a3348a76 + + /* x^78848 mod p(x)` << 1, x^78912 mod p(x)` << 1 */ + .octa 0x0000000181d2c73a00000001ad0aab92 + + /* x^77824 mod p(x)` << 1, x^77888 mod p(x)` << 1 */ + .octa 0x0000000141c9320a000000019e85f712 + + /* x^76800 mod p(x)` << 1, x^76864 mod p(x)` << 1 */ + .octa 0x000000015235719a000000005a871e76 + + /* x^75776 mod p(x)` << 1, x^75840 mod p(x)` << 1 */ + .octa 0x00000000be27d804000000017249c662 + + /* x^74752 mod p(x)` << 1, x^74816 mod p(x)` << 1 */ + .octa 0x000000006242d45a000000003a084712 + + /* x^73728 mod p(x)` << 1, x^73792 mod p(x)` << 1 */ + .octa 0x000000009a53638e00000000ed438478 + + /* x^72704 mod p(x)` << 1, x^72768 mod p(x)` << 1 */ + .octa 0x00000001001ecfb600000000abac34cc + + /* x^71680 mod p(x)` << 1, x^71744 mod p(x)` << 1 */ + .octa 0x000000016d7c2d64000000005f35ef3e + + /* x^70656 mod p(x)` << 1, x^70720 mod p(x)` << 1 */ + .octa 0x00000001d0ce46c00000000047d6608c + + /* x^69632 mod p(x)` << 1, x^69696 mod p(x)` << 1 */ + .octa 0x0000000124c907b4000000002d01470e + + /* x^68608 mod p(x)` << 1, x^68672 mod p(x)` << 1 */ + .octa 0x0000000018a555ca0000000158bbc7b0 + + /* x^67584 mod p(x)` << 1, x^67648 mod p(x)` << 1 */ + .octa 0x000000006b0980bc00000000c0a23e8e + + /* x^66560 mod p(x)` << 1, x^66624 mod p(x)` << 1 */ + .octa 0x000000008bbba96400000001ebd85c88 + + /* x^65536 mod p(x)` << 1, x^65600 mod p(x)` << 1 */ + .octa 0x00000001070a5a1e000000019ee20bb2 + + /* x^64512 mod p(x)` << 1, x^64576 mod p(x)` << 1 */ + .octa 0x000000002204322a00000001acabf2d6 + + /* x^63488 mod p(x)` << 1, x^63552 mod p(x)` << 1 */ + .octa 0x00000000a27524d000000001b7963d56 + + /* x^62464 mod p(x)` << 1, x^62528 mod p(x)` << 1 */ + .octa 0x0000000020b1e4ba000000017bffa1fe + + /* x^61440 mod p(x)` << 1, x^61504 mod p(x)` << 1 */ + .octa 0x0000000032cc27fc000000001f15333e + + /* x^60416 mod p(x)` << 1, x^60480 mod p(x)` << 1 */ + .octa 0x0000000044dd22b8000000018593129e + + /* x^59392 mod p(x)` << 1, x^59456 mod p(x)` << 1 */ + .octa 0x00000000dffc9e0a000000019cb32602 + + /* x^58368 mod p(x)` << 1, x^58432 mod p(x)` << 1 */ + .octa 0x00000001b7a0ed140000000142b05cc8 + + /* x^57344 mod p(x)` << 1, x^57408 mod p(x)` << 1 */ + .octa 0x00000000c784248800000001be49e7a4 + + /* x^56320 mod p(x)` << 1, x^56384 mod p(x)` << 1 */ + .octa 0x00000001c02a4fee0000000108f69d6c + + /* x^55296 mod p(x)` << 1, x^55360 mod p(x)` << 1 */ + .octa 0x000000003c273778000000006c0971f0 + + /* x^54272 mod p(x)` << 1, x^54336 mod p(x)` << 1 */ + .octa 0x00000001d63f8894000000005b16467a + + /* x^53248 mod p(x)` << 1, x^53312 mod p(x)` << 1 */ + .octa 0x000000006be557d600000001551a628e + + /* x^52224 mod p(x)` << 1, x^52288 mod p(x)` << 1 */ + .octa 0x000000006a7806ea000000019e42ea92 + + /* x^51200 mod p(x)` << 1, x^51264 mod p(x)` << 1 */ + .octa 0x000000016155aa0c000000012fa83ff2 + + /* x^50176 mod p(x)` << 1, x^50240 mod p(x)` << 1 */ + .octa 0x00000000908650ac000000011ca9cde0 + + /* x^49152 mod p(x)` << 1, x^49216 mod p(x)` << 1 */ + .octa 0x00000000aa5a808400000000c8e5cd74 + + /* x^48128 mod p(x)` << 1, x^48192 mod p(x)` << 1 */ + .octa 0x0000000191bb500a0000000096c27f0c + + /* x^47104 mod p(x)` << 1, x^47168 mod p(x)` << 1 */ + .octa 0x0000000064e9bed0000000002baed926 + + /* x^46080 mod p(x)` << 1, x^46144 mod p(x)` << 1 */ + .octa 0x000000009444f302000000017c8de8d2 + + /* x^45056 mod p(x)` << 1, x^45120 mod p(x)` << 1 */ + .octa 0x000000019db07d3c00000000d43d6068 + + /* x^44032 mod p(x)` << 1, x^44096 mod p(x)` << 1 */ + .octa 0x00000001359e3e6e00000000cb2c4b26 + + /* x^43008 mod p(x)` << 1, x^43072 mod p(x)` << 1 */ + .octa 0x00000001e4f10dd20000000145b8da26 + + /* x^41984 mod p(x)` << 1, x^42048 mod p(x)` << 1 */ + .octa 0x0000000124f5735e000000018fff4b08 + + /* x^40960 mod p(x)` << 1, x^41024 mod p(x)` << 1 */ + .octa 0x0000000124760a4c0000000150b58ed0 + + /* x^39936 mod p(x)` << 1, x^40000 mod p(x)` << 1 */ + .octa 0x000000000f1fc18600000001549f39bc + + /* x^38912 mod p(x)` << 1, x^38976 mod p(x)` << 1 */ + .octa 0x00000000150e4cc400000000ef4d2f42 + + /* x^37888 mod p(x)` << 1, x^37952 mod p(x)` << 1 */ + .octa 0x000000002a6204e800000001b1468572 + + /* x^36864 mod p(x)` << 1, x^36928 mod p(x)` << 1 */ + .octa 0x00000000beb1d432000000013d7403b2 + + /* x^35840 mod p(x)` << 1, x^35904 mod p(x)` << 1 */ + .octa 0x0000000135f3f1f000000001a4681842 + + /* x^34816 mod p(x)` << 1, x^34880 mod p(x)` << 1 */ + .octa 0x0000000074fe22320000000167714492 + + /* x^33792 mod p(x)` << 1, x^33856 mod p(x)` << 1 */ + .octa 0x000000001ac6e2ba00000001e599099a + + /* x^32768 mod p(x)` << 1, x^32832 mod p(x)` << 1 */ + .octa 0x0000000013fca91e00000000fe128194 + + /* x^31744 mod p(x)` << 1, x^31808 mod p(x)` << 1 */ + .octa 0x0000000183f4931e0000000077e8b990 + + /* x^30720 mod p(x)` << 1, x^30784 mod p(x)` << 1 */ + .octa 0x00000000b6d9b4e400000001a267f63a + + /* x^29696 mod p(x)` << 1, x^29760 mod p(x)` << 1 */ + .octa 0x00000000b518865600000001945c245a + + /* x^28672 mod p(x)` << 1, x^28736 mod p(x)` << 1 */ + .octa 0x0000000027a81a840000000149002e76 + + /* x^27648 mod p(x)` << 1, x^27712 mod p(x)` << 1 */ + .octa 0x000000012569925800000001bb8310a4 + + /* x^26624 mod p(x)` << 1, x^26688 mod p(x)` << 1 */ + .octa 0x00000001b23de796000000019ec60bcc + + /* x^25600 mod p(x)` << 1, x^25664 mod p(x)` << 1 */ + .octa 0x00000000fe4365dc000000012d8590ae + + /* x^24576 mod p(x)` << 1, x^24640 mod p(x)` << 1 */ + .octa 0x00000000c68f497a0000000065b00684 + + /* x^23552 mod p(x)` << 1, x^23616 mod p(x)` << 1 */ + .octa 0x00000000fbf521ee000000015e5aeadc + + /* x^22528 mod p(x)` << 1, x^22592 mod p(x)` << 1 */ + .octa 0x000000015eac337800000000b77ff2b0 + + /* x^21504 mod p(x)` << 1, x^21568 mod p(x)` << 1 */ + .octa 0x0000000134914b900000000188da2ff6 + + /* x^20480 mod p(x)` << 1, x^20544 mod p(x)` << 1 */ + .octa 0x0000000016335cfe0000000063da929a + + /* x^19456 mod p(x)` << 1, x^19520 mod p(x)` << 1 */ + .octa 0x000000010372d10c00000001389caa80 + + /* x^18432 mod p(x)` << 1, x^18496 mod p(x)` << 1 */ + .octa 0x000000015097b908000000013db599d2 + + /* x^17408 mod p(x)` << 1, x^17472 mod p(x)` << 1 */ + .octa 0x00000001227a75720000000122505a86 + + /* x^16384 mod p(x)` << 1, x^16448 mod p(x)` << 1 */ + .octa 0x000000009a8f75c0000000016bd72746 + + /* x^15360 mod p(x)` << 1, x^15424 mod p(x)` << 1 */ + .octa 0x00000000682c77a200000001c3faf1d4 + + /* x^14336 mod p(x)` << 1, x^14400 mod p(x)` << 1 */ + .octa 0x00000000231f091c00000001111c826c + + /* x^13312 mod p(x)` << 1, x^13376 mod p(x)` << 1 */ + .octa 0x000000007d4439f200000000153e9fb2 + + /* x^12288 mod p(x)` << 1, x^12352 mod p(x)` << 1 */ + .octa 0x000000017e221efc000000002b1f7b60 + + /* x^11264 mod p(x)` << 1, x^11328 mod p(x)` << 1 */ + .octa 0x0000000167457c3800000000b1dba570 + + /* x^10240 mod p(x)` << 1, x^10304 mod p(x)` << 1 */ + .octa 0x00000000bdf081c400000001f6397b76 + + /* x^9216 mod p(x)` << 1, x^9280 mod p(x)` << 1 */ + .octa 0x000000016286d6b00000000156335214 + + /* x^8192 mod p(x)` << 1, x^8256 mod p(x)` << 1 */ + .octa 0x00000000c84f001c00000001d70e3986 + + /* x^7168 mod p(x)` << 1, x^7232 mod p(x)` << 1 */ + .octa 0x0000000064efe7c0000000003701a774 + + /* x^6144 mod p(x)` << 1, x^6208 mod p(x)` << 1 */ + .octa 0x000000000ac2d90400000000ac81ef72 + + /* x^5120 mod p(x)` << 1, x^5184 mod p(x)` << 1 */ + .octa 0x00000000fd226d140000000133212464 + + /* x^4096 mod p(x)` << 1, x^4160 mod p(x)` << 1 */ + .octa 0x000000011cfd42e000000000e4e45610 + + /* x^3072 mod p(x)` << 1, x^3136 mod p(x)` << 1 */ + .octa 0x000000016e5a5678000000000c1bd370 + + /* x^2048 mod p(x)` << 1, x^2112 mod p(x)` << 1 */ + .octa 0x00000001d888fe2200000001a7b9e7a6 + + /* x^1024 mod p(x)` << 1, x^1088 mod p(x)` << 1 */ + .octa 0x00000001af77fcd4000000007d657a10 + +SHORT_CONSTANTS: + + /* Reduce final 1024-2048 bits to 64 bits, shifting 32 bits to include the trailing 32 bits of zeros */ + /* x^1952 mod p(x)`, x^1984 mod p(x)`, x^2016 mod p(x)`, x^2048 mod p(x)` */ + .octa 0xed837b2613e8221e99168a18ec447f11 + + /* x^1824 mod p(x)`, x^1856 mod p(x)`, x^1888 mod p(x)`, x^1920 mod p(x)` */ + .octa 0xc8acdd8147b9ce5ae23e954e8fd2cd3c + + /* x^1696 mod p(x)`, x^1728 mod p(x)`, x^1760 mod p(x)`, x^1792 mod p(x)` */ + .octa 0xd9ad6d87d4277e2592f8befe6b1d2b53 + + /* x^1568 mod p(x)`, x^1600 mod p(x)`, x^1632 mod p(x)`, x^1664 mod p(x)` */ + .octa 0xc10ec5e033fbca3bf38a3556291ea462 + + /* x^1440 mod p(x)`, x^1472 mod p(x)`, x^1504 mod p(x)`, x^1536 mod p(x)` */ + .octa 0xc0b55b0e82e02e2f974ac56262b6ca4b + + /* x^1312 mod p(x)`, x^1344 mod p(x)`, x^1376 mod p(x)`, x^1408 mod p(x)` */ + .octa 0x71aa1df0e172334d855712b3784d2a56 + + /* x^1184 mod p(x)`, x^1216 mod p(x)`, x^1248 mod p(x)`, x^1280 mod p(x)` */ + .octa 0xfee3053e3969324da5abe9f80eaee722 + + /* x^1056 mod p(x)`, x^1088 mod p(x)`, x^1120 mod p(x)`, x^1152 mod p(x)` */ + .octa 0xf44779b93eb2bd081fa0943ddb54814c + + /* x^928 mod p(x)`, x^960 mod p(x)`, x^992 mod p(x)`, x^1024 mod p(x)` */ + .octa 0xf5449b3f00cc3374a53ff440d7bbfe6a + + /* x^800 mod p(x)`, x^832 mod p(x)`, x^864 mod p(x)`, x^896 mod p(x)` */ + .octa 0x6f8346e1d777606eebe7e3566325605c + + /* x^672 mod p(x)`, x^704 mod p(x)`, x^736 mod p(x)`, x^768 mod p(x)` */ + .octa 0xe3ab4f2ac0b95347c65a272ce5b592b8 + + /* x^544 mod p(x)`, x^576 mod p(x)`, x^608 mod p(x)`, x^640 mod p(x)` */ + .octa 0xaa2215ea329ecc115705a9ca4721589f + + /* x^416 mod p(x)`, x^448 mod p(x)`, x^480 mod p(x)`, x^512 mod p(x)` */ + .octa 0x1ed8f66ed95efd26e3720acb88d14467 + + /* x^288 mod p(x)`, x^320 mod p(x)`, x^352 mod p(x)`, x^384 mod p(x)` */ + .octa 0x78ed02d5a700e96aba1aca0315141c31 + + /* x^160 mod p(x)`, x^192 mod p(x)`, x^224 mod p(x)`, x^256 mod p(x)` */ + .octa 0xba8ccbe832b39da3ad2a31b3ed627dae + + /* x^32 mod p(x)`, x^64 mod p(x)`, x^96 mod p(x)`, x^128 mod p(x)` */ + .octa 0xedb88320b1e6b0926655004fa06a2517 + + +BARRETT_CONSTANTS: + /* 33 bit reflected Barrett constant m - (4^32)/n */ + .octa 0x000000000000000000000001f7011641 /* x^64 div p(x)` */ + /* 33 bit reflected Barrett constant n */ + .octa 0x000000000000000000000001db710641 + +#endif /* __powerpc__ */ + +#endif diff --git a/extra/crc32-vpmsum/crc32ieee_wrapper.c b/extra/crc32-vpmsum/crc32ieee_wrapper.c new file mode 100644 index 00000000000..41c1f980097 --- /dev/null +++ b/extra/crc32-vpmsum/crc32ieee_wrapper.c @@ -0,0 +1,75 @@ +#ifdef __powerpc__ + +#define F crc32ieee_vpmsum +#define __F __crc32ieee_vpmsum + +static const unsigned int crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,}; + +#include "crc32_wrapper.ic" + +#endif + diff --git a/extra/crc32-vpmsum/ppc-opcode.h b/extra/crc32-vpmsum/ppc-opcode.h new file mode 100644 index 00000000000..5942bd4923a --- /dev/null +++ b/extra/crc32-vpmsum/ppc-opcode.h @@ -0,0 +1,23 @@ +#ifndef __OPCODES_H +#define __OPCODES_H + +#define __PPC_RA(a) (((a) & 0x1f) << 16) +#define __PPC_RB(b) (((b) & 0x1f) << 11) +#define __PPC_XA(a) ((((a) & 0x1f) << 16) | (((a) & 0x20) >> 3)) +#define __PPC_XB(b) ((((b) & 0x1f) << 11) | (((b) & 0x20) >> 4)) +#define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5)) +#define __PPC_XT(s) __PPC_XS(s) +#define VSX_XX3(t, a, b) (__PPC_XT(t) | __PPC_XA(a) | __PPC_XB(b)) +#define VSX_XX1(s, a, b) (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b)) + +#define PPC_INST_VPMSUMW 0x10000488 +#define PPC_INST_VPMSUMD 0x100004c8 +#define PPC_INST_MFVSRD 0x7c000066 +#define PPC_INST_MTVSRD 0x7c000166 + +#define VPMSUMW(t, a, b) .long PPC_INST_VPMSUMW | VSX_XX3((t), a, b) +#define VPMSUMD(t, a, b) .long PPC_INST_VPMSUMD | VSX_XX3((t), a, b) +#define MFVRD(a, t) .long PPC_INST_MFVSRD | VSX_XX1((t)+32, a, 0) +#define MTVRD(t, a) .long PPC_INST_MTVSRD | VSX_XX1((t)+32, a, 0) + +#endif diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc index 7ad71aa8159..b937cc6fa1a 100644 --- a/extra/innochecksum.cc +++ b/extra/innochecksum.cc @@ -45,14 +45,17 @@ The parts not included are excluded by #ifndef UNIV_INNOCHECKSUM. */ typedef void fil_space_t; #include "univ.i" /* include all of this */ +#include "page0size.h" #define FLST_BASE_NODE_SIZE (4 + 2 * FIL_ADDR_SIZE) #define FLST_NODE_SIZE (2 * FIL_ADDR_SIZE) #define FSEG_PAGE_DATA FIL_PAGE_DATA -#define MLOG_1BYTE (1) +#define FSEG_HEADER_SIZE 10 +#define UT_BITS_IN_BYTES(b) (((b) + 7) / 8) #include "ut0ut.h" #include "ut0byte.h" +#include "mtr0types.h" #include "mach0data.h" #include "fsp0types.h" #include "rem0rec.h" @@ -67,7 +70,6 @@ typedef void fil_space_t; #include "ut0crc32.h" /* ut_crc32_init() */ #include "fsp0pagecompress.h" /* fil_get_compression_alg_name */ #include "fil0crypt.h" /* fil_space_verify_crypt_checksum */ -#include "page0size.h" #include <string.h> @@ -91,7 +93,7 @@ static bool use_end_page; static bool do_one_page; static my_bool do_leaf; static my_bool per_page_details; -static ulong n_merge; +static ulint n_merge; extern ulong srv_checksum_algorithm; static ulong physical_page_size; /* Page size in bytes on disk. */ static ulong logical_page_size; /* Page size when uncompressed. */ @@ -492,8 +494,8 @@ is_page_corrupted( for uncompressed tablespace. */ logseq = mach_read_from_4(buf + FIL_PAGE_LSN + 4); logseqfield = mach_read_from_4( - buf + page_size.logical() - - FIL_PAGE_END_LSN_OLD_CHKSUM + 4); + buf + page_size.logical() - + FIL_PAGE_END_LSN_OLD_CHKSUM + 4); if (is_log_enabled) { fprintf(log_file, @@ -522,14 +524,14 @@ is_page_corrupted( normal method. */ if (is_encrypted && key_version != 0) { is_corrupted = !fil_space_verify_crypt_checksum(buf, - page_size.is_compressed() ? page_size.physical() : 0, NULL, cur_page_num); + page_size, space_id, (ulint)cur_page_num); } else { is_corrupted = true; } if (is_corrupted) { is_corrupted = buf_page_is_corrupted( - true, buf, page_size.is_compressed() ? page_size.physical() : 0, NULL); + true, buf, page_size, NULL); } return(is_corrupted); @@ -574,6 +576,7 @@ is_page_empty( return (false); } } + return (true); } @@ -843,12 +846,10 @@ parse_page( /* data_bytes is bigger than logical_page_size */ size_range_id = SIZE_RANGES_FOR_PAGE + 1; } - if (per_page_details) { printf("index id=%llu page " ULINTPF " leaf %d n_recs " ULINTPF " data_bytes " ULINTPF "\n", id, page_no, is_leaf, n_recs, data_bytes); } - /* update per-index statistics */ { if (index_ids.count(id) == 0) { @@ -1165,6 +1166,7 @@ print_summary( page_type.n_fil_page_type_page_compressed_encrypted); fprintf(fil_out, "%8d\tOther type of page\n", page_type.n_fil_page_type_other); + fprintf(fil_out, "\n===============================================\n"); fprintf(fil_out, "Additional information:\n"); fprintf(fil_out, "Undo page type: %d insert, %d update, %d other\n", @@ -1536,7 +1538,7 @@ int main( byte* buf = NULL; byte* xdes = NULL; /* bytes read count */ - ulong bytes; + ulint bytes; /* current time */ time_t now; /* last time */ @@ -1616,6 +1618,7 @@ int main( my_print_variables(innochecksum_options); } + buf_ptr = (byte*) malloc(UNIV_PAGE_SIZE_MAX * 2); xdes_ptr = (byte*)malloc(UNIV_PAGE_SIZE_MAX * 2); buf = (byte *) ut_align(buf_ptr, UNIV_PAGE_SIZE_MAX); @@ -1623,6 +1626,7 @@ int main( /* The file name is not optional. */ for (int i = 0; i < argc; ++i) { + /* Reset parameters for each file. */ filename = argv[i]; memset(&page_type, 0, sizeof(innodb_page_type)); @@ -1671,7 +1675,7 @@ int main( } /* Read the minimum page size. */ - bytes = ulong(fread(buf, 1, UNIV_ZIP_SIZE_MIN, fil_in)); + bytes = fread(buf, 1, UNIV_ZIP_SIZE_MIN, fil_in); partial_page_read = true; if (bytes != UNIV_ZIP_SIZE_MIN) { @@ -1694,6 +1698,7 @@ int main( /* Determine page size, zip_size and page compression from fsp_flags and encryption metadata from page 0 */ const page_size_t& page_size = get_page_size(buf); + ulint flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + buf); ulint zip_size = page_size.is_compressed() ? page_size.logical() : 0; logical_page_size = page_size.is_compressed() ? zip_size : 0; @@ -1858,6 +1863,7 @@ int main( /* main checksumming loop */ cur_page_num = start_page ? start_page : cur_page_num + 1; + lastt = 0; while (!feof(fil_in)) { diff --git a/extra/mariabackup/CMakeLists.txt b/extra/mariabackup/CMakeLists.txt index ac15460660c..78188d2f8e8 100644 --- a/extra/mariabackup/CMakeLists.txt +++ b/extra/mariabackup/CMakeLists.txt @@ -30,7 +30,6 @@ ENDIF() INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/storage/xtradb/include ${CMAKE_SOURCE_DIR}/sql ${CMAKE_CURRENT_SOURCE_DIR}/quicklz ${CMAKE_CURRENT_SOURCE_DIR} @@ -74,9 +73,9 @@ MYSQL_ADD_EXECUTABLE(mariabackup backup_mysql.cc backup_copy.cc encryption_plugin.cc - ${PROJECT_SOURCE_DIR}/libmysql/libmysql.c ${PROJECT_SOURCE_DIR}/sql/net_serv.cc ${NT_SERVICE_SOURCE} + ${PROJECT_SOURCE_DIR}/libmysqld/libmysql.c COMPONENT backup ) diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index c019209faad..1542e57c84c 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -46,6 +46,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include <ut0mem.h> #include <srv0start.h> #include <fil0fil.h> +#include <trx0sys.h> #include <set> #include <string> #include <mysqld.h> @@ -89,7 +90,7 @@ struct datadir_iter_t { ulint filepath_len; char *filepath_rel; ulint filepath_rel_len; - os_ib_mutex_t mutex; + pthread_mutex_t mutex; os_file_dir_t dir; os_file_dir_t dbdir; os_file_stat_t dbinfo; @@ -107,7 +108,7 @@ struct datadir_thread_ctxt_t { datadir_iter_t *it; uint n_thread; uint *count; - os_ib_mutex_t count_mutex; + pthread_mutex_t count_mutex; os_thread_id_t id; bool ret; }; @@ -134,12 +135,12 @@ datadir_node_fill(datadir_node_t *node, datadir_iter_t *it) { if (node->filepath_len < it->filepath_len) { free(node->filepath); - node->filepath = (char*)(ut_malloc(it->filepath_len)); + node->filepath = (char*)(malloc(it->filepath_len)); node->filepath_len = it->filepath_len; } if (node->filepath_rel_len < it->filepath_rel_len) { free(node->filepath_rel); - node->filepath_rel = (char*)(ut_malloc(it->filepath_rel_len)); + node->filepath_rel = (char*)(malloc(it->filepath_rel_len)); node->filepath_rel_len = it->filepath_rel_len; } @@ -153,8 +154,8 @@ static void datadir_node_free(datadir_node_t *node) { - ut_free(node->filepath); - ut_free(node->filepath_rel); + free(node->filepath); + free(node->filepath_rel); memset(node, 0, sizeof(datadir_node_t)); } @@ -178,10 +179,10 @@ datadir_iter_new(const char *path, bool skip_first_level = true) { datadir_iter_t *it; - it = static_cast<datadir_iter_t *>(ut_malloc(sizeof(datadir_iter_t))); + it = static_cast<datadir_iter_t *>(malloc(sizeof(datadir_iter_t))); memset(it, 0, sizeof(datadir_iter_t)); - it->mutex = os_mutex_create(); + pthread_mutex_init(&it->mutex, NULL); it->datadir_path = strdup(path); it->dir = os_file_opendir(it->datadir_path, TRUE); @@ -194,20 +195,20 @@ datadir_iter_new(const char *path, bool skip_first_level = true) it->err = DB_SUCCESS; it->dbpath_len = FN_REFLEN; - it->dbpath = static_cast<char*>(ut_malloc(it->dbpath_len)); + it->dbpath = static_cast<char*>(malloc(it->dbpath_len)); it->filepath_len = FN_REFLEN; - it->filepath = static_cast<char*>(ut_malloc(it->filepath_len)); + it->filepath = static_cast<char*>(malloc(it->filepath_len)); it->filepath_rel_len = FN_REFLEN; - it->filepath_rel = static_cast<char*>(ut_malloc(it->filepath_rel_len)); + it->filepath_rel = static_cast<char*>(malloc(it->filepath_rel_len)); it->skip_first_level = skip_first_level; return(it); error: - ut_free(it); + free(it); return(NULL); } @@ -246,19 +247,14 @@ datadir_iter_next_database(datadir_iter_t *it) + strlen (it->dbinfo.name) + 2; if (len > it->dbpath_len) { it->dbpath_len = len; + free(it->dbpath); - if (it->dbpath) { - - ut_free(it->dbpath); - } - - it->dbpath = static_cast<char*> - (ut_malloc(it->dbpath_len)); + it->dbpath = static_cast<char*>( + malloc(it->dbpath_len)); } - ut_snprintf(it->dbpath, it->dbpath_len, - "%s/%s", it->datadir_path, - it->dbinfo.name); - srv_normalize_path_for_win(it->dbpath); + snprintf(it->dbpath, it->dbpath_len, "%s/%s", + it->datadir_path, it->dbinfo.name); + os_normalize_path(it->dbpath); if (it->dbinfo.type == OS_FILE_TYPE_FILE) { it->is_file = true; @@ -306,8 +302,8 @@ make_path_n(int n, char **path, ulint *path_len, ...) va_end(vl); if (len_needed < *path_len) { - ut_free(*path); - *path = static_cast<char*>(ut_malloc(len_needed)); + free(*path); + *path = static_cast<char*>(malloc(len_needed)); } va_start(vl, path_len); @@ -378,7 +374,7 @@ datadir_iter_next(datadir_iter_t *it, datadir_node_t *node) { bool ret = true; - os_mutex_enter(it->mutex); + pthread_mutex_lock(&it->mutex); if (datadir_iter_next_file(it)) { @@ -413,7 +409,7 @@ datadir_iter_next(datadir_iter_t *it, datadir_node_t *node) ret = false; done: - os_mutex_exit(it->mutex); + pthread_mutex_unlock(&it->mutex); return(ret); } @@ -427,7 +423,7 @@ static void datadir_iter_free(datadir_iter_t *it) { - os_mutex_free(it->mutex); + pthread_mutex_destroy(&it->mutex); if (it->dbdir) { @@ -439,11 +435,11 @@ datadir_iter_free(datadir_iter_t *it) os_file_closedir(it->dir); } - ut_free(it->dbpath); - ut_free(it->filepath); - ut_free(it->filepath_rel); + free(it->dbpath); + free(it->filepath); + free(it->filepath_rel); free(it->datadir_path); - ut_free(it); + free(it); } @@ -466,17 +462,17 @@ static void datafile_close(datafile_cur_t *cursor) { - if (cursor->file != 0) { + if (cursor->file != OS_FILE_CLOSED) { os_file_close(cursor->file); } - ut_free(cursor->buf); + free(cursor->buf); } static bool datafile_open(const char *file, datafile_cur_t *cursor, uint thread_n) { - ulint success; + bool success; memset(cursor, 0, sizeof(datafile_cur_t)); @@ -490,11 +486,9 @@ datafile_open(const char *file, datafile_cur_t *cursor, uint thread_n) xb_get_relative_path(cursor->abs_path, FALSE), sizeof(cursor->rel_path)); - cursor->file = os_file_create_simple_no_error_handling(0, - cursor->abs_path, - OS_FILE_OPEN, - OS_FILE_READ_ONLY, - &success, 0); + cursor->file = os_file_create_simple_no_error_handling( + 0, cursor->abs_path, + OS_FILE_OPEN, OS_FILE_READ_ALLOW_DELETE, true, &success); if (!success) { /* The following call prints an error message */ os_file_get_last_error(TRUE); @@ -518,7 +512,7 @@ datafile_open(const char *file, datafile_cur_t *cursor, uint thread_n) posix_fadvise(cursor->file, 0, 0, POSIX_FADV_SEQUENTIAL); cursor->buf_size = 10 * 1024 * 1024; - cursor->buf = static_cast<byte *>(ut_malloc((ulint)cursor->buf_size)); + cursor->buf = static_cast<byte *>(malloc((ulint)cursor->buf_size)); return(true); } @@ -528,7 +522,6 @@ static xb_fil_cur_result_t datafile_read(datafile_cur_t *cursor) { - ulint success; ulint to_read; xtrabackup_io_throttling(); @@ -540,14 +533,14 @@ datafile_read(datafile_cur_t *cursor) return(XB_FIL_CUR_EOF); } - success = os_file_read(cursor->file, cursor->buf, cursor->buf_offset, - to_read); - if (!success) { + if (!os_file_read(IORequestRead, + cursor->file, cursor->buf, cursor->buf_offset, + to_read)) { return(XB_FIL_CUR_ERROR); } posix_fadvise(cursor->file, cursor->buf_offset, to_read, - POSIX_FADV_DONTNEED); + POSIX_FADV_DONTNEED); cursor->buf_read = to_read; cursor->buf_offset += to_read; @@ -601,7 +594,6 @@ trim_dotslash(const char *path) /************************************************************************ Check if string ends with given suffix. @return true if string ends with given suffix. */ -static bool ends_with(const char *str, const char *suffix) { @@ -917,13 +909,13 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n) { datadir_thread_ctxt_t *data_threads; uint i, count; - os_ib_mutex_t count_mutex; + pthread_mutex_t count_mutex; bool ret; data_threads = (datadir_thread_ctxt_t*) - (ut_malloc(sizeof(datadir_thread_ctxt_t) * n)); + malloc(sizeof(datadir_thread_ctxt_t) * n); - count_mutex = os_mutex_create(); + pthread_mutex_init(&count_mutex, NULL); count = n; for (i = 0; i < n; i++) { @@ -937,15 +929,15 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n) /* Wait for threads to exit */ while (1) { os_thread_sleep(100000); - os_mutex_enter(count_mutex); + pthread_mutex_lock(&count_mutex); if (count == 0) { - os_mutex_exit(count_mutex); + pthread_mutex_unlock(&count_mutex); break; } - os_mutex_exit(count_mutex); + pthread_mutex_unlock(&count_mutex); } - os_mutex_free(count_mutex); + pthread_mutex_destroy(&count_mutex); ret = true; for (i = 0; i < n; i++) { @@ -955,7 +947,7 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n) } } - ut_free(data_threads); + free(data_threads); return(ret); } @@ -974,7 +966,6 @@ copy_file(ds_ctxt_t *datasink, ds_file_t *dstfile = NULL; datafile_cur_t cursor; xb_fil_cur_result_t res; - const char *action; if (!datafile_open(src_file_path, &cursor, thread_n)) { goto error_close; @@ -991,9 +982,8 @@ copy_file(ds_ctxt_t *datasink, goto error; } - action = xb_get_copy_action(); msg_ts("[%02u] %s %s to %s\n", - thread_n, action, src_file_path, dstfile->path); + thread_n, xb_get_copy_action(), src_file_path, dstfile->path); /* The main copy loop */ while ((res = datafile_read(&cursor)) == XB_FIL_CUR_SUCCESS) { @@ -1043,8 +1033,8 @@ move_file(ds_ctxt_t *datasink, char dst_dir_abs[FN_REFLEN]; size_t dirname_length; - ut_snprintf(dst_file_path_abs, sizeof(dst_file_path_abs), - "%s/%s", dst_dir, dst_file_path); + snprintf(dst_file_path_abs, sizeof(dst_file_path_abs), + "%s/%s", dst_dir, dst_file_path); dirname_part(dst_dir_abs, dst_file_path_abs, &dirname_length); @@ -1111,7 +1101,7 @@ read_link_file(const char *ibd_filepath, const char *link_filepath) while (lastch > 4 && filepath[lastch] <= 0x20) { filepath[lastch--] = 0x00; } - srv_normalize_path_for_win(filepath); + os_normalize_path(filepath); } tablespace_locations[ibd_filepath] = filepath; @@ -1261,8 +1251,8 @@ backup_files(const char *from, bool prep_mode) } else if (!prep_mode) { /* backup fake file into empty directory */ char path[FN_REFLEN]; - ut_snprintf(path, sizeof(path), - "%s/db.opt", node.filepath); + snprintf(path, sizeof(path), + "%s/db.opt", node.filepath); if (!(ret = backup_file_printf( trim_dotslash(path), "%s", ""))) { msg("Failed to create file %s\n", path); @@ -1351,8 +1341,8 @@ out: return(ret); } -bool -backup_start() +/** Start --backup */ +bool backup_start() { if (!opt_no_lock) { if (opt_safe_slave_backup) { @@ -1427,9 +1417,8 @@ backup_start() return(true); } - -bool -backup_finish() +/** Release resources after backup_start() */ +void backup_release() { /* release all locks */ if (!opt_no_lock) { @@ -1444,7 +1433,11 @@ backup_finish() xb_mysql_query(mysql_connection, "START SLAVE SQL_THREAD", false); } +} +/** Finish after backup_start() and backup_release() */ +bool backup_finish() +{ /* Copy buffer pool dump or LRU dump */ if (!opt_rsync) { if (buffer_pool_filename && file_exists(buffer_pool_filename)) { @@ -1471,12 +1464,10 @@ backup_finish() return(false); } - if (!write_xtrabackup_info(mysql_connection)) { + if (!write_xtrabackup_info(mysql_connection, XTRABACKUP_INFO, opt_history != 0)) { return(false); } - - return(true); } @@ -1629,14 +1620,9 @@ apply_log_finish() return(true); } -extern void -os_io_init_simple(void); - bool copy_back() { - char *innobase_data_file_path_copy; - ulint i; bool ret; datadir_iter_t *it = NULL; datadir_node_t node; @@ -1679,24 +1665,16 @@ copy_back() if (!innobase_data_file_path) { innobase_data_file_path = (char*) "ibdata1:10M:autoextend"; } - innobase_data_file_path_copy = strdup(innobase_data_file_path); - if (!(ret = srv_parse_data_file_paths_and_sizes( - innobase_data_file_path_copy))) { + srv_sys_space.set_path("."); + + if (!srv_sys_space.parse_params(innobase_data_file_path, true)) { msg("syntax error in innodb_data_file_path\n"); return(false); } srv_max_n_threads = 1000; - //os_sync_mutex = NULL; - ut_mem_init(); - /* temporally dummy value to avoid crash */ - srv_page_size_shift = 14; - srv_page_size = (1 << srv_page_size_shift); - os_sync_init(); - sync_init(); - os_io_init_simple(); - mem_init(srv_mem_pool_size); + sync_check_init(); ut_crc32_init(); /* copy undo tablespaces */ @@ -1707,14 +1685,14 @@ copy_back() ds_data = ds_create(dst_dir, DS_TYPE_LOCAL); - for (i = 1; ; i++) { + for (uint i = 1; i <= TRX_SYS_MAX_UNDO_SPACES; i++) { char filename[20]; - sprintf(filename, "undo%03u", (uint)i); + sprintf(filename, "undo%03u", i); if (!file_exists(filename)) { break; } if (!(ret = copy_or_move_file(filename, filename, - dst_dir, 1))) { + dst_dir, 1))) { goto cleanup; } } @@ -1725,26 +1703,30 @@ copy_back() /* copy redo logs */ dst_dir = (srv_log_group_home_dir && *srv_log_group_home_dir) - ? srv_log_group_home_dir : mysql_data_home; - - ds_data = ds_create(dst_dir, DS_TYPE_LOCAL); - - for (i = 0; i < (ulong)innobase_log_files_in_group; i++) { - char filename[20]; - sprintf(filename, "ib_logfile%lu", i); + ? srv_log_group_home_dir : mysql_data_home; - if (!file_exists(filename)) { - continue; - } + /* --backup generates a single ib_logfile0, which we must copy + if it exists. */ - if (!(ret = copy_or_move_file(filename, filename, - dst_dir, 1))) { - goto cleanup; + ds_data = ds_create(dst_dir, DS_TYPE_LOCAL); + MY_STAT stat_arg; + if (!my_stat("ib_logfile0", &stat_arg, MYF(0)) || !stat_arg.st_size) { + /* After completed --prepare, redo log files are redundant. + We must delete any redo logs at the destination, so that + the database will not jump to a different log sequence number + (LSN). */ + + for (uint i = 0; i <= SRV_N_LOG_FILES_MAX + 1; i++) { + char filename[FN_REFLEN]; + snprintf(filename, sizeof filename, "%s/ib_logfile%u", + dst_dir, i); + unlink(filename); } + } else if (!(ret = copy_or_move_file("ib_logfile0", "ib_logfile0", + dst_dir, 1))) { + goto cleanup; } - ds_destroy(ds_data); - ds_data = NULL; /* copy innodb system tablespace(s) */ @@ -1753,17 +1735,19 @@ copy_back() ds_data = ds_create(dst_dir, DS_TYPE_LOCAL); - for (i = 0; i < srv_n_data_files; i++) { - const char *filename = base_name(srv_data_file_names[i]); + for (Tablespace::const_iterator iter(srv_sys_space.begin()), + end(srv_sys_space.end()); + iter != end; + ++iter) { + const char *filename = base_name(iter->name()); - if (!(ret = copy_or_move_file(filename, srv_data_file_names[i], + if (!(ret = copy_or_move_file(filename, iter->name(), dst_dir, 1))) { goto cleanup; } } ds_destroy(ds_data); - ds_data = NULL; /* copy the rest of tablespaces */ ds_data = ds_create(mysql_data_home, DS_TYPE_LOCAL); @@ -1773,7 +1757,7 @@ copy_back() datadir_node_init(&node); while (datadir_iter_next(it, &node)) { - const char *ext_list[] = {"backup-my.cnf", "xtrabackup_logfile", + const char *ext_list[] = {"backup-my.cnf", "xtrabackup_binary", "xtrabackup_binlog_info", "xtrabackup_checkpoints", ".qp", ".pmap", ".tmp", NULL}; @@ -1819,21 +1803,18 @@ copy_back() continue; } - /* skip redo logs */ - if (sscanf(filename, "ib_logfile%d%c", &i_tmp, &c_tmp) == 1) { + /* skip the redo log (it was already copied) */ + if (!strcmp(filename, "ib_logfile0")) { continue; } /* skip innodb data files */ is_ibdata_file = false; - for (i = 0; i < srv_n_data_files; i++) { - const char *ibfile; - - ibfile = base_name(srv_data_file_names[i]); - - if (strcmp(ibfile, filename) == 0) { + for (Tablespace::const_iterator iter(srv_sys_space.begin()), + end(srv_sys_space.end()); iter != end; ++iter) { + if (strcmp(iter->name(), filename) == 0) { is_ibdata_file = true; - continue; + break; } } if (is_ibdata_file) { @@ -1875,20 +1856,13 @@ cleanup: datadir_node_free(&node); - free(innobase_data_file_path_copy); - if (ds_data != NULL) { ds_destroy(ds_data); } ds_data = NULL; - //os_sync_free(); - mem_close(); - //os_sync_mutex = NULL; - ut_free_all_mem(); - sync_close(); - sync_initialized = FALSE; + sync_check_close(); return(ret); } @@ -1925,12 +1899,12 @@ decrypt_decompress_file(const char *filepath, uint thread_n) return(false); } - if (opt_remove_original) { - msg_ts("[%02u] removing %s\n", thread_n, filepath); - if (my_delete(filepath, MYF(MY_WME)) != 0) { - return(false); - } - } + if (opt_remove_original) { + msg_ts("[%02u] removing %s\n", thread_n, filepath); + if (my_delete(filepath, MYF(MY_WME)) != 0) { + return(false); + } + } } return(true); @@ -1967,13 +1941,13 @@ cleanup: datadir_node_free(&node); - os_mutex_enter(ctxt->count_mutex); + pthread_mutex_lock(&ctxt->count_mutex); --(*ctxt->count); - os_mutex_exit(ctxt->count_mutex); + pthread_mutex_unlock(&ctxt->count_mutex); ctxt->ret = ret; - os_thread_exit(NULL); + os_thread_exit(); OS_THREAD_DUMMY_RETURN; } @@ -1984,10 +1958,7 @@ decrypt_decompress() datadir_iter_t *it = NULL; srv_max_n_threads = 1000; - //os_sync_mutex = NULL; - ut_mem_init(); - os_sync_init(); - sync_init(); + sync_check_init(); /* cd to backup directory */ if (my_setwd(xtrabackup_target_dir, MYF(MY_WME))) @@ -2016,11 +1987,7 @@ decrypt_decompress() ds_data = NULL; - sync_close(); - sync_initialized = FALSE; - //os_sync_free(); - //os_sync_mutex = NULL; - ut_free_all_mem(); + sync_check_close(); return(ret); } diff --git a/extra/mariabackup/backup_copy.h b/extra/mariabackup/backup_copy.h index 4b829982764..fbc09eaded3 100644 --- a/extra/mariabackup/backup_copy.h +++ b/extra/mariabackup/backup_copy.h @@ -31,10 +31,12 @@ copy_file(ds_ctxt_t *datasink, const char *dst_file_path, uint thread_n); -bool -backup_start(); -bool -backup_finish(); +/** Start --backup */ +bool backup_start(); +/** Release resources after backup_start() */ +void backup_release(); +/** Finish after backup_start() and backup_release() */ +bool backup_finish(); bool apply_log_finish(); bool diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc index 6f425e9419f..91e659f679e 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -54,6 +54,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "mysqld.h" #include "encryption_plugin.h" #include <sstream> +#include <sql_error.h> +#include <ut0ut.h> char *tool_name; @@ -116,6 +118,7 @@ xb_mysql_connect() mysql_options(connection, MYSQL_PLUGIN_DIR, xb_plugin_dir); } mysql_options(connection, MYSQL_OPT_PROTOCOL, &opt_protocol); + mysql_options(connection,MYSQL_SET_CHARSET_NAME, "utf8"); msg_ts("Connecting to MySQL server host: %s, user: %s, password: %s, " "port: %s, socket: %s\n", opt_host ? opt_host : "localhost", @@ -494,13 +497,13 @@ get_mysql_vars(MYSQL *connection) } if (innodb_log_files_in_group_var) { - innobase_log_files_in_group = strtol( + srv_n_log_files = strtol( innodb_log_files_in_group_var, &endptr, 10); ut_ad(*endptr == 0); } if (innodb_log_file_size_var) { - innobase_log_file_size = strtoll( + srv_log_file_size = strtoll( innodb_log_file_size_var, &endptr, 10); ut_ad(*endptr == 0); } @@ -579,7 +582,6 @@ bool select_incremental_lsn_from_history(lsn_t *incremental_lsn) { MYSQL_RES *mysql_result; - MYSQL_ROW row; char query[1000]; char buf[100]; @@ -587,7 +589,7 @@ select_incremental_lsn_from_history(lsn_t *incremental_lsn) mysql_real_escape_string(mysql_connection, buf, opt_incremental_history_name, (unsigned long)strlen(opt_incremental_history_name)); - ut_snprintf(query, sizeof(query), + snprintf(query, sizeof(query), "SELECT innodb_to_lsn " "FROM PERCONA_SCHEMA.xtrabackup_history " "WHERE name = '%s' " @@ -600,7 +602,7 @@ select_incremental_lsn_from_history(lsn_t *incremental_lsn) mysql_real_escape_string(mysql_connection, buf, opt_incremental_history_uuid, (unsigned long)strlen(opt_incremental_history_uuid)); - ut_snprintf(query, sizeof(query), + snprintf(query, sizeof(query), "SELECT innodb_to_lsn " "FROM PERCONA_SCHEMA.xtrabackup_history " "WHERE uuid = '%s' " @@ -612,27 +614,27 @@ select_incremental_lsn_from_history(lsn_t *incremental_lsn) mysql_result = xb_mysql_query(mysql_connection, query, true); ut_ad(mysql_num_fields(mysql_result) == 1); - if (!(row = mysql_fetch_row(mysql_result))) { + const MYSQL_ROW row = mysql_fetch_row(mysql_result); + if (row) { + *incremental_lsn = strtoull(row[0], NULL, 10); + msg("Found and using lsn: " LSN_PF " for %s %s\n", + *incremental_lsn, + opt_incremental_history_uuid ? "uuid" : "name", + opt_incremental_history_uuid ? + opt_incremental_history_uuid : + opt_incremental_history_name); + } else { msg("Error while attempting to find history record " "for %s %s\n", opt_incremental_history_uuid ? "uuid" : "name", opt_incremental_history_uuid ? opt_incremental_history_uuid : opt_incremental_history_name); - return(false); } - *incremental_lsn = strtoull(row[0], NULL, 10); - mysql_free_result(mysql_result); - msg("Found and using lsn: " LSN_PF " for %s %s\n", *incremental_lsn, - opt_incremental_history_uuid ? "uuid" : "name", - opt_incremental_history_uuid ? - opt_incremental_history_uuid : - opt_incremental_history_name); - - return(true); + return(row != NULL); } static @@ -719,16 +721,14 @@ static bool have_queries_to_wait_for(MYSQL *connection, uint threshold) { - MYSQL_RES *result; - MYSQL_ROW row; - bool all_queries; - - result = xb_mysql_query(connection, "SHOW FULL PROCESSLIST", true); + MYSQL_RES *result = xb_mysql_query(connection, "SHOW FULL PROCESSLIST", + true); + const bool all_queries = (opt_lock_wait_query_type == QUERY_TYPE_ALL); + bool have_to_wait = false; - all_queries = (opt_lock_wait_query_type == QUERY_TYPE_ALL); - while ((row = mysql_fetch_row(result)) != NULL) { + while (MYSQL_ROW row = mysql_fetch_row(result)) { const char *info = row[7]; - int duration = atoi(row[5]); + int duration = row[5] ? atoi(row[5]) : 0; char *id = row[0]; if (info != NULL @@ -737,28 +737,27 @@ have_queries_to_wait_for(MYSQL *connection, uint threshold) || is_update_query(info))) { msg_ts("Waiting for query %s (duration %d sec): %s", id, duration, info); - return(true); + have_to_wait = true; + break; } } - return(false); + mysql_free_result(result); + return(have_to_wait); } static void kill_long_queries(MYSQL *connection, time_t timeout) { - MYSQL_RES *result; - MYSQL_ROW row; - bool all_queries; char kill_stmt[100]; - result = xb_mysql_query(connection, "SHOW FULL PROCESSLIST", true); - - all_queries = (opt_kill_long_query_type == QUERY_TYPE_ALL); - while ((row = mysql_fetch_row(result)) != NULL) { + MYSQL_RES *result = xb_mysql_query(connection, "SHOW FULL PROCESSLIST", + true); + const bool all_queries = (opt_kill_long_query_type == QUERY_TYPE_ALL); + while (MYSQL_ROW row = mysql_fetch_row(result)) { const char *info = row[7]; - long long duration = atoll(row[5]); + long long duration = row[5]? atoll(row[5]) : 0; char *id = row[0]; if (info != NULL && @@ -767,11 +766,13 @@ kill_long_queries(MYSQL *connection, time_t timeout) is_select_query(info))) { msg_ts("Killing query %s (duration %d sec): %s\n", id, (int)duration, info); - ut_snprintf(kill_stmt, sizeof(kill_stmt), + snprintf(kill_stmt, sizeof(kill_stmt), "KILL %s", id); xb_mysql_query(connection, kill_stmt, false, false); } } + + mysql_free_result(result); } static @@ -841,7 +842,7 @@ stop_thread: os_event_set(kill_query_thread_stopped); - os_thread_exit(NULL); + os_thread_exit(); OS_THREAD_DUMMY_RETURN; } @@ -850,9 +851,9 @@ static void start_query_killer() { - kill_query_thread_stop = os_event_create(); - kill_query_thread_started = os_event_create(); - kill_query_thread_stopped = os_event_create(); + kill_query_thread_stop = os_event_create(0); + kill_query_thread_started = os_event_create(0); + kill_query_thread_stopped = os_event_create(0); os_thread_create(kill_query_thread, NULL, &kill_query_thread_id); @@ -1287,8 +1288,8 @@ write_current_binlog_file(MYSQL *connection) goto cleanup; } - ut_snprintf(filepath, sizeof(filepath), "%s%c%s", - log_bin_dir, FN_LIBCHAR, log_bin_file); + snprintf(filepath, sizeof(filepath), "%s%c%s", + log_bin_dir, FN_LIBCHAR, log_bin_file); result = copy_file(ds_data, filepath, log_bin_file, 0); } @@ -1368,17 +1369,27 @@ cleanup: return(result); } -static string escape_and_quote(MYSQL *mysql,const char *str) +struct escape_and_quote +{ + escape_and_quote(MYSQL *mysql, const char *str) + : mysql(mysql), str(str) {} + MYSQL * const mysql; + const char * const str; +}; + +static +std::ostream& +operator<<(std::ostream& s, const escape_and_quote& eq) { - if (!str) - return "NULL"; - size_t len = strlen(str); - char* escaped = (char *)alloca(2 * len + 3); - escaped[0] = '\''; - size_t new_len = mysql_real_escape_string(mysql, escaped+1, str, len); - escaped[new_len + 1] = '\''; - escaped[new_len + 2] = 0; - return string(escaped); + if (!eq.str) + return s << "NULL"; + s << '\''; + size_t len = strlen(eq.str); + char* escaped = (char *)alloca(2 * len + 1); + len = mysql_real_escape_string(eq.mysql, escaped, eq.str, len); + s << std::string(escaped, len); + s << '\''; + return s; } /*********************************************************************//** @@ -1387,7 +1398,7 @@ PERCONA_SCHEMA.xtrabackup_history and writes a new history record to the table containing all the history info particular to the just completed backup. */ bool -write_xtrabackup_info(MYSQL *connection) +write_xtrabackup_info(MYSQL *connection, const char * filename, bool history) { char *uuid = NULL; @@ -1395,12 +1406,9 @@ write_xtrabackup_info(MYSQL *connection) char buf_start_time[100]; char buf_end_time[100]; tm tm; - ostringstream oss; + std::ostringstream oss; const char *xb_stream_name[] = {"file", "tar", "xbstream"}; - - ut_ad(xtrabackup_stream_fmt < 3); - uuid = read_mysql_one_value(connection, "SELECT UUID()"); server_version = read_mysql_one_value(connection, "SELECT VERSION()"); localtime_r(&history_start_time, &tm); @@ -1418,7 +1426,7 @@ write_xtrabackup_info(MYSQL *connection) || xtrabackup_databases_exclude ); - backup_file_printf(XTRABACKUP_INFO, + backup_file_printf(filename, "uuid = %s\n" "name = %s\n" "tool_name = %s\n" @@ -1455,7 +1463,7 @@ write_xtrabackup_info(MYSQL *connection) xb_stream_name[xtrabackup_stream_fmt], /* format */ xtrabackup_compress ? "compressed" : "N"); /* compressed */ - if (!opt_history) { + if (!history) { goto cleanup; } @@ -1528,28 +1536,21 @@ bool write_backup_config_file() "# The MySQL server\n" "[mysqld]\n" "innodb_checksum_algorithm=%s\n" - "innodb_log_checksum_algorithm=%s\n" "innodb_data_file_path=%s\n" "innodb_log_files_in_group=%lu\n" - "innodb_log_file_size=%lld\n" + "innodb_log_file_size=%llu\n" "innodb_page_size=%lu\n" - "innodb_log_block_size=%lu\n" "innodb_undo_directory=%s\n" "innodb_undo_tablespaces=%lu\n" "%s%s\n" - "%s%s\n" "%s\n", innodb_checksum_algorithm_names[srv_checksum_algorithm], - innodb_checksum_algorithm_names[srv_log_checksum_algorithm], innobase_data_file_path, srv_n_log_files, - innobase_log_file_size, + srv_log_file_size, srv_page_size, - srv_log_block_size, srv_undo_dir, srv_undo_tablespaces, - innobase_doublewrite_file ? "innodb_doublewrite_file=" : "", - innobase_doublewrite_file ? innobase_doublewrite_file : "", innobase_buffer_pool_filename ? "innodb_buffer_pool_filename=" : "", innobase_buffer_pool_filename ? @@ -1573,8 +1574,8 @@ char *make_argv(char *buf, size_t len, int argc, char **argv) if (strncmp(*argv, "--password", strlen("--password")) == 0) { arg = "--password=..."; } - left-= ut_snprintf(buf + len - left, left, - "%s%c", arg, argc > 1 ? ' ' : 0); + left-= snprintf(buf + len - left, left, + "%s%c", arg, argc > 1 ? ' ' : 0); ++argv; --argc; } @@ -1630,3 +1631,76 @@ backup_cleanup() mysql_close(mysql_connection); } } + + +static pthread_mutex_t mdl_lock_con_mutex; +static MYSQL *mdl_con = NULL; + +void +mdl_lock_init() +{ + pthread_mutex_init(&mdl_lock_con_mutex, NULL); + mdl_con = xb_mysql_connect(); + if (mdl_con) + { + xb_mysql_query(mdl_con, "BEGIN", false, true); + } +} + +#ifndef DBUG_OFF +/* Test that table is really locked, if lock_ddl_per_table is set. + The test is executed in DBUG_EXECUTE_IF block inside mdl_lock_table(). +*/ +static void check_mdl_lock_works(const char *table_name) +{ + MYSQL *test_con= xb_mysql_connect(); + char *query; + xb_a(asprintf(&query, + "SET STATEMENT max_statement_time=1 FOR ALTER TABLE %s" + " ADD COLUMN mdl_lock_column int", table_name)); + int err = mysql_query(test_con, query); + DBUG_ASSERT(err); + int err_no = mysql_errno(test_con); + DBUG_ASSERT(err_no == ER_STATEMENT_TIMEOUT); + mysql_close(test_con); + free(query); +} +#endif +void +mdl_lock_table(ulint space_id) +{ + std::ostringstream oss; + oss << "SELECT NAME " + "FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES " + "WHERE SPACE = " << space_id << " AND NAME LIKE '%%/%%'"; + + pthread_mutex_lock(&mdl_lock_con_mutex); + + MYSQL_RES *mysql_result = xb_mysql_query(mdl_con, oss.str().c_str(), true, true); + + while (MYSQL_ROW row = mysql_fetch_row(mysql_result)) { + std::string full_table_name = ut_get_name(0,row[0]); + std::ostringstream lock_query; + lock_query << "SELECT * FROM " << full_table_name << " LIMIT 0"; + + msg_ts("Locking MDL for %s\n", full_table_name.c_str()); + xb_mysql_query(mdl_con, lock_query.str().c_str(), false, false); + + DBUG_EXECUTE_IF("check_mdl_lock_works", + check_mdl_lock_works(full_table_name.c_str());); + } + + pthread_mutex_unlock(&mdl_lock_con_mutex); + mysql_free_result(mysql_result); +} + + +void +mdl_unlock_all() +{ + msg_ts("Unlocking MDL for all tables\n"); + xb_mysql_query(mdl_con, "COMMIT", false, true); + mysql_close(mdl_con); + pthread_mutex_destroy(&mdl_lock_con_mutex); +} + diff --git a/extra/mariabackup/backup_mysql.h b/extra/mariabackup/backup_mysql.h index 3ccd7bdb613..e2c56f88a8c 100644 --- a/extra/mariabackup/backup_mysql.h +++ b/extra/mariabackup/backup_mysql.h @@ -68,7 +68,7 @@ bool write_binlog_info(MYSQL *connection); bool -write_xtrabackup_info(MYSQL *connection); +write_xtrabackup_info(MYSQL *connection, const char * filename, bool history); bool write_backup_config_file(); diff --git a/extra/mariabackup/backup_wsrep.h b/extra/mariabackup/backup_wsrep.h index 5fa261f8db5..6537b304e12 100644 --- a/extra/mariabackup/backup_wsrep.h +++ b/extra/mariabackup/backup_wsrep.h @@ -19,8 +19,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *******************************************************/ -#ifndef MARIABACKUP_WSREP_H -#define MARIABACKUP_WSREP_H +#ifndef BACKUP_WSREP_H +#define BACKUP_WSREP_H /*********************************************************************** Store Galera checkpoint info in the 'xtrabackup_galera_info' file, if that diff --git a/extra/mariabackup/changed_page_bitmap.cc b/extra/mariabackup/changed_page_bitmap.cc index d5185b18971..46bb3a7bcb5 100644 --- a/extra/mariabackup/changed_page_bitmap.cc +++ b/extra/mariabackup/changed_page_bitmap.cc @@ -193,9 +193,9 @@ log_online_read_bitmap_page( ut_a(bitmap_file->offset <= bitmap_file->size - MODIFIED_PAGE_BLOCK_SIZE); ut_a(bitmap_file->offset % MODIFIED_PAGE_BLOCK_SIZE == 0); - - success = os_file_read(bitmap_file->file, page, bitmap_file->offset, - MODIFIED_PAGE_BLOCK_SIZE); + success = os_file_read(IORequestRead, + bitmap_file->file, page, bitmap_file->offset, + MODIFIED_PAGE_BLOCK_SIZE); if (UNIV_UNLIKELY(!success)) { @@ -355,8 +355,7 @@ log_online_setup_bitmap_file_range( bitmap_files->files = static_cast<log_online_bitmap_file_range_t::files_t *> - (ut_malloc(bitmap_files->count - * sizeof(bitmap_files->files[0]))); + (malloc(bitmap_files->count * sizeof(bitmap_files->files[0]))); memset(bitmap_files->files, 0, bitmap_files->count * sizeof(bitmap_files->files[0])); @@ -426,9 +425,9 @@ log_online_setup_bitmap_file_range( /****************************************************************//** Open a bitmap file for reading. -@return TRUE if opened successfully */ +@return whether opened successfully */ static -ibool +bool log_online_open_bitmap_file_read_only( /*==================================*/ const char* name, /*!<in: bitmap file @@ -438,23 +437,21 @@ log_online_open_bitmap_file_read_only( log_online_bitmap_file_t* bitmap_file) /*!<out: opened bitmap file */ { - ibool success = FALSE; + bool success = false; xb_ad(name[0] != '\0'); - ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%s", srv_data_home, name); - bitmap_file->file - = os_file_create_simple_no_error_handling(0, bitmap_file->name, - OS_FILE_OPEN, - OS_FILE_READ_ONLY, - &success,0); + snprintf(bitmap_file->name, FN_REFLEN, "%s%s", srv_data_home, name); + bitmap_file->file = os_file_create_simple_no_error_handling( + 0, bitmap_file->name, + OS_FILE_OPEN, OS_FILE_READ_ONLY, true, &success); if (UNIV_UNLIKELY(!success)) { /* Here and below assume that bitmap file names do not contain apostrophes, thus no need for ut_print_filename(). */ msg("InnoDB: Warning: error opening the changed page " "bitmap \'%s\'\n", bitmap_file->name); - return FALSE; + return success; } bitmap_file->size = os_file_get_size(bitmap_file->file); @@ -465,7 +462,7 @@ log_online_open_bitmap_file_read_only( posix_fadvise(bitmap_file->file, 0, 0, POSIX_FADV_NOREUSE); #endif - return TRUE; + return success; } /****************************************************************//** @@ -909,6 +906,37 @@ xb_page_bitmap_setup_next_page( return TRUE; } +/** Find the node with the smallest key that greater than equal to search key. +@param[in] tree red-black tree +@param[in] key search key +@return node with the smallest greater-than-or-equal key +@retval NULL if none was found */ +static +const ib_rbt_node_t* +rbt_lower_bound(const ib_rbt_t* tree, const void* key) +{ + ut_ad(!tree->cmp_arg); + const ib_rbt_node_t* ge = NULL; + + for (const ib_rbt_node_t *node = tree->root->left; + node != tree->nil; ) { + int result = tree->compare(node->value, key); + + if (result < 0) { + node = node->right; + } else { + ge = node; + if (result == 0) { + break; + } + + node = node->left; + } + } + + return(ge); +} + /****************************************************************//** Set up a new bitmap range iterator over a given space id changed pages in a given bitmap. @@ -922,8 +950,7 @@ xb_page_bitmap_range_init( { byte search_page[MODIFIED_PAGE_BLOCK_SIZE]; xb_page_bitmap_range *result - = static_cast<xb_page_bitmap_range *> - (ut_malloc(sizeof(*result))); + = static_cast<xb_page_bitmap_range *>(malloc(sizeof(*result))); memset(result, 0, sizeof(*result)); result->bitmap = bitmap; @@ -1014,5 +1041,5 @@ xb_page_bitmap_range_deinit( /*========================*/ xb_page_bitmap_range* bitmap_range) /*! in/out: bitmap range */ { - ut_free(bitmap_range); + free(bitmap_range); } diff --git a/extra/mariabackup/common.h b/extra/mariabackup/common.h index 340ad66e28a..fae466adc97 100644 --- a/extra/mariabackup/common.h +++ b/extra/mariabackup/common.h @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #include <mysql_version.h> #include <fcntl.h> #include <stdarg.h> +#include <my_sys.h> /** Determine if (i) is a user tablespace id or not. */ diff --git a/extra/mariabackup/encryption_plugin.cc b/extra/mariabackup/encryption_plugin.cc index 8f7741b057a..76512c185e2 100644 --- a/extra/mariabackup/encryption_plugin.cc +++ b/extra/mariabackup/encryption_plugin.cc @@ -8,6 +8,7 @@ #include <vector> #include <common.h> #include <backup_mysql.h> +#include <log0crypt.h> extern struct st_maria_plugin *mysql_optional_plugins[]; @@ -18,14 +19,14 @@ extern char *xb_plugin_load; extern char *xb_plugin_dir; const int PLUGIN_MAX_ARGS = 1024; -vector<string> backup_plugins_args; +std::vector<std::string> backup_plugins_args; const char *QUERY_PLUGIN = "SELECT plugin_name, plugin_library, @@plugin_dir" " FROM information_schema.plugins WHERE plugin_type='ENCRYPTION'" " AND plugin_status='ACTIVE'"; -string encryption_plugin_config; +std::string encryption_plugin_config; static void add_to_plugin_load_list(const char *plugin_def) { @@ -38,7 +39,7 @@ void encryption_plugin_backup_init(MYSQL *mysql) { MYSQL_RES *result; MYSQL_ROW row; - ostringstream oss; + std::ostringstream oss; char *argv[PLUGIN_MAX_ARGS]; int argc; @@ -59,17 +60,17 @@ void encryption_plugin_backup_init(MYSQL *mysql) if (*p == '\\') *p = '/'; #endif - string plugin_load(name); + std::string plugin_load(name); if (library) - plugin_load += string("=") + library; + plugin_load += std::string("=") + library; - oss << "plugin_load=" << plugin_load << endl; + oss << "plugin_load=" << plugin_load << std::endl; /* Required to load the plugin later.*/ add_to_plugin_load_list(plugin_load.c_str()); strncpy(opt_plugin_dir, dir, FN_REFLEN); - oss << "plugin_dir=" << '"' << dir << '"' << endl; + oss << "plugin_dir=" << '"' << dir << '"' << std::endl; /* Read plugin variables. */ @@ -80,12 +81,12 @@ void encryption_plugin_backup_init(MYSQL *mysql) result = xb_mysql_query(mysql, query, true, true); while ((row = mysql_fetch_row(result))) { - string arg("--"); + std::string arg("--"); arg += row[0]; arg += "="; arg += row[1]; backup_plugins_args.push_back(arg); - oss << row[0] << "=" << row[1] << endl; + oss << row[0] << "=" << row[1] << std::endl; } mysql_free_result(result); @@ -94,7 +95,7 @@ void encryption_plugin_backup_init(MYSQL *mysql) result = xb_mysql_query(mysql, "select @@innodb_encrypt_log", true, true); row = mysql_fetch_row(result); srv_encrypt_log = (row != 0 && row[0][0] == '1'); - oss << "innodb_encrypt_log=" << row[0] << endl; + oss << "innodb_encrypt_log=" << row[0] << std::endl; mysql_free_result(result); diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc index 54700ce6837..f6e6fe43085 100644 --- a/extra/mariabackup/fil_cur.cc +++ b/extra/mariabackup/fil_cur.cc @@ -24,8 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #include <my_base.h> -#include <univ.i> #include <fil0fil.h> +#include <fsp0fsp.h> #include <srv0start.h> #include <trx0sys.h> @@ -63,7 +63,7 @@ xb_get_relative_path( prev = NULL; cur = path; - while ((next = strchr(cur, SRV_PATH_SEPARATOR)) != NULL) { + while ((next = strchr(cur, OS_PATH_SEPARATOR)) != NULL) { prev = cur; cur = next + 1; @@ -96,7 +96,7 @@ xb_fil_node_close_file( ut_a(node->n_pending_flushes == 0); ut_a(!node->being_extended); - if (!node->open) { + if (!node->is_open()) { mutex_exit(&fil_system->mutex); @@ -106,19 +106,19 @@ xb_fil_node_close_file( ret = os_file_close(node->handle); ut_a(ret); - node->open = FALSE; + node->handle = OS_FILE_CLOSED; ut_a(fil_system->n_open > 0); fil_system->n_open--; fil_n_file_opened--; - if (node->space->purpose == FIL_TABLESPACE && + if (node->space->purpose == FIL_TYPE_TABLESPACE && fil_is_user_tablespace_id(node->space->id)) { ut_a(UT_LIST_GET_LEN(fil_system->LRU) > 0); /* The node is in the LRU list, remove it */ - UT_LIST_REMOVE(LRU, fil_system->LRU, node); + UT_LIST_REMOVE(fil_system->LRU, node); } mutex_exit(&fil_system->mutex); @@ -137,10 +137,7 @@ xb_fil_cur_open( fil_node_t* node, /*!< in: source tablespace node */ uint thread_n) /*!< thread number for diagnostics */ { - ulint page_size; - ulint page_size_shift; - ulint zip_size; - ibool success; + bool success; /* Initialize these first so xb_fil_cur_close() handles them correctly in case of error */ @@ -148,27 +145,26 @@ xb_fil_cur_open( cursor->node = NULL; cursor->space_id = node->space->id; - cursor->is_system = !fil_is_user_tablespace_id(node->space->id); strncpy(cursor->abs_path, node->name, sizeof(cursor->abs_path)); /* Get the relative path for the destination tablespace name, i.e. the one that can be appended to the backup root directory. Non-system - tablespaces may have absolute paths for remote tablespaces in MySQL - 5.6+. We want to make "local" copies for the backup. */ + tablespaces may have absolute paths for DATA DIRECTORY. + We want to make "local" copies for the backup. */ strncpy(cursor->rel_path, - xb_get_relative_path(cursor->abs_path, cursor->is_system), + xb_get_relative_path(cursor->abs_path, cursor->is_system()), sizeof(cursor->rel_path)); /* In the backup mode we should already have a tablespace handle created - by fil_load_single_table_tablespace() unless it is a system + by fil_ibd_load() unless it is a system tablespace. Otherwise we open the file here. */ - if (cursor->is_system || !srv_backup_mode || srv_close_files) { - node->handle = - os_file_create_simple_no_error_handling(0, node->name, - OS_FILE_OPEN, - OS_FILE_READ_ONLY, - &success,0); + if (cursor->is_system() || srv_operation == SRV_OPERATION_RESTORE_DELTA + || xb_close_files) { + node->handle = os_file_create_simple_no_error_handling( + 0, node->name, + OS_FILE_OPEN, + OS_FILE_READ_ALLOW_DELETE, true, &success); if (!success) { /* The following call prints an error message */ os_file_get_last_error(TRUE); @@ -181,22 +177,20 @@ xb_fil_cur_open( } mutex_enter(&fil_system->mutex); - node->open = TRUE; - fil_system->n_open++; fil_n_file_opened++; - if (node->space->purpose == FIL_TABLESPACE && + if (node->space->purpose == FIL_TYPE_TABLESPACE && fil_is_user_tablespace_id(node->space->id)) { /* Put the node to the LRU list */ - UT_LIST_ADD_FIRST(LRU, fil_system->LRU, node); + UT_LIST_ADD_FIRST(fil_system->LRU, node); } mutex_exit(&fil_system->mutex); } - ut_ad(node->open); + ut_ad(node->is_open()); cursor->node = node; cursor->file = node->handle; @@ -210,41 +204,21 @@ xb_fil_cur_open( return(XB_FIL_CUR_ERROR); } - if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT - || srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC) { + if (srv_file_flush_method == SRV_O_DIRECT + || srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC) { os_file_set_nocache(cursor->file, node->name, "OPEN"); } posix_fadvise(cursor->file, 0, 0, POSIX_FADV_SEQUENTIAL); - /* Determine the page size */ - zip_size = xb_get_zip_size(cursor->file); - if (zip_size == ULINT_UNDEFINED) { - xb_fil_cur_close(cursor); - return(XB_FIL_CUR_SKIP); - } else if (zip_size) { - page_size = zip_size; - page_size_shift = get_bit_shift(page_size); - msg("[%02u] %s is compressed with page size = " - "%lu bytes\n", thread_n, node->name, page_size); - if (page_size_shift < 10 || page_size_shift > 14) { - msg("[%02u] mariabackup: Error: Invalid " - "page size: %lu.\n", thread_n, page_size); - ut_error; - } - } else { - page_size = UNIV_PAGE_SIZE; - page_size_shift = UNIV_PAGE_SIZE_SHIFT; - } + const page_size_t page_size(cursor->node->space->flags); cursor->page_size = page_size; - cursor->page_size_shift = page_size_shift; - cursor->zip_size = zip_size; /* Allocate read buffer */ - cursor->buf_size = XB_FIL_CUR_PAGES * page_size; + cursor->buf_size = XB_FIL_CUR_PAGES * page_size.physical(); cursor->orig_buf = static_cast<byte *> - (ut_malloc(cursor->buf_size + UNIV_PAGE_SIZE)); + (malloc(cursor->buf_size + UNIV_PAGE_SIZE)); cursor->buf = static_cast<byte *> (ut_align(cursor->orig_buf, UNIV_PAGE_SIZE)); @@ -254,7 +228,8 @@ xb_fil_cur_open( cursor->buf_page_no = 0; cursor->thread_n = thread_n; - cursor->space_size = (ulint)(cursor->statinfo.st_size / page_size); + cursor->space_size = (ulint)(cursor->statinfo.st_size + / page_size.physical()); cursor->read_filter = read_filter; cursor->read_filter->init(&cursor->read_filter_ctxt, cursor, @@ -282,6 +257,8 @@ xb_fil_cur_read( xb_fil_cur_result_t ret; ib_int64_t offset; ib_int64_t to_read; + const ulint page_size = cursor->page_size.physical(); + xb_ad(!cursor->is_system() || page_size == UNIV_PAGE_SIZE); cursor->read_filter->get_next_batch(&cursor->read_filter_ctxt, &offset, &to_read); @@ -296,10 +273,10 @@ xb_fil_cur_read( xb_a(to_read > 0 && to_read <= 0xFFFFFFFFLL); - if (to_read % cursor->page_size != 0 && - offset + to_read == cursor->statinfo.st_size) { + if ((to_read & ~(page_size - 1)) + && offset + to_read == cursor->statinfo.st_size) { - if (to_read < (ib_int64_t) cursor->page_size) { + if (to_read < (ib_int64_t) page_size) { msg("[%02u] mariabackup: Warning: junk at the end of " "%s:\n", cursor->thread_n, cursor->abs_path); msg("[%02u] mariabackup: Warning: offset = %llu, " @@ -312,12 +289,12 @@ xb_fil_cur_read( } to_read = (ib_int64_t) (((ulint) to_read) & - ~(cursor->page_size - 1)); + ~(page_size - 1)); } - xb_a(to_read % cursor->page_size == 0); + xb_a((to_read & (page_size - 1)) == 0); - npages = (ulint) (to_read >> cursor->page_size_shift); + npages = (ulint) (to_read / cursor->page_size.physical()); retry_count = 10; ret = XB_FIL_CUR_SUCCESS; @@ -328,59 +305,59 @@ read_retry: cursor->buf_read = 0; cursor->buf_npages = 0; cursor->buf_offset = offset; - cursor->buf_page_no = (ulint)(offset >> cursor->page_size_shift); + cursor->buf_page_no = (ulint)(offset / cursor->page_size.physical()); - success = os_file_read(cursor->file, cursor->buf, offset, - (ulint)to_read); - if (!success) { + FilSpace space(cursor->space_id); + + if (!space()) { return(XB_FIL_CUR_ERROR); } - fil_system_enter(); - fil_space_t *space = fil_space_get_by_id(cursor->space_id); - fil_system_exit(); + success = os_file_read(IORequestRead, + cursor->file, cursor->buf, offset, + (ulint) to_read); + if (!success) { + return(XB_FIL_CUR_ERROR); + } /* check pages for corruption and re-read if necessary. i.e. in case of partially written pages */ for (page = cursor->buf, i = 0; i < npages; - page += cursor->page_size, i++) { - ib_int64_t page_no = cursor->buf_page_no + i; - - bool checksum_ok = fil_space_verify_crypt_checksum(page, cursor->zip_size,space, (ulint)page_no); - - if (!checksum_ok && - buf_page_is_corrupted(true, page, cursor->zip_size,space)) { - - if (cursor->is_system && - page_no >= (ib_int64_t)FSP_EXTENT_SIZE && - page_no < (ib_int64_t) FSP_EXTENT_SIZE * 3) { - /* skip doublewrite buffer pages */ - xb_a(cursor->page_size == UNIV_PAGE_SIZE); + page += page_size, i++) { + ulint page_no = cursor->buf_page_no + i; + + if (cursor->space_id == TRX_SYS_SPACE && + page_no >= FSP_EXTENT_SIZE && + page_no < FSP_EXTENT_SIZE * 3) { + /* We ignore the doublewrite buffer pages */ + } else if (!fil_space_verify_crypt_checksum( + page, cursor->page_size, space->id, page_no) + && buf_page_is_corrupted(true, page, + cursor->page_size, + space)) { + retry_count--; + if (retry_count == 0) { msg("[%02u] mariabackup: " - "Page %lu is a doublewrite buffer page, " - "skipping.\n", cursor->thread_n, page_no); - } else { - retry_count--; - if (retry_count == 0) { - msg("[%02u] mariabackup: " - "Error: failed to read page after " - "10 retries. File %s seems to be " - "corrupted.\n", cursor->thread_n, - cursor->abs_path); - ret = XB_FIL_CUR_ERROR; - break; - } + "Error: failed to read page after " + "10 retries. File %s seems to be " + "corrupted.\n", cursor->thread_n, + cursor->abs_path); + ret = XB_FIL_CUR_ERROR; + break; + } + + if (retry_count == 9) { msg("[%02u] mariabackup: " "Database page corruption detected at page " - "%lu, retrying...\n", cursor->thread_n, - page_no); + ULINTPF ", retrying...\n", + cursor->thread_n, page_no); + } - os_thread_sleep(100000); + os_thread_sleep(100000); - goto read_retry; - } + goto read_retry; } - cursor->buf_read += cursor->page_size; + cursor->buf_read += page_size; cursor->buf_npages++; } @@ -399,11 +376,10 @@ xb_fil_cur_close( { cursor->read_filter->deinit(&cursor->read_filter_ctxt); - if (cursor->orig_buf != NULL) { - ut_free(cursor->orig_buf); - } + free(cursor->orig_buf); + if (cursor->node != NULL) { xb_fil_node_close_file(cursor->node); - cursor->file = XB_FILE_UNDEFINED; + cursor->file = OS_FILE_CLOSED; } } diff --git a/extra/mariabackup/fil_cur.h b/extra/mariabackup/fil_cur.h index f3601823a5a..e3f356a346c 100644 --- a/extra/mariabackup/fil_cur.h +++ b/extra/mariabackup/fil_cur.h @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #include <my_dir.h> #include "read_filt.h" +#include "srv0start.h" struct xb_fil_cur_t { pfs_os_file_t file; /*!< source file handle */ @@ -36,14 +37,7 @@ struct xb_fil_cur_t { char abs_path[FN_REFLEN]; /*!< absolute file path */ MY_STAT statinfo; /*!< information about the file */ - ulint zip_size; /*!< compressed page size in bytes or 0 - for uncompressed pages */ - ulint page_size; /*!< = zip_size for compressed pages or - UNIV_PAGE_SIZE for uncompressed ones */ - ulint page_size_shift;/*!< bit shift corresponding to - page_size */ - my_bool is_system; /*!< TRUE for system tablespace, FALSE - otherwise */ + page_size_t page_size; /*!< page size */ xb_read_filt_t* read_filter; /*!< read filter */ xb_read_filt_ctxt_t read_filter_ctxt; /*!< read filter context */ @@ -61,6 +55,17 @@ struct xb_fil_cur_t { uint thread_n; /*!< thread number for diagnostics */ ulint space_id; /*!< ID of tablespace */ ulint space_size; /*!< space size in pages */ + + /** TODO: remove this default constructor */ + xb_fil_cur_t() : page_size(0), read_filter_ctxt() {} + + /** @return whether this is not a file-per-table tablespace */ + bool is_system() const + { + ut_ad(space_id != SRV_TMP_SPACE_ID); + return(space_id == TRX_SYS_SPACE + || srv_is_undo_tablespace(space_id)); + } }; typedef enum { diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc index 7e97b258489..c15e02cdff3 100644 --- a/extra/mariabackup/innobackupex.cc +++ b/extra/mariabackup/innobackupex.cc @@ -45,7 +45,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include <mysql.h> #include <my_dir.h> #include <ut0mem.h> -#include <os0sync.h> #include <os0file.h> #include <srv0start.h> #include <algorithm> @@ -70,7 +69,6 @@ using std::max; my_bool opt_ibx_version = FALSE; my_bool opt_ibx_help = FALSE; my_bool opt_ibx_apply_log = FALSE; -my_bool opt_ibx_redo_only = FALSE; my_bool opt_ibx_incremental = FALSE; my_bool opt_ibx_notimestamp = FALSE; @@ -95,8 +93,6 @@ char *opt_ibx_host = NULL; char *opt_ibx_defaults_group = NULL; char *opt_ibx_socket = NULL; uint opt_ibx_port = 0; -char *opt_ibx_login_path = NULL; - ulong opt_ibx_lock_wait_query_type; ulong opt_ibx_kill_long_query_type; @@ -226,21 +222,11 @@ static struct my_option ibx_long_options[] = GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"apply-log", OPT_APPLY_LOG, "Prepare a backup in BACKUP-DIR by " - "applying the transaction log file named \"xtrabackup_logfile\" " - "located in the same directory. Also, create new transaction logs. " + "applying the redo log 'ib_logfile0' and creating new redo log. " "The InnoDB configuration is read from the file \"backup-my.cnf\".", (uchar*) &opt_ibx_apply_log, (uchar*) &opt_ibx_apply_log, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"redo-only", OPT_REDO_ONLY, "This option should be used when " - "preparing the base full backup and when merging all incrementals " - "except the last one. This forces xtrabackup to skip the \"rollback\" " - "phase and do a \"redo\" only. This is necessary if the backup will " - "have incremental changes applied to it later. See the xtrabackup " - "documentation for details.", - (uchar *) &opt_ibx_redo_only, (uchar *) &opt_ibx_redo_only, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"copy-back", OPT_COPY_BACK, "Copy all the files in a previously made " "backup from the backup directory to their original locations.", (uchar *) &opt_ibx_copy_back, (uchar *) &opt_ibx_copy_back, 0, @@ -682,7 +668,7 @@ innobackupex [--compress] [--compress-threads=NUMBER-OF-THREADS] [--compress-chu \n\ innobackupex --apply-log [--use-memory=B]\n\ [--defaults-file=MY.CNF]\n\ - [--export] [--redo-only] [--ibbackup=IBBACKUP-BINARY]\n\ + [--export] [--ibbackup=IBBACKUP-BINARY]\n\ BACKUP-DIR\n\ \n\ innobackupex --copy-back [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME] BACKUP-DIR\n\ @@ -710,7 +696,7 @@ process.\n\ \n\ The --apply-log command prepares a backup for starting a MySQL\n\ server on the backup. This command recovers InnoDB data files as specified\n\ -in BACKUP-DIR/backup-my.cnf using BACKUP-DIR/xtrabackup_logfile,\n\ +in BACKUP-DIR/backup-my.cnf using BACKUP-DIR/ib_logfile0,\n\ and creates new InnoDB log files as specified in BACKUP-DIR/backup-my.cnf.\n\ The BACKUP-DIR should be the path to a backup directory created by\n\ xtrabackup. This command runs xtrabackup as a child process, but it does not \n\ @@ -909,7 +895,6 @@ ibx_init() opt_defaults_group = opt_ibx_defaults_group; opt_socket = opt_ibx_socket; opt_port = opt_ibx_port; - opt_login_path = opt_ibx_login_path; opt_lock_wait_query_type = opt_ibx_lock_wait_query_type; opt_kill_long_query_type = opt_ibx_kill_long_query_type; @@ -980,9 +965,6 @@ ibx_init() switch (ibx_mode) { case IBX_MODE_APPLY_LOG: xtrabackup_prepare = TRUE; - if (opt_ibx_redo_only) { - xtrabackup_apply_log_only = TRUE; - } xtrabackup_target_dir = ibx_position_arg; run = "apply-log"; break; diff --git a/extra/mariabackup/read_filt.cc b/extra/mariabackup/read_filt.cc index 05e6b7c86c7..a48591abf29 100644 --- a/extra/mariabackup/read_filt.cc +++ b/extra/mariabackup/read_filt.cc @@ -127,10 +127,11 @@ rf_bitmap_get_next_batch( of pages */ { ulint start_page_id; + const ulint page_size = ctxt->page_size.physical(); - start_page_id = (ulint)(ctxt->offset / ctxt->page_size); + start_page_id = (ulint)(ctxt->offset / page_size); - xb_a (ctxt->offset % ctxt->page_size == 0); + xb_a (ctxt->offset % page_size == 0); if (start_page_id == ctxt->filter_batch_end) { @@ -146,7 +147,7 @@ rf_bitmap_get_next_batch( return; } - ctxt->offset = next_page_id * ctxt->page_size; + ctxt->offset = next_page_id * page_size; /* Find the end of the current changed page block by searching for the next cleared bitmap bit */ @@ -162,7 +163,7 @@ rf_bitmap_get_next_batch( remaining pages. */ *read_batch_len = ctxt->data_file_size - ctxt->offset; } else { - *read_batch_len = ctxt->filter_batch_end * ctxt->page_size + *read_batch_len = ctxt->filter_batch_end * page_size - ctxt->offset; } @@ -175,9 +176,9 @@ rf_bitmap_get_next_batch( } ctxt->offset += *read_batch_len; - xb_a (ctxt->offset % ctxt->page_size == 0); - xb_a (*read_batch_start % ctxt->page_size == 0); - xb_a (*read_batch_len % ctxt->page_size == 0); + xb_a (ctxt->offset % page_size == 0); + xb_a (*read_batch_start % page_size == 0); + xb_a (*read_batch_len % page_size == 0); } /****************************************************************//** diff --git a/extra/mariabackup/read_filt.h b/extra/mariabackup/read_filt.h index d16f4e1093d..cebc714eed8 100644 --- a/extra/mariabackup/read_filt.h +++ b/extra/mariabackup/read_filt.h @@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #include "changed_page_bitmap.h" +typedef ulint space_id_t; + struct xb_fil_cur_t; /* The read filter context */ @@ -34,15 +36,17 @@ struct xb_read_filt_ctxt_t { ib_int64_t offset; /*!< current file offset */ ib_int64_t data_file_size; /*!< data file size */ size_t buffer_capacity;/*!< read buffer capacity */ - ib_int64_t space_id; /*!< space id */ + space_id_t space_id; /*!< space id */ /* The following fields used only in bitmap filter */ /* Move these to union if any other filters are added in future */ xb_page_bitmap_range *bitmap_range; /*!< changed page bitmap range iterator for space_id */ - size_t page_size; /*!< page size */ + page_size_t page_size; /*!< page size */ ulint filter_batch_end;/*!< the ending page id of the current changed page block in the bitmap */ + /** TODO: remove this default constructor */ + xb_read_filt_ctxt_t() : page_size(0) {} }; /* The read filter */ diff --git a/extra/mariabackup/write_filt.cc b/extra/mariabackup/write_filt.cc index 05981489bb6..40ecef6ff79 100644 --- a/extra/mariabackup/write_filt.cc +++ b/extra/mariabackup/write_filt.cc @@ -68,14 +68,14 @@ wf_incremental_init(xb_write_filt_ctxt_t *ctxt, char *dst_name, xb_fil_cur_t *cursor) { char meta_name[FN_REFLEN]; - xb_delta_info_t info; xb_wf_incremental_ctxt_t *cp = &(ctxt->u.wf_incremental_ctxt); ctxt->cursor = cursor; /* allocate buffer for incremental backup (4096 pages) */ - cp->delta_buf_size = (cursor->page_size / 4) * cursor->page_size; + cp->delta_buf_size = (cursor->page_size.physical() / 4) + * cursor->page_size.physical(); cp->delta_buf = (unsigned char *)os_mem_alloc_large(&cp->delta_buf_size); if (!cp->delta_buf) { @@ -88,9 +88,7 @@ wf_incremental_init(xb_write_filt_ctxt_t *ctxt, char *dst_name, /* write delta meta info */ snprintf(meta_name, sizeof(meta_name), "%s%s", dst_name, XB_DELTA_INFO_SUFFIX); - info.page_size = cursor->page_size; - info.zip_size = cursor->zip_size; - info.space_id = cursor->space_id; + const xb_delta_info_t info(cursor->page_size, cursor->space_id); if (!xb_write_delta_metadata(meta_name, &info)) { msg("[%02u] mariabackup: Error: " "failed to write meta info for %s\n", @@ -117,8 +115,9 @@ wf_incremental_process(xb_write_filt_ctxt_t *ctxt, ds_file_t *dstfile) { ulint i; xb_fil_cur_t *cursor = ctxt->cursor; - ulint page_size = cursor->page_size; byte *page; + const ulint page_size + = cursor->page_size.physical(); xb_wf_incremental_ctxt_t *cp = &(ctxt->u.wf_incremental_ctxt); for (i = 0, page = cursor->buf; i < cursor->buf_npages; @@ -163,7 +162,8 @@ static my_bool wf_incremental_finalize(xb_write_filt_ctxt_t *ctxt, ds_file_t *dstfile) { xb_fil_cur_t *cursor = ctxt->cursor; - ulint page_size = cursor->page_size; + const ulint page_size + = cursor->page_size.physical(); xb_wf_incremental_ctxt_t *cp = &(ctxt->u.wf_incremental_ctxt); if (cp->npages != page_size / 4) { diff --git a/extra/mariabackup/wsrep.cc b/extra/mariabackup/wsrep.cc index 3baa9e660d7..1cc16affbf2 100644 --- a/extra/mariabackup/wsrep.cc +++ b/extra/mariabackup/wsrep.cc @@ -46,7 +46,6 @@ permission notice: #include <trx0sys.h> #include "common.h" -#include "backup_wsrep.h" #ifdef WITH_WSREP #define WSREP_XID_PREFIX "WSREPXid" #define WSREP_XID_PREFIX_LEN MYSQL_XID_PREFIX_LEN diff --git a/extra/mariabackup/xb0xb.h b/extra/mariabackup/xb0xb.h index 6b09306c77e..59938a014c6 100644 --- a/extra/mariabackup/xb0xb.h +++ b/extra/mariabackup/xb0xb.h @@ -21,44 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #ifndef xb0xb_h #define xb0xb_h - -extern void os_io_init_simple(void); -extern pfs_os_file_t files[1000]; extern const char *innodb_checksum_algorithm_names[]; extern TYPELIB innodb_checksum_algorithm_typelib; -extern dberr_t open_or_create_data_files( - bool* create_new_db, -#ifdef UNIV_LOG_ARCHIVE - lsn_t* min_arch_log_no, - lsn_t* max_arch_log_no, -#endif - lsn_t* flushed_lsn, - ulint* sum_of_new_sizes) - ; -int -fil_file_readdir_next_file( -/*=======================*/ -dberr_t* err, /*!< out: this is set to DB_ERROR if an error - was encountered, otherwise not changed */ - const char* dirname,/*!< in: directory name or path */ - os_file_dir_t dir, /*!< in: directory stream */ - os_file_stat_t* info) /*!< in/out: buffer where the - info is returned */; -fil_space_t* -fil_space_get_by_name(const char *); -ibool -recv_check_cp_is_consistent(const byte* buf); -void -innodb_log_checksum_func_update( -/*============================*/ -ulint algorithm) /*!< in: algorithm */; -dberr_t recv_find_max_checkpoint(log_group_t** max_group, ulint* max_field); -dberr_t -srv_undo_tablespaces_init( -/*======================*/ -ibool create_new_db, -ibool backup_mode, -const ulint n_conf_tablespaces, -ulint* n_opened); #endif diff --git a/extra/mariabackup/xbstream.c b/extra/mariabackup/xbstream.c index f3880f9ec03..fa250132c04 100644 --- a/extra/mariabackup/xbstream.c +++ b/extra/mariabackup/xbstream.c @@ -531,8 +531,8 @@ mode_extract(int n_threads, int argc __attribute__((unused)), ctxt.ds_ctxt = ds_ctxt; ctxt.mutex = &mutex; - tids = malloc(sizeof(pthread_t) * n_threads); - retvals = malloc(sizeof(void*) * n_threads); + tids = calloc(n_threads, sizeof(pthread_t)); + retvals = calloc(n_threads, sizeof(void*)); for (i = 0; i < n_threads; i++) pthread_create(tids + i, NULL, extract_worker_thread_func, @@ -542,7 +542,7 @@ mode_extract(int n_threads, int argc __attribute__((unused)), pthread_join(tids[i], retvals + i); for (i = 0; i < n_threads; i++) { - if ((ulong)retvals[i] == XB_STREAM_READ_ERROR) { + if ((size_t)retvals[i] == XB_STREAM_READ_ERROR) { ret = 1; goto exit; } diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index b4931b5ebe7..8318485fa2f 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -4,6 +4,8 @@ MariaBackup: hot backup tool for InnoDB Originally Created 3/3/2009 Yasufumi Kinoshita Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. +(c) 2017, MariaDB Corporation. +Portions written by Marko Mäkelä. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,6 +43,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA //#define XTRABACKUP_TARGET_IS_PLUGIN +#include <my_config.h> +#include <unireg.h> #include <mysql_version.h> #include <my_base.h> #include <my_getopt.h> @@ -61,9 +65,11 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include <dict0priv.h> #include <lock0lock.h> #include <log0recv.h> +#include <log0crypt.h> #include <row0mysql.h> #include <row0quiesce.h> #include <srv0start.h> +#include "trx0sys.h" #include <buf0dblwr.h> #include <list> @@ -97,58 +103,49 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include <crc_glue.h> #include <log.h> -/* TODO: replace with appropriate macros used in InnoDB 5.6 */ -#define PAGE_ZIP_MIN_SIZE_SHIFT 10 -#define DICT_TF_ZSSIZE_SHIFT 1 -#define DICT_TF_FORMAT_ZIP 1 -#define DICT_TF_FORMAT_SHIFT 5 - int sys_var_init(); -my_bool innodb_inited= 0; - /* === xtrabackup specific options === */ char xtrabackup_real_target_dir[FN_REFLEN] = "./xtrabackup_backupfiles/"; char *xtrabackup_target_dir= xtrabackup_real_target_dir; -my_bool xtrabackup_version = FALSE; -my_bool xtrabackup_backup = FALSE; -my_bool xtrabackup_prepare = FALSE; -my_bool xtrabackup_copy_back = FALSE; -my_bool xtrabackup_move_back = FALSE; -my_bool xtrabackup_decrypt_decompress = FALSE; -my_bool xtrabackup_print_param = FALSE; +static my_bool xtrabackup_version; +my_bool xtrabackup_backup; +my_bool xtrabackup_prepare; +my_bool xtrabackup_copy_back; +my_bool xtrabackup_move_back; +my_bool xtrabackup_decrypt_decompress; +my_bool xtrabackup_print_param; -my_bool xtrabackup_export = FALSE; -my_bool xtrabackup_apply_log_only = FALSE; +my_bool xtrabackup_export; -longlong xtrabackup_use_memory = 100*1024*1024L; -my_bool xtrabackup_create_ib_logfile = FALSE; +longlong xtrabackup_use_memory; uint opt_protocol; -long xtrabackup_throttle = 0; /* 0:unlimited */ -lint io_ticket; -os_event_t wait_throttle = NULL; -os_event_t log_copying_stop = NULL; +long xtrabackup_throttle; /* 0:unlimited */ +static lint io_ticket; +static os_event_t wait_throttle; +static os_event_t log_copying_stop; -char *xtrabackup_incremental = NULL; +char *xtrabackup_incremental; lsn_t incremental_lsn; lsn_t incremental_to_lsn; lsn_t incremental_last_lsn; -xb_page_bitmap *changed_page_bitmap = NULL; +xb_page_bitmap *changed_page_bitmap; -char *xtrabackup_incremental_basedir = NULL; /* for --backup */ -char *xtrabackup_extra_lsndir = NULL; /* for --backup with --extra-lsndir */ -char *xtrabackup_incremental_dir = NULL; /* for --prepare */ +char *xtrabackup_incremental_basedir; /* for --backup */ +char *xtrabackup_extra_lsndir; /* for --backup with --extra-lsndir */ +char *xtrabackup_incremental_dir; /* for --prepare */ char xtrabackup_real_incremental_basedir[FN_REFLEN]; char xtrabackup_real_extra_lsndir[FN_REFLEN]; char xtrabackup_real_incremental_dir[FN_REFLEN]; + char *xtrabackup_tmpdir; -char *xtrabackup_tables = NULL; -char *xtrabackup_tables_file = NULL; -char *xtrabackup_tables_exclude = NULL; +char *xtrabackup_tables; +char *xtrabackup_tables_file; +char *xtrabackup_tables_exclude; typedef std::list<regex_t> regex_list_t; static regex_list_t regex_include_list; @@ -172,17 +169,12 @@ struct xb_filter_entry_struct{ }; typedef struct xb_filter_entry_struct xb_filter_entry_t; -static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6]; -static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6]; - lsn_t checkpoint_lsn_start; lsn_t checkpoint_no_start; -lsn_t log_copy_scanned_lsn; -ibool log_copying = TRUE; -ibool log_copying_running = FALSE; -ibool io_watching_thread_running = FALSE; - -ibool xtrabackup_logfile_is_renamed = FALSE; +static lsn_t log_copy_scanned_lsn; +static bool log_copying; +static bool log_copying_running; +static bool io_watching_thread_running; int xtrabackup_parallel; @@ -201,19 +193,16 @@ ulint xtrabackup_log_copy_interval = 1000; static ulong max_buf_pool_modified_pct; /* Ignored option (--log) for MySQL option compatibility */ -char* log_ignored_opt = NULL; +static char* log_ignored_opt; /* === metadata of backup === */ #define XTRABACKUP_METADATA_FILENAME "xtrabackup_checkpoints" -char metadata_type[30] = ""; /*[full-backuped|log-applied| - full-prepared|incremental]*/ -lsn_t metadata_from_lsn = 0; -lsn_t metadata_to_lsn = 0; -lsn_t metadata_last_lsn = 0; +char metadata_type[30] = ""; /*[full-backuped|log-applied|incremental]*/ +lsn_t metadata_from_lsn; +lsn_t metadata_to_lsn; +lsn_t metadata_last_lsn; -#define XB_LOG_FILENAME "xtrabackup_logfile" - -ds_file_t *dst_log_file = NULL; +static ds_file_t* dst_log_file; static char mysql_data_home_buff[2]; @@ -229,48 +218,34 @@ ulong innobase_large_page_size = 0; /* The default values for the following, type long or longlong, start-up parameters are declared in mysqld.cc: */ -long innobase_additional_mem_pool_size = 1*1024*1024L; long innobase_buffer_pool_awe_mem_mb = 0; long innobase_file_io_threads = 4; long innobase_read_io_threads = 4; long innobase_write_io_threads = 4; -long innobase_force_recovery = 0; long innobase_log_buffer_size = 1024*1024L; -long innobase_log_files_in_group = 2; long innobase_open_files = 300L; longlong innobase_page_size = (1LL << 14); /* 16KB */ -static ulong innobase_log_block_size = 512; -char* innobase_doublewrite_file = NULL; char* innobase_buffer_pool_filename = NULL; longlong innobase_buffer_pool_size = 8*1024*1024L; -longlong innobase_log_file_size = 48*1024*1024L; /* The default values for the following char* start-up parameters are determined in innobase_init below: */ -char* innobase_ignored_opt = NULL; -char* innobase_data_home_dir = NULL; -char* innobase_data_file_path = NULL; +static char* innobase_ignored_opt; +char* innobase_data_home_dir; +char* innobase_data_file_path; /* The following has a misleading name: starting from 4.0.5, this also affects Windows: */ -char* innobase_unix_file_flush_method = NULL; - -/* Below we have boolean-valued start-up parameters, and their default -values */ - -ulong innobase_fast_shutdown = 1; -my_bool innobase_use_doublewrite = TRUE; -my_bool innobase_use_checksums = TRUE; -my_bool innobase_use_large_pages = FALSE; -my_bool innobase_file_per_table = FALSE; -my_bool innobase_locks_unsafe_for_binlog = FALSE; -my_bool innobase_rollback_on_timeout = FALSE; -my_bool innobase_create_status_file = FALSE; -my_bool innobase_adaptive_hash_index = TRUE; +char* innobase_unix_file_flush_method; -static char *internal_innobase_data_file_path = NULL; +my_bool innobase_use_doublewrite; +my_bool innobase_use_large_pages; +my_bool innobase_file_per_table; +my_bool innobase_locks_unsafe_for_binlog; +my_bool innobase_rollback_on_timeout; +my_bool innobase_create_status_file; /* The following counter is used to convey information to InnoDB about server activity: in selects it is not sensible to call @@ -291,7 +266,7 @@ lsn_t flushed_lsn= 0; ulong xb_open_files_limit= 0; char *xb_plugin_dir; char *xb_plugin_load; -my_bool xb_close_files= FALSE; +my_bool xb_close_files; /* Datasinks */ ds_ctxt_t *ds_data = NULL; @@ -300,10 +275,6 @@ ds_ctxt_t *ds_redo = NULL; static bool innobackupex_mode = false; -static long innobase_log_files_in_group_save; -static char *srv_log_group_home_dir_save; -static longlong innobase_log_file_size_save; - /* String buffer used by --print-param to accumulate server options as they are parsed from the defaults file */ static std::ostringstream print_param_str; @@ -314,6 +285,7 @@ std::set<std::string> param_set; static ulonglong global_max_value; extern "C" sig_handler handle_fatal_signal(int sig); +extern LOGGER logger; my_bool opt_galera_info = FALSE; my_bool opt_slave_info = FALSE; @@ -324,7 +296,9 @@ my_bool opt_force_non_empty_dirs = FALSE; my_bool opt_noversioncheck = FALSE; my_bool opt_no_backup_locks = FALSE; my_bool opt_decompress = FALSE; -my_bool opt_remove_original = FALSE; +my_bool opt_remove_original; + +my_bool opt_lock_ddl_per_table = FALSE; static const char *binlog_info_values[] = {"off", "lockless", "on", "auto", NullS}; @@ -332,17 +306,16 @@ static TYPELIB binlog_info_typelib = {array_elements(binlog_info_values)-1, "", binlog_info_values, NULL}; ulong opt_binlog_info; -char *opt_incremental_history_name = NULL; -char *opt_incremental_history_uuid = NULL; +char *opt_incremental_history_name; +char *opt_incremental_history_uuid; -char *opt_user = NULL; -char *opt_password = NULL; -char *opt_host = NULL; -char *opt_defaults_group = NULL; -char *opt_socket = NULL; -uint opt_port = 0; -char *opt_login_path = NULL; -char *opt_log_bin = NULL; +char *opt_user; +char *opt_password; +char *opt_host; +char *opt_defaults_group; +char *opt_socket; +uint opt_port; +char *opt_log_bin; const char *query_type_names[] = { "ALL", "UPDATE", "SELECT", NullS}; @@ -364,6 +337,9 @@ const char *opt_history = NULL; my_bool opt_ssl_verify_server_cert = FALSE; #endif +char mariabackup_exe[FN_REFLEN]; +char orig_argv1[FN_REFLEN]; + /* Whether xtrabackup_binlog_info should be created on recovery */ static bool recover_binlog_info; @@ -380,15 +356,29 @@ xtrabackup_add_datasink(ds_ctxt_t *ds) datasinks[actual_datasinks] = ds; actual_datasinks++; } + +typedef void (*process_single_tablespace_func_t)(const char *dirname, const char *filname, bool is_remote); +static dberr_t enumerate_ibd_files(process_single_tablespace_func_t callback); + + +/* ======== Datafiles iterator ======== */ +struct datafiles_iter_t { + fil_system_t *system; + fil_space_t *space; + fil_node_t *node; + ibool started; + pthread_mutex_t mutex; +}; + /* ======== Datafiles iterator ======== */ +static datafiles_iter_t * datafiles_iter_new(fil_system_t *f_system) { datafiles_iter_t *it; - it = static_cast<datafiles_iter_t *> - (ut_malloc(sizeof(datafiles_iter_t))); - it->mutex = os_mutex_create(); + it = static_cast<datafiles_iter_t *>(malloc(sizeof(datafiles_iter_t))); + pthread_mutex_init(&it->mutex, NULL); it->system = f_system; it->space = NULL; @@ -398,12 +388,13 @@ datafiles_iter_new(fil_system_t *f_system) return it; } +static fil_node_t * datafiles_iter_next(datafiles_iter_t *it) { fil_node_t *new_node; - os_mutex_enter(it->mutex); + pthread_mutex_lock(&it->mutex); if (it->node == NULL) { if (it->started) @@ -420,7 +411,7 @@ datafiles_iter_next(datafiles_iter_t *it) UT_LIST_GET_NEXT(space_list, it->space); while (it->space != NULL && - (it->space->purpose != FIL_TABLESPACE || + (it->space->purpose != FIL_TYPE_TABLESPACE || UT_LIST_GET_LEN(it->space->chain) == 0)) it->space = UT_LIST_GET_NEXT(space_list, it->space); if (it->space == NULL) @@ -430,16 +421,72 @@ datafiles_iter_next(datafiles_iter_t *it) end: new_node = it->node; - os_mutex_exit(it->mutex); + pthread_mutex_unlock(&it->mutex); return new_node; } +static void datafiles_iter_free(datafiles_iter_t *it) { - os_mutex_free(it->mutex); - ut_free(it); + pthread_mutex_destroy(&it->mutex); + free(it); +} + +void mdl_lock_all() +{ + mdl_lock_init(); + datafiles_iter_t *it = datafiles_iter_new(fil_system); + if (!it) + return; + + while (fil_node_t *node = datafiles_iter_next(it)){ + if (fil_is_user_tablespace_id(node->space->id) + && check_if_skip_table(node->space->name)) + continue; + + mdl_lock_table(node->space->id); + } + datafiles_iter_free(it); +} + +/** Check if the space id belongs to the table which name should +be skipped based on the --tables, --tables-file and --table-exclude +options. +@param[in] space_id space id to check +@return true if the space id belongs to skip table/database list. */ +static bool backup_includes(space_id_t space_id) +{ + datafiles_iter_t *it = datafiles_iter_new(fil_system); + if (!it) + return true; + + while (fil_node_t *node = datafiles_iter_next(it)){ + if (space_id == 0 + || (node->space->id == space_id + && !check_if_skip_table(node->space->name))) { + + msg("mariabackup: Unsupported redo log detected " + "and it belongs to %s\n", + space_id ? node->name: "the InnoDB system tablespace"); + + msg("mariabackup: ALTER TABLE or OPTIMIZE TABLE " + "was being executed during the backup.\n"); + + if (!opt_lock_ddl_per_table) { + msg("mariabackup: Use --lock-ddl-per-table " + "parameter to lock all the table before " + "backup operation.\n"); + } + + datafiles_iter_free(it); + return false; + } + } + + datafiles_iter_free(it); + return true; } /* ======== Date copying thread context ======== */ @@ -448,7 +495,7 @@ typedef struct { datafiles_iter_t *it; uint num; uint *count; - os_ib_mutex_t count_mutex; + pthread_mutex_t count_mutex; os_thread_id_t id; } data_thread_ctxt_t; @@ -461,7 +508,6 @@ enum options_xtrabackup OPT_XTRA_BACKUP, OPT_XTRA_PREPARE, OPT_XTRA_EXPORT, - OPT_XTRA_APPLY_LOG_ONLY, OPT_XTRA_PRINT_PARAM, OPT_XTRA_USE_MEMORY, OPT_XTRA_THROTTLE, @@ -474,7 +520,6 @@ enum options_xtrabackup OPT_XTRA_TABLES_FILE, OPT_XTRA_DATABASES, OPT_XTRA_DATABASES_FILE, - OPT_XTRA_CREATE_IB_LOGFILE, OPT_XTRA_PARALLEL, OPT_XTRA_STREAM, OPT_XTRA_COMPRESS, @@ -482,12 +527,10 @@ enum options_xtrabackup OPT_XTRA_COMPRESS_CHUNK_SIZE, OPT_LOG, OPT_INNODB, - OPT_INNODB_CHECKSUMS, OPT_INNODB_DATA_FILE_PATH, OPT_INNODB_DATA_HOME_DIR, OPT_INNODB_ADAPTIVE_HASH_INDEX, OPT_INNODB_DOUBLEWRITE, - OPT_INNODB_FAST_SHUTDOWN, OPT_INNODB_FILE_PER_TABLE, OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT, OPT_INNODB_FLUSH_METHOD, @@ -497,7 +540,6 @@ enum options_xtrabackup OPT_INNODB_MAX_PURGE_LAG, OPT_INNODB_ROLLBACK_ON_TIMEOUT, OPT_INNODB_STATUS_FILE, - OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE, OPT_INNODB_AUTOEXTEND_INCREMENT, OPT_INNODB_BUFFER_POOL_SIZE, OPT_INNODB_COMMIT_CONCURRENCY, @@ -508,24 +550,17 @@ enum options_xtrabackup OPT_INNODB_WRITE_IO_THREADS, OPT_INNODB_USE_NATIVE_AIO, OPT_INNODB_PAGE_SIZE, - OPT_INNODB_LOG_BLOCK_SIZE, - OPT_INNODB_DOUBLEWRITE_FILE, OPT_INNODB_BUFFER_POOL_FILENAME, - OPT_INNODB_FORCE_RECOVERY, OPT_INNODB_LOCK_WAIT_TIMEOUT, OPT_INNODB_LOG_BUFFER_SIZE, OPT_INNODB_LOG_FILE_SIZE, OPT_INNODB_LOG_FILES_IN_GROUP, - OPT_INNODB_MIRRORED_LOG_GROUPS, OPT_INNODB_OPEN_FILES, - OPT_INNODB_SYNC_SPIN_LOOPS, - OPT_INNODB_THREAD_CONCURRENCY, - OPT_INNODB_THREAD_SLEEP_DELAY, OPT_XTRA_DEBUG_SYNC, OPT_INNODB_CHECKSUM_ALGORITHM, OPT_INNODB_UNDO_DIRECTORY, OPT_INNODB_UNDO_TABLESPACES, - OPT_INNODB_LOG_CHECKSUM_ALGORITHM, + OPT_INNODB_LOG_CHECKSUMS, OPT_XTRA_INCREMENTAL_FORCE_SCAN, OPT_DEFAULTS_GROUP, OPT_OPEN_FILES_LIMIT, @@ -562,7 +597,8 @@ enum options_xtrabackup OPT_XTRA_TABLES_EXCLUDE, OPT_XTRA_DATABASES_EXCLUDE, - OPT_PROTOCOL + OPT_PROTOCOL, + OPT_LOCK_DDL_PER_TABLE }; struct my_option xb_client_options[] = @@ -581,10 +617,6 @@ struct my_option xb_client_options[] = {"export", OPT_XTRA_EXPORT, "create files to import to another database when prepare.", (G_PTR*) &xtrabackup_export, (G_PTR*) &xtrabackup_export, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"apply-log-only", OPT_XTRA_APPLY_LOG_ONLY, - "stop recovery process not to progress LSN after applying log when prepare.", - (G_PTR*) &xtrabackup_apply_log_only, (G_PTR*) &xtrabackup_apply_log_only, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"print-param", OPT_XTRA_PRINT_PARAM, "print parameter of mysqld needed for copyback.", (G_PTR*) &xtrabackup_print_param, (G_PTR*) &xtrabackup_print_param, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -636,9 +668,6 @@ struct my_option xb_client_options[] = "Note that this option has a higher priority than --databases.", (G_PTR*) &xtrabackup_databases_exclude, (G_PTR*) &xtrabackup_databases_exclude, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"create-ib-logfile", OPT_XTRA_CREATE_IB_LOGFILE, "** not work for now** creates ib_logfile* also after '--prepare'. ### If you want create ib_logfile*, only re-execute this command in same options. ###", - (G_PTR*) &xtrabackup_create_ib_logfile, (G_PTR*) &xtrabackup_create_ib_logfile, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"stream", OPT_XTRA_STREAM, "Stream all backup files to the standard output " "in the specified format." @@ -924,6 +953,11 @@ struct my_option xb_client_options[] = uint xb_client_options_count = array_elements(xb_client_options); +#ifndef DBUG_OFF +/** Parameters to DBUG */ +static const char *dbug_option; +#endif + struct my_option xb_server_options[] = { {"datadir", 'h', "Path to the database root.", (G_PTR*) &mysql_data_home, @@ -949,45 +983,39 @@ struct my_option xb_server_options[] = GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log_bin", OPT_LOG, "Base name for the log sequence", - &opt_log_bin, &opt_log_bin, 0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0}, + &opt_log_bin, &opt_log_bin, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb", OPT_INNODB, "Ignored option for MySQL option compatibility", (G_PTR*) &innobase_ignored_opt, (G_PTR*) &innobase_ignored_opt, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - +#ifdef BTR_CUR_HASH_ADAPT {"innodb_adaptive_hash_index", OPT_INNODB_ADAPTIVE_HASH_INDEX, "Enable InnoDB adaptive hash index (enabled by default). " "Disable with --skip-innodb-adaptive-hash-index.", - (G_PTR*) &innobase_adaptive_hash_index, - (G_PTR*) &innobase_adaptive_hash_index, + &btr_search_enabled, + &btr_search_enabled, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"innodb_additional_mem_pool_size", OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE, - "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.", - (G_PTR*) &innobase_additional_mem_pool_size, - (G_PTR*) &innobase_additional_mem_pool_size, 0, GET_LONG, REQUIRED_ARG, - 1*1024*1024L, 512*1024L, LONG_MAX, 0, 1024, 0}, +#endif /* BTR_CUR_HASH_ADAPT */ {"innodb_autoextend_increment", OPT_INNODB_AUTOEXTEND_INCREMENT, "Data file autoextend increment in megabytes", - (G_PTR*) &srv_auto_extend_increment, - (G_PTR*) &srv_auto_extend_increment, + (G_PTR*) &sys_tablespace_auto_extend_increment, + (G_PTR*) &sys_tablespace_auto_extend_increment, 0, GET_ULONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0}, {"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE, "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", (G_PTR*) &innobase_buffer_pool_size, (G_PTR*) &innobase_buffer_pool_size, 0, GET_LL, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, LONGLONG_MAX, 0, 1024*1024L, 0}, - {"innodb_checksums", OPT_INNODB_CHECKSUMS, "Enable InnoDB checksums validation (enabled by default). \ -Disable with --skip-innodb-checksums.", (G_PTR*) &innobase_use_checksums, - (G_PTR*) &innobase_use_checksums, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH, "Path to individual files and their sizes.", &innobase_data_file_path, - &innobase_data_file_path, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + &innobase_data_file_path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_data_home_dir", OPT_INNODB_DATA_HOME_DIR, "The common part for InnoDB table spaces.", &innobase_data_home_dir, - &innobase_data_home_dir, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"innodb_doublewrite", OPT_INNODB_DOUBLEWRITE, "Enable InnoDB doublewrite buffer (enabled by default). \ -Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite, - (G_PTR*) &innobase_use_doublewrite, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + &innobase_data_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"innodb_doublewrite", OPT_INNODB_DOUBLEWRITE, + "Enable InnoDB doublewrite buffer during --prepare.", + (G_PTR*) &innobase_use_doublewrite, + (G_PTR*) &innobase_use_doublewrite, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_io_capacity", OPT_INNODB_IO_CAPACITY, "Number of IOPs the server can do. Tunes the background IO rate", (G_PTR*) &srv_io_capacity, (G_PTR*) &srv_io_capacity, @@ -1015,29 +1043,22 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite, (G_PTR*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -/* ####### Should we use this option? ####### */ - {"innodb_force_recovery", OPT_INNODB_FORCE_RECOVERY, - "Helps to save your data in case the disk image of the database becomes corrupt.", - (G_PTR*) &innobase_force_recovery, (G_PTR*) &innobase_force_recovery, 0, - GET_LONG, REQUIRED_ARG, 0, 0, 6, 0, 1, 0}, - {"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE, "The size of the buffer which InnoDB uses to write log to the log files on disk.", (G_PTR*) &innobase_log_buffer_size, (G_PTR*) &innobase_log_buffer_size, 0, GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, LONG_MAX, 0, 1024, 0}, {"innodb_log_file_size", OPT_INNODB_LOG_FILE_SIZE, - "Size of each log file in a log group.", - (G_PTR*) &innobase_log_file_size, (G_PTR*) &innobase_log_file_size, 0, - GET_LL, REQUIRED_ARG, 48*1024*1024L, 1*1024*1024L, LONGLONG_MAX, 0, - 1024*1024L, 0}, + "Ignored for mysqld option compatibility", + (G_PTR*) &srv_log_file_size, (G_PTR*) &srv_log_file_size, 0, + GET_ULL, REQUIRED_ARG, 48 << 20, 1 << 20, 512ULL << 30, 0, + UNIV_PAGE_SIZE_MAX, 0}, {"innodb_log_files_in_group", OPT_INNODB_LOG_FILES_IN_GROUP, - "Number of log files in the log group. InnoDB writes to the files in a " - "circular fashion. Value 3 is recommended here.", - &innobase_log_files_in_group, &innobase_log_files_in_group, - 0, GET_LONG, REQUIRED_ARG, 2, 2, 100, 0, 1, 0}, + "Ignored for mysqld option compatibility", + &srv_n_log_files, &srv_n_log_files, + 0, GET_LONG, REQUIRED_ARG, 1, 1, 100, 0, 1, 0}, {"innodb_log_group_home_dir", OPT_INNODB_LOG_GROUP_HOME_DIR, "Path to InnoDB log files.", &srv_log_group_home_dir, - &srv_log_group_home_dir, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + &srv_log_group_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_max_dirty_pages_pct", OPT_INNODB_MAX_DIRTY_PAGES_PCT, "Percentage of dirty pages allowed in bufferpool.", (G_PTR*) &srv_max_buf_pool_modified_pct, (G_PTR*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, @@ -1056,21 +1077,17 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite, /* Use GET_LL to support numeric suffixes in 5.6 */ GET_LL, REQUIRED_ARG, (1LL << 14), (1LL << 12), (1LL << UNIV_PAGE_SIZE_SHIFT_MAX), 0, 1L, 0}, - {"innodb_log_block_size", OPT_INNODB_LOG_BLOCK_SIZE, - "The log block size of the transaction log file. " - "Changing for created log file is not supported. Use on your own risk!", - (G_PTR*) &innobase_log_block_size, (G_PTR*) &innobase_log_block_size, 0, - GET_ULONG, REQUIRED_ARG, 512, 512, 1 << UNIV_PAGE_SIZE_SHIFT_MAX, 0, 1L, 0}, - {"innodb_doublewrite_file", OPT_INNODB_DOUBLEWRITE_FILE, - "Path to special datafile for doublewrite buffer. (default is "": not used)", - (G_PTR*) &innobase_doublewrite_file, (G_PTR*) &innobase_doublewrite_file, - 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_buffer_pool_filename", OPT_INNODB_BUFFER_POOL_FILENAME, - "Filename to/from which to dump/load the InnoDB buffer pool", + "Ignored for mysqld option compatibility", (G_PTR*) &innobase_buffer_pool_filename, (G_PTR*) &innobase_buffer_pool_filename, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef DBUG_OFF /* unfortunately "debug" collides with existing options */ + {"dbug", '#', "Built in DBUG debugger.", + &dbug_option, &dbug_option, 0, GET_STR, OPT_ARG, + 0, 0, 0, 0, 0, 0}, +#endif #ifndef __WIN__ {"debug-sync", OPT_XTRA_DEBUG_SYNC, "Debug sync point. This is only used by the xtrabackup test suite", @@ -1084,14 +1101,10 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite, "INNODB, STRICT_INNODB, NONE, STRICT_NONE]", &srv_checksum_algorithm, &srv_checksum_algorithm, &innodb_checksum_algorithm_typelib, GET_ENUM, REQUIRED_ARG, SRV_CHECKSUM_ALGORITHM_INNODB, 0, 0, 0, 0, 0}, - {"innodb_log_checksum_algorithm", OPT_INNODB_LOG_CHECKSUM_ALGORITHM, - "The algorithm InnoDB uses for log checksumming. [CRC32, STRICT_CRC32, " - "INNODB, STRICT_INNODB, NONE, STRICT_NONE]", &srv_log_checksum_algorithm, - &srv_log_checksum_algorithm, &innodb_checksum_algorithm_typelib, GET_ENUM, - REQUIRED_ARG, SRV_CHECKSUM_ALGORITHM_INNODB, 0, 0, 0, 0, 0}, + {"innodb_undo_directory", OPT_INNODB_UNDO_DIRECTORY, "Directory where undo tablespace files live, this path can be absolute.", - &srv_undo_dir, &srv_undo_dir, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, + &srv_undo_dir, &srv_undo_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_undo_tablespaces", OPT_INNODB_UNDO_TABLESPACES, @@ -1116,12 +1129,22 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite, { "innodb-encrypt-log", OPT_INNODB_ENCRYPT_LOG, "encrypton plugin to load", &srv_encrypt_log, &srv_encrypt_log, 0, GET_BOOL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - + + {"innodb-log-checksums", OPT_INNODB_LOG_CHECKSUMS, + "Whether to require checksums for InnoDB redo log blocks", + &innodb_log_checksums, &innodb_log_checksums, + 0, GET_BOOL, REQUIRED_ARG, 1, 0, 0, 0, 0, 0 }, + {"open_files_limit", OPT_OPEN_FILES_LIMIT, "the maximum number of file " "descriptors to reserve with setrlimit().", (G_PTR*) &xb_open_files_limit, (G_PTR*) &xb_open_files_limit, 0, GET_ULONG, REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0}, + {"lock-ddl-per-table", OPT_LOCK_DDL_PER_TABLE, "Lock DDL for each table " + "before xtrabackup starts to copy it and until the backup is completed.", + (uchar*) &opt_lock_ddl_per_table, (uchar*) &opt_lock_ddl_per_table, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1182,6 +1205,104 @@ debug_sync_point(const char *name) #endif } + +static std::vector<std::string> tables_for_export; + +static void append_export_table(const char *dbname, const char *tablename, bool is_remote) +{ + if(dbname && tablename && !is_remote) + { + char buf[3*FN_REFLEN]; + snprintf(buf,sizeof(buf),"%s/%s",dbname, tablename); + // trim .ibd + char *p=strrchr(buf, '.'); + if (p) *p=0; + + tables_for_export.push_back(ut_get_name(0,buf)); + } +} + + +#define BOOTSTRAP_FILENAME "mariabackup_prepare_for_export.sql" + +static int create_bootstrap_file() +{ + FILE *f= fopen(BOOTSTRAP_FILENAME,"wb"); + if(!f) + return -1; + + fputs("SET NAMES UTF8;\n",f); + enumerate_ibd_files(append_export_table); + for (size_t i= 0; i < tables_for_export.size(); i++) + { + const char *tab = tables_for_export[i].c_str(); + fprintf(f, + "BEGIN NOT ATOMIC " + "DECLARE CONTINUE HANDLER FOR NOT FOUND,SQLEXCEPTION BEGIN END;" + "FLUSH TABLES %s FOR EXPORT;" + "END;\n" + "UNLOCK TABLES;\n", + tab); + } + fclose(f); + return 0; +} + +static int prepare_export() +{ + int err= -1; + + char cmdline[2*FN_REFLEN]; + FILE *outf; + + if (create_bootstrap_file()) + return -1; + + // Process defaults-file , it can have some --lc-language stuff, + // which is* unfortunately* still necessary to get mysqld up + if (strncmp(orig_argv1,"--defaults-file=",16) == 0) + { + sprintf(cmdline, + IF_WIN("\"","") "\"%s\" --mysqld \"%s\" " + " --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." + " --innodb --innodb-fast-shutdown=0" + " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" + " --console --skip-log-error --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""), + mariabackup_exe, + orig_argv1, (my_defaults_group_suffix?my_defaults_group_suffix:""), + xtrabackup_use_memory); + } + else + { + sprintf(cmdline, + IF_WIN("\"","") "\"%s\" --mysqld" + " --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." + " --innodb --innodb-fast-shutdown=0" + " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" + " --console --log-error= --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""), + mariabackup_exe, + (my_defaults_group_suffix?my_defaults_group_suffix:""), + xtrabackup_use_memory); + } + + msg("Prepare export : executing %s\n", cmdline); + fflush(stderr); + + outf= popen(cmdline,"r"); + if (!outf) + goto end; + + char outline[FN_REFLEN]; + while(fgets(outline, sizeof(outline)-1, outf)) + fprintf(stderr,"%s",outline); + + err = pclose(outf); +end: + unlink(BOOTSTRAP_FILENAME); + return err; +} + + static const char *xb_client_default_groups[]= { "xtrabackup", "mariabackup", "client", 0, 0, 0 }; @@ -1270,13 +1391,7 @@ xb_get_one_option(int optid, break; case OPT_INNODB_LOG_FILES_IN_GROUP: - - ADD_PRINT_PARAM_OPT(innobase_log_files_in_group); - break; - case OPT_INNODB_LOG_FILE_SIZE: - - ADD_PRINT_PARAM_OPT(innobase_log_file_size); break; case OPT_INNODB_FLUSH_METHOD: @@ -1289,16 +1404,6 @@ xb_get_one_option(int optid, ADD_PRINT_PARAM_OPT(innobase_page_size); break; - case OPT_INNODB_LOG_BLOCK_SIZE: - - ADD_PRINT_PARAM_OPT(innobase_log_block_size); - break; - - case OPT_INNODB_DOUBLEWRITE_FILE: - - ADD_PRINT_PARAM_OPT(innobase_doublewrite_file); - break; - case OPT_INNODB_UNDO_DIRECTORY: ADD_PRINT_PARAM_OPT(srv_undo_dir); @@ -1316,13 +1421,6 @@ xb_get_one_option(int optid, ADD_PRINT_PARAM_OPT(innodb_checksum_algorithm_names[srv_checksum_algorithm]); break; - case OPT_INNODB_LOG_CHECKSUM_ALGORITHM: - - ut_a(srv_log_checksum_algorithm <= SRV_CHECKSUM_ALGORITHM_STRICT_NONE); - - ADD_PRINT_PARAM_OPT(innodb_checksum_algorithm_names[srv_log_checksum_algorithm]); - break; - case OPT_INNODB_BUFFER_POOL_FILENAME: ADD_PRINT_PARAM_OPT(innobase_buffer_pool_filename); @@ -1404,40 +1502,9 @@ xb_get_one_option(int optid, return 0; } -/*********************************************************************** -Initializes log_block_size */ -static -ibool -xb_init_log_block_size(void) -{ - srv_log_block_size = 0; - if (innobase_log_block_size != 512) { - uint n_shift = (uint)get_bit_shift(innobase_log_block_size);; - - if (n_shift > 0) { - srv_log_block_size = (ulint)(1LL << n_shift); - msg("InnoDB: The log block size is set to %lu.\n", - srv_log_block_size); - } - } else { - srv_log_block_size = 512; - } - if (!srv_log_block_size) { - msg("InnoDB: Error: %lu is not valid value for " - "innodb_log_block_size.\n", innobase_log_block_size); - return FALSE; - } - - return TRUE; -} - static my_bool innodb_init_param(void) { - /* innobase_init */ - static char current_dir[3]; /* Set if using current lib */ - my_bool ret; - char *default_path; srv_is_being_started = TRUE; /* === some variables from mysqld === */ memset((G_PTR) &mysql_tmpdir_list, 0, sizeof(mysql_tmpdir_list)); @@ -1469,10 +1536,6 @@ innodb_init_param(void) srv_page_size = (1 << srv_page_size_shift); } - if (!xb_init_log_block_size()) { - goto error; - } - /* Check that values don't overflow on 32-bit systems. */ if (sizeof(ulint) == 4) { if (xtrabackup_use_memory > UINT_MAX32) { @@ -1486,30 +1549,10 @@ innodb_init_param(void) goto error; } - - if (innobase_log_file_size > UINT_MAX32) { - msg("mariabackup: innobase_log_file_size can't be " - "over 4GB on 32-bit systemsi\n"); - - goto error; - } } - os_innodb_umask = (ulint)0664; - - /* First calculate the default path for innodb_data_home_dir etc., - in case the user has not given any value. - - Note that when using the embedded server, the datadirectory is not - necessarily the current directory of this program. */ - - /* It's better to use current lib, to keep paths short */ - current_dir[0] = FN_CURLIB; - current_dir[1] = FN_LIBCHAR; - current_dir[2] = 0; - default_path = current_dir; - - ut_a(default_path); + static char default_path[2] = { FN_CURLIB, 0 }; + fil_path_to_mysql_datadir = default_path; /* Set InnoDB initialization parameters according to the values read from MySQL .cnf file */ @@ -1539,37 +1582,20 @@ innodb_init_param(void) msg("mariabackup: innodb_data_file_path = %s\n", innobase_data_file_path); - /* Since InnoDB edits the argument in the next call, we make another - copy of it: */ + /* This is the first time univ_page_size is used. + It was initialized to 16k pages before srv_page_size was set */ + univ_page_size.copy_from( + page_size_t(srv_page_size, srv_page_size, false)); - internal_innobase_data_file_path = strdup(innobase_data_file_path); + srv_sys_space.set_space_id(TRX_SYS_SPACE); + srv_sys_space.set_name("innodb_system"); + srv_sys_space.set_path(srv_data_home); + srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE()); - ret = (my_bool) srv_parse_data_file_paths_and_sizes( - internal_innobase_data_file_path); - if (ret == FALSE) { - msg("mariabackup: syntax error in innodb_data_file_path\n"); -mem_free_and_error: - free(internal_innobase_data_file_path); - internal_innobase_data_file_path = NULL; + if (!srv_sys_space.parse_params(innobase_data_file_path, true)) { goto error; } - if (xtrabackup_prepare) { - /* "--prepare" needs filenames only */ - ulint i; - - for (i=0; i < srv_n_data_files; i++) { - char *p; - - p = srv_data_file_names[i]; - while ((p = strchr(p, SRV_PATH_SEPARATOR)) != NULL) - { - p++; - srv_data_file_names[i] = p; - } - } - } - /* -------------- Log files ---------------------------*/ /* The default dir for log files is the datadir of MySQL */ @@ -1583,60 +1609,38 @@ mem_free_and_error: msg("mariabackup: innodb_log_group_home_dir = %s\n", srv_log_group_home_dir); - srv_normalize_path_for_win(srv_log_group_home_dir); + os_normalize_path(srv_log_group_home_dir); if (strchr(srv_log_group_home_dir, ';')) { msg("syntax error in innodb_log_group_home_dir, "); - - goto mem_free_and_error; + goto error; } srv_adaptive_flushing = FALSE; - srv_use_sys_malloc = TRUE; srv_file_format = 1; /* Barracuda */ srv_max_file_format_at_startup = UNIV_FORMAT_MIN; /* on */ /* --------------------------------------------------*/ srv_file_flush_method_str = innobase_unix_file_flush_method; - srv_n_log_files = (ulint) innobase_log_files_in_group; - srv_log_file_size = (ulint) innobase_log_file_size; - msg("mariabackup: innodb_log_files_in_group = %ld\n", - srv_n_log_files); - msg("mariabackup: innodb_log_file_size = %lld\n", - (long long int) srv_log_file_size); - srv_log_buffer_size = (ulint) innobase_log_buffer_size; /* We set srv_pool_size here in units of 1 kB. InnoDB internally changes the value so that it becomes the number of database pages. */ - //srv_buf_pool_size = (ulint) innobase_buffer_pool_size; srv_buf_pool_size = (ulint) xtrabackup_use_memory; - - srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size; + srv_buf_pool_chunk_unit = srv_buf_pool_size; + srv_buf_pool_instances = 1; srv_n_file_io_threads = (ulint) innobase_file_io_threads; srv_n_read_io_threads = (ulint) innobase_read_io_threads; srv_n_write_io_threads = (ulint) innobase_write_io_threads; - srv_force_recovery = (ulint) innobase_force_recovery; - srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite; - if (!innobase_use_checksums) { - - srv_checksum_algorithm = SRV_CHECKSUM_ALGORITHM_NONE; - } - - btr_search_enabled = (char) innobase_adaptive_hash_index; - btr_search_index_num = 1; - os_use_large_pages = (ibool) innobase_use_large_pages; os_large_page_size = (ulint) innobase_large_page_size; - static char default_dir[3] = "./"; - srv_arch_dir = default_dir; row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout; srv_file_per_table = (my_bool) innobase_file_per_table; @@ -1654,18 +1658,8 @@ mem_free_and_error: /* We cannot treat characterset here for now!! */ data_mysql_default_charset_coll = (ulint)default_charset_info->number; - ut_a(DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL == - my_charset_latin1.number); ut_a(DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number); - /* Store the latin1_swedish_ci character ordering table to InnoDB. For - non-latin1_swedish_ci charsets we use the MySQL comparison functions, - and consequently we do not need to know the ordering internally in - InnoDB. */ - - ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci")); - srv_latin1_ordering = my_charset_latin1.sort_order; - //innobase_commit_concurrency_init_default(); /* Since we in this module access directly the fields of a trx @@ -1679,31 +1673,8 @@ mem_free_and_error: innobase_start_or_create_for_mysql(). As we don't call it in xtrabackup, we have to duplicate checks from that function here. */ -#ifdef __WIN__ - switch (os_get_os_version()) { - case OS_WIN95: - case OS_WIN31: - case OS_WINNT: - /* On Win 95, 98, ME, Win32 subsystem for Windows 3.1, - and NT use simulated aio. In NT Windows provides async i/o, - but when run in conjunction with InnoDB Hot Backup, it seemed - to corrupt the data files. */ - - srv_use_native_aio = FALSE; - break; - - case OS_WIN2000: - case OS_WINXP: - /* On 2000 and XP, async IO is available. */ - srv_use_native_aio = TRUE; - break; - - default: - /* Vista and later have both async IO and condition variables */ - srv_use_native_aio = TRUE; - srv_use_native_conditions = TRUE; - break; - } +#ifdef _WIN32 + srv_use_native_aio = TRUE; #elif defined(LINUX_NATIVE_AIO) @@ -1726,11 +1697,12 @@ mem_free_and_error: directory. */ if (!srv_undo_dir || !xtrabackup_backup) { - my_free(srv_undo_dir); - srv_undo_dir = my_strdup(".", MYF(MY_FAE)); + srv_undo_dir = (char*) "."; } - innodb_log_checksum_func_update(srv_log_checksum_algorithm); + log_checksum_algorithm_ptr = innodb_log_checksums || srv_encrypt_log + ? log_block_calc_checksum_crc32 + : log_block_calc_checksum_none; return(FALSE); @@ -1739,57 +1711,17 @@ error: return(TRUE); } -static my_bool -innodb_init(void) +static bool innodb_init() { - int err; - srv_is_being_started = TRUE; - err = innobase_start_or_create_for_mysql(); - + dberr_t err = innobase_start_or_create_for_mysql(); if (err != DB_SUCCESS) { - free(internal_innobase_data_file_path); - internal_innobase_data_file_path = NULL; - goto error; + msg("mariabackup: innodb_init() returned %d (%s).\n", + err, ut_strerr(err)); + innodb_shutdown(); + return(TRUE); } - /* They may not be needed for now */ -// (void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0, -// (hash_get_key) innobase_get_key, 0, 0); -// pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST); -// pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST); -// pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST); -// pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST); -// pthread_cond_init(&commit_cond, NULL); - - innodb_inited= 1; - return(FALSE); - -error: - msg("mariabackup: innodb_init(): Error occured.\n"); - return(TRUE); -} - -static void -innodb_end() -{ - srv_fast_shutdown = (ulint) innobase_fast_shutdown; - innodb_inited = 0; - - msg("mariabackup: starting shutdown with innodb_fast_shutdown = %lu\n", - srv_fast_shutdown); - - innodb_shutdown(); - free(internal_innobase_data_file_path); - internal_innobase_data_file_path = NULL; - - /* They may not be needed for now */ -// hash_free(&innobase_open_tables); -// pthread_mutex_destroy(&innobase_share_mutex); -// pthread_mutex_destroy(&prepare_commit_mutex); -// pthread_mutex_destroy(&commit_threads_m); -// pthread_mutex_destroy(&commit_cond_m); -// pthread_cond_destroy(&commit_cond); } /* ================= common ================= */ @@ -1944,8 +1876,7 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info) my_bool r = TRUE; /* set defaults */ - info->page_size = ULINT_UNDEFINED; - info->zip_size = ULINT_UNDEFINED; + ulint page_size = ULINT_UNDEFINED, zip_size = 0; info->space_id = ULINT_UNDEFINED; fp = fopen(filepath, "r"); @@ -1957,9 +1888,9 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info) while (!feof(fp)) { if (fscanf(fp, "%50s = %50s\n", key, value) == 2) { if (strcmp(key, "page_size") == 0) { - info->page_size = strtoul(value, NULL, 10); + page_size = strtoul(value, NULL, 10); } else if (strcmp(key, "zip_size") == 0) { - info->zip_size = strtoul(value, NULL, 10); + zip_size = strtoul(value, NULL, 10); } else if (strcmp(key, "space_id") == 0) { info->space_id = strtoul(value, NULL, 10); } @@ -1968,10 +1899,14 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info) fclose(fp); - if (info->page_size == ULINT_UNDEFINED) { + if (page_size == ULINT_UNDEFINED) { msg("mariabackup: page_size is required in %s\n", filepath); r = FALSE; + } else { + info->page_size = page_size_t(zip_size ? zip_size : page_size, + page_size, zip_size != 0); } + if (info->space_id == ULINT_UNDEFINED) { msg("mariabackup: Warning: This backup was taken with XtraBackup 2.0.1 " "or earlier, some DDL operations between full and incremental " @@ -1994,10 +1929,13 @@ xb_write_delta_metadata(const char *filename, const xb_delta_info_t *info) MY_STAT mystat; snprintf(buf, sizeof(buf), - "page_size = %lu\n" - "zip_size = %lu\n" - "space_id = %lu\n", - info->page_size, info->zip_size, info->space_id); + "page_size = " ULINTPF "\n" + "zip_size = " ULINTPF " \n" + "space_id = " ULINTPF "\n", + info->page_size.logical(), + info->page_size.is_compressed() + ? info->page_size.physical() : 0, + info->space_id); len = strlen(buf); mystat.st_size = len; @@ -2154,7 +2092,7 @@ check_if_skip_database_by_path( return(FALSE); } - const char* db_name = strrchr(path, SRV_PATH_SEPARATOR); + const char* db_name = strrchr(path, OS_PATH_SEPARATOR); if (db_name == NULL) { db_name = path; } else { @@ -2262,35 +2200,6 @@ check_if_skip_table( return(FALSE); } -/*********************************************************************** -Reads the space flags from a given data file and returns the compressed -page size, or 0 if the space is not compressed. */ -ulint -xb_get_zip_size(pfs_os_file_t file) -{ - byte *buf; - byte *page; - ulint zip_size = ULINT_UNDEFINED; - ibool success; - ulint space; - - buf = static_cast<byte *>(ut_malloc(2 * UNIV_PAGE_SIZE)); - page = static_cast<byte *>(ut_align(buf, UNIV_PAGE_SIZE)); - - success = os_file_read(file, page, 0, UNIV_PAGE_SIZE); - if (!success) { - goto end; - } - - space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); - zip_size = (space == 0 ) ? 0 : - dict_tf_get_zip_size(fsp_header_get_flags(page)); -end: - ut_free(buf); - - return(zip_size); -} - const char* xb_get_copy_action(const char *dflt) { @@ -2327,7 +2236,6 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n) xb_write_filt_ctxt_t write_filt_ctxt; const char *action; xb_read_filt_t *read_filter; - ibool is_system; my_bool rc = FALSE; /* Get the name and the path for the tablespace. node->name always @@ -2342,9 +2250,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n) const char* const node_name = node->space->name; const char* const node_path = node->name; - is_system = !fil_is_user_tablespace_id(node->space->id); - - if (!is_system && check_if_skip_table(node_name)) { + if (fil_is_user_tablespace_id(node->space->id) + && check_if_skip_table(node_name)) { msg("[%02u] Skipping %s.\n", thread_n, node_name); return(FALSE); } @@ -2453,357 +2360,160 @@ skip: return(FALSE); } -static -void -xtrabackup_choose_lsn_offset(lsn_t start_lsn) -{ -#if SUPPORT_PERCONA_5_5 - ulint no, alt_no, expected_no; - ulint blocks_in_group; - lsn_t tmp_offset, end_lsn; - int lsn_chosen = 0; - log_group_t *group; - - start_lsn = ut_uint64_align_down(start_lsn, OS_FILE_LOG_BLOCK_SIZE); - end_lsn = start_lsn + RECV_SCAN_SIZE; - - group = UT_LIST_GET_FIRST(log_sys->log_groups); - - if (mysql_server_version < 50500 || mysql_server_version > 50600) { - /* only make sense for Percona Server 5.5 */ - return; - } - - if (server_flavor == FLAVOR_PERCONA_SERVER) { - /* it is Percona Server 5.5 */ - group->alt_offset_chosen = true; - group->lsn_offset = group->lsn_offset_alt; - return; - } - - if (group->lsn_offset_alt == group->lsn_offset || - group->lsn_offset_alt == (lsn_t) -1) { - /* we have only one option */ - return; - } - - no = alt_no = (ulint) -1; - lsn_chosen = 0; - - blocks_in_group = log_block_convert_lsn_to_no( - log_group_get_capacity(group)) - 1; - - /* read log block number from usual offset */ - if (group->lsn_offset < group->file_size * group->n_files && - (log_group_calc_lsn_offset(start_lsn, group) % - UNIV_PAGE_SIZE) % OS_MIN_LOG_BLOCK_SIZE == 0) { - log_group_read_log_seg(LOG_RECOVER, log_sys->buf, - group, start_lsn, end_lsn); - no = log_block_get_hdr_no(log_sys->buf); - } - - /* read log block number from Percona Server 5.5 offset */ - tmp_offset = group->lsn_offset; - group->lsn_offset = group->lsn_offset_alt; - - if (group->lsn_offset < group->file_size * group->n_files && - (log_group_calc_lsn_offset(start_lsn, group) % - UNIV_PAGE_SIZE) % OS_MIN_LOG_BLOCK_SIZE == 0) { - log_group_read_log_seg(LOG_RECOVER, log_sys->buf, - group, start_lsn, end_lsn); - alt_no = log_block_get_hdr_no(log_sys->buf); - } - - expected_no = log_block_convert_lsn_to_no(start_lsn); - - ut_a(!(no == expected_no && alt_no == expected_no)); - - group->lsn_offset = tmp_offset; - - if ((no <= expected_no && - ((expected_no - no) % blocks_in_group) == 0) || - ((expected_no | 0x40000000UL) - no) % blocks_in_group == 0) { - /* default offset looks ok */ - ++lsn_chosen; - } - - if ((alt_no <= expected_no && - ((expected_no - alt_no) % blocks_in_group) == 0) || - ((expected_no | 0x40000000UL) - alt_no) % blocks_in_group == 0) { - /* PS 5.5 style offset looks ok */ - ++lsn_chosen; - group->alt_offset_chosen = true; - group->lsn_offset = group->lsn_offset_alt; - } - - /* We are in trouble, because we can not make a - decision to choose one over the other. Die just - like a Buridan's ass */ - ut_a(lsn_chosen == 1); -#endif -} - -extern ibool log_block_checksum_is_ok_or_old_format(const byte* block); +/** How to copy a redo log segment in backup */ +enum copy_logfile { + /** Initial copying: copy at least one block */ + COPY_FIRST, + /** Tracking while copying data files */ + COPY_ONLINE, + /** Final copying: copy until the end of the log */ + COPY_LAST +}; -/*******************************************************//** -Scans log from a buffer and writes new log data to the outpud datasinc. -@return true if success */ +/** Copy redo log blocks to the data sink. +@param[in] copy how to copy the log +@param[in] start_lsn buffer start LSN +@param[in] end_lsn buffer end LSN +@return last scanned LSN (equals to last copied LSN if copy=COPY_LAST) +@retval 0 on failure */ static -bool -xtrabackup_scan_log_recs( -/*===============*/ - log_group_t* group, /*!< in: log group */ - bool is_last, /*!< in: whether it is last segment - to copy */ - lsn_t start_lsn, /*!< in: buffer start lsn */ - lsn_t* contiguous_lsn, /*!< in/out: it is known that all log - groups contain contiguous log data up - to this lsn */ - lsn_t* group_scanned_lsn,/*!< out: scanning succeeded up to - this lsn */ - bool* finished, /*!< out: false if is not able to scan - any more in this log group */ - bool* must_reread_log) /*!< out: should re-read buffer from disk, incomplete read*/ +lsn_t +xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn) { - lsn_t scanned_lsn; - ulint data_len; - ulint write_size; - const byte* log_block; - - ulint scanned_checkpoint_no = 0; - - *finished = false; - *must_reread_log = false; - scanned_lsn = start_lsn; - log_block = log_sys->buf; - - while (log_block < log_sys->buf + RECV_SCAN_SIZE && !*finished) { - ulint no = log_block_get_hdr_no(log_block); - ulint scanned_no = log_block_convert_lsn_to_no(scanned_lsn); - ibool checksum_is_ok = - log_block_checksum_is_ok_or_old_format(log_block); - - if (no != scanned_no && checksum_is_ok) { - ulint blocks_in_group; - - blocks_in_group = log_block_convert_lsn_to_no( - log_group_get_capacity(group)) - 1; - - if ((no < scanned_no && - ((scanned_no - no) % blocks_in_group) == 0) || - no == 0 || - /* Log block numbers wrap around at 0x3FFFFFFF */ - ((scanned_no | 0x40000000UL) - no) % - blocks_in_group == 0) { - - /* old log block, do nothing */ - *finished = true; - break; - } + lsn_t scanned_lsn = start_lsn; + const byte* log_block = log_sys->buf; + bool more_data = false; - msg("mariabackup: error:" - " log block numbers mismatch:\n" - "mariabackup: error: expected log block no. %lu," - " but got no. %lu from the log file.\n", - (ulong) scanned_no, (ulong) no); - - if ((no - scanned_no) % blocks_in_group == 0) { - msg("mariabackup: error:" - " it looks like InnoDB log has wrapped" - " around before xtrabackup could" - " process all records due to either" - " log copying being too slow, or " - " log files being too small.\n"); - } + for (ulint scanned_checkpoint = 0; + scanned_lsn < end_lsn; + log_block += OS_FILE_LOG_BLOCK_SIZE) { + ulint checkpoint = log_block_get_checkpoint_no(log_block); - return(false); - } else if (!checksum_is_ok) { - /* Garbage or an incompletely written log block */ - - msg("mariabackup: warning: Log block checksum mismatch" - " (block no %lu at lsn " LSN_PF "): \n" - "expected %lu, calculated checksum %lu\n", - (ulong) no, - scanned_lsn, - (ulong) log_block_get_checksum(log_block), - (ulong) log_block_calc_checksum(log_block)); - msg("mariabackup: warning: this is possible when the " - "log block has not been fully written by the " - "server, will retry later.\n"); - *finished = false; - *must_reread_log = true; - my_sleep(1000); - return false; + if (scanned_checkpoint > checkpoint + && scanned_checkpoint - checkpoint >= 0x80000000UL) { + /* Garbage from a log buffer flush which was made + before the most recent database recovery */ + break; } - if (log_block_get_flush_bit(log_block)) { - /* This block was a start of a log flush operation: - we know that the previous flush operation must have - been completed for all log groups before this block - can have been flushed to any of the groups. Therefore, - we know that log data is contiguous up to scanned_lsn - in all non-corrupt log groups. */ - - if (scanned_lsn > *contiguous_lsn) { - - *contiguous_lsn = scanned_lsn; - } - } + scanned_checkpoint = checkpoint; - data_len = log_block_get_data_len(log_block); + ulint data_len = log_block_get_data_len(log_block); - if ( - (scanned_checkpoint_no > 0) - && (log_block_get_checkpoint_no(log_block) - < scanned_checkpoint_no) - && (scanned_checkpoint_no - - log_block_get_checkpoint_no(log_block) - > 0x80000000UL)) { + more_data = recv_sys_add_to_parsing_buf( + log_block, + scanned_lsn + data_len); - /* Garbage from a log buffer flush which was made - before the most recent database recovery */ + recv_sys->scanned_lsn = scanned_lsn + data_len; - *finished = true; + if (data_len == OS_FILE_LOG_BLOCK_SIZE) { + /* We got a full log block. */ + scanned_lsn += data_len; + } else if (data_len + >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE + || data_len <= LOG_BLOCK_HDR_SIZE) { + /* We got a garbage block (abrupt end of the log). */ + break; + } else { + /* We got a partial block (abrupt end of the log). */ + scanned_lsn += data_len; break; } + } - scanned_lsn = scanned_lsn + data_len; - scanned_checkpoint_no = log_block_get_checkpoint_no(log_block); + if (more_data && recv_parse_log_recs(0, STORE_NO, false)) { - if (data_len < OS_FILE_LOG_BLOCK_SIZE) { - /* Log data for this group ends here */ + msg("mariabackup: copying the log failed \n"); - *finished = true; - } else { - log_block += OS_FILE_LOG_BLOCK_SIZE; - } + return(0); } - *group_scanned_lsn = scanned_lsn; + recv_sys_justify_left_parsing_buf(); - /* ===== write log to 'xtrabackup_logfile' ====== */ - if (!*finished) { - write_size = RECV_SCAN_SIZE; - } else { - write_size = (ulint)(ut_uint64_align_up(scanned_lsn, - OS_FILE_LOG_BLOCK_SIZE) - start_lsn); - if (!is_last && scanned_lsn % OS_FILE_LOG_BLOCK_SIZE) { - write_size -= OS_FILE_LOG_BLOCK_SIZE; - } - } + log_sys->log.scanned_lsn = scanned_lsn; - if (write_size == 0) { - return(true); - } + end_lsn = copy == COPY_LAST + ? ut_uint64_align_up(scanned_lsn, OS_FILE_LOG_BLOCK_SIZE) + : scanned_lsn & ~lsn_t(OS_FILE_LOG_BLOCK_SIZE - 1); - if (srv_encrypt_log) { - log_encrypt_before_write(scanned_checkpoint_no, - log_sys->buf, start_lsn, write_size); - } + if (ulint write_size = ulint(end_lsn - start_lsn)) { + if (srv_encrypt_log) { + log_crypt(log_sys->buf, start_lsn, write_size); + } - if (ds_write(dst_log_file, log_sys->buf, write_size)) { - msg("mariabackup: Error: " - "write to logfile failed\n"); - return(false); + if (ds_write(dst_log_file, log_sys->buf, write_size)) { + msg("mariabackup: Error: " + "write to logfile failed\n"); + return(0); + } } - return(true); + return(scanned_lsn); } -static my_bool -xtrabackup_copy_logfile(lsn_t from_lsn, my_bool is_last) +/** Copy redo log until the current end of the log is reached +@param copy how to copy the log +@return whether the operation failed */ +static bool +xtrabackup_copy_logfile(copy_logfile copy) { - /* definition from recv_recovery_from_checkpoint_start() */ - log_group_t* group; - lsn_t group_scanned_lsn; - lsn_t contiguous_lsn; - ut_a(dst_log_file != NULL); + ut_ad(recv_sys != NULL); - /* read from checkpoint_lsn_start to current */ - contiguous_lsn = ut_uint64_align_down(from_lsn, OS_FILE_LOG_BLOCK_SIZE); - - /* TODO: We must check the contiguous_lsn still exists in log file.. */ - - group = UT_LIST_GET_FIRST(log_sys->log_groups); - - while (group) { - bool finished; - lsn_t start_lsn; - lsn_t end_lsn; - - /* reference recv_group_scan_log_recs() */ - finished = false; + lsn_t start_lsn; + lsn_t end_lsn; - start_lsn = contiguous_lsn; + recv_sys->parse_start_lsn = log_copy_scanned_lsn; + recv_sys->scanned_lsn = log_copy_scanned_lsn; + recv_sys->recovered_lsn = log_copy_scanned_lsn; - while (!finished) { + start_lsn = ut_uint64_align_down(log_copy_scanned_lsn, + OS_FILE_LOG_BLOCK_SIZE); + /* When copying the first or last part of the log, retry a few + times to ensure that all log up to the last checkpoint will be + read. */ + do { + end_lsn = start_lsn + RECV_SCAN_SIZE; - end_lsn = start_lsn + RECV_SCAN_SIZE; + xtrabackup_io_throttling(); - xtrabackup_io_throttling(); + log_mutex_enter(); - mutex_enter(&log_sys->mutex); - - bool scan_ok = false; - bool must_reread_log; - int retries = 0; - do { - - log_group_read_log_seg(LOG_RECOVER, log_sys->buf, - group, start_lsn, end_lsn, false); - - scan_ok = xtrabackup_scan_log_recs(group, is_last, - start_lsn, &contiguous_lsn, &group_scanned_lsn, - &finished, &must_reread_log); - - } while (!scan_ok && must_reread_log && retries++ < 100); - - if (!scan_ok) { - goto error; + lsn_t lsn= start_lsn; + for(int retries= 0; retries < 100; retries++) { + if (log_group_read_log_seg(log_sys->buf, &log_sys->log, + &lsn, end_lsn)){ + break; } - - mutex_exit(&log_sys->mutex); - - start_lsn = end_lsn; - + msg("Retrying read of a redo log block"); + my_sleep(1000); } - group->scanned_lsn = group_scanned_lsn; - - msg_ts(">> log scanned up to (" LSN_PF ")\n", - group->scanned_lsn); - - group = UT_LIST_GET_NEXT(log_groups, group); - - /* update global variable*/ - log_copy_scanned_lsn = group_scanned_lsn; + start_lsn = xtrabackup_copy_log(copy, start_lsn, lsn); - /* innodb_mirrored_log_groups must be 1, no other groups */ - ut_a(group == NULL); + log_mutex_exit(); - debug_sync_point("xtrabackup_copy_logfile_pause"); + if (!start_lsn) { + ds_close(dst_log_file); + dst_log_file = NULL; + msg("mariabackup: Error: xtrabackup_copy_logfile()" + " failed.\n"); + return(true); + } + } while (start_lsn == end_lsn); - } + ut_ad(start_lsn == log_sys->log.scanned_lsn); + msg_ts(">> log scanned up to (" LSN_PF ")\n", start_lsn); - return(FALSE); + /* update global variable*/ + log_copy_scanned_lsn = start_lsn; -error: - mutex_exit(&log_sys->mutex); - ds_close(dst_log_file); - msg("mariabackup: Error: xtrabackup_copy_logfile() failed.\n"); - return(TRUE); + debug_sync_point("xtrabackup_copy_logfile_pause"); + return(false); } -static -#ifndef __WIN__ -void* -#else -ulint -#endif -log_copying_thread( - void* arg __attribute__((unused))) +static os_thread_ret_t log_copying_thread(void*) { /* Initialize mysys thread-specific memory so we can @@ -2811,53 +2521,26 @@ log_copying_thread( */ my_thread_init(); - ut_a(dst_log_file != NULL); - - log_copying_running = TRUE; - - while(log_copying) { + do { os_event_reset(log_copying_stop); os_event_wait_time_low(log_copying_stop, xtrabackup_log_copy_interval * 1000ULL, 0); - if (log_copying) { - if(xtrabackup_copy_logfile(log_copy_scanned_lsn, - FALSE)) { - - exit(EXIT_FAILURE); - } - } - } - - /* last copying */ - if(xtrabackup_copy_logfile(log_copy_scanned_lsn, TRUE)) { + } while (log_copying && xtrabackup_copy_logfile(COPY_ONLINE)); - exit(EXIT_FAILURE); - } - - log_copying_running = FALSE; + log_copying_running = false; my_thread_end(); - os_thread_exit(NULL); + os_thread_exit(); return(0); } /* io throttle watching (rough) */ -static -#ifndef __WIN__ -void* -#else -ulint -#endif -io_watching_thread( - void* arg) +static os_thread_ret_t io_watching_thread(void*) { - (void)arg; /* currently, for --backup only */ ut_a(xtrabackup_backup); - io_watching_thread_running = TRUE; - while (log_copying) { os_thread_sleep(1000000); /*1 sec*/ io_ticket = xtrabackup_throttle; @@ -2868,49 +2551,13 @@ io_watching_thread( xtrabackup_throttle = 0; os_event_set(wait_throttle); - io_watching_thread_running = FALSE; + io_watching_thread_running = false; - os_thread_exit(NULL); + os_thread_exit(); return(0); } -/************************************************************************ -I/o-handler thread function. */ -static - -#ifndef __WIN__ -void* -#else -ulint -#endif -io_handler_thread( -/*==============*/ - void* arg) -{ - ulint segment; - - - segment = *((ulint*)arg); - - while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) { - fil_aio_wait(segment); - } - - /* We count the number of threads in os_thread_exit(). A created - thread should always use that to exit and not use return() to exit. - The thread actually never comes here because it is exited in an - os_event_wait(). */ - - os_thread_exit(NULL); - -#ifndef __WIN__ - return(NULL); /* Not reached */ -#else - return(0); -#endif -} - /************************************************************************** Datafiles copying thread.*/ static @@ -2941,12 +2588,12 @@ data_copy_thread_func( } } - os_mutex_enter(ctxt->count_mutex); + pthread_mutex_lock(&ctxt->count_mutex); (*ctxt->count)--; - os_mutex_exit(ctxt->count_mutex); + pthread_mutex_unlock(&ctxt->count_mutex); my_thread_end(); - os_thread_exit(NULL); + os_thread_exit(); OS_THREAD_DUMMY_RETURN; } @@ -2956,7 +2603,7 @@ Initialize the appropriate datasink(s). Both local backups and streaming in the Otherwise (i.e. when streaming in the 'tar' format) we need 2 separate datasinks for the data stream (and don't allow parallel data copying) and for metainfo -files (including xtrabackup_logfile). The second datasink writes to temporary +files (including ib_logfile0). The second datasink writes to temporary files first, and then streams them in a serialized way when closed. */ static void xtrabackup_init_datasinks(void) @@ -3042,41 +2689,254 @@ static void xtrabackup_destroy_datasinks(void) ds_redo = NULL; } -#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD #define SRV_MAX_N_PENDING_SYNC_IOS 100 -/************************************************************************ -@return TRUE if table should be opened. */ +/** Initialize the tablespace cache subsystem. */ static -ibool -xb_check_if_open_tablespace( - const char* db, - const char* table) +void +xb_fil_io_init() { - char buf[FN_REFLEN]; - - snprintf(buf, sizeof(buf), "%s/%s", db, table); + fil_init(srv_file_per_table ? 50000 : 5000, LONG_MAX); + fsp_init(); +} - return !check_if_skip_table(buf); +static +Datafile* +xb_new_datafile(const char *name, bool is_remote) +{ + if (is_remote) { + RemoteDatafile *remote_file = new RemoteDatafile(); + remote_file->set_name(name); + return(remote_file); + } else { + Datafile *file = new Datafile(); + file->set_name(name); + file->make_filepath(".", name, IBD); + return(file); + } } -/************************************************************************ -Initializes the I/O and tablespace cache subsystems. */ + static void -xb_fil_io_init(void) -/*================*/ +xb_load_single_table_tablespace( + const char *dirname, + const char *filname, + bool is_remote) { - srv_n_file_io_threads = srv_n_read_io_threads; + ut_ad(srv_operation == SRV_OPERATION_BACKUP + || srv_operation == SRV_OPERATION_RESTORE_DELTA); + /* Ignore .isl files on XtraBackup recovery. All tablespaces must be + local. */ + if (is_remote && srv_operation == SRV_OPERATION_RESTORE_DELTA) { + return; + } + if (check_if_skip_table(filname)) { + return; + } - os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD, - srv_n_read_io_threads, - srv_n_write_io_threads, - SRV_MAX_N_PENDING_SYNC_IOS); + /* The name ends in .ibd or .isl; + try opening the file */ + char* name; + size_t dirlen = dirname == NULL ? 0 : strlen(dirname); + size_t namelen = strlen(filname); + ulint pathlen = dirname == NULL ? namelen + 1: dirlen + namelen + 2; + lsn_t flush_lsn; + dberr_t err; + fil_space_t *space; - fil_init(srv_file_per_table ? 50000 : 5000, LONG_MAX); + name = static_cast<char*>(ut_malloc_nokey(pathlen)); - fsp_init(); + if (dirname != NULL) { + snprintf(name, pathlen, "%s/%s", dirname, filname); + name[pathlen - 5] = 0; + } else { + snprintf(name, pathlen, "%s", filname); + name[pathlen - 5] = 0; + } + + Datafile *file = xb_new_datafile(name, is_remote); + + if (file->open_read_only(true) != DB_SUCCESS) { + ut_free(name); + exit(EXIT_FAILURE); + } + + err = file->validate_first_page(&flush_lsn); + + if (err == DB_SUCCESS && file->space_id() != SRV_TMP_SPACE_ID) { + os_offset_t node_size = os_file_get_size(file->handle()); + os_offset_t n_pages; + + ut_a(node_size != (os_offset_t) -1); + + n_pages = node_size / page_size_t(file->flags()).physical(); + + space = fil_space_create( + name, file->space_id(), file->flags(), + FIL_TYPE_TABLESPACE, NULL/* TODO: crypt_data */); + + ut_a(space != NULL); + + if (!fil_node_create(file->filepath(), ulint(n_pages), space, + false, false)) { + ut_error; + } + + /* by opening the tablespace we forcing node and space objects + in the cache to be populated with fields from space header */ + fil_space_open(space->name); + + if (srv_operation == SRV_OPERATION_RESTORE_DELTA + || xb_close_files) { + fil_space_close(space->name); + } + } + + ut_free(name); + + delete file; + + if (err != DB_SUCCESS && err != DB_CORRUPTION && xtrabackup_backup) { + /* allow corrupted first page for xtrabackup, it could be just + zero-filled page, which we restore from redo log later */ + exit(EXIT_FAILURE); + } +} + +/** Scan the database directories under the MySQL datadir, looking for +.ibd files and determining the space id in each of them. +@return DB_SUCCESS or error number */ + +static dberr_t enumerate_ibd_files(process_single_tablespace_func_t callback) +{ + int ret; + char* dbpath = NULL; + ulint dbpath_len = 100; + os_file_dir_t dir; + os_file_dir_t dbdir; + os_file_stat_t dbinfo; + os_file_stat_t fileinfo; + dberr_t err = DB_SUCCESS; + size_t len; + + /* The datadir of MySQL is always the default directory of mysqld */ + + dir = os_file_opendir(fil_path_to_mysql_datadir, true); + + if (dir == NULL) { + + return(DB_ERROR); + } + + dbpath = static_cast<char*>(ut_malloc_nokey(dbpath_len)); + + /* Scan all directories under the datadir. They are the database + directories of MySQL. */ + + ret = fil_file_readdir_next_file(&err, fil_path_to_mysql_datadir, dir, + &dbinfo); + while (ret == 0) { + + /* General tablespaces are always at the first level of the + data home dir */ + if (dbinfo.type == OS_FILE_TYPE_FILE) { + bool is_isl = ends_with(dbinfo.name, ".isl"); + bool is_ibd = !is_isl && ends_with(dbinfo.name,".ibd"); + + if (is_isl || is_ibd) { + (*callback)(NULL, dbinfo.name, is_isl); + } + } + + if (dbinfo.type == OS_FILE_TYPE_FILE + || dbinfo.type == OS_FILE_TYPE_UNKNOWN) { + + goto next_datadir_item; + } + + /* We found a symlink or a directory; try opening it to see + if a symlink is a directory */ + + len = strlen(fil_path_to_mysql_datadir) + + strlen (dbinfo.name) + 2; + if (len > dbpath_len) { + dbpath_len = len; + + if (dbpath) { + ut_free(dbpath); + } + + dbpath = static_cast<char*>(ut_malloc_nokey(dbpath_len)); + } + snprintf(dbpath, dbpath_len, + "%s/%s", fil_path_to_mysql_datadir, dbinfo.name); + os_normalize_path(dbpath); + + if (check_if_skip_database_by_path(dbpath)) { + fprintf(stderr, "Skipping db: %s\n", dbpath); + goto next_datadir_item; + } + + /* We want wrong directory permissions to be a fatal error for + XtraBackup. */ + dbdir = os_file_opendir(dbpath, true); + + if (dbdir != NULL) { + + /* We found a database directory; loop through it, + looking for possible .ibd files in it */ + + for (ret = fil_file_readdir_next_file(&err, dbpath, + dbdir, + &fileinfo); + ret == 0; + ret = fil_file_readdir_next_file(&err, dbpath, + dbdir, + &fileinfo)) { + if (fileinfo.type == OS_FILE_TYPE_DIR) { + continue; + } + + /* We found a symlink or a file */ + if (strlen(fileinfo.name) > 4) { + bool is_isl= false; + if (ends_with(fileinfo.name, ".ibd") || ((is_isl = ends_with(fileinfo.name, ".isl")))) + (*callback)(dbinfo.name, fileinfo.name, is_isl); + } + } + + if (0 != os_file_closedir(dbdir)) { + fprintf(stderr, "InnoDB: Warning: could not" + " close database directory %s\n", + dbpath); + + err = DB_ERROR; + } + + } else { + + err = DB_ERROR; + break; + + } + +next_datadir_item: + ret = fil_file_readdir_next_file(&err, + fil_path_to_mysql_datadir, + dir, &dbinfo); + } + + ut_free(dbpath); + + if (0 != os_file_closedir(dir)) { + fprintf(stderr, + "InnoDB: Error: could not close MySQL datadir\n"); + + return(DB_ERROR); + } + + return(err); } /** Assign srv_undo_space_id_start variable if there are undo tablespace present. @@ -3091,7 +2951,7 @@ static dberr_t xb_assign_undo_space_start() pfs_os_file_t file; byte* buf; byte* page; - ibool ret; + bool ret; dberr_t error = DB_SUCCESS; ulint space, page_no; @@ -3099,40 +2959,38 @@ static dberr_t xb_assign_undo_space_start() return error; } - srv_normalize_path_for_win(srv_data_home); + os_normalize_path(srv_data_home); dirnamelen = strlen(srv_data_home); memcpy(name, srv_data_home, dirnamelen); - if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) { - name[dirnamelen++] = SRV_PATH_SEPARATOR; + if (dirnamelen && name[dirnamelen - 1] != OS_PATH_SEPARATOR) { + name[dirnamelen++] = OS_PATH_SEPARATOR; } - ut_snprintf(name + dirnamelen, strlen(name) + strlen("ibdata1"), + snprintf(name + dirnamelen, strlen(name) + strlen("ibdata1"), "%s", "ibdata1"); - file = os_file_create(innodb_file_data_key, name, OS_FILE_OPEN, - OS_FILE_NORMAL, OS_DATA_FILE, &ret, 0); + file = os_file_create(0, name, OS_FILE_OPEN, + OS_FILE_NORMAL, OS_DATA_FILE, true, &ret); - if (ret == FALSE) { - fprintf(stderr, "InnoDB: Error in opening %s\n", name); + if (!ret) { + msg("mariabackup: Error in opening %s\n", name); return DB_ERROR; } - buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE)); + buf = static_cast<byte*>(ut_malloc_nokey(2 * UNIV_PAGE_SIZE)); page = static_cast<byte*>(ut_align(buf, UNIV_PAGE_SIZE)); retry: - ret = os_file_read(file, page, TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE, - UNIV_PAGE_SIZE); - - if (!ret) { - fprintf(stderr, "InnoDB: Reading TRX_SYS page failed."); + if (!os_file_read(IORequestRead, file, page, TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE, + UNIV_PAGE_SIZE)) { + msg("mariabackup: Reading TRX_SYS page failed.\n"); error = DB_ERROR; goto func_exit; } /* TRX_SYS page can't be compressed or encrypted. */ - if (buf_page_is_corrupted(false, page, 0, NULL)) { + if (buf_page_is_corrupted(false, page, univ_page_size)) { goto retry; } @@ -3162,53 +3020,34 @@ func_exit: Populates the tablespace memory cache by scanning for and opening data files. @returns DB_SUCCESS or error code.*/ static -ulint -xb_load_tablespaces(void) -/*=====================*/ +dberr_t +xb_load_tablespaces() { - ulint i; bool create_new_db; - ulint err; + dberr_t err; ulint sum_of_new_sizes; - lsn_t min_arch_logno, max_arch_logno; - - for (i = 0; i < srv_n_file_io_threads; i++) { - thread_nr[i] = i; - - os_thread_create(io_handler_thread, thread_nr + i, - thread_ids + i); - } + lsn_t flush_lsn; - os_thread_sleep(200000); /*0.2 sec*/ + ut_ad(srv_operation == SRV_OPERATION_BACKUP + || srv_operation == SRV_OPERATION_RESTORE_DELTA); - err = open_or_create_data_files(&create_new_db, - &min_arch_logno, &max_arch_logno, - &flushed_lsn, - &sum_of_new_sizes); - if (err != DB_SUCCESS) { - msg("mariabackup: Could not open or create data files.\n" - "mariabackup: If you tried to add new data files, and it " - "failed here,\n" - "mariabackup: you should now edit innodb_data_file_path in " - "my.cnf back\n" - "mariabackup: to what it was, and remove the new ibdata " - "files InnoDB created\n" - "mariabackup: in this failed attempt. InnoDB only wrote " - "those files full of\n" - "mariabackup: zeros, but did not yet use them in any way. " - "But be careful: do not\n" - "mariabackup: remove old data files which contain your " - "precious data!\n"); - return(err); - } + err = srv_sys_space.check_file_spec(&create_new_db, 0); - /* create_new_db must not be TRUE.. */ - if (create_new_db) { + /* create_new_db must not be true. */ + if (err != DB_SUCCESS || create_new_db) { msg("mariabackup: could not find data files at the " "specified datadir\n"); return(DB_ERROR); } + err = srv_sys_space.open_or_create(false, false, &sum_of_new_sizes, + &flush_lsn); + + if (err != DB_SUCCESS) { + msg("mariabackup: Could not open data files.\n"); + return(err); + } + /* Add separate undo tablespaces to fil_system */ err = xb_assign_undo_space_start(); @@ -3217,21 +3056,19 @@ xb_load_tablespaces(void) return err; } - err = srv_undo_tablespaces_init(FALSE, - TRUE, - srv_undo_tablespaces, - &srv_undo_tablespaces_open); + err = srv_undo_tablespaces_init(false); + if (err != DB_SUCCESS) { return(err); } - /* It is important to call fil_load_single_table_tablespace() after + /* It is important to call xb_load_single_table_tablespaces() after srv_undo_tablespaces_init(), because fil_is_user_tablespace_id() * relies on srv_undo_tablespaces_open to be properly initialized */ msg("mariabackup: Generating a list of tablespaces\n"); - err = fil_load_single_table_tablespaces(xb_check_if_open_tablespace); + err = enumerate_ibd_files(xb_load_single_table_tablespace); if (err != DB_SUCCESS) { return(err); } @@ -3245,9 +3082,9 @@ xb_load_tablespaces(void) Initialize the tablespace memory cache and populate it by scanning for and opening data files. @returns DB_SUCCESS or error code.*/ -ulint -xb_data_files_init(void) -/*====================*/ +static +dberr_t +xb_data_files_init() { xb_fil_io_init(); @@ -3256,46 +3093,15 @@ xb_data_files_init(void) /************************************************************************ Destroy the tablespace memory cache. */ +static void -xb_data_files_close(void) -/*====================*/ +xb_data_files_close() { - ulint i; - - /* Shutdown the aio threads. This has been copied from - innobase_shutdown_for_mysql(). */ - - srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS; - - for (i = 0; i < 1000; i++) { - os_aio_wake_all_threads_at_shutdown(); - - if (os_thread_count == 0) { - break; - } - os_thread_sleep(10000); - } - - if (i == 1000) { - msg("mariabackup: Warning: %lu threads created by InnoDB" - " had not exited at shutdown!\n", - (ulong) os_thread_count); - } - - os_aio_free(); - + ut_ad(!os_thread_count); fil_close_all_files(); - - /* Free the double write data structures. */ if (buf_dblwr) { buf_dblwr_free(); } - - /* Reset srv_file_io_threads to its default value to avoid confusing - warning on --prepare in innobase_start_or_create_for_mysql()*/ - srv_n_file_io_threads = 4; - - srv_shutdown_state = SRV_SHUTDOWN_NONE; } /*********************************************************************** @@ -3314,7 +3120,7 @@ xb_new_filter_entry( ut_a(namelen <= NAME_LEN * 2 + 1); entry = static_cast<xb_filter_entry_t *> - (ut_malloc(sizeof(xb_filter_entry_t) + namelen + 1)); + (malloc(sizeof(xb_filter_entry_t) + namelen + 1)); memset(entry, '\0', sizeof(xb_filter_entry_t) + namelen + 1); entry->name = ((char*)entry) + sizeof(xb_filter_entry_t); strcpy(entry->name, name); @@ -3367,7 +3173,7 @@ xb_validate_name( exit(EXIT_FAILURE); } p = strpbrk(name, "/\\~"); - if (p && p - name < NAME_LEN) { + if (p && (uint) (p - name) < NAME_LEN) { msg("mariabackup: name `%s` is not valid.\n", name); exit(EXIT_FAILURE); } @@ -3613,7 +3419,7 @@ xb_filter_hash_free(hash_table_t* hash) HASH_DELETE(xb_filter_entry_t, name_hash, hash, ut_fold_string(prev_table->name), prev_table); - ut_free(prev_table); + free(prev_table); } } @@ -3662,86 +3468,33 @@ static ulint open_or_create_log_file( /*====================*/ - ibool create_new_db, /*!< in: TRUE if we should create a - new database */ + fil_space_t* space, ibool* log_file_created, /*!< out: TRUE if new log file created */ - ibool log_file_has_been_opened,/*!< in: TRUE if a log file has been - opened before: then it is an error - to try to create another log file */ - ulint k, /*!< in: log group number */ ulint i) /*!< in: log file number in group */ { - ibool ret; - os_offset_t size; char name[10000]; ulint dirnamelen; - UT_NOT_USED(create_new_db); - UT_NOT_USED(log_file_has_been_opened); - UT_NOT_USED(k); - ut_ad(k == 0); - *log_file_created = FALSE; - srv_normalize_path_for_win(srv_log_group_home_dir); + os_normalize_path(srv_log_group_home_dir); dirnamelen = strlen(srv_log_group_home_dir); ut_a(dirnamelen < (sizeof name) - 10 - sizeof "ib_logfile"); memcpy(name, srv_log_group_home_dir, dirnamelen); /* Add a path separator if needed. */ - if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) { - name[dirnamelen++] = SRV_PATH_SEPARATOR; + if (dirnamelen && name[dirnamelen - 1] != OS_PATH_SEPARATOR) { + name[dirnamelen++] = OS_PATH_SEPARATOR; } sprintf(name + dirnamelen, "%s%lu", "ib_logfile", (ulong) i); - files[i] = os_file_create(innodb_file_log_key, name, - OS_FILE_OPEN, OS_FILE_NORMAL, - OS_LOG_FILE, &ret,0); - if (ret == FALSE) { - fprintf(stderr, "InnoDB: Error in opening %s\n", name); - - return(DB_ERROR); - } - - size = os_file_get_size(files[i]); - - if (size != srv_log_file_size * UNIV_PAGE_SIZE) { - - fprintf(stderr, - "InnoDB: Error: log file %s is" - " of different size " UINT64PF " bytes\n" - "InnoDB: than specified in the .cnf" - " file " UINT64PF " bytes!\n", - name, size, srv_log_file_size * UNIV_PAGE_SIZE); - - return(DB_ERROR); - } - - ret = os_file_close(files[i]); - ut_a(ret); - - if (i == 0) { - /* Create in memory the file space object - which is for this log group */ - - fil_space_create(name, - 2 * k + SRV_LOG_SPACE_FIRST_ID, 0, FIL_LOG, 0, 0); - } - ut_a(fil_validate()); - ut_a(fil_node_create(name, (ulint)srv_log_file_size, - 2 * k + SRV_LOG_SPACE_FIRST_ID, FALSE)); - if (i == 0) { - log_group_init(k, srv_n_log_files, - srv_log_file_size * UNIV_PAGE_SIZE, - 2 * k + SRV_LOG_SPACE_FIRST_ID, - SRV_LOG_SPACE_FIRST_ID + 1); /* dummy arch - space id */ - } + ut_a(fil_node_create(name, ulint(srv_log_file_size >> srv_page_size_shift), + space, false, false)); return(DB_SUCCESS); } @@ -3754,20 +3507,8 @@ void xb_normalize_init_values(void) /*==========================*/ { - ulint i; - - for (i = 0; i < srv_n_data_files; i++) { - srv_data_file_sizes[i] = srv_data_file_sizes[i] - * ((1024 * 1024) / UNIV_PAGE_SIZE); - } - - srv_last_file_size_max = srv_last_file_size_max - * ((1024 * 1024) / UNIV_PAGE_SIZE); - - srv_log_file_size = srv_log_file_size / UNIV_PAGE_SIZE; - - srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE; - + srv_sys_space.normalize(); + srv_log_buffer_size /= UNIV_PAGE_SIZE; srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE); } @@ -3828,14 +3569,114 @@ end: #endif } -void -xtrabackup_backup_func(void) +static void stop_backup_threads() +{ + log_copying = false; + + if (log_copying_stop) { + os_event_set(log_copying_stop); + msg("mariabackup: Stopping log copying thread.\n"); + while (log_copying_running) { + msg("."); + os_thread_sleep(200000); /*0.2 sec*/ + } + msg("\n"); + os_event_destroy(log_copying_stop); + } + + if (wait_throttle) { + /* wait for io_watching_thread completion */ + while (io_watching_thread_running) { + os_thread_sleep(1000000); + } + os_event_destroy(wait_throttle); + } +} + +/** Implement the core of --backup +@return whether the operation succeeded */ +static +bool +xtrabackup_backup_low() +{ + /* read the latest checkpoint lsn */ + { + ulint max_cp_field; + + log_mutex_enter(); + + if (recv_find_max_checkpoint(&max_cp_field) == DB_SUCCESS + && log_sys->log.format != 0) { + metadata_to_lsn = mach_read_from_8( + log_sys->checkpoint_buf + LOG_CHECKPOINT_LSN); + msg("mariabackup: The latest check point" + " (for incremental): '" LSN_PF "'\n", + metadata_to_lsn); + } else { + metadata_to_lsn = 0; + msg("mariabackup: Error: recv_find_max_checkpoint() failed.\n"); + } + log_mutex_exit(); + } + + stop_backup_threads(); + + if (!dst_log_file || xtrabackup_copy_logfile(COPY_LAST)) { + return false; + } + + if (ds_close(dst_log_file)) { + dst_log_file = NULL; + return false; + } + + dst_log_file = NULL; + + if(!xtrabackup_incremental) { + strcpy(metadata_type, "full-backuped"); + metadata_from_lsn = 0; + } else { + strcpy(metadata_type, "incremental"); + metadata_from_lsn = incremental_lsn; + } + metadata_last_lsn = log_copy_scanned_lsn; + + if (!xtrabackup_stream_metadata(ds_meta)) { + msg("mariabackup: Error: failed to stream metadata.\n"); + return false; + } + if (xtrabackup_extra_lsndir) { + char filename[FN_REFLEN]; + + sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, + XTRABACKUP_METADATA_FILENAME); + if (!xtrabackup_write_metadata(filename)) { + msg("mariabackup: Error: failed to write metadata " + "to '%s'.\n", filename); + return false; + } + sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, + XTRABACKUP_INFO); + if (!write_xtrabackup_info(mysql_connection, filename, false)) { + msg("mariabackup: Error: failed to write info " + "to '%s'.\n", filename); + return false; + } + } + + return true; +} + +/** Implement --backup +@return whether the operation succeeded */ +static +bool +xtrabackup_backup_func() { MY_STAT stat_info; - lsn_t latest_cp; uint i; uint count; - os_ib_mutex_t count_mutex; + pthread_mutex_t count_mutex; data_thread_ctxt_t *data_threads; #ifdef USE_POSIX_FADVISE @@ -3847,7 +3688,7 @@ xtrabackup_backup_func(void) if (my_setwd(mysql_real_data_home,MYF(MY_WME))) { msg("mariabackup: cannot my_setwd %s\n", mysql_real_data_home); - exit(EXIT_FAILURE); + return(false); } msg("mariabackup: cd to %s\n", mysql_real_data_home); @@ -3862,54 +3703,58 @@ xtrabackup_backup_func(void) srv_n_purge_threads = 1; srv_read_only_mode = TRUE; - srv_backup_mode = TRUE; - srv_close_files = (bool)xb_close_files; + srv_operation = SRV_OPERATION_BACKUP; - if (srv_close_files) + if (xb_close_files) msg("mariabackup: warning: close-files specified. Use it " "at your own risk. If there are DDL operations like table DROP TABLE " "or RENAME TABLE during the backup, inconsistent backup will be " "produced.\n"); /* initialize components */ - if(innodb_init_param()) - exit(EXIT_FAILURE); + if(innodb_init_param()) { +fail: + stop_backup_threads(); + if (fil_system) { + innodb_shutdown(); + } + return(false); + } xb_normalize_init_values(); if (srv_file_flush_method_str == NULL) { - /* These are the default options */ - srv_unix_file_flush_method = SRV_UNIX_FSYNC; + /* These are the default options */ + srv_file_flush_method = SRV_FSYNC; } else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) { - srv_unix_file_flush_method = SRV_UNIX_FSYNC; + srv_file_flush_method = SRV_FSYNC; } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DSYNC")) { - srv_unix_file_flush_method = SRV_UNIX_O_DSYNC; + srv_file_flush_method = SRV_O_DSYNC; } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) { - srv_unix_file_flush_method = SRV_UNIX_O_DIRECT; + srv_file_flush_method = SRV_O_DIRECT; msg("mariabackup: using O_DIRECT\n"); } else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) { - srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC; - + srv_file_flush_method = SRV_LITTLESYNC; } else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) { - srv_unix_file_flush_method = SRV_UNIX_NOSYNC; + srv_file_flush_method = SRV_NOSYNC; } else if (0 == ut_strcmp(srv_file_flush_method_str, "ALL_O_DIRECT")) { - srv_unix_file_flush_method = SRV_UNIX_ALL_O_DIRECT; + srv_file_flush_method = SRV_ALL_O_DIRECT_FSYNC; msg("mariabackup: using ALL_O_DIRECT\n"); } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT_NO_FSYNC")) { - srv_unix_file_flush_method = SRV_UNIX_O_DIRECT_NO_FSYNC; + srv_file_flush_method = SRV_O_DIRECT_NO_FSYNC; msg("mariabackup: using O_DIRECT_NO_FSYNC\n"); } else { - msg("mariabackup: Unrecognized value %s for " + msg("mariabackup: Unrecognized value %s for " "innodb_flush_method\n", srv_file_flush_method_str); - exit(EXIT_FAILURE); + goto fail; } #ifdef _WIN32 - srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED; - srv_use_native_aio = FALSE; + srv_file_flush_method = SRV_ALL_O_DIRECT_FSYNC; + srv_use_native_aio = TRUE; #endif if (srv_buf_pool_size >= 1000 * 1024 * 1024) { @@ -3929,12 +3774,18 @@ xtrabackup_backup_func(void) computers */ } - srv_general_init(); + sync_check_init(); + ut_d(sync_check_enable()); + /* Reset the system variables in the recovery module. */ + recv_sys_var_init(); + trx_pool_init(); + ut_crc32_init(); crc_init(); + recv_sys_init(); #ifdef WITH_INNODB_DISALLOW_WRITES - srv_allow_writes_event = os_event_create(); + srv_allow_writes_event = os_event_create(0); os_event_set(srv_allow_writes_event); #endif @@ -3948,18 +3799,23 @@ xtrabackup_backup_func(void) ulint i; xb_fil_io_init(); + srv_n_file_io_threads = srv_n_read_io_threads; + + os_aio_init(srv_n_read_io_threads, srv_n_write_io_threads, + SRV_MAX_N_PENDING_SYNC_IOS); - log_init(); + log_sys_init(); + log_init(srv_n_log_files); + fil_space_t* space = fil_space_create( + "innodb_redo_log", SRV_LOG_SPACE_FIRST_ID, 0, + FIL_TYPE_LOG, NULL); lock_sys_create(srv_lock_table_size); for (i = 0; i < srv_n_log_files; i++) { - err = open_or_create_log_file(FALSE, &log_file_created, - log_opened, 0, i); + err = open_or_create_log_file(space, &log_file_created, i); if (err != DB_SUCCESS) { - - //return((int) err); - exit(EXIT_FAILURE); + goto fail; } if (log_file_created) { @@ -3976,15 +3832,14 @@ xtrabackup_backup_func(void) "mariabackup: Then delete the existing log files. Edit the .cnf file\n" "mariabackup: and start the database again.\n"); - //return(DB_ERROR); - exit(EXIT_FAILURE); + goto fail; } } /* log_file_created must not be TRUE, if online */ if (log_file_created) { msg("mariabackup: Something wrong with source files...\n"); - exit(EXIT_FAILURE); + goto fail; } } @@ -3995,7 +3850,7 @@ xtrabackup_backup_func(void) && (my_mkdir(xtrabackup_extra_lsndir,0777,MYF(0)) < 0)) { msg("mariabackup: Error: cannot mkdir %d: %s\n", my_errno, xtrabackup_extra_lsndir); - exit(EXIT_FAILURE); + goto fail; } /* create target dir if not exist */ @@ -4003,111 +3858,115 @@ xtrabackup_backup_func(void) && (my_mkdir(xtrabackup_target_dir,0777,MYF(0)) < 0)){ msg("mariabackup: Error: cannot mkdir %d: %s\n", my_errno, xtrabackup_target_dir); - exit(EXIT_FAILURE); + goto fail; } { - fil_system_t* f_system = fil_system; - /* definition from recv_recovery_from_checkpoint_start() */ - log_group_t* max_cp_group; ulint max_cp_field; - byte* buf; - byte* log_hdr_buf_; - byte* log_hdr_buf; - ulint err; /* start back ground thread to copy newer log */ os_thread_id_t log_copying_thread_id; datafiles_iter_t *it; - log_hdr_buf_ = static_cast<byte *> - (ut_malloc(LOG_FILE_HDR_SIZE + UNIV_PAGE_SIZE_MAX)); - log_hdr_buf = static_cast<byte *> - (ut_align(log_hdr_buf_, UNIV_PAGE_SIZE_MAX)); - /* get current checkpoint_lsn */ /* Look for the latest checkpoint from any of the log groups */ - mutex_enter(&log_sys->mutex); + log_mutex_enter(); - err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field); + dberr_t err = recv_find_max_checkpoint(&max_cp_field); if (err != DB_SUCCESS) { - - ut_free(log_hdr_buf_); - exit(EXIT_FAILURE); +log_fail: + log_mutex_exit(); + goto fail; } - log_group_read_checkpoint_info(max_cp_group, max_cp_field); - buf = log_sys->checkpoint_buf; + if (log_sys->log.format == 0) { +old_format: + msg("mariabackup: Error: cannot process redo log" + " before MariaDB 10.2.2\n"); + log_mutex_exit(); + goto log_fail; + } - checkpoint_lsn_start = mach_read_from_8(buf + LOG_CHECKPOINT_LSN); - checkpoint_no_start = mach_read_from_8(buf + LOG_CHECKPOINT_NO); + ut_ad(!((log_sys->log.format ^ LOG_HEADER_FORMAT_CURRENT) + & ~LOG_HEADER_FORMAT_ENCRYPTED)); - mutex_exit(&log_sys->mutex); + const byte* buf = log_sys->checkpoint_buf; reread_log_header: - fil_io(OS_FILE_READ | OS_FILE_LOG, true, max_cp_group->space_id, - 0, - 0, 0, LOG_FILE_HDR_SIZE, - log_hdr_buf, max_cp_group, NULL); - - /* check consistency of log file header to copy */ - mutex_enter(&log_sys->mutex); + checkpoint_lsn_start = log_sys->log.lsn; + checkpoint_no_start = log_sys->next_checkpoint_no; - err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field); + err = recv_find_max_checkpoint(&max_cp_field); - if (err != DB_SUCCESS) { + if (err != DB_SUCCESS) { + goto log_fail; + } - ut_free(log_hdr_buf_); - exit(EXIT_FAILURE); - } + if (log_sys->log.format == 0) { + goto old_format; + } - log_group_read_checkpoint_info(max_cp_group, max_cp_field); - buf = log_sys->checkpoint_buf; + ut_ad(!((log_sys->log.format ^ LOG_HEADER_FORMAT_CURRENT) + & ~LOG_HEADER_FORMAT_ENCRYPTED)); - if(checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) { + log_group_header_read(&log_sys->log, max_cp_field); - checkpoint_lsn_start = mach_read_from_8(buf + LOG_CHECKPOINT_LSN); - checkpoint_no_start = mach_read_from_8(buf + LOG_CHECKPOINT_NO); - mutex_exit(&log_sys->mutex); + if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) { goto reread_log_header; } - mutex_exit(&log_sys->mutex); + log_mutex_exit(); xtrabackup_init_datasinks(); if (!select_history()) { - exit(EXIT_FAILURE); + goto fail; } /* open the log file */ memset(&stat_info, 0, sizeof(MY_STAT)); - dst_log_file = ds_open(ds_redo, XB_LOG_FILENAME, &stat_info); + dst_log_file = ds_open(ds_redo, "ib_logfile0", &stat_info); if (dst_log_file == NULL) { msg("mariabackup: error: failed to open the target stream for " - "'%s'.\n", XB_LOG_FILENAME); - ut_free(log_hdr_buf_); - exit(EXIT_FAILURE); + "'ib_logfile0'.\n"); + goto fail; } /* label it */ - strcpy((char*) log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, - "xtrabkup "); - ut_sprintf_timestamp( - (char*) log_hdr_buf + (LOG_FILE_WAS_CREATED_BY_HOT_BACKUP - + (sizeof "xtrabkup ") - 1)); - - if (ds_write(dst_log_file, log_hdr_buf, LOG_FILE_HDR_SIZE)) { + byte MY_ALIGNED(OS_FILE_LOG_BLOCK_SIZE) log_hdr[OS_FILE_LOG_BLOCK_SIZE]; + memset(log_hdr, 0, sizeof log_hdr); + mach_write_to_4(LOG_HEADER_FORMAT + log_hdr, log_sys->log.format); + mach_write_to_8(LOG_HEADER_START_LSN + log_hdr, checkpoint_lsn_start); + strcpy(reinterpret_cast<char*>(LOG_HEADER_CREATOR + log_hdr), + "Backup " MYSQL_SERVER_VERSION); + log_block_set_checksum(log_hdr, + log_block_calc_checksum_crc32(log_hdr)); + + /* Write the log header. */ + if (ds_write(dst_log_file, log_hdr, sizeof log_hdr)) { + log_write_fail: msg("mariabackup: error: write to logfile failed\n"); - ut_free(log_hdr_buf_); - exit(EXIT_FAILURE); + goto fail; + } + /* Adjust the checkpoint page. */ + memcpy(log_hdr, buf, OS_FILE_LOG_BLOCK_SIZE); + mach_write_to_8(log_hdr + LOG_CHECKPOINT_OFFSET, + (checkpoint_lsn_start & (OS_FILE_LOG_BLOCK_SIZE - 1)) + | LOG_FILE_HDR_SIZE); + log_block_set_checksum(log_hdr, + log_block_calc_checksum_crc32(log_hdr)); + /* Write checkpoint page 1 and two empty log pages before the + payload. */ + if (ds_write(dst_log_file, log_hdr, OS_FILE_LOG_BLOCK_SIZE) + || !memset(log_hdr, 0, sizeof log_hdr) + || ds_write(dst_log_file, log_hdr, sizeof log_hdr) + || ds_write(dst_log_file, log_hdr, sizeof log_hdr)) { + goto log_write_fail; } - ut_free(log_hdr_buf_); - /* start flag */ log_copying = TRUE; @@ -4116,35 +3975,33 @@ reread_log_header: os_thread_id_t io_watching_thread_id; io_ticket = xtrabackup_throttle; - wait_throttle = os_event_create(); + wait_throttle = os_event_create(0); + io_watching_thread_running = true; os_thread_create(io_watching_thread, NULL, &io_watching_thread_id); } - mutex_enter(&log_sys->mutex); - xtrabackup_choose_lsn_offset(checkpoint_lsn_start); - mutex_exit(&log_sys->mutex); - - /* copy log file by current position */ - if(xtrabackup_copy_logfile(checkpoint_lsn_start, FALSE)) - exit(EXIT_FAILURE); - - - log_copying_stop = os_event_create(); - os_thread_create(log_copying_thread, NULL, &log_copying_thread_id); - /* Populate fil_system with tablespaces to copy */ err = xb_load_tablespaces(); if (err != DB_SUCCESS) { msg("mariabackup: error: xb_load_tablespaces() failed with" - "error code %lu\n", err); - exit(EXIT_FAILURE); + " error %s.\n", ut_strerr(err)); + goto fail; } + /* copy log file by current position */ + log_copy_scanned_lsn = checkpoint_lsn_start; + if (xtrabackup_copy_logfile(COPY_FIRST)) + goto fail; + + log_copying_stop = os_event_create(0); + log_copying_running = true; + os_thread_create(log_copying_thread, NULL, &log_copying_thread_id); + /* FLUSH CHANGED_PAGE_BITMAPS call */ if (!flush_changed_page_bitmaps()) { - exit(EXIT_FAILURE); + goto fail; } debug_sync_point("xtrabackup_suspend_at_start"); @@ -4169,17 +4026,21 @@ reread_log_header: "files transfer\n", xtrabackup_parallel); } - it = datafiles_iter_new(f_system); + if (opt_lock_ddl_per_table) { + mdl_lock_all(); + } + + it = datafiles_iter_new(fil_system); if (it == NULL) { msg("mariabackup: Error: datafiles_iter_new() failed.\n"); - exit(EXIT_FAILURE); + goto fail; } /* Create data copying threads */ data_threads = (data_thread_ctxt_t *) - ut_malloc(sizeof(data_thread_ctxt_t) * xtrabackup_parallel); + malloc(sizeof(data_thread_ctxt_t) * xtrabackup_parallel); count = xtrabackup_parallel; - count_mutex = os_mutex_create(); + pthread_mutex_init(&count_mutex, NULL); for (i = 0; i < (uint) xtrabackup_parallel; i++) { data_threads[i].it = it; @@ -4193,16 +4054,16 @@ reread_log_header: /* Wait for threads to exit */ while (1) { os_thread_sleep(1000000); - os_mutex_enter(count_mutex); - if (count == 0) { - os_mutex_exit(count_mutex); + pthread_mutex_lock(&count_mutex); + bool stop = count == 0; + pthread_mutex_unlock(&count_mutex); + if (stop) { break; } - os_mutex_exit(count_mutex); } - os_mutex_free(count_mutex); - ut_free(data_threads); + pthread_mutex_destroy(&count_mutex); + free(data_threads); datafiles_iter_free(it); if (changed_page_bitmap) { @@ -4210,394 +4071,48 @@ reread_log_header: } } - if (!backup_start()) { - exit(EXIT_FAILURE); - } - - /* read the latest checkpoint lsn */ - latest_cp = 0; - { - log_group_t* max_cp_group; - ulint max_cp_field; - ulint err; + bool ok = backup_start(); - mutex_enter(&log_sys->mutex); + if (ok) { + ok = xtrabackup_backup_low(); - err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field); + backup_release(); - if (err != DB_SUCCESS) { - msg("mariabackup: Error: recv_find_max_checkpoint() failed.\n"); - mutex_exit(&log_sys->mutex); - goto skip_last_cp; + if (ok) { + backup_finish(); } - - log_group_read_checkpoint_info(max_cp_group, max_cp_field); - - xtrabackup_choose_lsn_offset(checkpoint_lsn_start); - - latest_cp = mach_read_from_8(log_sys->checkpoint_buf + - LOG_CHECKPOINT_LSN); - - mutex_exit(&log_sys->mutex); - - msg("mariabackup: The latest check point (for incremental): " - "'" LSN_PF "'\n", latest_cp); - } -skip_last_cp: - /* stop log_copying_thread */ - log_copying = FALSE; - os_event_set(log_copying_stop); - msg("mariabackup: Stopping log copying thread.\n"); - while (log_copying_running) { - msg("."); - os_thread_sleep(200000); /*0.2 sec*/ } - msg("\n"); - os_event_free(log_copying_stop); - if (ds_close(dst_log_file)) { - exit(EXIT_FAILURE); + if (!ok) { + goto fail; } - if(!xtrabackup_incremental) { - strcpy(metadata_type, "full-backuped"); - metadata_from_lsn = 0; - } else { - strcpy(metadata_type, "incremental"); - metadata_from_lsn = incremental_lsn; - } - metadata_to_lsn = latest_cp; - metadata_last_lsn = log_copy_scanned_lsn; - - if (!xtrabackup_stream_metadata(ds_meta)) { - msg("mariabackup: Error: failed to stream metadata.\n"); - exit(EXIT_FAILURE); - } - if (xtrabackup_extra_lsndir) { - char filename[FN_REFLEN]; - - sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, - XTRABACKUP_METADATA_FILENAME); - if (!xtrabackup_write_metadata(filename)) { - msg("mariabackup: Error: failed to write metadata " - "to '%s'.\n", filename); - exit(EXIT_FAILURE); - } - - } - - if (!backup_finish()) { - exit(EXIT_FAILURE); + if (opt_lock_ddl_per_table) { + mdl_unlock_all(); } xtrabackup_destroy_datasinks(); - if (wait_throttle) { - /* wait for io_watching_thread completion */ - while (io_watching_thread_running) { - os_thread_sleep(1000000); - } - os_event_free(wait_throttle); - wait_throttle = NULL; - } - - msg("mariabackup: Transaction log of lsn (" LSN_PF ") to (" LSN_PF + msg("mariabackup: Redo log (from LSN " LSN_PF " to " LSN_PF ") was copied.\n", checkpoint_lsn_start, log_copy_scanned_lsn); xb_filters_free(); xb_data_files_close(); - /* Make sure that the latest checkpoint made it to xtrabackup_logfile */ - if (latest_cp > log_copy_scanned_lsn) { - msg("mariabackup: error: last checkpoint LSN (" LSN_PF - ") is larger than last copied LSN (" LSN_PF ").\n", - latest_cp, log_copy_scanned_lsn); - exit(EXIT_FAILURE); + /* Make sure that the latest checkpoint was included */ + if (metadata_to_lsn > log_copy_scanned_lsn) { + msg("mariabackup: error: failed to copy enough redo log (" + "LSN=" LSN_PF "; checkpoint LSN=" LSN_PF ").\n", + log_copy_scanned_lsn, metadata_to_lsn); + goto fail; } + + innodb_shutdown(); + return(true); } /* ================= prepare ================= */ -static my_bool -xtrabackup_init_temp_log(void) -{ - pfs_os_file_t src_file; - char src_path[FN_REFLEN]; - char dst_path[FN_REFLEN]; - ibool success; - - ulint field; - byte* log_buf= (byte *)malloc(UNIV_PAGE_SIZE_MAX * 128); /* 2 MB */ - - ib_int64_t file_size; - - lsn_t max_no = 0; - lsn_t max_lsn = 0; - - ulint fold; - - if (!log_buf) { - goto error; - } - - if (!xb_init_log_block_size()) { - goto error; - } - - if(!xtrabackup_incremental_dir) { - sprintf(dst_path, "%s/ib_logfile0", xtrabackup_target_dir); - sprintf(src_path, "%s/%s", xtrabackup_target_dir, - XB_LOG_FILENAME); - } else { - sprintf(dst_path, "%s/ib_logfile0", xtrabackup_incremental_dir); - sprintf(src_path, "%s/%s", xtrabackup_incremental_dir, - XB_LOG_FILENAME); - } - - srv_normalize_path_for_win(dst_path); - srv_normalize_path_for_win(src_path); -retry: - src_file = os_file_create_simple_no_error_handling(0, src_path, - OS_FILE_OPEN, - OS_FILE_READ_WRITE, - &success,0); - if (!success) { - /* The following call prints an error message */ - os_file_get_last_error(TRUE); - - msg("mariabackup: Warning: cannot open %s. will try to find.\n", - src_path); - - /* check if ib_logfile0 may be xtrabackup_logfile */ - src_file = os_file_create_simple_no_error_handling(0, dst_path, - OS_FILE_OPEN, - OS_FILE_READ_WRITE, - &success,0); - if (!success) { - os_file_get_last_error(TRUE); - msg("mariabackup: Fatal error: cannot find %s.\n", - src_path); - - goto error; - } - - success = os_file_read(src_file, log_buf, 0, - LOG_FILE_HDR_SIZE); - if (!success) { - goto error; - } - - if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, - (byte*)"xtrabkup", (sizeof "xtrabkup") - 1) == 0) { - msg("mariabackup: 'ib_logfile0' seems to be " - "'xtrabackup_logfile'. will retry.\n"); - - os_file_close(src_file); - src_file = XB_FILE_UNDEFINED; - - /* rename and try again */ - success = os_file_rename(0, dst_path, src_path); - if (!success) { - goto error; - } - - goto retry; - } - - msg("mariabackup: Fatal error: cannot find %s.\n", src_path); - - os_file_close(src_file); - src_file = XB_FILE_UNDEFINED; - - goto error; - } - - file_size = os_file_get_size(src_file); - - - /* TODO: We should skip the following modifies, if it is not the first time. */ - - /* read log file header */ - success = os_file_read(src_file, log_buf, 0, LOG_FILE_HDR_SIZE); - if (!success) { - goto error; - } - - if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, - (byte*)"xtrabkup", (sizeof "xtrabkup") - 1) != 0 ) { - msg("mariabackup: notice: xtrabackup_logfile was already used " - "to '--prepare'.\n"); - goto skip_modify; - } else { - /* clear it later */ - //memset(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, - // ' ', 4); - } - - /* read last checkpoint lsn */ - for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2; - field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) { - if (!recv_check_cp_is_consistent(const_cast<const byte *> - (log_buf + field))) - continue; - - lsn_t checkpoint_no = mach_read_from_8(log_buf + field + - LOG_CHECKPOINT_NO); - - if (checkpoint_no >= max_no) { - - max_no = checkpoint_no; - max_lsn = mach_read_from_8(log_buf + field + - LOG_CHECKPOINT_LSN); - } - } - - if (!max_lsn) { - msg("mariabackup: No valid checkpoint found.\n"); - goto error; - } - - /* It seems to be needed to overwrite the both checkpoint area. */ - mach_write_to_8(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN, - max_lsn); - mach_write_to_4(log_buf + LOG_CHECKPOINT_1 - + LOG_CHECKPOINT_OFFSET_LOW32, - LOG_FILE_HDR_SIZE + - (ulint)(max_lsn - - ut_uint64_align_down(max_lsn, - OS_FILE_LOG_BLOCK_SIZE))); - mach_write_to_4(log_buf + LOG_CHECKPOINT_1 - + LOG_CHECKPOINT_OFFSET_HIGH32, 0); - fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_1, LOG_CHECKPOINT_CHECKSUM_1); - mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_CHECKSUM_1, fold); - - fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN, - LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN); - mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_CHECKSUM_2, fold); - - mach_write_to_8(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_LSN, - max_lsn); - mach_write_to_4(log_buf + LOG_CHECKPOINT_2 - + LOG_CHECKPOINT_OFFSET_LOW32, - LOG_FILE_HDR_SIZE + - (ulint)(max_lsn - - ut_uint64_align_down(max_lsn, - OS_FILE_LOG_BLOCK_SIZE))); - mach_write_to_4(log_buf + LOG_CHECKPOINT_2 - + LOG_CHECKPOINT_OFFSET_HIGH32, 0); - fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_2, LOG_CHECKPOINT_CHECKSUM_1); - mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_CHECKSUM_1, fold); - - fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_LSN, - LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN); - mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_CHECKSUM_2, fold); - - - success = os_file_write(src_path, src_file, log_buf, 0, - LOG_FILE_HDR_SIZE); - if (!success) { - goto error; - } - - /* expand file size (9/8) and align to UNIV_PAGE_SIZE_MAX */ - - if (file_size % UNIV_PAGE_SIZE_MAX) { - memset(log_buf, 0, UNIV_PAGE_SIZE_MAX); - success = os_file_write(src_path, src_file, log_buf, - file_size, - UNIV_PAGE_SIZE_MAX - - (ulint) (file_size - % UNIV_PAGE_SIZE_MAX)); - if (!success) { - goto error; - } - - file_size = os_file_get_size(src_file); - } - - /* TODO: We should judge whether the file is already expanded or not... */ - { - ulint expand; - - memset(log_buf, 0, UNIV_PAGE_SIZE_MAX * 128); - expand = (ulint) (file_size / UNIV_PAGE_SIZE_MAX / 8); - - for (; expand > 128; expand -= 128) { - success = os_file_write(src_path, src_file, log_buf, - file_size, - UNIV_PAGE_SIZE_MAX * 128); - if (!success) { - goto error; - } - file_size += UNIV_PAGE_SIZE_MAX * 128; - } - - if (expand) { - success = os_file_write(src_path, src_file, log_buf, - file_size, - expand * UNIV_PAGE_SIZE_MAX); - if (!success) { - goto error; - } - file_size += UNIV_PAGE_SIZE_MAX * expand; - } - } - - /* make larger than 2MB */ - if (file_size < 2*1024*1024L) { - memset(log_buf, 0, UNIV_PAGE_SIZE_MAX); - while (file_size < 2*1024*1024L) { - success = os_file_write(src_path, src_file, log_buf, - file_size, - UNIV_PAGE_SIZE_MAX); - if (!success) { - goto error; - } - file_size += UNIV_PAGE_SIZE_MAX; - } - file_size = os_file_get_size(src_file); - } - - msg("mariabackup: xtrabackup_logfile detected: size=" INT64PF ", " - "start_lsn=(" LSN_PF ")\n", file_size, max_lsn); - - os_file_close(src_file); - src_file = XB_FILE_UNDEFINED; - - /* fake InnoDB */ - innobase_log_files_in_group_save = innobase_log_files_in_group; - srv_log_group_home_dir_save = srv_log_group_home_dir; - innobase_log_file_size_save = innobase_log_file_size; - - srv_log_group_home_dir = NULL; - innobase_log_file_size = file_size; - innobase_log_files_in_group = 1; - - srv_thread_concurrency = 0; - - /* rename 'xtrabackup_logfile' to 'ib_logfile0' */ - success = os_file_rename(0, src_path, dst_path); - if (!success) { - goto error; - } - xtrabackup_logfile_is_renamed = TRUE; - free(log_buf); - return(FALSE); - -skip_modify: - free(log_buf); - os_file_close(src_file); - src_file = XB_FILE_UNDEFINED; - return(FALSE); - -error: - free(log_buf); - if (src_file != XB_FILE_UNDEFINED) - os_file_close(src_file); - msg("mariabackup: Error: xtrabackup_init_temp_log() failed.\n"); - return(TRUE); /*ERROR*/ -} - /*********************************************************************** Generates path to the meta file path from a given path to an incremental .delta by replacing trailing ".delta" with ".meta", or returns error if 'delta_path' @@ -4627,24 +4142,22 @@ file. Code adopted from fil_create_new_single_table_tablespace with the main difference that only disk file is created without updating the InnoDB in-memory dictionary data structures. -@return TRUE on success, FALSE on error. */ +@return true on success, false on error. */ static -ibool +bool xb_space_create_file( /*==================*/ const char* path, /*!<in: path to tablespace */ ulint space_id, /*!<in: space id */ - ulint flags __attribute__((unused)),/*!<in: tablespace - flags */ + ulint flags, /*!<in: tablespace flags */ pfs_os_file_t* file) /*!<out: file handle */ { - ibool ret; + bool ret; byte* buf; byte* page; - *file = os_file_create_simple_no_error_handling(0, path, OS_FILE_CREATE, - OS_FILE_READ_WRITE, - &ret,0); + *file = os_file_create_simple_no_error_handling( + 0, path, OS_FILE_CREATE, OS_FILE_READ_WRITE, false, &ret); if (!ret) { msg("mariabackup: cannot create file %s\n", path); return ret; @@ -4659,7 +4172,7 @@ xb_space_create_file( return ret; } - buf = static_cast<byte *>(ut_malloc(3 * UNIV_PAGE_SIZE)); + buf = static_cast<byte *>(malloc(3 * UNIV_PAGE_SIZE)); /* Align the memory for file i/o if we might have O_DIRECT set */ page = static_cast<byte *>(ut_align(buf, UNIV_PAGE_SIZE)); @@ -4668,19 +4181,19 @@ xb_space_create_file( fsp_header_init_fields(page, space_id, flags); mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id); - if (!fsp_flags_is_compressed(flags)) { - buf_flush_init_for_writing(page, NULL, 0); + const page_size_t page_size(flags); - ret = os_file_write(path, *file, page, 0, UNIV_PAGE_SIZE); - } - else { - page_zip_des_t page_zip; - ulint zip_size; + if (!page_size.is_compressed()) { + buf_flush_init_for_writing(NULL, page, NULL, 0); - zip_size = fsp_flags_get_zip_size(flags); + ret = os_file_write(IORequestWrite, path, *file, page, 0, + UNIV_PAGE_SIZE); + } else { + page_zip_des_t page_zip; + ulint zip_size = page_size.physical(); page_zip_set_size(&page_zip, zip_size); page_zip.data = page + UNIV_PAGE_SIZE; - fprintf(stderr, "zip_size = %lu\n", zip_size); + fprintf(stderr, "zip_size = " ULINTPF "\n", zip_size); #ifdef UNIV_DEBUG page_zip.m_start = @@ -4688,13 +4201,13 @@ xb_space_create_file( page_zip.m_end = page_zip.m_nonempty = page_zip.n_blobs = 0; - buf_flush_init_for_writing(page, &page_zip, 0); + buf_flush_init_for_writing(NULL, page, &page_zip, 0); - ret = os_file_write(path, *file, page_zip.data, 0, - zip_size); + ret = os_file_write(IORequestWrite, path, *file, + page_zip.data, 0, zip_size); } - ut_free(buf); + free(buf); if (!ret) { msg("mariabackup: could not write the first page to %s\n", @@ -4719,35 +4232,32 @@ pfs_os_file_t xb_delta_open_matching_space( const char* dbname, /* in: path to destination database dir */ const char* name, /* in: name of delta file (without .delta) */ - ulint space_id, /* in: space id of delta file */ - ulint zip_size, /* in: zip_size of tablespace */ + const xb_delta_info_t& info, char* real_name, /* out: full path of destination file */ size_t real_name_len, /* out: buffer size for real_name */ - ibool* success) /* out: indicates error. TRUE = success */ + bool* success) /* out: indicates error. true = success */ { char dest_dir[FN_REFLEN]; char dest_space_name[FN_REFLEN]; - ibool ok; fil_space_t* fil_space; pfs_os_file_t file; - ulint tablespace_flags; xb_filter_entry_t* table; ut_a(dbname != NULL || - !fil_is_user_tablespace_id(space_id) || - space_id == ULINT_UNDEFINED); + !fil_is_user_tablespace_id(info.space_id) || + info.space_id == ULINT_UNDEFINED); - *success = FALSE; + *success = false; if (dbname) { snprintf(dest_dir, FN_REFLEN, "%s/%s", xtrabackup_target_dir, dbname); - srv_normalize_path_for_win(dest_dir); + os_normalize_path(dest_dir); snprintf(dest_space_name, FN_REFLEN, "%s/%s", dbname, name); } else { snprintf(dest_dir, FN_REFLEN, "%s", xtrabackup_target_dir); - srv_normalize_path_for_win(dest_dir); + os_normalize_path(dest_dir); snprintf(dest_space_name, FN_REFLEN, "%s", name); } @@ -4755,7 +4265,7 @@ xb_delta_open_matching_space( snprintf(real_name, real_name_len, "%s/%s", xtrabackup_target_dir, dest_space_name); - srv_normalize_path_for_win(real_name); + os_normalize_path(real_name); /* Truncate ".ibd" */ dest_space_name[strlen(dest_space_name) - 4] = '\0'; @@ -4765,13 +4275,26 @@ xb_delta_open_matching_space( return file; } - if (!fil_is_user_tablespace_id(space_id)) { - goto found; + log_mutex_enter(); + if (!fil_is_user_tablespace_id(info.space_id)) { +found: + /* open the file and return its handle */ + + file = os_file_create_simple_no_error_handling( + 0, real_name, + OS_FILE_OPEN, OS_FILE_READ_WRITE, false, success); + + if (!*success) { + msg("mariabackup: Cannot open file %s\n", real_name); + } +exit: + log_mutex_exit(); + return file; } /* remember space name for further reference */ table = static_cast<xb_filter_entry_t *> - (ut_malloc(sizeof(xb_filter_entry_t) + + (malloc(sizeof(xb_filter_entry_t) + strlen(dest_space_name) + 1)); table->name = ((char*)table) + sizeof(xb_filter_entry_t); @@ -4784,21 +4307,24 @@ xb_delta_open_matching_space( mutex_exit(&fil_system->mutex); if (fil_space != NULL) { - if (fil_space->id == space_id || space_id == ULINT_UNDEFINED) { + if (fil_space->id == info.space_id + || info.space_id == ULINT_UNDEFINED) { /* we found matching space */ goto found; } else { char tmpname[FN_REFLEN]; - snprintf(tmpname, FN_REFLEN, "%s/xtrabackup_tmp_#%lu", + snprintf(tmpname, FN_REFLEN, "%s/xtrabackup_tmp_#" ULINTPF, dbname, fil_space->id); msg("mariabackup: Renaming %s to %s.ibd\n", fil_space->name, tmpname); - if (!fil_rename_tablespace(NULL, fil_space->id, - tmpname, NULL)) + if (!fil_rename_tablespace( + fil_space->id, + fil_space->chain.start->name, + tmpname, NULL)) { msg("mariabackup: Cannot rename %s to %s\n", fil_space->name, tmpname); @@ -4807,14 +4333,14 @@ xb_delta_open_matching_space( } } - if (space_id == ULINT_UNDEFINED) + if (info.space_id == ULINT_UNDEFINED) { msg("mariabackup: Error: Cannot handle DDL operation on tablespace " "%s\n", dest_space_name); exit(EXIT_FAILURE); } mutex_enter(&fil_system->mutex); - fil_space = fil_space_get_by_id(space_id); + fil_space = fil_space_get_by_id(info.space_id); mutex_exit(&fil_system->mutex); if (fil_space != NULL) { char tmpname[FN_REFLEN]; @@ -4824,7 +4350,9 @@ xb_delta_open_matching_space( msg("mariabackup: Renaming %s to %s\n", fil_space->name, dest_space_name); - if (!fil_rename_tablespace(NULL, fil_space->id, tmpname, + if (!fil_rename_tablespace(fil_space->id, + fil_space->chain.start->name, + tmpname, NULL)) { msg("mariabackup: Cannot rename %s to %s\n", @@ -4836,49 +4364,30 @@ xb_delta_open_matching_space( } /* No matching space found. create the new one. */ - - if (!fil_space_create(dest_space_name, space_id, 0, - FIL_TABLESPACE, 0, false)) { + const ulint flags = info.page_size.is_compressed() + ? get_bit_shift(info.page_size.physical() + >> (UNIV_ZIP_SIZE_SHIFT_MIN - 1)) + << FSP_FLAGS_POS_ZIP_SSIZE + | FSP_FLAGS_MASK_POST_ANTELOPE + | FSP_FLAGS_MASK_ATOMIC_BLOBS + | (info.page_size.logical() == UNIV_PAGE_SIZE_ORIG + ? 0 + : get_bit_shift(info.page_size.logical() + >> (UNIV_ZIP_SIZE_SHIFT_MIN - 1)) + << FSP_FLAGS_POS_PAGE_SSIZE) + : FSP_FLAGS_PAGE_SSIZE(); + ut_ad(page_size_t(flags).equals_to(info.page_size)); + + if (fil_space_create(dest_space_name, info.space_id, flags, + FIL_TYPE_TABLESPACE, 0)) { + *success = xb_space_create_file(real_name, info.space_id, + flags, &file); + } else { msg("mariabackup: Cannot create tablespace %s\n", - dest_space_name); - goto exit; + dest_space_name); } - /* Calculate correct tablespace flags for compressed tablespaces. */ - if (!zip_size || zip_size == ULINT_UNDEFINED) { - tablespace_flags = 0; - } - else { - tablespace_flags - = (get_bit_shift(zip_size >> PAGE_ZIP_MIN_SIZE_SHIFT - << 1) - << DICT_TF_ZSSIZE_SHIFT) - | DICT_TF_COMPACT - | (DICT_TF_FORMAT_ZIP << DICT_TF_FORMAT_SHIFT); - ut_a(dict_tf_get_zip_size(tablespace_flags) - == zip_size); - } - *success = xb_space_create_file(real_name, space_id, tablespace_flags, - &file); goto exit; - -found: - /* open the file and return it's handle */ - - file = os_file_create_simple_no_error_handling(0, real_name, - OS_FILE_OPEN, - OS_FILE_READ_WRITE, - &ok,0); - - if (ok) { - *success = TRUE; - } else { - msg("mariabackup: Cannot open file %s\n", real_name); - } - -exit: - - return file; } /************************************************************************ @@ -4899,13 +4408,13 @@ xtrabackup_apply_delta( char dst_path[FN_REFLEN]; char meta_path[FN_REFLEN]; char space_name[FN_REFLEN]; - ibool success; + bool success; ibool last_buffer = FALSE; ulint page_in_buffer; ulint incremental_buffers = 0; - xb_delta_info_t info; + xb_delta_info_t info(univ_page_size, SRV_TMP_SPACE_ID); ulint page_size; ulint page_size_shift; byte* incremental_buffer_base = NULL; @@ -4935,29 +4444,28 @@ xtrabackup_apply_delta( goto error; } - srv_normalize_path_for_win(dst_path); - srv_normalize_path_for_win(src_path); - srv_normalize_path_for_win(meta_path); + os_normalize_path(dst_path); + os_normalize_path(src_path); + os_normalize_path(meta_path); if (!xb_read_delta_metadata(meta_path, &info)) { goto error; } - page_size = info.page_size; + page_size = info.page_size.physical(); page_size_shift = get_bit_shift(page_size); - msg("mariabackup: page size for %s is %lu bytes\n", + msg("mariabackup: page size for %s is %zu bytes\n", src_path, page_size); if (page_size_shift < 10 || page_size_shift > UNIV_PAGE_SIZE_SHIFT_MAX) { msg("mariabackup: error: invalid value of page_size " - "(%lu bytes) read from %s\n", page_size, meta_path); + "(%zu bytes) read from %s\n", page_size, meta_path); goto error; } - src_file = os_file_create_simple_no_error_handling(0, src_path, - OS_FILE_OPEN, - OS_FILE_READ_WRITE, - &success,0); + src_file = os_file_create_simple_no_error_handling( + 0, src_path, + OS_FILE_OPEN, OS_FILE_READ_WRITE, false, &success); if (!success) { os_file_get_last_error(TRUE); msg("mariabackup: error: cannot open %s\n", src_path); @@ -4969,7 +4477,7 @@ xtrabackup_apply_delta( os_file_set_nocache(src_file, src_path, "OPEN"); dst_file = xb_delta_open_matching_space( - dbname, space_name, info.space_id, info.zip_size, + dbname, space_name, info, dst_path, sizeof(dst_path), &success); if (!success) { msg("mariabackup: error: cannot open %s\n", dst_path); @@ -4982,8 +4490,7 @@ xtrabackup_apply_delta( /* allocate buffer for incremental backup (4096 pages) */ incremental_buffer_base = static_cast<byte *> - (ut_malloc((page_size / 4 + 1) * - page_size)); + (malloc((page_size / 4 + 1) * page_size)); incremental_buffer = static_cast<byte *> (ut_align(incremental_buffer_base, page_size)); @@ -4997,8 +4504,8 @@ xtrabackup_apply_delta( /* first block of block cluster */ offset = ((incremental_buffers * (page_size / 4)) << page_size_shift); - success = os_file_read(src_file, incremental_buffer, - offset, page_size); + success = os_file_read(IORequestRead, src_file, + incremental_buffer, offset, page_size); if (!success) { goto error; } @@ -5016,6 +4523,9 @@ xtrabackup_apply_delta( goto error; } + /* FIXME: If the .delta modifies FSP_SIZE on page 0, + extend the file to that size. */ + for (page_in_buffer = 1; page_in_buffer < page_size / 4; page_in_buffer++) { if (mach_read_from_4(incremental_buffer + page_in_buffer * 4) @@ -5026,8 +4536,9 @@ xtrabackup_apply_delta( ut_a(last_buffer || page_in_buffer == page_size / 4); /* read whole of the cluster */ - success = os_file_read(src_file, incremental_buffer, - offset, page_in_buffer * page_size); + success = os_file_read(IORequestRead, src_file, + incremental_buffer, + offset, page_in_buffer * page_size); if (!success) { goto error; } @@ -5049,31 +4560,34 @@ xtrabackup_apply_delta( if (off == 0) { /* Read tablespace size from page 0, - extend the tablespace to specified size. */ - os_offset_t n_pages = mach_read_from_4(buf + FSP_HEADER_OFFSET + FSP_SIZE); - ulint space_id = mach_read_from_4(buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); - if (space_id != TRX_SYS_SPACE) { - if (!os_file_set_size(dst_path, dst_file, n_pages*page_size)) + and extend the file to specified size.*/ + os_offset_t n_pages = mach_read_from_4( + buf + FSP_HEADER_OFFSET + FSP_SIZE); + if (mach_read_from_4(buf + + FIL_PAGE_SPACE_ID)) { + if (!os_file_set_size( + dst_path, dst_file, + n_pages * page_size)) goto error; - } else { - /* System tablespace needs special handling , since - it can consist of multiple files. The first one has full - tablespace size in page 0, but only last file should be extended. */ - mutex_enter(&fil_system->mutex); - fil_space_t* space = fil_space_get_by_id(space_id); - mutex_exit(&fil_system->mutex); - DBUG_ASSERT(space); - fil_node_t* n = UT_LIST_GET_FIRST(space->chain); - if(strcmp(n->name, dst_path) == 0) { - /* Got first tablespace file, with correct size */ - ulint actual_size; - if (!fil_extend_space_to_desired_size(&actual_size, 0, (ulint)n_pages)) - goto error; - } + } else if (fil_space_t* space + = fil_space_acquire(0)) { + /* The system tablespace can + consist of multiple files. The + first one has full tablespace + size in page 0, but only the last + file should be extended. */ + fil_node_t* n = UT_LIST_GET_FIRST( + space->chain); + bool fail = !strcmp(n->name, dst_path) + && !fil_space_extend( + space, (ulint)n_pages); + fil_space_release(space); + if (fail) goto error; } } - success = os_file_write(dst_path, dst_file, buf, off, page_size); + success = os_file_write(IORequestWrite, + dst_path, dst_file, buf, off, page_size); if (!success) { goto error; } @@ -5082,23 +4596,20 @@ xtrabackup_apply_delta( incremental_buffers++; } - if (incremental_buffer_base) - ut_free(incremental_buffer_base); - if (src_file != XB_FILE_UNDEFINED) { + free(incremental_buffer_base); + if (src_file != OS_FILE_CLOSED) { os_file_close(src_file); - /* Remove .delta file after it was successfully applied.*/ os_file_delete(0,src_path); } - if (dst_file != XB_FILE_UNDEFINED) + if (dst_file != OS_FILE_CLOSED) os_file_close(dst_file); return TRUE; error: - if (incremental_buffer_base) - ut_free(incremental_buffer_base); - if (src_file != XB_FILE_UNDEFINED) + free(incremental_buffer_base); + if (src_file != OS_FILE_CLOSED) os_file_close(src_file); - if (dst_file != XB_FILE_UNDEFINED) + if (dst_file != OS_FILE_CLOSED) os_file_close(dst_file); msg("mariabackup: Error: xtrabackup_apply_delta(): " "failed to apply %s to %s.\n", src_path, dst_path); @@ -5159,9 +4670,7 @@ xb_process_datadir( const char* path, /*!<in: datadir path */ const char* suffix, /*!<in: suffix to match against */ - handle_datadir_entry_func_t func, /*!<in: callback */ - void* data) /*!<in: additional argument for - callback */ + handle_datadir_entry_func_t func) /*!<in: callback */ { ulint ret; char dbpath[OS_FILE_MAX_PATH]; @@ -5196,7 +4705,7 @@ xb_process_datadir( suffix)) { if (!func( path, NULL, - fileinfo.name, data)) + fileinfo.name, NULL)) { return(FALSE); } @@ -5231,7 +4740,8 @@ next_file_item_1: } snprintf(dbpath, sizeof(dbpath), "%s/%s", path, dbinfo.name); - srv_normalize_path_for_win(dbpath); + + os_normalize_path(dbpath); dbdir = os_file_opendir(dbpath, FALSE); @@ -5256,7 +4766,7 @@ next_file_item_1: if (!func( path, dbinfo.name, - fileinfo.name, data)) + fileinfo.name, NULL)) { return(FALSE); } @@ -5288,476 +4798,45 @@ ibool xtrabackup_apply_deltas() { return xb_process_datadir(xtrabackup_incremental_dir, ".delta", - xtrabackup_apply_delta, NULL); -} - -static my_bool -xtrabackup_close_temp_log(my_bool clear_flag) -{ - pfs_os_file_t src_file; - char src_path[FN_REFLEN]; - char dst_path[FN_REFLEN]; - ibool success; - byte log_buf[UNIV_PAGE_SIZE_MAX]; - - if (!xtrabackup_logfile_is_renamed) - return(FALSE); - - /* rename 'ib_logfile0' to 'xtrabackup_logfile' */ - if(!xtrabackup_incremental_dir) { - sprintf(dst_path, "%s/ib_logfile0", xtrabackup_target_dir); - sprintf(src_path, "%s/%s", xtrabackup_target_dir, - XB_LOG_FILENAME); - } else { - sprintf(dst_path, "%s/ib_logfile0", xtrabackup_incremental_dir); - sprintf(src_path, "%s/%s", xtrabackup_incremental_dir, - XB_LOG_FILENAME); - } - - srv_normalize_path_for_win(dst_path); - srv_normalize_path_for_win(src_path); - - success = os_file_rename(0, dst_path, src_path); - if (!success) { - goto error; - } - xtrabackup_logfile_is_renamed = FALSE; - - if (!clear_flag) - return(FALSE); - - /* clear LOG_FILE_WAS_CREATED_BY_HOT_BACKUP field */ - src_file = os_file_create_simple_no_error_handling(0, src_path, - OS_FILE_OPEN, - OS_FILE_READ_WRITE, - &success,0); - if (!success) { - goto error; - } - - success = os_file_read(src_file, log_buf, 0, LOG_FILE_HDR_SIZE); - if (!success) { - goto error; - } - - memset(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, ' ', 4); - - success = os_file_write(src_path, src_file, log_buf, 0, - LOG_FILE_HDR_SIZE); - if (!success) { - goto error; - } - - os_file_close(src_file); - src_file = XB_FILE_UNDEFINED; - - innobase_log_files_in_group = innobase_log_files_in_group_save; - srv_log_group_home_dir = srv_log_group_home_dir_save; - innobase_log_file_size = innobase_log_file_size_save; - - return(FALSE); -error: - if (src_file != XB_FILE_UNDEFINED) - os_file_close(src_file); - msg("mariabackup: Error: xtrabackup_close_temp_log() failed.\n"); - return(TRUE); /*ERROR*/ + xtrabackup_apply_delta); } -/*********************************************************************//** -Write the meta data (index user fields) config file. -@return true in case of success otherwise false. */ -static -bool -xb_export_cfg_write_index_fields( -/*===========================*/ - const dict_index_t* index, /*!< in: write the meta data for - this index */ - FILE* file) /*!< in: file to write to */ -{ - byte row[sizeof(ib_uint32_t) * 2]; - - for (ulint i = 0; i < index->n_fields; ++i) { - byte* ptr = row; - const dict_field_t* field = &index->fields[i]; - - mach_write_to_4(ptr, field->prefix_len); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, field->fixed_len); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - - msg("mariabackup: Error: writing index fields."); - - return(false); - } - - /* Include the NUL byte in the length. */ - ib_uint32_t len = (ib_uint32_t)strlen(field->name) + 1; - ut_a(len > 1); - - mach_write_to_4(row, len); - - if (fwrite(row, 1, sizeof(len), file) != sizeof(len) - || fwrite(field->name, 1, len, file) != len) { - - msg("mariabackup: Error: writing index column."); - - return(false); - } - } - - return(true); -} - -/*********************************************************************//** -Write the meta data config file index information. -@return true in case of success otherwise false. */ -static __attribute__((nonnull, warn_unused_result)) -bool -xb_export_cfg_write_indexes( -/*======================*/ - const dict_table_t* table, /*!< in: write the meta data for - this table */ - FILE* file) /*!< in: file to write to */ -{ - { - byte row[sizeof(ib_uint32_t)]; - - /* Write the number of indexes in the table. */ - mach_write_to_4(row, UT_LIST_GET_LEN(table->indexes)); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - msg("mariabackup: Error: writing index count."); - - return(false); - } - } - - bool ret = true; - - /* Write the index meta data. */ - for (const dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); - index != 0 && ret; - index = UT_LIST_GET_NEXT(indexes, index)) { - - byte* ptr; - byte row[sizeof(ib_uint64_t) - + sizeof(ib_uint32_t) * 8]; - - ptr = row; - - ut_ad(sizeof(ib_uint64_t) == 8); - mach_write_to_8(ptr, index->id); - ptr += sizeof(ib_uint64_t); - - mach_write_to_4(ptr, index->space); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->page); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->type); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->trx_id_offset); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->n_user_defined_cols); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->n_uniq); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->n_nullable); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->n_fields); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - - msg("mariabackup: Error: writing index meta-data."); - - return(false); - } - - /* Write the length of the index name. - NUL byte is included in the length. */ - ib_uint32_t len = (ib_uint32_t)strlen(index->name) + 1; - ut_a(len > 1); - - mach_write_to_4(row, len); - - if (fwrite(row, 1, sizeof(len), file) != sizeof(len) - || fwrite(index->name, 1, len, file) != len) { - - msg("mariabackup: Error: writing index name."); - - return(false); - } - - ret = xb_export_cfg_write_index_fields(index, file); - } - - return(ret); -} - -/*********************************************************************//** -Write the meta data (table columns) config file. Serialise the contents of -dict_col_t structure, along with the column name. All fields are serialized -as ib_uint32_t. -@return true in case of success otherwise false. */ -static __attribute__((nonnull, warn_unused_result)) -bool -xb_export_cfg_write_table( -/*====================*/ - const dict_table_t* table, /*!< in: write the meta data for - this table */ - FILE* file) /*!< in: file to write to */ -{ - dict_col_t* col; - byte row[sizeof(ib_uint32_t) * 7]; - - col = table->cols; - - for (ulint i = 0; i < table->n_cols; ++i, ++col) { - byte* ptr = row; - - mach_write_to_4(ptr, col->prtype); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->mtype); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->len); - ptr += sizeof(ib_uint32_t); - - /* FIXME: This will not work if mbminlen>4. - This field is also redundant, because the lengths - are a property of the character set encoding, which - in turn is encodedin prtype above. */ - mach_write_to_4(ptr, col->mbmaxlen * 5 + col->mbminlen); - - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->ind); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->ord_part); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->max_prefix); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - msg("mariabackup: Error: writing table column data."); - - return(false); - } - - /* Write out the column name as [len, byte array]. The len - includes the NUL byte. */ - ib_uint32_t len; - const char* col_name; - - col_name = dict_table_get_col_name(table, dict_col_get_no(col)); - - /* Include the NUL byte in the length. */ - len = (ib_uint32_t)strlen(col_name) + 1; - ut_a(len > 1); - - mach_write_to_4(row, len); - - if (fwrite(row, 1, sizeof(len), file) != sizeof(len) - || fwrite(col_name, 1, len, file) != len) { - - msg("mariabackup: Error: writing column name."); - - return(false); - } - } - - return(true); -} - -/*********************************************************************//** -Write the meta data config file header. -@return true in case of success otherwise false. */ -static __attribute__((nonnull, warn_unused_result)) -bool -xb_export_cfg_write_header( -/*=====================*/ - const dict_table_t* table, /*!< in: write the meta data for - this table */ - FILE* file) /*!< in: file to write to */ -{ - byte value[sizeof(ib_uint32_t)]; - - /* Write the meta-data version number. */ - mach_write_to_4(value, IB_EXPORT_CFG_VERSION_V1); - - if (fwrite(&value, 1, sizeof(value), file) != sizeof(value)) { - msg("mariabackup: Error: writing meta-data version number."); - - return(false); - } - - /* Write the server hostname. */ - ib_uint32_t len; - const char* hostname = "Hostname unknown"; - - /* The server hostname includes the NUL byte. */ - len = (ib_uint32_t)strlen(hostname) + 1; - mach_write_to_4(value, len); - - if (fwrite(&value, 1, sizeof(value), file) != sizeof(value) - || fwrite(hostname, 1, len, file) != len) { - - msg("mariabackup: Error: writing hostname."); - - return(false); - } - - /* The table name includes the NUL byte. */ - ut_a(table->name != 0); - len = (ib_uint32_t)strlen(table->name) + 1; - - /* Write the table name. */ - mach_write_to_4(value, len); - - if (fwrite(&value, 1, sizeof(value), file) != sizeof(value) - || fwrite(table->name, 1, len, file) != len) { - - msg("mariabackup: Error: writing table name."); - - return(false); - } - - byte row[sizeof(ib_uint32_t) * 3]; - - /* Write the next autoinc value. */ - mach_write_to_8(row, table->autoinc); - - if (fwrite(row, 1, sizeof(ib_uint64_t), file) != sizeof(ib_uint64_t)) { - msg("mariabackup: Error: writing table autoinc value."); - - return(false); - } - - byte* ptr = row; - - /* Write the system page size. */ - mach_write_to_4(ptr, UNIV_PAGE_SIZE); - ptr += sizeof(ib_uint32_t); - - /* Write the table->flags. */ - mach_write_to_4(ptr, table->flags); - ptr += sizeof(ib_uint32_t); - - /* Write the number of columns in the table. */ - mach_write_to_4(ptr, table->n_cols); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - msg("mariabackup: Error: writing table meta-data."); - - return(false); - } - - return(true); -} - -/*********************************************************************//** -Write MySQL 5.6-style meta data config file. -@return true in case of success otherwise false. */ -static -bool -xb_export_cfg_write( - const fil_node_t* node, - const dict_table_t* table) /*!< in: write the meta data for - this table */ -{ - char file_path[FN_REFLEN]; - FILE* file; - bool success; - - strcpy(file_path, node->name); - strcpy(file_path + strlen(file_path) - 4, ".cfg"); - - file = fopen(file_path, "w+b"); - - if (file == NULL) { - msg("mariabackup: Error: cannot open %s\n", node->name); - - success = false; - } else { - - success = xb_export_cfg_write_header(table, file); - - if (success) { - success = xb_export_cfg_write_table(table, file); - } - - if (success) { - success = xb_export_cfg_write_indexes(table, file); - } - - if (fclose(file) != 0) { - msg("mariabackup: Error: cannot close %s\n", node->name); - success = false; - } - - } - - return(success); - -} - static void innodb_free_param() { - srv_free_paths_and_sizes(); - free(internal_innobase_data_file_path); - internal_innobase_data_file_path = NULL; + srv_sys_space.shutdown(); free_tmpdir(&mysql_tmpdir_list); } -/************************************************************************** -Store the current binary log coordinates in a specified file. -@return 'false' on error. */ +/** Store the current binary log coordinates in a specified file. +@param[in] filename file name +@param[in] name binary log file name +@param[in] pos binary log file position +@return whether the operation succeeded */ static bool -store_binlog_info( -/*==============*/ - const char *filename) /*!< in: output file name */ +store_binlog_info(const char* filename, const char* name, ulonglong pos) { - FILE *fp; - - if (trx_sys_mysql_bin_log_name[0] == '\0') { - return(true); - } - - fp = fopen(filename, "w"); + FILE *fp = fopen(filename, "w"); if (!fp) { msg("mariabackup: failed to open '%s'\n", filename); return(false); } - fprintf(fp, "%s\t" UINT64PF "\n", - trx_sys_mysql_bin_log_name, trx_sys_mysql_bin_log_pos); + fprintf(fp, "%s\t%llu\n", name, pos); fclose(fp); return(true); } -static void -xtrabackup_prepare_func(int argc, char ** argv) +/** Implement --prepare +@return whether the operation succeeded */ +static bool +xtrabackup_prepare_func(char** argv) { - ulint err; - datafiles_iter_t *it; - fil_node_t *node; - fil_space_t *space; char metadata_path[FN_REFLEN]; /* cd to target-dir */ @@ -5766,15 +4845,18 @@ xtrabackup_prepare_func(int argc, char ** argv) { msg("mariabackup: cannot my_setwd %s\n", xtrabackup_real_target_dir); - exit(EXIT_FAILURE); + return(false); } msg("mariabackup: cd to %s\n", xtrabackup_real_target_dir); + int argc; for (argc = 0; argv[argc]; argc++) {} encryption_plugin_prepare_init(argc, argv); xtrabackup_target_dir= mysql_data_home_buff; xtrabackup_target_dir[0]=FN_CURLIB; // all paths are relative from here xtrabackup_target_dir[1]=0; + const lsn_t target_lsn = xtrabackup_incremental + ? incremental_to_lsn : metadata_to_lsn; /* read metadata of target @@ -5785,116 +4867,102 @@ xtrabackup_prepare_func(int argc, char ** argv) if (!xtrabackup_read_metadata(metadata_path)) { msg("mariabackup: Error: failed to read metadata from '%s'\n", metadata_path); - exit(EXIT_FAILURE); + return(false); } if (!strcmp(metadata_type, "full-backuped")) { + if (xtrabackup_incremental) { + msg("mariabackup: error: applying incremental backup " + "needs a prepared target.\n"); + return(false); + } msg("mariabackup: This target seems to be not prepared yet.\n"); } else if (!strcmp(metadata_type, "log-applied")) { - msg("mariabackup: This target seems to be already " - "prepared with --apply-log-only.\n"); - goto skip_check; - } else if (!strcmp(metadata_type, "full-prepared")) { msg("mariabackup: This target seems to be already prepared.\n"); } else { - msg("mariabackup: This target seems not to have correct " - "metadata...\n"); - exit(EXIT_FAILURE); + msg("mariabackup: This target does not have correct metadata.\n"); + return(false); } - if (xtrabackup_incremental) { - msg("mariabackup: error: applying incremental backup " - "needs target prepared with --apply-log-only.\n"); - exit(EXIT_FAILURE); - } -skip_check: - if (xtrabackup_incremental - && metadata_to_lsn != incremental_lsn) { + bool ok = !xtrabackup_incremental + || metadata_to_lsn == incremental_lsn; + if (!ok) { msg("mariabackup: error: This incremental backup seems " "not to be proper for the target.\n" "mariabackup: Check 'to_lsn' of the target and " "'from_lsn' of the incremental.\n"); - exit(EXIT_FAILURE); + return(false); } - /* Create logfiles for recovery from 'xtrabackup_logfile', before start InnoDB */ srv_max_n_threads = 1000; + srv_undo_logs = 1; srv_n_purge_threads = 1; - ut_mem_init(); - /* temporally dummy value to avoid crash */ - srv_page_size_shift = 14; - srv_page_size = (1 << srv_page_size_shift); - os_sync_init(); - sync_init(); - os_io_init_simple(); - mem_init(srv_mem_pool_size); - ut_crc32_init(); - -#ifdef WITH_INNODB_DISALLOW_WRITES - srv_allow_writes_event = os_event_create(); - os_event_set(srv_allow_writes_event); -#endif xb_filters_init(); - if (xtrabackup_init_temp_log()) - goto error_cleanup; + srv_log_group_home_dir = NULL; + srv_thread_concurrency = 1; - if(innodb_init_param()) { - goto error_cleanup; - } + if (xtrabackup_incremental) { + srv_operation = SRV_OPERATION_RESTORE_DELTA; - xb_normalize_init_values(); + if (innodb_init_param()) { + goto error_cleanup; + } - if (xtrabackup_incremental) { - err = xb_data_files_init(); + xb_normalize_init_values(); + sync_check_init(); + ut_d(sync_check_enable()); + ut_crc32_init(); + recv_sys_init(); + log_sys_init(); + recv_recovery_on = true; + +#ifdef WITH_INNODB_DISALLOW_WRITES + srv_allow_writes_event = os_event_create(0); + os_event_set(srv_allow_writes_event); +#endif + dberr_t err = xb_data_files_init(); if (err != DB_SUCCESS) { msg("mariabackup: error: xb_data_files_init() failed " - "with error code %lu\n", err); + "with error %s\n", ut_strerr(err)); goto error_cleanup; } - } - if (xtrabackup_incremental) { + inc_dir_tables_hash = hash_create(1000); - if(!xtrabackup_apply_deltas()) { - xb_data_files_close(); - xb_filter_hash_free(inc_dir_tables_hash); - goto error_cleanup; - } - } - if (xtrabackup_incremental) { + ok = xtrabackup_apply_deltas(); + xb_data_files_close(); - } - if (xtrabackup_incremental) { - /* Cleanup datadir from tablespaces deleted between full and - incremental backups */ - xb_process_datadir("./", ".ibd", rm_if_not_found, NULL); + if (ok) { + /* Cleanup datadir from tablespaces deleted + between full and incremental backups */ + + xb_process_datadir("./", ".ibd", rm_if_not_found); + } xb_filter_hash_free(inc_dir_tables_hash); - } - if (fil_system) { + fil_close(); +#ifdef WITH_INNODB_DISALLOW_WRITES + os_event_destroy(srv_allow_writes_event); +#endif + innodb_free_param(); + log_shutdown(); + sync_check_close(); + if (!ok) goto error_cleanup; } - mem_close(); - ut_free_all_mem(); + srv_operation = xtrabackup_export + ? SRV_OPERATION_RESTORE_EXPORT : SRV_OPERATION_RESTORE; - innodb_free_param(); - sync_close(); - sync_initialized = FALSE; - - /* Reset the configuration as it might have been changed by - xb_data_files_init(). */ - if(innodb_init_param()) { + if (innodb_init_param()) { goto error_cleanup; } - srv_apply_log_only = (bool) xtrabackup_apply_log_only; - /* increase IO threads */ - if(srv_n_file_io_threads < 10) { + if (srv_n_file_io_threads < 10) { srv_n_read_io_threads = 4; srv_n_write_io_threads = 4; } @@ -5909,223 +4977,65 @@ skip_check: srv_max_dirty_pages_pct_lwm = srv_max_buf_pool_modified_pct; } - if(innodb_init()) + if (innodb_init()) { goto error_cleanup; - - if (xtrabackup_export) { - msg("mariabackup: export option is specified.\n"); - pfs_os_file_t info_file; - char info_file_path[FN_REFLEN]; - ibool success; - char table_name[FN_REFLEN]; - - byte* page; - byte* buf = NULL; - - buf = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE * 2)); - page = static_cast<byte *>(ut_align(buf, UNIV_PAGE_SIZE)); - - /* flush insert buffer at shutdwon */ - innobase_fast_shutdown = 0; - - it = datafiles_iter_new(fil_system); - if (it == NULL) { - msg("mariabackup: Error: datafiles_iter_new() " - "failed.\n"); - exit(EXIT_FAILURE); - } - while ((node = datafiles_iter_next(it)) != NULL) { - int len; - char *next, *prev, *p; - dict_table_t* table; - dict_index_t* index; - ulint n_index; - - space = node->space; - - /* treat file_per_table only */ - if (!fil_is_user_tablespace_id(space->id)) { - continue; - } - - /* node exist == file exist, here */ - strcpy(info_file_path, node->name); -#ifdef _WIN32 - for (int i = 0; info_file_path[i]; i++) - if (info_file_path[i] == '\\') - info_file_path[i]= '/'; -#endif - strcpy(info_file_path + - strlen(info_file_path) - - 4, ".exp"); - - len =(ib_uint32_t)strlen(info_file_path); - - p = info_file_path; - prev = NULL; - while ((next = strchr(p, '/')) != NULL) - { - prev = p; - p = next + 1; - } - info_file_path[len - 4] = 0; - strncpy(table_name, prev, FN_REFLEN); - - info_file_path[len - 4] = '.'; - - mutex_enter(&(dict_sys->mutex)); - - table = dict_table_get_low(table_name); - if (!table) { - msg("mariabackup: error: " - "cannot find dictionary " - "record of table %s\n", - table_name); - goto next_node; - } - - /* Write MySQL 5.6 .cfg file */ - if (!xb_export_cfg_write(node, table)) { - goto next_node; - } - - index = dict_table_get_first_index(table); - n_index = UT_LIST_GET_LEN(table->indexes); - if (n_index > 31) { - msg("mariabackup: warning: table '%s' has more " - "than 31 indexes, .exp file was not " - "generated. Table will fail to import " - "on server version prior to 5.6.\n", - table->name); - goto next_node; - } - - /* init exp file */ - memset(page, 0, UNIV_PAGE_SIZE); - mach_write_to_4(page , 0x78706f72UL); - mach_write_to_4(page + 4, 0x74696e66UL);/*"xportinf"*/ - mach_write_to_4(page + 8, n_index); - strncpy((char *) page + 12, - table_name, 500); - - msg("mariabackup: export metadata of " - "table '%s' to file `%s` " - "(%lu indexes)\n", - table_name, info_file_path, - n_index); - - n_index = 1; - while (index) { - mach_write_to_8(page + n_index * 512, index->id); - mach_write_to_4(page + n_index * 512 + 8, - index->page); - strncpy((char *) page + n_index * 512 + - 12, index->name, 500); - - msg("mariabackup: name=%s, " - "id.low=%lu, page=%lu\n", - index->name, - (ulint)(index->id & - 0xFFFFFFFFUL), - (ulint) index->page); - index = dict_table_get_next_index(index); - n_index++; - } - - srv_normalize_path_for_win(info_file_path); - info_file = os_file_create( - 0, - info_file_path, - OS_FILE_OVERWRITE, - OS_FILE_NORMAL, OS_DATA_FILE, - &success,0); - if (!success) { - os_file_get_last_error(TRUE); - goto next_node; - } - success = os_file_write(info_file_path, - info_file, page, - 0, UNIV_PAGE_SIZE); - if (!success) { - os_file_get_last_error(TRUE); - goto next_node; - } - success = os_file_flush(info_file); - if (!success) { - os_file_get_last_error(TRUE); - goto next_node; - } -next_node: - if (info_file != XB_FILE_UNDEFINED) { - os_file_close(info_file); - info_file = XB_FILE_UNDEFINED; - } - mutex_exit(&(dict_sys->mutex)); - } - - ut_free(buf); } - /* print the binary log position */ - trx_sys_print_mysql_binlog_offset(); - msg("\n"); - - /* output to xtrabackup_binlog_pos_innodb and (if - backup_safe_binlog_info was available on the server) to - xtrabackup_binlog_info. In the latter case xtrabackup_binlog_pos_innodb - becomes redundant and is created only for compatibility. */ - if (!store_binlog_info("xtrabackup_binlog_pos_innodb") || - (recover_binlog_info && - !store_binlog_info(XTRABACKUP_BINLOG_INFO))) { + if (ok) { + mtr_t mtr; + mtr.start(); + const trx_sysf_t* sys_header = trx_sysf_get(&mtr); + + if (mach_read_from_4(TRX_SYS_MYSQL_LOG_INFO + + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD + + sys_header) + == TRX_SYS_MYSQL_LOG_MAGIC_N) { + ulonglong pos = mach_read_from_8( + TRX_SYS_MYSQL_LOG_INFO + + TRX_SYS_MYSQL_LOG_OFFSET + + sys_header); + const char* name = reinterpret_cast<const char*>( + TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME + + sys_header); + msg("Last binlog file %s, position %llu\n", name, pos); + + /* output to xtrabackup_binlog_pos_innodb and + (if backup_safe_binlog_info was available on + the server) to xtrabackup_binlog_info. In the + latter case xtrabackup_binlog_pos_innodb + becomes redundant and is created only for + compatibility. */ + ok = store_binlog_info( + "xtrabackup_binlog_pos_innodb", name, pos) + && (!recover_binlog_info || store_binlog_info( + XTRABACKUP_BINLOG_INFO, + name, pos)); + } - exit(EXIT_FAILURE); + mtr.commit(); } /* Check whether the log is applied enough or not. */ - if ((xtrabackup_incremental - && srv_start_lsn < incremental_to_lsn) - ||(!xtrabackup_incremental - && srv_start_lsn < metadata_to_lsn)) { + if ((srv_start_lsn || fil_space_get(SRV_LOG_SPACE_FIRST_ID)) + && srv_start_lsn < target_lsn) { msg("mariabackup: error: " - "The transaction log file is corrupted.\n" - "mariabackup: error: " - "The log was not applied to the intended LSN!\n"); - msg("mariabackup: Log applied to lsn " LSN_PF "\n", - srv_start_lsn); - if (xtrabackup_incremental) { - msg("mariabackup: The intended lsn is " LSN_PF "\n", - incremental_to_lsn); - } else { - msg("mariabackup: The intended lsn is " LSN_PF "\n", - metadata_to_lsn); - } - exit(EXIT_FAILURE); + "The log was only applied up to LSN " LSN_PF + ", instead of " LSN_PF "\n", + srv_start_lsn, target_lsn); + ok = false; } #ifdef WITH_WSREP - xb_write_galera_info(xtrabackup_incremental); + else if (ok) xb_write_galera_info(xtrabackup_incremental); #endif - innodb_end(); - - innodb_free_param(); - - sync_initialized = FALSE; - - /* re-init necessary components */ - ut_mem_init(); - os_sync_init(); - sync_init(); - os_io_init_simple(); - - if(xtrabackup_close_temp_log(TRUE)) - exit(EXIT_FAILURE); + innodb_shutdown(); + innodb_free_param(); /* output to metadata file */ - { + if (ok) { char filename[FN_REFLEN]; - strcpy(metadata_type, srv_apply_log_only ? - "log-applied" : "full-prepared"); + strcpy(metadata_type, "log-applied"); if(xtrabackup_incremental && metadata_to_lsn < incremental_to_lsn) @@ -6139,73 +5049,25 @@ next_node: msg("mariabackup: Error: failed to write metadata " "to '%s'\n", filename); - exit(EXIT_FAILURE); - } - - if(xtrabackup_extra_lsndir) { + ok = false; + } else if (xtrabackup_extra_lsndir) { sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME); if (!xtrabackup_write_metadata(filename)) { msg("mariabackup: Error: failed to write " "metadata to '%s'\n", filename); - exit(EXIT_FAILURE); + ok = false; } } } - if (!apply_log_finish()) { - exit(EXIT_FAILURE); - } - - sync_close(); - sync_initialized = FALSE; - if (fil_system) { - fil_close(); - } - - ut_free_all_mem(); - - /* start InnoDB once again to create log files */ - - if (!xtrabackup_apply_log_only) { - - /* xtrabackup_incremental_dir is used to indicate that - we are going to apply incremental backup. Here we already - applied incremental backup and are about to do final prepare - of the full backup */ - xtrabackup_incremental_dir = NULL; - - if(innodb_init_param()) { - goto error; - } - - srv_apply_log_only = false; - - /* increase IO threads */ - if(srv_n_file_io_threads < 10) { - srv_n_read_io_threads = 4; - srv_n_write_io_threads = 4; - } - - srv_shutdown_state = SRV_SHUTDOWN_NONE; - - if(innodb_init()) - goto error; - - innodb_end(); - innodb_free_param(); - - } - - xb_filters_free(); + if (ok) ok = apply_log_finish(); - return; + if (ok && xtrabackup_export) + ok= (prepare_export() == 0); error_cleanup: - xtrabackup_close_temp_log(FALSE); xb_filters_free(); - -error: - exit(EXIT_FAILURE); + return ok; } /************************************************************************** @@ -6308,7 +5170,8 @@ extern void init_signals(void); /* Messages . Avoid loading errmsg.sys file */ void setup_error_messages() { - static const char *all_msgs[ER_ERROR_LAST - ER_ERROR_FIRST +1]; + static const char *my_msgs[ERRORS_PER_RANGE]; + static const char **all_msgs[] = { my_msgs, my_msgs, my_msgs, my_msgs }; my_default_lc_messages = &my_locale_en_US; my_default_lc_messages->errmsgs->errmsgs = all_msgs; @@ -6335,29 +5198,26 @@ void setup_error_messages() }; for (int i = 0; i < (int)array_elements(all_msgs); i++) - all_msgs[i] = "Unknown error"; + all_msgs[0][i] = "Unknown error"; for (int i = 0; i < (int)array_elements(xb_msgs); i++) - all_msgs[xb_msgs[i].id - ER_ERROR_FIRST] = xb_msgs[i].fmt; + all_msgs[0][xb_msgs[i].id - ER_ERROR_FIRST] = xb_msgs[i].fmt; } -extern my_bool(*dict_check_if_skip_table)(const char* name) ; - void handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) { /* Setup some variables for Innodb.*/ - srv_xtrabackup = true; - + srv_operation = SRV_OPERATION_RESTORE; files_charset_info = &my_charset_utf8_general_ci; - dict_check_if_skip_table = check_if_skip_table; + check_if_backup_includes = backup_includes; setup_error_messages(); sys_var_init(); plugin_mutex_init(); - mysql_rwlock_init(key_rwlock_LOCK_system_variables_hash, &LOCK_system_variables_hash); + mysql_prlock_init(key_rwlock_LOCK_system_variables_hash, &LOCK_system_variables_hash); opt_stack_trace = 1; test_flags |= TEST_SIGINT; init_signals(); @@ -6366,7 +5226,7 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) my_sigset(SIGINT, SIG_DFL); #endif - sf_leaking_memory = 0; /* don't report memory leaks on early exist */ + sf_leaking_memory = 1; /* don't report memory leaks on early exist */ int i; int ho_error; @@ -6531,22 +5391,42 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) } } -/* ================= main =================== */ -extern my_bool(*fil_check_if_skip_database_by_path)(const char* name); +static int main_low(char** argv); +static int get_exepath(char *buf, size_t size, const char *argv0); +/* ================= main =================== */ int main(int argc, char **argv) { char **client_defaults, **server_defaults; - char cwd[FN_REFLEN]; - if (argc > 1 && (strcmp(argv[1], "--innobackupex") == 0)) + + if (get_exepath(mariabackup_exe,FN_REFLEN, argv[0])) + strncpy(mariabackup_exe,argv[0], FN_REFLEN-1); + + + if (argc > 1 ) { - argv++; - argc--; - innobackupex_mode = true; + /* In "prepare export", we need to start mysqld + Since it is not always be installed on the machine, + we start "mariabackup --mysqld", which acts as mysqld + */ + if (strcmp(argv[1], "--mysqld") == 0) + { + extern int mysqld_main(int argc, char **argv); + argc--; + argv++; + argv[0]+=2; + return mysqld_main(argc, argv); + } + if(strcmp(argv[1], "--innobackupex") == 0) + { + argv++; + argc--; + innobackupex_mode = true; + } } - - /* Setup skip fil_load_single_tablespaces callback.*/ - fil_check_if_skip_database_by_path = check_if_skip_database_by_path; + + if (argc > 1) + strncpy(orig_argv1,argv[1],sizeof(orig_argv1) -1); init_signals(); MY_INIT(argv[0]); @@ -6573,28 +5453,62 @@ int main(int argc, char **argv) handle_options(argc, argv, &client_defaults, &server_defaults); - int argc_server; - for (argc_server = 0; server_defaults[argc_server]; argc_server++) {} +#ifndef DBUG_OFF + if (dbug_option) { + DBUG_SET_INITIAL(dbug_option); + DBUG_SET(dbug_option); + } +#endif + + int status = main_low(server_defaults); + + backup_cleanup(); + + if (innobackupex_mode) { + ibx_cleanup(); + } + + free_defaults(client_defaults); + free_defaults(server_defaults); + +#ifndef DBUG_OFF + if (dbug_option) { + DBUG_END(); + } +#endif + + if (THR_THD) + (void) pthread_key_delete(THR_THD); + + logger.cleanup_base(); + mysql_mutex_destroy(&LOCK_error_log); - int argc_client; - for (argc_client = 0; client_defaults[argc_client]; argc_client++) {} + if (status == EXIT_SUCCESS) { + msg_ts("completed OK!\n"); + } + return status; +} +static int main_low(char** argv) +{ if (innobackupex_mode) { if (!ibx_init()) { - exit(EXIT_FAILURE); + return(EXIT_FAILURE); } } - if ((!xtrabackup_print_param) && (!xtrabackup_prepare) && (strcmp(mysql_data_home, "./") == 0)) { + if (!xtrabackup_print_param && !xtrabackup_prepare + && !strcmp(mysql_data_home, "./")) { if (!xtrabackup_print_param) usage(); msg("\nmariabackup: Error: Please set parameter 'datadir'\n"); - exit(EXIT_FAILURE); + return(EXIT_FAILURE); } /* Expand target-dir, incremental-basedir, etc. */ + char cwd[FN_REFLEN]; my_getwd(cwd, sizeof(cwd), MYF(0)); my_load_path(xtrabackup_real_target_dir, @@ -6660,7 +5574,7 @@ int main(int argc, char **argv) if (error) { msg("mariabackup: value '%s' may be wrong format for " "incremental option.\n", xtrabackup_incremental); - exit(EXIT_FAILURE); + return(EXIT_FAILURE); } } else if (xtrabackup_backup && xtrabackup_incremental_basedir) { char filename[FN_REFLEN]; @@ -6670,7 +5584,7 @@ int main(int argc, char **argv) if (!xtrabackup_read_metadata(filename)) { msg("mariabackup: error: failed to read metadata from " "%s\n", filename); - exit(EXIT_FAILURE); + return(EXIT_FAILURE); } incremental_lsn = metadata_to_lsn; @@ -6683,7 +5597,7 @@ int main(int argc, char **argv) if (!xtrabackup_read_metadata(filename)) { msg("mariabackup: error: failed to read metadata from " "%s\n", filename); - exit(EXIT_FAILURE); + return(EXIT_FAILURE); } incremental_lsn = metadata_from_lsn; @@ -6700,15 +5614,13 @@ int main(int argc, char **argv) } if (!xb_init()) { - exit(EXIT_FAILURE); + return(EXIT_FAILURE); } /* --print-param */ if (xtrabackup_print_param) { - printf("%s", print_param_str.str().c_str()); - - exit(EXIT_SUCCESS); + return(EXIT_SUCCESS); } print_version(); @@ -6734,7 +5646,7 @@ int main(int argc, char **argv) if (xtrabackup_decrypt_decompress) num++; if (num != 1) { /* !XOR (for now) */ usage(); - exit(EXIT_FAILURE); + return(EXIT_FAILURE); } } @@ -6745,41 +5657,44 @@ int main(int argc, char **argv) #endif /* --backup */ - if (xtrabackup_backup) - xtrabackup_backup_func(); + if (xtrabackup_backup && !xtrabackup_backup_func()) { + return(EXIT_FAILURE); + } /* --prepare */ - if (xtrabackup_prepare) { - xtrabackup_prepare_func(argc_server, server_defaults); + if (xtrabackup_prepare + && !xtrabackup_prepare_func(argv)) { + return(EXIT_FAILURE); } if (xtrabackup_copy_back || xtrabackup_move_back) { if (!check_if_param_set("datadir")) { msg("Error: datadir must be specified.\n"); - exit(EXIT_FAILURE); + return(EXIT_FAILURE); } if (!copy_back()) - exit(EXIT_FAILURE); + return(EXIT_FAILURE); } if (xtrabackup_decrypt_decompress && !decrypt_decompress()) { - exit(EXIT_FAILURE); - } - - backup_cleanup(); - - if (innobackupex_mode) { - ibx_cleanup(); + return(EXIT_FAILURE); } + return(EXIT_SUCCESS); +} - free_defaults(client_defaults); - free_defaults(server_defaults); - if (THR_THD) - (void) pthread_key_delete(THR_THD); - - msg_ts("completed OK!\n"); +static int get_exepath(char *buf, size_t size, const char *argv0) +{ +#ifdef _WIN32 + DWORD ret = GetModuleFileNameA(NULL, buf, size); + if (ret > 0) + return 0; +#elif defined(__linux__) + ssize_t ret = readlink("/proc/self/exe", buf, size-1); + if(ret > 0) + return 0; +#endif - exit(EXIT_SUCCESS); + return my_realpath(buf, argv0, 0); } diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h index 3b2a25d451b..8eabf8f0e7e 100644 --- a/extra/mariabackup/xtrabackup.h +++ b/extra/mariabackup/xtrabackup.h @@ -26,26 +26,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #include "xbstream.h" #include "changed_page_bitmap.h" -#ifdef __WIN__ -#define XB_FILE_UNDEFINED INVALID_HANDLE_VALUE -#else -#define XB_FILE_UNDEFINED (-1) -#endif +struct xb_delta_info_t +{ + xb_delta_info_t(page_size_t page_size, ulint space_id) + : page_size(page_size), space_id(space_id) {} -typedef struct { - ulint page_size; - ulint zip_size; - ulint space_id; -} xb_delta_info_t; - -/* ======== Datafiles iterator ======== */ -typedef struct { - fil_system_t *system; - fil_space_t *space; - fil_node_t *node; - ibool started; - os_ib_mutex_t mutex; -} datafiles_iter_t; + page_size_t page_size; + ulint space_id; +}; /* value of the --incremental option */ extern lsn_t incremental_lsn; @@ -86,15 +74,11 @@ extern ibool xtrabackup_compress; extern my_bool xtrabackup_backup; extern my_bool xtrabackup_prepare; -extern my_bool xtrabackup_apply_log_only; extern my_bool xtrabackup_copy_back; extern my_bool xtrabackup_move_back; extern my_bool xtrabackup_decrypt_decompress; extern char *innobase_data_file_path; -extern char *innobase_doublewrite_file; -extern longlong innobase_log_file_size; -extern long innobase_log_files_in_group; extern longlong innobase_page_size; extern int xtrabackup_parallel; @@ -110,9 +94,7 @@ extern "C"{ } #endif extern my_bool xtrabackup_export; -extern char *xtrabackup_incremental_basedir; extern char *xtrabackup_extra_lsndir; -extern char *xtrabackup_incremental_dir; extern ulint xtrabackup_log_copy_interval; extern char *xtrabackup_stream_str; extern long xtrabackup_throttle; @@ -138,7 +120,6 @@ extern char *opt_host; extern char *opt_defaults_group; extern char *opt_socket; extern uint opt_port; -extern char *opt_login_path; extern char *opt_log_bin; extern const char *query_type_names[]; @@ -168,24 +149,6 @@ void xtrabackup_io_throttling(void); my_bool xb_write_delta_metadata(const char *filename, const xb_delta_info_t *info); -datafiles_iter_t *datafiles_iter_new(fil_system_t *f_system); -fil_node_t *datafiles_iter_next(datafiles_iter_t *it); -void datafiles_iter_free(datafiles_iter_t *it); - -/************************************************************************ -Initialize the tablespace memory cache and populate it by scanning for and -opening data files */ -ulint xb_data_files_init(void); - -/************************************************************************ -Destroy the tablespace memory cache. */ -void xb_data_files_close(void); - -/*********************************************************************** -Reads the space flags from a given data file and returns the compressed -page size, or 0 if the space is not compressed. */ -ulint xb_get_zip_size(pfs_os_file_t file); - /************************************************************************ Checks if a table specified as a name in the form "database/name" (InnoDB 5.6) or "./database/name.ibd" (InnoDB 5.5-) should be skipped from backup based on @@ -219,9 +182,6 @@ extern my_bool opt_ssl_verify_server_cert; #endif -void -xtrabackup_backup_func(void); - my_bool xb_get_one_option(int optid, const struct my_option *opt __attribute__((unused)), @@ -230,4 +190,8 @@ xb_get_one_option(int optid, const char* xb_get_copy_action(const char *dflt = "Copying"); +void mdl_lock_init(); +void mdl_lock_table(ulint space_id); +void mdl_unlock_all(); +bool ends_with(const char *str, const char *suffix); #endif /* XB_XTRABACKUP_H */ diff --git a/extra/perror.c b/extra/perror.c index 062a04003c2..e96002cbb7b 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -222,7 +222,7 @@ static my_bool print_win_error_msg(DWORD error, my_bool verbose) will ignore calls to register already registered error numbers. */ -static const char **get_handler_error_messages(void) +static const char **get_handler_error_messages(int e __attribute__((unused))) { return handler_error_messages; } diff --git a/extra/resolve_stack_dump.c b/extra/resolve_stack_dump.c index 576710e0bde..dbd9941141d 100644 --- a/extra/resolve_stack_dump.c +++ b/extra/resolve_stack_dump.c @@ -192,7 +192,7 @@ static my_long_addr_t read_addr(char** buf) while((c = hex_val(*p++)) != HEX_INVALID) addr = (addr << 4) + c; - *buf = p; + *buf= p-1; return addr; } @@ -203,6 +203,7 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf) if (!se->addr) return -1; + buf++; while (my_isspace(&my_charset_latin1,*buf++)) /* empty */; @@ -281,32 +282,47 @@ static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se) } +/* + Resolve anything that starts with [0x or (+0x or start of line and 0x + Skip '_end' as this is an indication of a wrong symbol (stack?) +*/ + static void do_resolve() { char buf[1024], *p; while (fgets(buf, sizeof(buf), fp_dump)) { - /* skip bracket */ - p= (p= strchr(buf, '[')) ? p+1 : buf; - /* skip space */ - while (my_isspace(&my_charset_latin1,*p)) - ++p; - - if (*p++ == '0' && *p++ == 'x') + for (p= buf ; *p ; p++) { - SYM_ENTRY se ; - uchar* addr = (uchar*)read_addr(&p); - if (resolve_addr(addr, &se)) - fprintf(fp_out, "%p %s + %d\n", addr, se.symbol, - (int) (addr - se.addr)); + int found= 0; + if (p[0] == '[' && p[1] == '0' && p[2] == 'x') + found= 3; + if (p[0] == '(' && p[1] == '+' && p[2] == '0' && p[3] == 'x') + found= 4; + + /* For stdin */ + if (p == buf && p[0] == '0' && p[1] == 'x') + found= 2; + + if (found) + { + SYM_ENTRY se ; + uchar *addr; + char *tmp= p + found; + addr= (uchar*)read_addr(&tmp); + if (resolve_addr(addr, &se) && strcmp(se.symbol, "_end")) + { + fprintf(fp_out, "%c%p %s + %d", *p, addr, se.symbol, + (int) (addr - se.addr)); + p= tmp-1; + } + else + { + fputc(*p, stdout); + } + } else - fprintf(fp_out, "%p (?)\n", addr); - - } - else - { - fputs(buf, fp_out); - continue; + fputc(*p, stdout); } } } diff --git a/extra/yassl/include/openssl/crypto.h b/extra/yassl/include/openssl/crypto.h index 103fcbb0e30..ac1e7ebc8eb 100644 --- a/extra/yassl/include/openssl/crypto.h +++ b/extra/yassl/include/openssl/crypto.h @@ -19,7 +19,7 @@ /* crypto.h for openSSL */ -#ifndef ysSSL_crypto_h__ +#ifndef yaSSL_crypto_h__ #define yaSSL_crypto_h__ #ifdef YASSL_PREFIX diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index a5ccef102b9..f750f601d29 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -541,7 +541,7 @@ void MD5_Final(unsigned char*, MD5_CTX*); /* yaSSL extensions */ int SSL_set_compression(SSL*); /* turn on yaSSL zlib compression */ -char *yaSSL_ASN1_TIME_to_string(ASN1_TIME *time, char *buf, size_t len); +char *yaSSL_ASN1_TIME_to_string(const ASN1_TIME *time, char *buf, size_t len); #include "transport_types.h" diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 781eaa38dda..4f35c7e7c92 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -346,6 +346,7 @@ private: Sessions& GetSessions(); // forward singletons sslFactory& GetSSL_Factory(); Errors& GetErrors(); +bool HasErrors(); // openSSL method and context types diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 28927c41c5c..51e1bd1ab21 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -1514,7 +1514,8 @@ int SSLeay_add_ssl_algorithms() // compatibility only void ERR_remove_state(unsigned long) { - GetErrors().Remove(); + if (HasErrors()) + GetErrors().Remove(); } @@ -1735,7 +1736,7 @@ unsigned long ERR_get_error() // end stunnel needs - char *yaSSL_ASN1_TIME_to_string(ASN1_TIME *time, char *buf, size_t len) + char *yaSSL_ASN1_TIME_to_string(const ASN1_TIME *time, char *buf, size_t len) { tm t; static const char *month_names[12]= diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 884e8b5fa9d..1dc89df9d86 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -1694,6 +1694,11 @@ Errors& GetErrors() return *errorsInstance; } +bool HasErrors() +{ + return (errorsInstance != 0); +} + typedef Mutex::Lock Lock; diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index cb4d26e70c6..159b63c89d7 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -1,5 +1,6 @@ /* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -599,8 +600,8 @@ inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte* block, word16*) { return (order == BigEndianOrder) - ? block[1] | (block[0] << 8) - : block[0] | (block[1] << 8); + ? word16(block[1] | (word16(block[0]) << 8)) + : word16(block[0] | (word16(block[1]) << 8)); } inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte* block, @@ -625,7 +626,7 @@ inline void UnalignedPutWord(ByteOrder order, byte *block, byte value, block[0] = xorBlock ? (value ^ xorBlock[0]) : value; } -#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y))) +#define GETBYTE(x, y) byte((x)>>(8*(y))) inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value, const byte *xorBlock = 0) @@ -827,7 +828,7 @@ word ShiftWordsLeftByBits(word* r, unsigned int n, unsigned int shiftBits) inline -word ShiftWordsRightByBits(word* r, unsigned int n, unsigned int shiftBits) +word ShiftWordsRightByBits(word* r, int n, unsigned int shiftBits) { word u, carry=0; if (shiftBits) diff --git a/extra/yassl/taocrypt/include/modes.hpp b/extra/yassl/taocrypt/include/modes.hpp index bfe8c6ec5d4..f65bc217947 100644 --- a/extra/yassl/taocrypt/include/modes.hpp +++ b/extra/yassl/taocrypt/include/modes.hpp @@ -1,5 +1,6 @@ /* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -57,7 +58,7 @@ class Mode_BASE : public virtual_base { public: enum { MaxBlockSz = 16 }; - explicit Mode_BASE(int sz, CipherDir dir, Mode mode) + explicit Mode_BASE(unsigned sz, CipherDir dir, Mode mode) : blockSz_(sz), reg_(reinterpret_cast<byte*>(r_)), tmp_(reinterpret_cast<byte*>(t_)), dir_(dir), mode_(mode) {} @@ -67,7 +68,7 @@ public: void SetIV(const byte* iv) { memcpy(reg_, iv, blockSz_); } protected: - int blockSz_; + unsigned blockSz_; byte* reg_; byte* tmp_; diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp index 7dae7d6a917..892de25587e 100644 --- a/extra/yassl/taocrypt/src/algebra.cpp +++ b/extra/yassl/taocrypt/src/algebra.cpp @@ -218,7 +218,7 @@ struct WindowSlider exp >>= skipCount; windowBegin += skipCount; - expWindow = exp % (1 << windowSize); + expWindow = (unsigned int)(exp % (1LL << windowSize)); if (fastNegate && exp.GetBit(windowSize)) { @@ -248,7 +248,7 @@ void AbstractGroup::SimultaneousMultiply(Integer *results, const Integer &base, { exponents.push_back(WindowSlider(*expBegin++, InversionIsFast(), 0)); exponents[i].FindNextWindow(); - buckets[i].resize(1<<(exponents[i].windowSize-1), Identity()); + buckets[i].resize(size_t(1)<<(exponents[i].windowSize-1), Identity()); } unsigned int expBitPosition = 0; diff --git a/extra/yassl/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp index 4b89b5b32c5..26dae7d1993 100644 --- a/extra/yassl/taocrypt/src/random.cpp +++ b/extra/yassl/taocrypt/src/random.cpp @@ -27,7 +27,6 @@ #include <time.h> #if defined(_WIN32) - #define _WIN32_WINNT 0x0400 #include <windows.h> #include <wincrypt.h> #else |