summaryrefslogtreecommitdiff
path: root/extra
diff options
context:
space:
mode:
Diffstat (limited to 'extra')
-rw-r--r--extra/CMakeLists.txt18
-rw-r--r--extra/comp_err.c156
-rw-r--r--extra/crc32-vpmsum/CMakeLists.txt2
-rw-r--r--extra/crc32-vpmsum/crc32.iS734
-rw-r--r--extra/crc32-vpmsum/crc32_wrapper.ic52
-rw-r--r--extra/crc32-vpmsum/crc32c.S14
-rw-r--r--extra/crc32-vpmsum/crc32c_constants.h837
-rw-r--r--extra/crc32-vpmsum/crc32c_wrapper.c78
-rw-r--r--extra/crc32-vpmsum/crc32ieee.S14
-rw-r--r--extra/crc32-vpmsum/crc32ieee_constants.h835
-rw-r--r--extra/crc32-vpmsum/crc32ieee_wrapper.c75
-rw-r--r--extra/crc32-vpmsum/ppc-opcode.h23
-rw-r--r--extra/innochecksum.cc28
-rw-r--r--extra/mariabackup/CMakeLists.txt3
-rw-r--r--extra/mariabackup/backup_copy.cc567
-rw-r--r--extra/mariabackup/backup_copy.h10
-rw-r--r--extra/mariabackup/backup_mysql.cc286
-rw-r--r--extra/mariabackup/backup_mysql.h2
-rw-r--r--extra/mariabackup/backup_wsrep.h4
-rw-r--r--extra/mariabackup/changed_page_bitmap.cc65
-rw-r--r--extra/mariabackup/common.h1
-rw-r--r--extra/mariabackup/datasink.c3
-rw-r--r--extra/mariabackup/encryption_plugin.cc71
-rw-r--r--extra/mariabackup/fil_cur.cc230
-rw-r--r--extra/mariabackup/fil_cur.h24
-rw-r--r--extra/mariabackup/innobackupex.cc24
-rw-r--r--extra/mariabackup/read_filt.cc15
-rw-r--r--extra/mariabackup/read_filt.h8
-rw-r--r--extra/mariabackup/write_filt.cc14
-rw-r--r--extra/mariabackup/wsrep.cc1
-rw-r--r--extra/mariabackup/xb0xb.h37
-rw-r--r--extra/mariabackup/xbstream.c6
-rw-r--r--extra/mariabackup/xtrabackup.cc4365
-rw-r--r--extra/mariabackup/xtrabackup.h64
-rw-r--r--extra/perror.c2
-rw-r--r--extra/resolve_stack_dump.c56
-rw-r--r--extra/yassl/include/openssl/crypto.h2
-rw-r--r--extra/yassl/include/openssl/ssl.h2
-rw-r--r--extra/yassl/include/yassl_int.hpp1
-rw-r--r--extra/yassl/src/ssl.cpp5
-rw-r--r--extra/yassl/src/yassl_int.cpp5
-rw-r--r--extra/yassl/taocrypt/include/misc.hpp9
-rw-r--r--extra/yassl/taocrypt/include/modes.hpp5
-rw-r--r--extra/yassl/taocrypt/src/algebra.cpp4
-rw-r--r--extra/yassl/taocrypt/src/random.cpp1
45 files changed, 5714 insertions, 3044 deletions
diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt
index c8e15dd4fb4..136a802d1ba 100644
--- a/extra/CMakeLists.txt
+++ b/extra/CMakeLists.txt
@@ -73,6 +73,17 @@ IF(WITH_INNOBASE_STORAGE_ENGINE OR WITH_XTRADB_STORAGE_ENGINE)
# We use the InnoDB code directly in case the code changes.
ADD_DEFINITIONS("-DUNIV_INNOCHECKSUM")
+ # Avoid generating Hardware Capabilities due to crc32 instructions
+ IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_SYSTEM_PROCESSOR MATCHES "i386")
+ MY_CHECK_CXX_COMPILER_FLAG("-Wa,-nH")
+ IF(have_CXX__Wa__nH)
+ ADD_COMPILE_FLAGS(
+ ../storage/innobase/ut/ut0crc32.cc
+ COMPILE_FLAGS "-Wa,-nH"
+ )
+ ENDIF()
+ ENDIF()
+
SET(INNOBASE_SOURCES
../storage/innobase/buf/buf0checksum.cc
../storage/innobase/ut/ut0crc32.cc
@@ -82,13 +93,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= &current_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 aa05b36153f..e71f24e0b92 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 895ef744ea1..3a5a5bc5a2a 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>
@@ -58,6 +59,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <btr0btr.h>
#include "xb0xb.h"
+#define ROCKSDB_BACKUP_DIR "#rocksdb"
/* list of files to sync for --rsync mode */
static std::set<std::string> rsync_list;
@@ -67,6 +69,21 @@ static std::map<std::string, std::string> tablespace_locations;
/* Whether LOCK BINLOG FOR BACKUP has been issued during backup */
bool binlog_locked;
+static void rocksdb_create_checkpoint();
+static bool has_rocksdb_plugin();
+static void copy_or_move_dir(const char *from, const char *to, bool copy, bool allow_hardlinks);
+static void rocksdb_backup_checkpoint();
+static void rocksdb_copy_back();
+
+static bool is_abs_path(const char *path)
+{
+#ifdef _WIN32
+ return path[0] && path[1] == ':' && (path[2] == '/' || path[2] == '\\');
+#else
+ return path[0] == '/';
+#endif
+}
+
/************************************************************************
Struct represents file or directory. */
struct datadir_node_t {
@@ -89,7 +106,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 +124,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 +151,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 +170,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 +195,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 +211,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 +263,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 +318,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 +390,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 +425,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 +439,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 +451,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);
}
@@ -481,17 +493,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;
new (cursor) datafile_cur_t(file);
@@ -503,11 +515,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);
@@ -531,7 +541,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);
}
@@ -541,7 +551,6 @@ static
xb_fil_cur_result_t
datafile_read(datafile_cur_t *cursor)
{
- ulint success;
ulint to_read;
xtrabackup_io_throttling();
@@ -553,14 +562,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;
@@ -614,7 +623,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)
{
@@ -646,7 +654,7 @@ mkdirp(const char *pathname, int Flags, myf MyFlags)
parent[len-1]= 0;
for (p = parent + strlen(parent);
- !is_path_separator(*p) && p != parent; p--);
+ !is_path_separator(*p) && p != parent; p--) ;
*p = 0;
@@ -944,13 +952,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++) {
@@ -964,15 +972,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++) {
@@ -982,7 +990,7 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n)
}
}
- ut_free(data_threads);
+ free(data_threads);
return(ret);
}
@@ -1001,7 +1009,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;
const char *dst_path =
(xtrabackup_copy_back || xtrabackup_move_back)?
dst_file_path : trim_dotslash(dst_file_path);
@@ -1020,9 +1027,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) {
@@ -1072,8 +1078,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);
@@ -1140,7 +1146,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;
@@ -1177,7 +1183,8 @@ bool
copy_or_move_file(const char *src_file_path,
const char *dst_file_path,
const char *dst_dir,
- uint thread_n)
+ uint thread_n,
+ bool copy = xtrabackup_copy_back)
{
ds_ctxt_t *datasink = ds_data; /* copy to datadir by default */
char filedir[FN_REFLEN];
@@ -1225,7 +1232,7 @@ copy_or_move_file(const char *src_file_path,
free(link_filepath);
}
- ret = (xtrabackup_copy_back ?
+ ret = (copy ?
copy_file(datasink, src_file_path, dst_file_path, thread_n) :
move_file(datasink, src_file_path, dst_file_path,
dst_dir, thread_n));
@@ -1242,6 +1249,7 @@ cleanup:
+static
bool
backup_files(const char *from, bool prep_mode)
{
@@ -1290,8 +1298,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);
@@ -1380,8 +1388,32 @@ out:
return(ret);
}
-bool
-backup_start()
+void backup_fix_ddl(void);
+
+#define LSN_PREFIX_IN_SHOW_STATUS "\nLog sequence number "
+static lsn_t get_current_lsn(MYSQL *connection) {
+ MYSQL_RES *res = xb_mysql_query(connection, "SHOW ENGINE INNODB STATUS", true, false);
+ if (!res)
+ return 0;
+ MYSQL_ROW row = mysql_fetch_row(res);
+ DBUG_ASSERT(row);
+ if (row) {
+ const char *p = strstr(row[2],LSN_PREFIX_IN_SHOW_STATUS);
+ DBUG_ASSERT(p);
+ if (p)
+ {
+ p += sizeof(LSN_PREFIX_IN_SHOW_STATUS) - 1;
+ return (lsn_t)strtoll(p, NULL, 10);
+ }
+ }
+ mysql_free_result(res);
+ return 0;
+}
+
+lsn_t server_lsn_after_lock;
+extern void backup_wait_for_lsn(lsn_t lsn);
+/** Start --backup */
+bool backup_start()
{
if (!opt_no_lock) {
if (opt_safe_slave_backup) {
@@ -1399,6 +1431,7 @@ backup_start()
if (!lock_tables(mysql_connection)) {
return(false);
}
+ server_lsn_after_lock = get_current_lsn(mysql_connection);
}
if (!backup_files(fil_path_to_mysql_datadir, false)) {
@@ -1409,6 +1442,14 @@ backup_start()
return false;
}
+ if (has_rocksdb_plugin()) {
+ rocksdb_create_checkpoint();
+ }
+
+ msg_ts("Waiting for log copy thread to read lsn %llu\n", (ulonglong)server_lsn_after_lock);
+ backup_wait_for_lsn(server_lsn_after_lock);
+ backup_fix_ddl();
+
// There is no need to stop slave thread before coping non-Innodb data when
// --no-lock option is used because --no-lock option requires that no DDL or
// DML to non-transaction tables can occur.
@@ -1456,9 +1497,8 @@ backup_start()
return(true);
}
-
-bool
-backup_finish()
+/** Release resources after backup_start() */
+void backup_release()
{
/* release all locks */
if (!opt_no_lock) {
@@ -1468,12 +1508,20 @@ backup_finish()
history_lock_time = time(NULL) - history_lock_time;
}
+ if (opt_lock_ddl_per_table) {
+ mdl_unlock_all();
+ }
+
if (opt_safe_slave_backup && sql_thread_started) {
msg("Starting slave SQL thread\n");
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)) {
@@ -1487,6 +1535,10 @@ backup_finish()
}
}
+ if (has_rocksdb_plugin()) {
+ rocksdb_backup_checkpoint();
+ }
+
msg_ts("Backup created in directory '%s'\n", xtrabackup_target_dir);
if (mysql_binlog_position != NULL) {
msg("MySQL binlog position: %s\n", mysql_binlog_position);
@@ -1500,12 +1552,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);
}
@@ -1658,14 +1708,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;
@@ -1708,24 +1753,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 */
@@ -1736,14 +1773,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;
}
}
@@ -1754,26 +1791,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;
+ ? 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);
-
- 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) */
@@ -1782,17 +1823,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);
@@ -1802,7 +1845,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};
@@ -1811,6 +1854,16 @@ copy_back()
int i_tmp;
bool is_ibdata_file;
+ if (strstr(node.filepath,"/" ROCKSDB_BACKUP_DIR "/")
+#ifdef _WIN32
+ || strstr(node.filepath,"\\" ROCKSDB_BACKUP_DIR "\\")
+#endif
+ )
+ {
+ // copied at later step
+ continue;
+ }
+
/* create empty directories */
if (node.is_empty_dir) {
char path[FN_REFLEN];
@@ -1848,21 +1901,19 @@ 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]);
-
+ for (Tablespace::const_iterator iter(srv_sys_space.begin()),
+ end(srv_sys_space.end()); iter != end; ++iter) {
+ const char *ibfile = base_name(iter->name());
if (strcmp(ibfile, filename) == 0) {
is_ibdata_file = true;
- continue;
+ break;
}
}
if (is_ibdata_file) {
@@ -1897,6 +1948,8 @@ copy_back()
}
}
+ rocksdb_copy_back();
+
cleanup:
if (it != NULL) {
datadir_iter_free(it);
@@ -1904,20 +1957,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);
}
@@ -1954,12 +2000,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);
@@ -1996,13 +2042,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;
}
@@ -2013,10 +2059,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)))
@@ -2045,11 +2088,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);
}
@@ -2087,3 +2126,235 @@ static bool backup_files_from_datadir(const char *dir_path)
os_file_closedir(dir);
return ret;
}
+
+
+static int rocksdb_remove_checkpoint_directory()
+{
+ xb_mysql_query(mysql_connection, "set global rocksdb_remove_mariabackup_checkpoint=ON", false);
+ return 0;
+}
+
+static bool has_rocksdb_plugin()
+{
+ static bool first_time = true;
+ static bool has_plugin= false;
+ if (!first_time || !xb_backup_rocksdb)
+ return has_plugin;
+
+ const char *query = "SELECT COUNT(*) FROM information_schema.plugins WHERE plugin_name='rocksdb'";
+ MYSQL_RES* result = xb_mysql_query(mysql_connection, query, true);
+ MYSQL_ROW row = mysql_fetch_row(result);
+ if (row)
+ has_plugin = !strcmp(row[0], "1");
+ mysql_free_result(result);
+ first_time = false;
+ return has_plugin;
+}
+
+static char *trim_trailing_dir_sep(char *path)
+{
+ size_t path_len = strlen(path);
+ while (path_len)
+ {
+ char c = path[path_len - 1];
+ if (c == '/' IF_WIN(|| c == '\\', ))
+ path_len--;
+ else
+ break;
+ }
+ path[path_len] = 0;
+ return path;
+}
+
+/*
+Create a file hardlink.
+@return true on success, false on error.
+*/
+static bool make_hardlink(const char *from_path, const char *to_path)
+{
+ DBUG_EXECUTE_IF("no_hardlinks", return false;);
+ char to_path_full[FN_REFLEN];
+ if (!is_abs_path(to_path))
+ {
+ fn_format(to_path_full, to_path, ds_data->root, "", MYF(MY_RELATIVE_PATH));
+ }
+ else
+ {
+ strncpy(to_path_full, to_path, sizeof(to_path_full));
+ }
+#ifdef _WIN32
+ return CreateHardLink(to_path_full, from_path, NULL);
+#else
+ return !link(from_path, to_path_full);
+#endif
+}
+
+/*
+ Copies or moves a directory (non-recursively so far).
+ Helper function used to backup rocksdb checkpoint, or copy-back the
+ rocksdb files.
+
+ Has optimization that allows to use hardlinks when possible
+ (source and destination are directories on the same device)
+*/
+static void copy_or_move_dir(const char *from, const char *to, bool do_copy, bool allow_hardlinks)
+{
+ datadir_node_t node;
+ datadir_node_init(&node);
+ datadir_iter_t *it = datadir_iter_new(from, false);
+
+ while (datadir_iter_next(it, &node))
+ {
+ char to_path[FN_REFLEN];
+ const char *from_path = node.filepath;
+ snprintf(to_path, sizeof(to_path), "%s/%s", to, base_name(from_path));
+ bool rc = false;
+ if (do_copy && allow_hardlinks)
+ {
+ rc = make_hardlink(from_path, to_path);
+ if (rc)
+ {
+ msg_ts("[%02u] Creating hardlink from %s to %s\n",
+ 1, from_path, to_path);
+ }
+ else
+ {
+ allow_hardlinks = false;
+ }
+ }
+
+ if (!rc)
+ {
+ rc = (do_copy ?
+ copy_file(ds_data, from_path, to_path, 1) :
+ move_file(ds_data, from_path, node.filepath_rel,
+ to, 1));
+ }
+ if (!rc)
+ exit(EXIT_FAILURE);
+ }
+ datadir_iter_free(it);
+ datadir_node_free(&node);
+
+}
+
+/*
+ Obtain user level lock , to protect the checkpoint directory of the server
+ from being user/overwritten by different backup processes, if backups are
+ running in parallel.
+
+ This lock will be acquired before rocksdb checkpoint is created, held
+ while all files from it are being copied to their final backup destination,
+ and finally released after the checkpoint is removed.
+*/
+static void rocksdb_lock_checkpoint()
+{
+ msg_ts("Obtaining rocksdb checkpoint lock.\n");
+ MYSQL_RES *res =
+ xb_mysql_query(mysql_connection, "SELECT GET_LOCK('mariabackup_rocksdb_checkpoint',3600)", true, true);
+
+ MYSQL_ROW r = mysql_fetch_row(res);
+ if (r && r[0] && strcmp(r[0], "1"))
+ {
+ msg_ts("Could not obtain rocksdb checkpont lock\n");
+ exit(EXIT_FAILURE);
+ }
+ mysql_free_result(res);
+}
+
+static void rocksdb_unlock_checkpoint()
+{
+ xb_mysql_query(mysql_connection,
+ "SELECT RELEASE_LOCK('mariabackup_rocksdb_checkpoint')", false, true);
+}
+
+
+/*
+ Create temporary checkpoint in $rocksdb_datadir/mariabackup-checkpoint
+ directory.
+ A (user-level) lock named 'mariabackup_rocksdb_checkpoint' will also be
+ acquired be this function.
+*/
+#define MARIADB_CHECKPOINT_DIR "mariabackup-checkpoint"
+static char rocksdb_checkpoint_dir[FN_REFLEN];
+
+static void rocksdb_create_checkpoint()
+{
+ MYSQL_RES *result = xb_mysql_query(mysql_connection, "SELECT @@rocksdb_datadir,@@datadir", true, true);
+ MYSQL_ROW row = mysql_fetch_row(result);
+
+ DBUG_ASSERT(row && row[0] && row[1]);
+
+ char *rocksdbdir = row[0];
+ char *datadir = row[1];
+
+ if (is_abs_path(rocksdbdir))
+ {
+ snprintf(rocksdb_checkpoint_dir, sizeof(rocksdb_checkpoint_dir),
+ "%s/" MARIADB_CHECKPOINT_DIR, trim_trailing_dir_sep(rocksdbdir));
+ }
+ else
+ {
+ snprintf(rocksdb_checkpoint_dir, sizeof(rocksdb_checkpoint_dir),
+ "%s/%s/" MARIADB_CHECKPOINT_DIR, trim_trailing_dir_sep(datadir),
+ trim_dotslash(rocksdbdir));
+ }
+ mysql_free_result(result);
+
+#ifdef _WIN32
+ for (char *p = rocksdb_checkpoint_dir; *p; p++)
+ if (*p == '\\') *p = '/';
+#endif
+
+ rocksdb_lock_checkpoint();
+
+ if (!access(rocksdb_checkpoint_dir, 0))
+ {
+ msg_ts("Removing rocksdb checkpoint from previous backup attempt.\n");
+ rocksdb_remove_checkpoint_directory();
+ }
+
+ char query[FN_REFLEN + 32];
+ snprintf(query, sizeof(query), "SET GLOBAL rocksdb_create_checkpoint='%s'", rocksdb_checkpoint_dir);
+ xb_mysql_query(mysql_connection, query, false, true);
+}
+
+/*
+ Copy files from rocksdb temporary checkpoint to final destination.
+ remove temp.checkpoint directory (in server's datadir)
+ and release user level lock acquired inside rocksdb_create_checkpoint().
+*/
+static void rocksdb_backup_checkpoint()
+{
+ msg_ts("Backing up rocksdb files.\n");
+ char rocksdb_backup_dir[FN_REFLEN];
+ snprintf(rocksdb_backup_dir, sizeof(rocksdb_backup_dir), "%s/" ROCKSDB_BACKUP_DIR , xtrabackup_target_dir);
+ bool backup_to_directory = xtrabackup_backup && xtrabackup_stream_fmt == XB_STREAM_FMT_NONE;
+ if (backup_to_directory)
+ {
+ if (my_mkdir(rocksdb_backup_dir, 0777, MYF(0))){
+ msg_ts("Can't create rocksdb backup directory %s\n", rocksdb_backup_dir);
+ exit(EXIT_FAILURE);
+ }
+ }
+ copy_or_move_dir(rocksdb_checkpoint_dir, ROCKSDB_BACKUP_DIR, true, backup_to_directory);
+ rocksdb_remove_checkpoint_directory();
+ rocksdb_unlock_checkpoint();
+}
+
+/*
+ Copies #rocksdb directory to the $rockdb_data_dir, on copy-back
+*/
+static void rocksdb_copy_back() {
+ if (access(ROCKSDB_BACKUP_DIR, 0))
+ return;
+ char rocksdb_home_dir[FN_REFLEN];
+ if (xb_rocksdb_datadir && is_abs_path(xb_rocksdb_datadir)) {
+ strncpy(rocksdb_home_dir, xb_rocksdb_datadir, sizeof(rocksdb_home_dir));
+ } else {
+ snprintf(rocksdb_home_dir, sizeof(rocksdb_home_dir), "%s/%s", mysql_data_home,
+ xb_rocksdb_datadir?trim_dotslash(xb_rocksdb_datadir): ROCKSDB_BACKUP_DIR);
+ }
+ mkdirp(rocksdb_home_dir, 0777, MYF(0));
+ copy_or_move_dir(ROCKSDB_BACKUP_DIR, rocksdb_home_dir, xtrabackup_copy_back, xtrabackup_copy_back);
+}
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 7f0ad8a8361..efa21965965 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",
@@ -183,6 +186,7 @@ xb_mysql_query(MYSQL *connection, const char *query, bool use_result,
if (!use_result) {
mysql_free_result(mysql_result);
+ mysql_result = NULL;
}
}
@@ -494,13 +498,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 +583,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 +590,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 +603,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 +615,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 +722,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 +738,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 +767,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 +843,7 @@ stop_thread:
os_event_set(kill_query_thread_stopped);
- os_thread_exit(NULL);
+ os_thread_exit();
OS_THREAD_DUMMY_RETURN;
}
@@ -850,9 +852,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);
@@ -867,6 +869,83 @@ stop_query_killer()
os_event_wait_time(kill_query_thread_stopped, 60000);
}
+
+/*
+Killing connections that wait for MDL lock.
+If lock-ddl-per-table is used, there can be some DDL statements
+
+FLUSH TABLES would hang infinitely, if DDL statements are waiting for
+MDL lock, which mariabackup currently holds. Therefore we start killing
+those statements from a dedicated thread, until FLUSH TABLES WITH READ LOCK
+succeeds.
+*/
+
+static os_event_t mdl_killer_stop_event;
+static os_event_t mdl_killer_finished_event;
+
+static
+os_thread_ret_t
+DECLARE_THREAD(kill_mdl_waiters_thread(void *))
+{
+ MYSQL *mysql;
+ if ((mysql = xb_mysql_connect()) == NULL) {
+ msg("Error: kill mdl waiters thread failed to connect\n");
+ goto stop_thread;
+ }
+
+ for(;;){
+ if (os_event_wait_time(mdl_killer_stop_event, 1000) == 0)
+ break;
+
+ MYSQL_RES *result = xb_mysql_query(mysql,
+ "SELECT ID, COMMAND, INFO FROM INFORMATION_SCHEMA.PROCESSLIST "
+ " WHERE State='Waiting for table metadata lock'",
+ true, true);
+ while (MYSQL_ROW row = mysql_fetch_row(result))
+ {
+ char query[64];
+
+ if (row[1] && !strcmp(row[1], "Killed"))
+ continue;
+
+ msg_ts("Killing MDL waiting %s ('%s') on connection %s\n",
+ row[1], row[2], row[0]);
+ snprintf(query, sizeof(query), "KILL QUERY %s", row[0]);
+ if (mysql_query(mysql, query) && (mysql_errno(mysql) != ER_NO_SUCH_THREAD)) {
+ msg("Error: failed to execute query %s: %s\n", query,mysql_error(mysql));
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+
+ mysql_close(mysql);
+
+stop_thread:
+ msg_ts("Kill mdl waiters thread stopped\n");
+ os_event_set(mdl_killer_finished_event);
+ os_thread_exit();
+ return os_thread_ret_t(0);
+}
+
+
+static void start_mdl_waiters_killer()
+{
+ mdl_killer_stop_event = os_event_create(0);
+ mdl_killer_finished_event = os_event_create(0);
+ os_thread_create(kill_mdl_waiters_thread, 0, 0);
+}
+
+
+/* Tell MDL killer to stop and finish for its completion*/
+static void stop_mdl_waiters_killer()
+{
+ os_event_set(mdl_killer_stop_event);
+ os_event_wait(mdl_killer_finished_event);
+
+ os_event_destroy(mdl_killer_stop_event);
+ os_event_destroy(mdl_killer_finished_event);
+}
+
/*********************************************************************//**
Function acquires either a backup tables lock, if supported
by the server, or a global read lock (FLUSH TABLES WITH READ LOCK)
@@ -889,6 +968,10 @@ lock_tables(MYSQL *connection)
return(true);
}
+ if (opt_lock_ddl_per_table) {
+ start_mdl_waiters_killer();
+ }
+
if (!opt_lock_wait_timeout && !opt_kill_long_queries_timeout) {
/* We do first a FLUSH TABLES. If a long update is running, the
@@ -929,6 +1012,10 @@ lock_tables(MYSQL *connection)
xb_mysql_query(connection, "FLUSH TABLES WITH READ LOCK", false);
+ if (opt_lock_ddl_per_table) {
+ stop_mdl_waiters_killer();
+ }
+
if (opt_kill_long_queries_timeout) {
stop_query_killer();
}
@@ -1287,8 +1374,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 +1455,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 +1484,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 +1492,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 +1512,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 +1549,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;
}
@@ -1566,28 +1660,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],
make_local_paths(innobase_data_file_path).c_str(),
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 ?
@@ -1611,8 +1698,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;
}
@@ -1668,3 +1755,64 @@ 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);
+ }
+}
+
+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)) {
+
+ DBUG_EXECUTE_IF("rename_during_mdl_lock_table",
+ if (strcmp(row[0], "test/t1") == 0)
+ xb_mysql_query(mysql_connection, "RENAME TABLE test.t1 to test.t2", false, true
+ ););
+
+ std::string full_table_name = ut_get_name(0,row[0]);
+ std::ostringstream lock_query;
+ lock_query << "SELECT 1 FROM " << full_table_name << " LIMIT 0";
+ msg_ts("Locking MDL for %s\n", full_table_name.c_str());
+ if (mysql_query(mdl_con, lock_query.str().c_str())) {
+ msg_ts("Warning : locking MDL failed for space id %zu, name %s\n", space_id, full_table_name.c_str());
+ } else {
+ MYSQL_RES *r = mysql_store_result(mdl_con);
+ mysql_free_result(r);
+ }
+ }
+
+ 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/datasink.c b/extra/mariabackup/datasink.c
index 1459da2fb57..cb31538726f 100644
--- a/extra/mariabackup/datasink.c
+++ b/extra/mariabackup/datasink.c
@@ -108,6 +108,9 @@ Write to a datasink file.
int
ds_write(ds_file_t *file, const void *buf, size_t len)
{
+ if (len == 0) {
+ return 0;
+ }
return file->datasink->write(file, (const uchar *)buf, len);
}
diff --git a/extra/mariabackup/encryption_plugin.cc b/extra/mariabackup/encryption_plugin.cc
index 8f7741b057a..91dc526b2f2 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)
{
@@ -34,11 +35,41 @@ static void add_to_plugin_load_list(const char *plugin_def)
static char XTRABACKUP_EXE[] = "xtrabackup";
+/*
+ Read "plugin-load" value (encryption plugin) from backup-my.cnf during
+ prepare phase.
+ The value is stored during backup phase.
+*/
+static std::string get_encryption_plugin_from_cnf()
+{
+ FILE *f = fopen("backup-my.cnf", "r");
+ if (!f)
+ {
+ msg("cannot open backup-my.cnf for reading\n");
+ exit(EXIT_FAILURE);
+ }
+ char line[512];
+ std::string plugin_load;
+ while (fgets(line, sizeof(line), f))
+ {
+ if (strncmp(line, "plugin_load=", 12) == 0)
+ {
+ plugin_load = line + 12;
+ // remote \n at the end of string
+ plugin_load.resize(plugin_load.size() - 1);
+ break;
+ }
+ }
+ fclose(f);
+ return plugin_load;
+}
+
+
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 +90,27 @@ 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;
+ {
+ /* Remove shared library suffixes, in case we'll prepare on different OS.*/
+ const char *extensions[] = { ".dll", ".so", 0 };
+ for (size_t i = 0; extensions[i]; i++)
+ {
+ const char *ext = extensions[i];
+ if (ends_with(library, ext))
+ library[strlen(library) - strlen(ext)] = 0;
+ }
+ 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 +121,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 +135,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);
@@ -123,14 +164,18 @@ extern int finalize_encryption_plugin(st_plugin_int *plugin);
void encryption_plugin_prepare_init(int argc, char **argv)
{
-
- if (!xb_plugin_load)
+ std::string plugin_load= get_encryption_plugin_from_cnf();
+ if (plugin_load.size())
+ {
+ msg("Loading encryption plugin from %s\n", plugin_load.c_str());
+ }
+ else
{
finalize_encryption_plugin(0);
return;
}
- add_to_plugin_load_list(xb_plugin_load);
+ add_to_plugin_load_list(plugin_load.c_str());
if (xb_plugin_dir)
strncpy(opt_plugin_dir, xb_plugin_dir, FN_REFLEN);
diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc
index be4a625342b..f5b3db1e184 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);
@@ -131,44 +131,41 @@ Open a source file cursor and initialize the associated read filter.
be skipped and XB_FIL_CUR_ERROR on error. */
xb_fil_cur_result_t
xb_fil_cur_open(
-/*============*/
+ /*============*/
xb_fil_cur_t* cursor, /*!< out: source file cursor */
xb_read_filt_t* read_filter, /*!< in/out: the read filter */
fil_node_t* node, /*!< in: source tablespace node */
- uint thread_n) /*!< thread number for diagnostics */
+ uint thread_n, /*!< thread number for diagnostics */
+ ulonglong max_file_size)
{
- ulint page_size;
- ulint page_size_shift;
- ulint zip_size;
- ibool success;
-
+ bool success;
+ int err;
/* Initialize these first so xb_fil_cur_close() handles them correctly
in case of error */
cursor->orig_buf = NULL;
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);
@@ -177,74 +174,69 @@ xb_fil_cur_open(
"tablespace %s\n",
thread_n, cursor->abs_path);
- return(XB_FIL_CUR_ERROR);
+ return(XB_FIL_CUR_SKIP);
}
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;
-
- if (stat(cursor->abs_path, &cursor->statinfo)) {
- msg("[%02u] mariabackup: error: cannot stat %s\n",
+#ifdef _WIN32
+ HANDLE hDup;
+ DuplicateHandle(GetCurrentProcess(),cursor->file.m_file,
+ GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ int filenr = _open_osfhandle((intptr_t)hDup, 0);
+ if (filenr < 0) {
+ err = EINVAL;
+ }
+ else {
+ err = _fstat64(filenr, &cursor->statinfo);
+ close(filenr);
+ }
+#else
+ err = fstat(cursor->file.m_file, &cursor->statinfo);
+#endif
+ if (max_file_size < (ulonglong)cursor->statinfo.st_size) {
+ cursor->statinfo.st_size = (ulonglong)max_file_size;
+ }
+ if (err) {
+ msg("[%02u] mariabackup: error: cannot fstat %s\n",
thread_n, cursor->abs_path);
xb_fil_cur_close(cursor);
- return(XB_FIL_CUR_ERROR);
+ return(XB_FIL_CUR_SKIP);
}
- 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 +246,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 +275,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 +291,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 +307,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,60 +323,60 @@ 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);
- msg("[%02u] mariabackup: "
- "Page " UINT64PF " 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;
- }
- msg("[%02u] mariabackup: "
- "Database page corruption detected at page "
- UINT64PF ", retrying...\n", cursor->thread_n,
- page_no);
-
- os_thread_sleep(100000);
-
- goto read_retry;
- }
- }
- cursor->buf_read += cursor->page_size;
- cursor->buf_npages++;
+ 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: "
+ "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 "
+ ULINTPF ", retrying...\n",
+ cursor->thread_n, page_no);
+ }
+
+ os_thread_sleep(100000);
+
+ goto read_retry;
+ }
+ cursor->buf_read += page_size;
+ cursor->buf_npages++;
}
posix_fadvise(cursor->file, offset, to_read, POSIX_FADV_DONTNEED);
@@ -397,13 +392,14 @@ xb_fil_cur_close(
/*=============*/
xb_fil_cur_t *cursor) /*!< in/out: source file cursor */
{
- cursor->read_filter->deinit(&cursor->read_filter_ctxt);
-
- if (cursor->orig_buf != NULL) {
- ut_free(cursor->orig_buf);
+ if (cursor->read_filter) {
+ cursor->read_filter->deinit(&cursor->read_filter_ctxt);
}
+
+ 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..4d7f7fd84d9 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(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 {
@@ -81,7 +86,8 @@ xb_fil_cur_open(
xb_fil_cur_t* cursor, /*!< out: source file cursor */
xb_read_filt_t* read_filter, /*!< in/out: the read filter */
fil_node_t* node, /*!< in: source tablespace node */
- uint thread_n); /*!< thread number for diagnostics */
+ uint thread_n, /*!< thread number for diagnostics */
+ ulonglong max_file_size = ULLONG_MAX);
/************************************************************************
Reads and verifies the next block of pages from the source
diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc
index a134abb314d..1e174c0fec8 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 7b0b26d803a..8e755171647 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 84f57bde64f..d506228e8c6 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, 2018, 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,52 @@ 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;
+static my_bool verbose;
+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;
+char *xb_rocksdb_datadir;
+my_bool xb_backup_rocksdb = 1;
typedef std::list<regex_t> regex_list_t;
static regex_list_t regex_include_list;
@@ -172,17 +172,11 @@ 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_running;
+static bool io_watching_thread_running;
int xtrabackup_parallel;
@@ -201,7 +195,7 @@ 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;
extern my_bool opt_use_ssl;
@@ -209,15 +203,12 @@ my_bool opt_ssl_verify_server_cert;
/* === 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;
-
-#define XB_LOG_FILENAME "xtrabackup_logfile"
+char metadata_type[30] = ""; /*[full-backuped|log-applied|incremental]*/
+static lsn_t metadata_from_lsn;
+lsn_t metadata_to_lsn;
+static lsn_t metadata_last_lsn;
-ds_file_t *dst_log_file = NULL;
+static ds_file_t* dst_log_file;
static char mysql_data_home_buff[2];
@@ -233,48 +224,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;
+char* innobase_unix_file_flush_method;
-/* 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;
-
-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
@@ -295,7 +272,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;
@@ -304,10 +281,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;
@@ -318,6 +291,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;
@@ -328,7 +302,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};
@@ -336,17 +312,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};
@@ -365,6 +340,27 @@ uint opt_safe_slave_backup_timeout = 0;
const char *opt_history = NULL;
+char mariabackup_exe[FN_REFLEN];
+char orig_argv1[FN_REFLEN];
+
+pthread_mutex_t backup_mutex;
+pthread_cond_t scanned_lsn_cond;
+
+typedef std::map<space_id_t,std::string> space_id_to_name_t;
+
+struct ddl_tracker_t {
+ /** Tablspaces with their ID and name, as they were copied to backup.*/
+ space_id_to_name_t tables_in_backup;
+ /** Tablespaces for that optimized DDL without redo log was found.*/
+ std::set<space_id_t> optimized_ddl;
+ /** Drop operations found in redo log. */
+ std::set<space_id_t> drops;
+ /* For DDL operation found in redo log, */
+ space_id_to_name_t id_to_name;
+};
+
+static ddl_tracker_t ddl_tracker;
+
/* Whether xtrabackup_binlog_info should be created on recovery */
static bool recover_binlog_info;
@@ -381,15 +377,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;
@@ -399,12 +409,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)
@@ -421,7 +432,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)
@@ -431,16 +442,200 @@ 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);
+}
+
+#ifndef DBUG_OFF
+struct dbug_thread_param_t
+{
+ MYSQL *con;
+ const char *query;
+ int expect_err;
+ int expect_errno;
+ os_event_t done_event;
+};
+
+
+/* Thread procedure used in dbug_start_query_thread. */
+extern "C"
+os_thread_ret_t
+DECLARE_THREAD(dbug_execute_in_new_connection)(void *arg)
+{
+ mysql_thread_init();
+ dbug_thread_param_t *par= (dbug_thread_param_t *)arg;
+ int err = mysql_query(par->con, par->query);
+ int err_no = mysql_errno(par->con);
+ DBUG_ASSERT(par->expect_err == err);
+ if (err && par->expect_errno)
+ DBUG_ASSERT(err_no == par->expect_errno);
+ mysql_close(par->con);
+ mysql_thread_end();
+ os_event_t done = par->done_event;
+ delete par;
+ os_event_set(done);
+ os_thread_exit();
+ return os_thread_ret_t(0);
+}
+
+/*
+Execute query from a new connection, in own thread.
+
+@param query - query to be executed
+@param wait_state - if not NULL, wait until query from new connection
+ reaches this state (value of column State in I_S.PROCESSLIST)
+@param expected_err - if 0, query is supposed to finish successfully,
+ otherwise query should return error.
+@param expected_errno - if not 0, and query finished with error,
+ expected mysql_errno()
+*/
+static os_event_t dbug_start_query_thread(
+ const char *query,
+ const char *wait_state,
+ int expected_err,
+ int expected_errno)
+
+{
+ dbug_thread_param_t *par = new dbug_thread_param_t;
+ par->query = query;
+ par->expect_err = expected_err;
+ par->expect_errno = expected_errno;
+ par->done_event = os_event_create(0);
+ par->con = xb_mysql_connect();
+ os_thread_create(dbug_execute_in_new_connection, par, 0);
+
+ if (!wait_state)
+ return par->done_event;
+
+ char q[256];
+ snprintf(q, sizeof(q),
+ "SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST where ID=%lu"
+ " AND Command='Query' AND State='%s'",
+ mysql_thread_id(par->con), wait_state);
+ for (;;) {
+ MYSQL_RES *result = xb_mysql_query(mysql_connection,q, true, true);
+ if (mysql_fetch_row(result)) {
+ goto end;
+ }
+ msg_ts("Waiting for query '%s' on connection %lu to "
+ " reach state '%s'", query, mysql_thread_id(par->con),
+ wait_state);
+ my_sleep(1000);
+ }
+end:
+ msg_ts("query '%s' on connection %lu reached state '%s'", query,
+ mysql_thread_id(par->con), wait_state);
+ return par->done_event;
+}
+
+os_event_t dbug_alter_thread_done;
+#endif
+
+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);
+}
+
+
+// Convert non-null terminated filename to space name
+std::string filename_to_spacename(const byte *filename, size_t len)
+{
+ // null- terminate filename
+ char *f = (char *)malloc(len + 1);
+ ut_a(f);
+ memcpy(f, filename, len);
+ f[len] = 0;
+ for (size_t i = 0; i < len; i++)
+ if (f[i] == '\\')
+ f[i] = '/';
+ char *p = strrchr(f, '.');
+ ut_a(p);
+ *p = 0;
+ char *table = strrchr(f, '/');
+ ut_a(table);
+ *table = 0;
+ char *db = strrchr(f, '/');
+ ut_a(db);
+ *table = '/';
+ return std::string(db+1);
+}
+
+/** Report an operation to create, delete, or rename a file during backup.
+@param[in] space_id tablespace identifier
+@param[in] flags tablespace flags (NULL if not create)
+@param[in] name file name (not NUL-terminated)
+@param[in] len length of name, in bytes
+@param[in] new_name new file name (NULL if not rename)
+@param[in] new_len length of new_name, in bytes (0 if NULL) */
+void backup_file_op(ulint space_id, const byte* flags,
+ const byte* name, ulint len,
+ const byte* new_name, ulint new_len)
+{
+
+ ut_ad(!flags || !new_name);
+ ut_ad(name);
+ ut_ad(len);
+ ut_ad(!new_name == !new_len);
+ pthread_mutex_lock(&backup_mutex);
+
+ if (flags) {
+ ddl_tracker.id_to_name[space_id] = filename_to_spacename(name, len);
+ msg("DDL tracking : create %zu \"%.*s\": %x\n",
+ space_id, int(len), name, mach_read_from_4(flags));
+ }
+ else if (new_name) {
+ ddl_tracker.id_to_name[space_id] = filename_to_spacename(new_name, new_len);
+ msg("DDL tracking : rename %zu \"%.*s\",\"%.*s\"\n",
+ space_id, int(len), name, int(new_len), new_name);
+ } else {
+ ddl_tracker.drops.insert(space_id);
+ msg("DDL tracking : delete %zu \"%.*s\"\n", space_id, int(len), name);
+ }
+ pthread_mutex_unlock(&backup_mutex);
+}
+
+
+/** Callback whenever MLOG_INDEX_LOAD happens.
+@param[in] space_id space id to check */
+static void backup_optimized_ddl_op(ulint space_id)
+{
+ // TODO : handle incremental
+ if (xtrabackup_incremental)
+ return;
+
+ pthread_mutex_lock(&backup_mutex);
+ ddl_tracker.optimized_ddl.insert(space_id);
+ pthread_mutex_unlock(&backup_mutex);
+}
+
+/** Callback whenever MLOG_TRUNCATE happens. */
+static void backup_truncate_fail()
+{
+ msg("mariabackup: Incompatible TRUNCATE operation detected.%s\n",
+ opt_lock_ddl_per_table
+ ? ""
+ : " Use --lock-ddl-per-table to lock all tables before backup.");
}
/* ======== Date copying thread context ======== */
@@ -449,7 +644,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;
@@ -463,7 +658,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,
@@ -476,7 +670,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,
@@ -484,12 +677,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,
@@ -499,7 +690,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,
@@ -510,27 +700,19 @@ 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_PLUGIN_LOAD,
OPT_INNODB_ENCRYPT_LOG,
OPT_CLOSE_FILES,
OPT_CORE_FILE,
@@ -562,11 +744,17 @@ enum options_xtrabackup
OPT_XTRA_TABLES_EXCLUDE,
OPT_XTRA_DATABASES_EXCLUDE,
- OPT_PROTOCOL
+ OPT_PROTOCOL,
+ OPT_LOCK_DDL_PER_TABLE,
+ OPT_ROCKSDB_DATADIR,
+ OPT_BACKUP_ROCKSDB
};
struct my_option xb_client_options[] =
{
+ {"verbose", 'V', "display verbose output",
+ (G_PTR*) &verbose, (G_PTR*) &verbose, 0, GET_BOOL, NO_ARG,
+ FALSE, 0, 0, 0, 0, 0},
{"version", 'v', "print xtrabackup version information",
(G_PTR *) &xtrabackup_version, (G_PTR *) &xtrabackup_version, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -581,10 +769,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 +820,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 +1105,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 +1135,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 +1195,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},
@@ -1049,28 +1222,24 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite,
"Use native AIO if supported on this platform.",
(G_PTR*) &srv_use_native_aio,
(G_PTR*) &srv_use_native_aio, 0, GET_BOOL, NO_ARG,
- FALSE, 0, 0, 0, 0, 0},
+ TRUE, 0, 0, 0, 0, 0},
{"innodb_page_size", OPT_INNODB_PAGE_SIZE,
"The universal page size of the database.",
(G_PTR*) &innobase_page_size, (G_PTR*) &innobase_page_size, 0,
/* 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",
@@ -1083,15 +1252,11 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite,
"The algorithm InnoDB uses for page checksumming. [CRC32, STRICT_CRC32, "
"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},
+ REQUIRED_ARG, SRV_CHECKSUM_ALGORITHM_CRC32, 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,
@@ -1109,19 +1274,36 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite,
&xb_plugin_dir, &xb_plugin_dir,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load during 'prepare' phase.",
- &xb_plugin_load, &xb_plugin_load,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "innodb-encrypt-log", OPT_INNODB_ENCRYPT_LOG, "encrypton plugin to load",
+ { "innodb-encrypt-log", OPT_INNODB_ENCRYPT_LOG, "Whether to encrypt innodb log",
&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},
+
+ {"rocksdb-datadir", OPT_ROCKSDB_DATADIR, "RocksDB data directory."
+ "This option is only used with --copy-back or --move-back option",
+ &xb_rocksdb_datadir, &xb_rocksdb_datadir,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+
+ { "rocksdb-backup", OPT_BACKUP_ROCKSDB, "Backup rocksdb data, if rocksdb plugin is installed."
+ "Used only with --backup option. Can be useful for partial backups, to exclude all rocksdb data",
+ &xb_backup_rocksdb, &xb_backup_rocksdb,
+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
+
+
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -1182,6 +1364,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)
+ {
+ snprintf(cmdline, sizeof 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 +1550,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 +1563,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 +1580,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);
@@ -1406,40 +1663,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));
@@ -1471,10 +1697,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) {
@@ -1488,30 +1710,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 */
@@ -1541,37 +1743,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 */
@@ -1585,60 +1770,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;
@@ -1648,7 +1811,7 @@ mem_free_and_error:
srv_max_n_open_files = (ulint) innobase_open_files;
srv_innodb_status = (ibool) innobase_create_status_file;
- srv_print_verbose_log = 1;
+ srv_print_verbose_log = verbose ? 2 : 1;
/* Store the default charset-collation number of this MySQL
installation */
@@ -1656,18 +1819,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
@@ -1681,31 +1834,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)
@@ -1728,11 +1858,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);
@@ -1741,57 +1872,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 ================= */
@@ -1946,8 +2037,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");
@@ -1959,9 +2049,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);
}
@@ -1970,10 +2060,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 "
@@ -1996,10 +2090,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;
@@ -2156,7 +2253,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 {
@@ -2264,35 +2361,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)
{
@@ -2319,7 +2387,7 @@ xb_get_copy_action(const char *dflt)
static
my_bool
-xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
+xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=0, ulonglong max_size=ULLONG_MAX)
{
char dst_name[FN_REFLEN];
ds_file_t *dstfile = NULL;
@@ -2329,7 +2397,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
@@ -2344,27 +2411,37 @@ 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);
}
+ bool was_dropped;
+ pthread_mutex_lock(&backup_mutex);
+ was_dropped = (ddl_tracker.drops.find(node->space->id) != ddl_tracker.drops.end());
+ pthread_mutex_unlock(&backup_mutex);
+ if (was_dropped) {
+ fil_space_close(node->space->name);
+ goto skip;
+ }
+
if (!changed_page_bitmap) {
read_filter = &rf_pass_through;
}
else {
read_filter = &rf_bitmap;
}
- res = xb_fil_cur_open(&cursor, read_filter, node, thread_n);
+
+ res = xb_fil_cur_open(&cursor, read_filter, node, thread_n,max_size);
if (res == XB_FIL_CUR_SKIP) {
goto skip;
} else if (res == XB_FIL_CUR_ERROR) {
goto error;
}
- strncpy(dst_name, cursor.rel_path, sizeof(dst_name));
+ strncpy(dst_name, (dest_name)?dest_name : cursor.rel_path, sizeof(dst_name));
+
/* Setup the page write filter */
if (xtrabackup_incremental) {
@@ -2416,6 +2493,10 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
goto error;
}
+ pthread_mutex_lock(&backup_mutex);
+ ddl_tracker.tables_in_backup[node->space->id] = node_name;
+ pthread_mutex_unlock(&backup_mutex);
+
/* close */
msg_ts("[%02u] ...done\n", thread_n);
xb_fil_cur_close(&cursor);
@@ -2455,357 +2536,165 @@ 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);
-
-/*******************************************************//**
-Scans log from a buffer and writes new log data to the outpud datasinc.
-@return true if success */
-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*/
+/** Copy redo log blocks to the data sink.
+@param start_lsn buffer start LSN
+@param end_lsn buffer end LSN
+@param last whether we are copying the final part of the log
+@return last scanned LSN
+@retval 0 on failure */
+static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last)
{
- 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 */
+ msg("mariabackup: checkpoint wrap: "
+ LSN_PF ",%zx,%zx\n",
+ scanned_lsn, scanned_checkpoint, checkpoint);
+ 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. */
+ scanned_checkpoint = checkpoint;
- if (scanned_lsn > *contiguous_lsn) {
+ ulint data_len = log_block_get_data_len(log_block);
- *contiguous_lsn = scanned_lsn;
- }
- }
-
- data_len = log_block_get_data_len(log_block);
+ more_data = recv_sys_add_to_parsing_buf(
+ log_block,
+ scanned_lsn + data_len);
- 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)) {
-
- /* 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). */
+ msg("mariabackup: garbage block: " LSN_PF ",%zu\n",
+ scanned_lsn, data_len);
+ 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 = 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 last whether we are copying the final part of the log
+@return whether the operation failed */
+static bool xtrabackup_copy_logfile(bool last = false)
{
- /* 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;
-
- start_lsn = contiguous_lsn;
-
- while (!finished) {
-
- end_lsn = start_lsn + RECV_SCAN_SIZE;
-
- xtrabackup_io_throttling();
+ lsn_t start_lsn;
+ lsn_t end_lsn;
- mutex_enter(&log_sys->mutex);
+ recv_sys->parse_start_lsn = log_copy_scanned_lsn;
+ recv_sys->scanned_lsn = log_copy_scanned_lsn;
- bool scan_ok = false;
- bool must_reread_log;
- int retries = 0;
- do {
+ start_lsn = ut_uint64_align_down(log_copy_scanned_lsn,
+ OS_FILE_LOG_BLOCK_SIZE);
+ do {
+ end_lsn = start_lsn + RECV_SCAN_SIZE;
- log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
- group, start_lsn, end_lsn, false);
+ xtrabackup_io_throttling();
- 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;
+ log_mutex_enter();
+ 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)
+ || lsn != start_lsn) {
+ break;
}
-
- mutex_exit(&log_sys->mutex);
-
- start_lsn = end_lsn;
-
+ msg("Retrying read of log at LSN=" LSN_PF "\n", lsn);
+ 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);
+ start_lsn = (lsn == start_lsn)
+ ? 0 : xtrabackup_copy_log(start_lsn, lsn, last);
- /* update global variable*/
- log_copy_scanned_lsn = group_scanned_lsn;
+ log_mutex_exit();
- /* innodb_mirrored_log_groups must be 1, no other groups */
- ut_a(group == NULL);
+ if (!start_lsn) {
+ msg("mariabackup: Error: xtrabackup_copy_logfile()"
+ " failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ } while (start_lsn == end_lsn);
- debug_sync_point("xtrabackup_copy_logfile_pause");
+ ut_ad(start_lsn == log_sys->log.scanned_lsn);
- }
+ msg_ts(">> log scanned up to (" LSN_PF ")\n", start_lsn);
+ /* update global variable*/
+ pthread_mutex_lock(&backup_mutex);
+ log_copy_scanned_lsn = start_lsn;
+ pthread_cond_broadcast(&scanned_lsn_cond);
+ pthread_mutex_unlock(&backup_mutex);
- return(FALSE);
+ debug_sync_point("xtrabackup_copy_logfile_pause");
+ return(false);
+}
-error:
- mutex_exit(&log_sys->mutex);
- ds_close(dst_log_file);
- msg("mariabackup: Error: xtrabackup_copy_logfile() failed.\n");
- return(TRUE);
+/**
+Wait until redo log copying thread processes given lsn
+*/
+void backup_wait_for_lsn(lsn_t lsn) {
+ bool completed = false;
+ pthread_mutex_lock(&backup_mutex);
+ do {
+ pthread_cond_wait(&scanned_lsn_cond, &backup_mutex);
+ completed = log_copy_scanned_lsn >= lsn;
+ } while (!completed);
+ pthread_mutex_unlock(&backup_mutex);
}
-static
-#ifndef __WIN__
-void*
-#else
-ulint
-#endif
-log_copying_thread(
- void* arg __attribute__((unused)))
+extern lsn_t server_lsn_after_lock;
+
+static os_thread_ret_t log_copying_thread(void*)
{
/*
Initialize mysys thread-specific memory so we can
@@ -2813,54 +2702,38 @@ log_copying_thread(
*/
my_thread_init();
- ut_a(dst_log_file != NULL);
-
- log_copying_running = TRUE;
-
- while(log_copying) {
+ for (;;) {
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);
- }
+ if (xtrabackup_copy_logfile()) {
+ break;
}
- }
-
- /* last copying */
- if(xtrabackup_copy_logfile(log_copy_scanned_lsn, TRUE)) {
- exit(EXIT_FAILURE);
+ log_mutex_enter();
+ bool completed = metadata_to_lsn
+ && metadata_to_lsn <= log_copy_scanned_lsn;
+ log_mutex_exit();
+ if (completed) {
+ break;
+ }
}
- 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) {
+ while (log_copying_running && !metadata_to_lsn) {
os_thread_sleep(1000000); /*1 sec*/
io_ticket = xtrabackup_throttle;
os_event_set(wait_throttle);
@@ -2870,48 +2743,48 @@ 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)
+#ifndef DBUG_OFF
+/*
+In debug mode, execute SQL statement that was passed via environment.
+To use this facility, you need to
+
+1. Add code DBUG_EXECUTE_MARIABACKUP_EVENT("my_event_name", key););
+ to the code. key is usually a table name
+2. Set environment variable my_event_name_$key SQL statement you want to execute
+ when event occurs, in DBUG_EXECUTE_IF from above.
+ In mtr , you can set environment via 'let' statement (do not use $ as the first char
+ for the variable)
+3. start mariabackup with --dbug=+d,debug_mariabackup_events
+*/
+static void dbug_mariabackup_event(const char *event,const char *key)
{
- ulint segment;
-
-
- segment = *((ulint*)arg);
-
- while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
- fil_aio_wait(segment);
+ char envvar[FN_REFLEN];
+ if (key) {
+ snprintf(envvar, sizeof(envvar), "%s_%s", event, key);
+ char *slash = strchr(envvar, '/');
+ if (slash)
+ *slash = '_';
+ } else {
+ strncpy(envvar, event, sizeof(envvar));
+ }
+ char *sql = getenv(envvar);
+ if (sql) {
+ msg("dbug_mariabackup_event : executing '%s'\n", sql);
+ xb_mysql_query(mysql_connection, sql, false, true);
}
- /* 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 */
+}
+#define DBUG_MARIABACKUP_EVENT(A, B) DBUG_EXECUTE_IF("mariabackup_events", dbug_mariabackup_event(A,B););
#else
- return(0);
+#define DBUG_MARIABACKUP_EVENT(A,B)
#endif
-}
/**************************************************************************
Datafiles copying thread.*/
@@ -2935,20 +2808,26 @@ data_copy_thread_func(
while ((node = datafiles_iter_next(ctxt->it)) != NULL) {
+ DBUG_MARIABACKUP_EVENT("before_copy", node->space->name);
+
+
/* copy the datafile */
if(xtrabackup_copy_datafile(node, num)) {
msg("[%02u] mariabackup: Error: "
"failed to copy datafile.\n", num);
exit(EXIT_FAILURE);
}
+
+ DBUG_MARIABACKUP_EVENT("after_copy", node->space->name);
+
}
- 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;
}
@@ -2958,7 +2837,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)
@@ -3044,41 +2923,255 @@ 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) {
+ msg("Can't open datafile %s\n", name);
+ 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.
@@ -3093,7 +3186,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;
@@ -3101,40 +3194,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, (sizeof name) - dirnamelen,
- "%s", "ibdata1");
+ snprintf(name + dirnamelen, (sizeof name) - dirnamelen,
+ "%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;
}
@@ -3164,53 +3255,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;
+ lsn_t flush_lsn;
- os_thread_create(io_handler_thread, thread_nr + i,
- thread_ids + i);
- }
+ ut_ad(srv_operation == SRV_OPERATION_BACKUP
+ || srv_operation == SRV_OPERATION_RESTORE_DELTA);
- os_thread_sleep(200000); /*0.2 sec*/
+ err = srv_sys_space.check_file_spec(&create_new_db, 0);
- 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);
- }
-
- /* 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();
@@ -3219,27 +3291,25 @@ 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);
}
debug_sync_point("xtrabackup_load_tablespaces_pause");
-
+ DBUG_MARIABACKUP_EVENT("after_load_tablespaces", 0);
return(DB_SUCCESS);
}
@@ -3247,9 +3317,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();
@@ -3258,46 +3328,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;
}
/***********************************************************************
@@ -3316,7 +3355,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);
@@ -3369,7 +3408,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);
}
@@ -3615,7 +3654,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);
}
}
@@ -3664,86 +3703,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);
}
@@ -3756,20 +3742,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);
}
@@ -3830,15 +3804,122 @@ end:
#endif
}
-void
-xtrabackup_backup_func(void)
+static void stop_backup_threads()
+{
+ if (log_copying_stop && log_copying_running) {
+ os_event_set(log_copying_stop);
+ fputs("mariabackup: Stopping log copying thread", stderr);
+ fflush(stderr);
+ while (log_copying_running) {
+ putc('.', stderr);
+ fflush(stderr);
+ os_thread_sleep(200000); /*0.2 sec*/
+ }
+ putc('\n', stderr);
+ 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()
+{
+ ut_ad(!metadata_to_lsn);
+
+ /* 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) {
+ if (max_cp_field == LOG_CHECKPOINT_1) {
+ log_group_header_read(&log_sys->log,
+ max_cp_field);
+ }
+ 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 {
+ msg("mariabackup: Error: recv_find_max_checkpoint() failed.\n");
+ }
+ log_mutex_exit();
+ }
+
+ stop_backup_threads();
+
+ if (metadata_to_lsn && xtrabackup_copy_logfile(true)) {
+ ds_close(dst_log_file);
+ dst_log_file = NULL;
+ return false;
+ }
+
+ if (ds_close(dst_log_file) || !metadata_to_lsn) {
+ 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;
+ pthread_mutex_init(&backup_mutex, NULL);
+ pthread_cond_init(&scanned_lsn_cond, NULL);
#ifdef USE_POSIX_FADVISE
msg("mariabackup: uses posix_fadvise().\n");
@@ -3849,10 +3930,10 @@ 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);
-
+ encryption_plugin_backup_init(mysql_connection);
msg("mariabackup: open files limit requested %u, set to %u\n",
(uint) xb_open_files_limit,
xb_set_max_open_files(xb_open_files_limit));
@@ -3864,54 +3945,65 @@ 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;
+ log_file_op = backup_file_op;
+ metadata_to_lsn = 0;
- 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:
+ metadata_to_lsn = log_copying_running;
+ stop_backup_threads();
+ log_file_op = NULL;
+ if (dst_log_file) {
+ ds_close(dst_log_file);
+ dst_log_file = NULL;
+ }
+ 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) {
@@ -3931,12 +4023,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
@@ -3950,18 +4048,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) {
@@ -3978,15 +4081,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;
}
}
@@ -3997,7 +4099,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 */
@@ -4005,164 +4107,156 @@ 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);
- }
-
- ut_free(log_hdr_buf_);
-
- /* start flag */
- log_copying = TRUE;
-
+ 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;
+ }
+
+ log_copying_running = true;
/* start io throttle */
if(xtrabackup_throttle) {
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));
+fail_before_log_copying_thread_start:
+ log_copying_running = false;
+ goto fail;
}
+ /* copy log file by current position */
+ log_copy_scanned_lsn = checkpoint_lsn_start;
+ recv_sys->recovered_lsn = log_copy_scanned_lsn;
+ log_optimized_ddl_op = backup_optimized_ddl_op;
+ log_truncate = backup_truncate_fail;
+
+ if (xtrabackup_copy_logfile())
+ goto fail_before_log_copying_thread_start;
+
+ log_copying_stop = os_event_create(0);
+ 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");
- if (xtrabackup_incremental) {
- if (!xtrabackup_incremental_force_scan) {
- changed_page_bitmap = xb_page_bitmap_init();
- }
- if (!changed_page_bitmap) {
- msg("mariabackup: using the full scan for incremental "
- "backup\n");
- } else if (incremental_lsn != checkpoint_lsn_start) {
- /* Do not print that bitmaps are used when dummy bitmap
- is build for an empty LSN range. */
- msg("mariabackup: using the changed page bitmap\n");
- }
- }
ut_a(xtrabackup_parallel > 0);
@@ -4171,17 +4265,26 @@ reread_log_header:
"files transfer\n", xtrabackup_parallel);
}
- it = datafiles_iter_new(f_system);
+ if (opt_lock_ddl_per_table) {
+ mdl_lock_all();
+
+ DBUG_EXECUTE_IF("check_mdl_lock_works",
+ dbug_alter_thread_done =
+ dbug_start_query_thread("ALTER TABLE test.t ADD COLUMN mdl_lock_column int",
+ "Waiting for table metadata lock", 1, ER_QUERY_INTERRUPTED););
+ }
+
+ 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;
@@ -4195,411 +4298,234 @@ 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) {
- xb_page_bitmap_deinit(changed_page_bitmap);
- }
}
- if (!backup_start()) {
- exit(EXIT_FAILURE);
- }
+ bool ok = backup_start();
- /* read the latest checkpoint lsn */
- latest_cp = 0;
- {
- log_group_t* max_cp_group;
- ulint max_cp_field;
- ulint err;
+ if (ok) {
+ ok = xtrabackup_backup_low();
- mutex_enter(&log_sys->mutex);
+ backup_release();
- err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
+ DBUG_EXECUTE_IF("check_mdl_lock_works",
+ os_event_wait(dbug_alter_thread_done);
+ os_event_destroy(dbug_alter_thread_done);
+ );
- 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(!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 (!ok) {
+ goto fail;
}
- if (!backup_finish()) {
- exit(EXIT_FAILURE);
+ if (changed_page_bitmap) {
+ xb_page_bitmap_deinit(changed_page_bitmap);
}
-
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;
}
-}
-
-/* ================= 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;
+ innodb_shutdown();
+ log_file_op = NULL;
+ pthread_mutex_destroy(&backup_mutex);
+ pthread_cond_destroy(&scanned_lsn_cond);
+ return(true);
+}
- lsn_t max_no = 0;
- lsn_t max_lsn = 0;
- ulint fold;
+/**
+This function handles DDL changes at the end of backup, under protection of
+FTWRL. This ensures consistent backup in presence of DDL.
- if (!log_buf) {
- goto error;
- }
+- New tables, that were created during backup, are now copied into backup.
+ Also, tablespaces with optimized (no redo loggin DDL) are re-copied into
+ backup. This tablespaces will get the extension ".new" in the backup
- if (!xb_init_log_block_size()) {
- goto error;
- }
+- Tables that were renamed during backup, are marked as renamed
+ For these, file <old_name>.ren will be created.
+ The content of the file is the new tablespace name.
- 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);
- }
+- Tables that were deleted during backup, are marked as deleted
+ For these , an empty file <name>.del will be created
- 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);
+ It is the responsibility of the prepare phase to deal with .new, .ren, and .del
+ files.
+*/
+void backup_fix_ddl(void)
+{
+ std::set<std::string> new_tables;
+ std::set<std::string> dropped_tables;
+ std::map<std::string, std::string> renamed_tables;
- /* 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);
+ for (space_id_to_name_t::iterator iter = ddl_tracker.tables_in_backup.begin();
+ iter != ddl_tracker.tables_in_backup.end();
+ iter++) {
- goto error;
- }
+ const std::string name = iter->second;
+ ulint id = iter->first;
- success = os_file_read(src_file, log_buf, 0,
- LOG_FILE_HDR_SIZE);
- if (!success) {
- goto error;
+ if (ddl_tracker.drops.find(id) != ddl_tracker.drops.end()) {
+ dropped_tables.insert(name);
+ continue;
}
- 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");
+ bool has_optimized_ddl =
+ ddl_tracker.optimized_ddl.find(id) != ddl_tracker.optimized_ddl.end();
- 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;
+ if (ddl_tracker.id_to_name.find(id) == ddl_tracker.id_to_name.end()) {
+ if (has_optimized_ddl) {
+ new_tables.insert(name);
}
-
- goto retry;
+ continue;
}
- msg("mariabackup: Fatal error: cannot find %s.\n", src_path);
-
- os_file_close(src_file);
- src_file = XB_FILE_UNDEFINED;
-
- goto error;
+ /* tablespace was affected by DDL. */
+ const std::string new_name = ddl_tracker.id_to_name[id];
+ if (new_name != name) {
+ if (has_optimized_ddl) {
+ /* table was renamed, but we need a full copy
+ of it because of optimized DDL. We emulate a drop/create.*/
+ dropped_tables.insert(name);
+ new_tables.insert(new_name);
+ } else {
+ /* Renamed, and no optimized DDL*/
+ renamed_tables[name] = new_name;
+ }
+ } else if (has_optimized_ddl) {
+ /* Table was recreated, or optimized DDL ran.
+ In both cases we need a full copy in the backup.*/
+ new_tables.insert(name);
+ }
}
- 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;
- }
+ /* Find tables that were created during backup (and not removed).*/
+ for(space_id_to_name_t::iterator iter = ddl_tracker.id_to_name.begin();
+ iter != ddl_tracker.id_to_name.end();
+ iter++) {
- 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);
- }
+ ulint id = iter->first;
+ std::string name = iter->second;
- /* 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)))
+ if (ddl_tracker.tables_in_backup.find(id) != ddl_tracker.tables_in_backup.end()) {
+ /* already processed above */
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 (ddl_tracker.drops.find(id) == ddl_tracker.drops.end()) {
+ dropped_tables.erase(name);
+ new_tables.insert(name);
}
}
- if (!max_lsn) {
- msg("mariabackup: No valid checkpoint found.\n");
- goto error;
+ // Mark tablespaces for rename
+ for (std::map<std::string, std::string>::iterator iter = renamed_tables.begin();
+ iter != renamed_tables.end(); ++iter) {
+ const std::string old_name = iter->first;
+ std::string new_name = iter->second;
+ backup_file_printf((old_name + ".ren").c_str(), "%s", new_name.c_str());
}
- /* 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;
+ // Mark tablespaces for drop
+ for (std::set<std::string>::iterator iter = dropped_tables.begin();
+ iter != dropped_tables.end();
+ iter++) {
+ const std::string name(*iter);
+ backup_file_printf((name + ".del").c_str(), "%s", "");
}
- /* 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);
+ // Load and copy new tables.
+ // Close all datanodes first, reload only new tables.
+ std::vector<fil_node_t *> all_nodes;
+ datafiles_iter_t *it = datafiles_iter_new(fil_system);
+ if (!it)
+ return;
+ while (fil_node_t *node = datafiles_iter_next(it)) {
+ all_nodes.push_back(node);
}
-
- /* 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;
- }
+ for (size_t i = 0; i < all_nodes.size(); i++) {
+ fil_node_t *n = all_nodes[i];
+ if (n->space->id == 0)
+ continue;
+ fil_space_close(n->space->name);
+ fil_space_free(n->space->id, false);
}
- /* 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;
+
+ for (std::set<std::string>::iterator iter = new_tables.begin();
+ iter != new_tables.end(); iter++) {
+ const char *space_name = iter->c_str();
+ if (check_if_skip_table(space_name))
+ continue;
+ std::string name(*iter);
+ bool is_remote = access((name + ".ibd").c_str(), R_OK) != 0;
+ const char *extension = is_remote ? ".isl" : ".ibd";
+ name.append(extension);
+ char buf[FN_REFLEN];
+ strncpy(buf, name.c_str(), sizeof(buf));
+ const char *dbname = buf;
+ char *p = strchr(buf, '/');
+ if (p == 0) {
+ msg("Unexpected tablespace %s filename %s\n", space_name, name.c_str());
+ ut_a(0);
}
- file_size = os_file_get_size(src_file);
+ ut_a(p);
+ *p = 0;
+ const char *tablename = p + 1;
+ xb_load_single_table_tablespace(dbname, tablename, is_remote);
}
- 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;
+ it = datafiles_iter_new(fil_system);
+ if (!it)
+ return;
- /* rename 'xtrabackup_logfile' to 'ib_logfile0' */
- success = os_file_rename(0, src_path, dst_path);
- if (!success) {
- goto error;
+ while (fil_node_t *node = datafiles_iter_next(it)) {
+ fil_space_t * space = node->space;
+ if (!fil_is_user_tablespace_id(space->id))
+ continue;
+ std::string dest_name(node->space->name);
+ dest_name.append(".new");
+#if 0
+ bool do_full_copy = ddl_tracker.optimized_ddl.find(n->space->id) != ddl_tracker.optimized_ddl.end();
+ if (do_full_copy) {
+ msg(
+ "Performing a full copy of the tablespace %s, because optimized (without redo logging) DDL operation"
+ "ran during backup. You can use set innodb_log_optimize_ddl=OFF to improve backup performance"
+ "in the future.\n",
+ n->space->name);
+ }
+#endif
+ xtrabackup_copy_datafile(node, 0, dest_name.c_str()/*, do_full_copy ? ULONGLONG_MAX:UNIV_PAGE_SIZE */);
}
- 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*/
}
+/* ================= prepare ================= */
+
/***********************************************************************
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'
@@ -4629,24 +4555,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;
@@ -4661,7 +4585,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));
@@ -4670,19 +4594,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 =
@@ -4690,13 +4614,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",
@@ -4721,35 +4645,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);
}
@@ -4757,7 +4678,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';
@@ -4767,13 +4688,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);
@@ -4786,21 +4720,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);
@@ -4809,14 +4746,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];
@@ -4826,7 +4763,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",
@@ -4838,49 +4777,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;
}
/************************************************************************
@@ -4901,13 +4821,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;
@@ -4937,29 +4857,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 +4888,7 @@ xtrabackup_apply_delta(
posix_fadvise(src_file, 0, 0, POSIX_FADV_SEQUENTIAL);
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);
@@ -4980,8 +4899,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));
@@ -4995,8 +4913,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;
}
@@ -5014,6 +4932,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)
@@ -5024,8 +4945,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;
}
@@ -5047,31 +4969,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;
}
@@ -5087,29 +5012,47 @@ 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);
return FALSE;
}
+
+std::string change_extension(std::string filename, std::string new_ext) {
+ DBUG_ASSERT(new_ext.size() == 3);
+ std::string new_name(filename);
+ new_name.resize(new_name.size() - new_ext.size());
+ new_name.append(new_ext);
+ return new_name;
+}
+
+
+static void rename_file(const char *from,const char *to) {
+ msg("Renaming %s to %s\n", from, to);
+ if (my_rename(from, to, MY_WME)) {
+ msg("Cannot rename %s to %s errno %d", from, to, errno);
+ exit(EXIT_FAILURE);
+ }
+}
+
+static void rename_file(const std::string& from, const std::string &to) {
+ rename_file(from.c_str(), to.c_str());
+}
/************************************************************************
Callback to handle datadir entry. Function of this type will be called
for each entry which matches the mask by xb_process_datadir.
@@ -5121,6 +5064,37 @@ typedef ibool (*handle_datadir_entry_func_t)(
const char* file_name, /*!<in: file name with suffix */
void* arg); /*!<in: caller-provided data */
+/** Rename, and replace destination file, if exists */
+static void rename_force(const char *from, const char *to) {
+ if (access(to, R_OK) == 0) {
+ msg("Removing %s\n", to);
+ if (my_delete(to, MYF(MY_WME))) {
+ msg("Can't remove %s, errno %d", to, errno);
+ exit(EXIT_FAILURE);
+ }
+ }
+ rename_file(from,to);
+}
+
+/* During prepare phase, rename ".new" files , that were created in backup_fix_ddl(),
+ to ".ibd".*/
+static ibool prepare_handle_new_files(
+ const char* data_home_dir, /*!<in: path to datadir */
+ const char* db_name, /*!<in: database name */
+ const char* file_name, /*!<in: file name with suffix */
+ void *)
+{
+
+ std::string src_path = std::string(data_home_dir) + '/' + std::string(db_name) + '/' + file_name;
+ std::string dest_path = src_path;
+
+ size_t index = dest_path.find(".new");
+ DBUG_ASSERT(index != std::string::npos);
+ dest_path.replace(index, 4, ".ibd");
+ rename_force(src_path.c_str(),dest_path.c_str());
+ return TRUE;
+}
+
/************************************************************************
Callback to handle datadir entry. Deletes entry if it has no matching
fil_space in fil_system directory.
@@ -5164,9 +5138,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];
@@ -5201,7 +5173,7 @@ xb_process_datadir(
suffix)) {
if (!func(
path, NULL,
- fileinfo.name, data))
+ fileinfo.name, NULL))
{
return(FALSE);
}
@@ -5236,7 +5208,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);
@@ -5261,7 +5234,7 @@ next_file_item_1:
if (!func(
path,
dbinfo.name,
- fileinfo.name, data))
+ fileinfo.name, NULL))
{
return(FALSE);
}
@@ -5293,476 +5266,142 @@ 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 */
+void
+innodb_free_param()
{
- 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);
+ srv_sys_space.shutdown();
+ free_tmpdir(&mysql_tmpdir_list);
}
-/*********************************************************************//**
-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 */
+/** 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, const char* name, ulonglong pos)
{
- 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);
+ FILE *fp = fopen(filename, "w");
- 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);
- }
+ if (!fp) {
+ msg("mariabackup: failed to open '%s'\n", filename);
+ return(false);
}
+ fprintf(fp, "%s\t%llu\n", name, pos);
+ fclose(fp);
+
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 */
+/** Check if file exists*/
+static bool file_exists(std::string name)
{
- 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 access(name.c_str(), R_OK) == 0 ;
+}
- return(false);
+/** Read file content into STL string */
+static std::string read_file_as_string(const std::string file) {
+ char content[FN_REFLEN];
+ FILE *f = fopen(file.c_str(), "r");
+ if (!f) {
+ msg("Can not open %s\n", file.c_str());
}
+ size_t len = fread(content, 1, FN_REFLEN, f);
+ fclose(f);
+ return std::string(content, len);
+}
- /* 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);
+/** Delete file- Provide verbose diagnostics and exit, if operation fails. */
+static void delete_file(const std::string& file, bool if_exists = false) {
+ if (if_exists && !file_exists(file))
+ return;
+ if (my_delete(file.c_str(), MYF(MY_WME))) {
+ msg("Can't remove %s, errno %d", file.c_str(), errno);
+ exit(EXIT_FAILURE);
}
+}
- /* 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);
+/**
+Rename tablespace during prepare.
+Backup in its end phase may generate some .ren files, recording
+tablespaces that should be renamed in --prepare.
+*/
+static void rename_table_in_prepare(const std::string &datadir, const std::string& from , const std::string& to,
+ const char *extension=0) {
+ if (!extension) {
+ static const char *extensions_nonincremental[] = { ".ibd", 0 };
+ static const char *extensions_incremental[] = { ".ibd.delta", ".ibd.meta", 0 };
+ const char **extensions = xtrabackup_incremental_dir ?
+ extensions_incremental : extensions_nonincremental;
+ for (size_t i = 0; extensions[i]; i++) {
+ rename_table_in_prepare(datadir, from, to, extensions[i]);
+ }
+ return;
}
-
- 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);
+ std::string src = std::string(datadir) + "/" + from + extension;
+ std::string dest = std::string(datadir) + "/" + to + extension;
+ std::string ren2, tmp;
+ if (file_exists(dest)) {
+ ren2= std::string(datadir) + "/" + to + ".ren";
+ if (!file_exists(ren2)) {
+ msg("ERROR : File %s was not found, but expected during rename processing\n", ren2.c_str());
+ ut_a(0);
+ }
+ tmp = to + "#";
+ rename_table_in_prepare(datadir, to, tmp);
}
-
- 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);
+ rename_file(src, dest);
+ if (ren2.size()) {
+ // Make sure the temp. renamed file is processed.
+ std::string to2 = read_file_as_string(ren2);
+ rename_table_in_prepare(datadir, tmp, to2);
+ delete_file(ren2);
}
-
- 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);
+static ibool prepare_handle_ren_files(const char *datadir, const char *db, const char *filename, void *) {
- success = false;
- } else {
-
- success = xb_export_cfg_write_header(table, file);
-
- if (success) {
- success = xb_export_cfg_write_table(table, file);
- }
+ std::string ren_file = std::string(datadir) + "/" + db + "/" + filename;
+ if (!file_exists(ren_file))
+ return TRUE;
- if (success) {
- success = xb_export_cfg_write_indexes(table, file);
- }
+ std::string to = read_file_as_string(ren_file);
+ std::string source_space_name = std::string(db) + "/" + filename;
+ source_space_name.resize(source_space_name.size() - 4); // remove extension
- 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;
- free_tmpdir(&mysql_tmpdir_list);
+ rename_table_in_prepare(datadir, source_space_name.c_str(), to.c_str());
+ delete_file(ren_file);
+ return TRUE;
}
-
-/**************************************************************************
-Store the current binary log coordinates in a specified file.
-@return 'false' on error. */
-static bool
-store_binlog_info(
-/*==============*/
- const char *filename) /*!< in: output file name */
-{
- FILE *fp;
-
- if (trx_sys_mysql_bin_log_name[0] == '\0') {
- return(true);
+/* Remove tablespaces during backup, based on */
+static ibool prepare_handle_del_files(const char *datadir, const char *db, const char *filename, void *) {
+ std::string del_file = std::string(datadir) + "/" + db + "/" + filename;
+ std::string path(del_file);
+ path.resize(path.size() - 4); // remove extension;
+ if (xtrabackup_incremental) {
+ delete_file(path + ".ibd.delta", true);
+ delete_file(path + ".ibd.meta", true);
}
-
- fp = fopen(filename, "w");
-
- if (!fp) {
- msg("mariabackup: failed to open '%s'\n", filename);
- return(false);
+ else {
+ delete_file(path + ".ibd", true);
}
-
- fprintf(fp, "%s\t" UINT64PF "\n",
- trx_sys_mysql_bin_log_name, trx_sys_mysql_bin_log_pos);
- fclose(fp);
-
- return(true);
+ delete_file(del_file);
+ 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 */
@@ -5771,15 +5410,33 @@ 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);
+ fil_path_to_mysql_datadir = ".";
+
+ if (xtrabackup_incremental_dir) {
+ xb_process_datadir(xtrabackup_incremental_dir, ".new.meta", prepare_handle_new_files);
+ xb_process_datadir(xtrabackup_incremental_dir, ".new.delta", prepare_handle_new_files);
+ }
+ else {
+ xb_process_datadir(".", ".new", prepare_handle_new_files);
+ }
+ xb_process_datadir(xtrabackup_incremental_dir? xtrabackup_incremental_dir:".",
+ ".ren", prepare_handle_ren_files);
+ xb_process_datadir(xtrabackup_incremental_dir ? xtrabackup_incremental_dir : ".",
+ ".del", prepare_handle_del_files);
+
+
+ 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
@@ -5790,116 +5447,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;
}
@@ -5914,223 +5557,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)
@@ -6144,73 +5629,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;
}
/**************************************************************************
@@ -6297,7 +5734,6 @@ xb_init()
return(false);
}
- encryption_plugin_backup_init(mysql_connection);
history_start_time = time(NULL);
}
@@ -6313,7 +5749,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;
@@ -6340,29 +5777,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;
+
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();
@@ -6371,7 +5805,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;
@@ -6536,22 +5970,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]);
@@ -6578,28 +6032,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
- int argc_client;
- for (argc_client = 0; client_defaults[argc_client]; argc_client++) {}
+ if (THR_THD)
+ (void) pthread_key_delete(THR_THD);
+ logger.cleanup_base();
+ mysql_mutex_destroy(&LOCK_error_log);
+ 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,
@@ -6665,7 +6153,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];
@@ -6675,7 +6163,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;
@@ -6688,7 +6176,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;
@@ -6709,15 +6197,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();
@@ -6743,7 +6229,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);
}
}
@@ -6754,41 +6240,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..857c253f803 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;
@@ -56,6 +44,9 @@ extern char *xtrabackup_incremental_basedir;
extern char *innobase_data_home_dir;
extern char *innobase_buffer_pool_filename;
extern char *xb_plugin_dir;
+extern char *xb_rocksdb_datadir;
+extern my_bool xb_backup_rocksdb;
+
extern uint opt_protocol;
extern ds_ctxt_t *ds_meta;
extern ds_ctxt_t *ds_data;
@@ -68,9 +59,7 @@ extern xb_page_bitmap *changed_page_bitmap;
extern char *xtrabackup_incremental;
extern my_bool xtrabackup_incremental_force_scan;
-extern lsn_t metadata_from_lsn;
extern lsn_t metadata_to_lsn;
-extern lsn_t metadata_last_lsn;
extern xb_stream_fmt_t xtrabackup_stream_fmt;
extern ibool xtrabackup_stream;
@@ -86,15 +75,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 +95,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;
@@ -128,6 +111,7 @@ extern my_bool opt_noversioncheck;
extern my_bool opt_no_backup_locks;
extern my_bool opt_decompress;
extern my_bool opt_remove_original;
+extern my_bool opt_lock_ddl_per_table;
extern char *opt_incremental_history_name;
extern char *opt_incremental_history_uuid;
@@ -138,7 +122,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 +151,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 +184,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 +192,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