Merge bb-10.2-ext into 10.3

This commit is contained in:
Marko Mäkelä 2017-06-19 17:28:08 +03:00
commit 1e3886ae80
725 changed files with 17193 additions and 16743 deletions

View File

@ -39,8 +39,4 @@ else
fi
fi
# main.mysqlhotcopy_myisam consitently failed in travis containers
# https://travis-ci.org/grooverdan/mariadb-server/builds/217661580
echo 'main.mysqlhotcopy_myisam : unstable in containers' >> ${TRAVIS_BUILD_DIR}/mysql-test/unstable-tests
echo 'archive.mysqlhotcopy_archive : unstable in containers' >> ${TRAVIS_BUILD_DIR}/mysql-test/unstable-tests
set +v +x

View File

@ -42,13 +42,33 @@ matrix:
compiler: gcc
script:
- ${CC} --version ; ${CXX} --version
# Just for disabling hotcopy tests for now
- source .travis.compiler.sh
# https://github.com/travis-ci/travis-ci/issues/7062 - /run/shm isn't writable or executable
# in trusty containers
- export MTR_MEM=/tmp
- env DEB_BUILD_OPTIONS="parallel=6" debian/autobake-deb.sh;
- ccache --show-stats
# Until OSX becomes a bit more stable: MDEV-12435
allow_failures:
- os: osx
compiler: clang
env: GCC_VERSION=4.8 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=rpl
- os: osx
compiler: clang
env: GCC_VERSION=5 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=main,archive,optimizer_unfixed_bugs,parts,sys_vars,unit,vcol,innodb,innodb_gis,innodb_zip,innodb_fts
- os: osx
compiler: clang
env: GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=binlog,binlog_encryption,encryption,rocksdb
- os: osx
compiler: clang
env: GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=csv,federated,funcs_1,funcs_2,gcol,handler,heap,json,maria,percona,perfschema,plugins,multi_source,roles
# MDEV-13002 plugins.server_audit and plugins.thread_pool_server_audit test fail due to mysqltest error
- os: linux
compiler: gcc
env: GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=csv,federated,funcs_1,funcs_2,gcol,handler,heap,json,maria,percona,perfschema,plugins,multi_source,roles
- os: linux
compiler: clang
env: GCC_VERSION=6 TYPE=RelWithDebInfo MYSQL_TEST_SUITES=csv,federated,funcs_1,funcs_2,gcol,handler,heap,json,maria,percona,perfschema,plugins,multi_source,roles
# Matrix include for coverity
# - env:
@ -108,6 +128,7 @@ addons:
- libaio-dev
- libboost-dev
- libcurl3-dev
- libdbd-mysql
- libjudy-dev
- libncurses5-dev
- libpam0g-dev
@ -128,6 +149,7 @@ addons:
- liblzma-dev
- libzmq-dev
- libdistro-info-perl
- uuid-dev
- devscripts # implicit for any build on Ubuntu
# libsystemd-daemon-dev # https://github.com/travis-ci/apt-package-whitelist/issues/3882

View File

@ -3059,7 +3059,6 @@ static int com_server_help(String *buffer __attribute__((unused)),
{
unsigned int num_fields= mysql_num_fields(result);
my_ulonglong num_rows= mysql_num_rows(result);
mysql_fetch_fields(result);
if (num_fields==3 && num_rows==1)
{
if (!(cur= mysql_fetch_row(result)))

View File

@ -1130,7 +1130,7 @@ static int check_version_match(void)
int main(int argc, char **argv)
{
char self_name[FN_REFLEN];
char self_name[FN_REFLEN + 1];
MY_INIT(argv[0]);
@ -1138,7 +1138,7 @@ int main(int argc, char **argv)
if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
#endif
{
strncpy(self_name, argv[0], FN_REFLEN);
strmake_buf(self_name, argv[0]);
}
if (init_dynamic_string(&ds_args, "", 512, 256) ||

View File

@ -47,6 +47,7 @@ static uint opt_count_iterations= 0, my_end_arg;
static ulong opt_connect_timeout, opt_shutdown_timeout;
static char * unix_port=0;
static char *opt_plugin_dir= 0, *opt_default_auth= 0;
static bool sql_log_bin_off= false;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
@ -600,6 +601,31 @@ static my_bool sql_connect(MYSQL *mysql, uint wait)
}
static int maybe_disable_binlog(MYSQL *mysql)
{
if (opt_local && !sql_log_bin_off)
{
if (mysql_query(mysql, "set local sql_log_bin=0"))
{
my_printf_error(0, "SET LOCAL SQL_LOG_BIN=0 failed; error: '%-.200s'",
error_flags, mysql_error(mysql));
return -1;
}
}
sql_log_bin_off= true;
return 0;
}
int flush(MYSQL *mysql, const char *what)
{
char buf[FN_REFLEN];
my_snprintf(buf, sizeof(buf), "flush %s%s",
(opt_local && !sql_log_bin_off ? "local " : ""), what);
return mysql_query(mysql, buf);
}
/**
@brief Execute all commands
@ -616,6 +642,7 @@ static my_bool sql_connect(MYSQL *mysql, uint wait)
static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
int ret = 0;
const char *status;
/*
MySQL documentation relies on the fact that mysqladmin will
@ -628,17 +655,6 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
struct my_rnd_struct rand_st;
char buff[FN_REFLEN + 20];
if (opt_local)
{
sprintf(buff, "set local sql_log_bin=0");
if (mysql_query(mysql, buff))
{
my_printf_error(0, "SET LOCAL SQL_LOG_BIN=0 failed; error: '%-.200s'",
error_flags, mysql_error(mysql));
return -1;
}
}
for (; argc > 0 ; argv++,argc--)
{
int command;
@ -650,6 +666,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
my_printf_error(0, "Too few arguments to create", error_flags);
return 1;
}
if (maybe_disable_binlog(mysql))
return -1;
sprintf(buff,"create database `%.*s`",FN_REFLEN,argv[1]);
if (mysql_query(mysql,buff))
{
@ -667,6 +685,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
my_printf_error(0, "Too few arguments to drop", error_flags);
return 1;
}
if (maybe_disable_binlog(mysql))
return -1;
if (drop_db(mysql,argv[1]))
return -1;
argc--; argv++;
@ -707,7 +727,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_PRIVILEGES:
case ADMIN_RELOAD:
if (mysql_query(mysql,"flush privileges"))
if (flush(mysql, "privileges"))
{
my_printf_error(0, "reload failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -911,7 +931,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_LOGS:
{
if (mysql_query(mysql,"flush logs"))
if (flush(mysql, "logs"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -921,7 +941,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_BINARY_LOG:
{
if (mysql_query(mysql, "flush binary logs"))
if (flush(mysql, "binary logs"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -931,7 +951,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_ENGINE_LOG:
{
if (mysql_query(mysql,"flush engine logs"))
if (flush(mysql, "engine logs"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -941,7 +961,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_ERROR_LOG:
{
if (mysql_query(mysql, "flush error logs"))
if (flush(mysql, "error logs"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -951,7 +971,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_GENERAL_LOG:
{
if (mysql_query(mysql, "flush general logs"))
if (flush(mysql, "general logs"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -961,7 +981,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_RELAY_LOG:
{
if (mysql_query(mysql, "flush relay logs"))
if (flush(mysql, "relay logs"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -971,7 +991,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_SLOW_LOG:
{
if (mysql_query(mysql,"flush slow logs"))
if (flush(mysql, "slow logs"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -981,7 +1001,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_HOSTS:
{
if (mysql_query(mysql,"flush hosts"))
if (flush(mysql, "hosts"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -991,7 +1011,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_TABLES:
{
if (mysql_query(mysql,"flush tables"))
if (flush(mysql, "tables"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -1001,7 +1021,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_STATUS:
{
if (mysql_query(mysql,"flush status"))
if (flush(mysql, "status"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -1011,7 +1031,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_TABLE_STATISTICS:
{
if (mysql_query(mysql,"flush table_statistics"))
if (flush(mysql, "table_statistics"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -1021,7 +1041,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_INDEX_STATISTICS:
{
if (mysql_query(mysql,"flush index_statistics"))
if (flush(mysql, "index_statistics"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -1031,7 +1051,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_USER_STATISTICS:
{
if (mysql_query(mysql,"flush user_statistics"))
if (flush(mysql, "user_statistics"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -1041,7 +1061,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_USER_RESOURCES:
{
if (mysql_query(mysql, "flush user_resources"))
if (flush(mysql, "user_resources"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -1051,7 +1071,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_CLIENT_STATISTICS:
{
if (mysql_query(mysql,"flush client_statistics"))
if (flush(mysql, "client_statistics"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -1061,9 +1081,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_ALL_STATISTICS:
{
if (mysql_query(mysql,
"flush table_statistics,index_statistics,"
"user_statistics,client_statistics"))
if (flush(mysql, "table_statistics,index_statistics,"
"user_statistics,client_statistics"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -1073,9 +1092,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_FLUSH_ALL_STATUS:
{
if (mysql_query(mysql,
"flush status,table_statistics,index_statistics,"
"user_statistics,client_statistics"))
if (flush(mysql, "status,table_statistics,index_statistics,"
"user_statistics,client_statistics"))
{
my_printf_error(0, "flush failed; error: '%s'", error_flags,
mysql_error(mysql));
@ -1093,6 +1111,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
start_time=time((time_t*) 0);
my_rnd_init(&rand_st,(ulong) start_time,(ulong) start_time/2);
if (maybe_disable_binlog(mysql))
return -1;
if (argc < 1)
{
my_printf_error(0, "Too few arguments to change password", error_flags);
@ -1106,7 +1126,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (strcmp(typed_password, verified) != 0)
{
my_printf_error(0,"Passwords don't match",MYF(ME_BELL));
return -1;
ret = -1;
goto password_done;
}
}
else
@ -1133,7 +1154,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
my_printf_error(0, "Could not determine old_passwords setting from server; error: '%s'",
error_flags, mysql_error(mysql));
return -1;
ret = -1;
goto password_done;
}
else
{
@ -1144,7 +1166,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
"Could not get old_passwords setting from "
"server; error: '%s'",
error_flags, mysql_error(mysql));
return -1;
ret = -1;
goto password_done;
}
if (!mysql_num_rows(res))
old= 1;
@ -1169,15 +1192,15 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
my_printf_error(0, "Can't turn off logging; error: '%s'",
error_flags, mysql_error(mysql));
return -1;
ret = -1;
}
else
if (mysql_query(mysql,buff))
{
if (mysql_errno(mysql)!=1290)
{
my_printf_error(0,"unable to change password; error: '%s'",
error_flags, mysql_error(mysql));
return -1;
}
else
{
@ -1191,9 +1214,10 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
" --skip-grant-tables).\n"
"Use: \"mysqladmin flush-privileges password '*'\""
" instead", error_flags);
return -1;
}
ret = -1;
}
password_done:
/* free up memory from prompted password */
if (typed_password != argv[1])
{
@ -1300,7 +1324,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
return 1;
}
}
return 0;
return ret;
}
/**

View File

@ -2480,7 +2480,7 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags);
size_t tlen = strlen(logname);
if (tlen > UINT_MAX)
if (tlen > sizeof(buf) - 10)
{
error("Log name too long.");
DBUG_RETURN(ERROR_STOP);

View File

@ -2174,6 +2174,7 @@ static void print_xml_comment(FILE *xml_file, size_t len,
case '-':
if (*(comment_string + 1) == '-') /* Only one hyphen allowed. */
break;
/* fall through */
default:
fputc(*comment_string, xml_file);
break;
@ -2850,6 +2851,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
my_free(scv_buff);
if (path)
my_fclose(sql_file, MYF(MY_WME));
DBUG_RETURN(0);
}
else
@ -5940,8 +5943,7 @@ static my_bool get_view_structure(char *table, char* db)
dynstr_free(&ds_view);
}
if (switch_character_set_results(mysql, default_charset))
DBUG_RETURN(1);
switch_character_set_results(mysql, default_charset);
/* If a separate .sql file was opened, close it now */
if (sql_file != md_result_file)

View File

@ -1720,13 +1720,12 @@ void log_msg(const char *fmt, ...)
int cat_file(DYNAMIC_STRING* ds, const char* filename)
{
int fd;
size_t len;
int len;
char buff[16384];
if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0)
return 1;
while((len= my_read(fd, (uchar*)&buff,
sizeof(buff)-1, MYF(0))) > 0)
while((len= (int)my_read(fd, (uchar*)&buff, sizeof(buff)-1, MYF(0))) > 0)
{
char *p= buff, *start= buff,*end=buff+len;
while (p < end)

View File

@ -41,4 +41,3 @@ SET(WSREP_PROC_INFO ${WITH_WSREP})
IF(WITH_WSREP)
SET(WSREP_PATCH_VERSION "wsrep_${WSREP_VERSION}")
ENDIF()

View File

@ -575,21 +575,4 @@
#define __STDC_FORMAT_MACROS
#endif
/*
stat structure (from <sys/stat.h>) is conditionally defined
to have different layout and size depending on the defined macros.
The correct macro is defined in my_config.h, which means it MUST be
included first (or at least before <features.h> - so, practically,
before including any system headers).
Check the include order by looking at __GLIBC__ (defined in <features.h>)
But we cannot force all third-party clients/connectors to include
my_config.h first. So, their crashes are their responsibility,
we enable this check only for MariaDB sources (SAFE_MUTEX check).
*/
#if defined(__GLIBC__) && defined(SAFE_MUTEX)
#error <my_config.h> MUST be included first!
#endif
#endif

View File

@ -82,7 +82,7 @@ uintmax_t cur_page_num;
/* Skip the checksum verification. */
static bool no_check;
/* Enabled for strict checksum verification. */
bool strict_verify = 0;
bool strict_verify;
/* Enabled for rewrite checksum. */
static bool do_write;
/* Mismatches count allowed (0 by default). */
@ -280,7 +280,8 @@ void print_index_leaf_stats(
fprintf(fil_out, "page_no\tdata_size\tn_recs\n");
while (it_page != index.leaves.end()) {
const per_page_stats& stat = it_page->second;
fprintf(fil_out, "%llu\t%lu\t%lu\n", it_page->first, stat.data_size, stat.n_recs);
fprintf(fil_out, "%llu\t" ULINTPF "\t" ULINTPF "\n",
it_page->first, stat.data_size, stat.n_recs);
page_no = stat.right_page_no;
it_page = index.leaves.find(page_no);
}
@ -315,12 +316,15 @@ void defrag_analysis(
}
if (index.leaf_pages) {
fprintf(fil_out, "count = %lu free = %lu\n", index.count, index.free_pages);
fprintf(fil_out, "count = " ULINTPF " free = " ULINTPF "\n",
index.count, index.free_pages);
}
fprintf(fil_out, "%llu\t\t%llu\t\t%lu\t\t%lu\t\t%lu\t\t%.2f\t%lu\n",
fprintf(fil_out, "%llu\t\t%llu\t\t"
ULINTPF "\t\t%lu\t\t" ULINTPF "\t\t%.2f\t" ULINTPF "\n",
id, index.leaf_pages, n_leaf_pages, n_merge, n_pages,
1.0 - (double)n_pages / (double)n_leaf_pages, index.max_data_size);
1.0 - (double)n_pages / (double)n_leaf_pages,
index.max_data_size);
}
void print_leaf_stats(

View File

@ -27,101 +27,6 @@ IF(NOT WIN32)
ENDIF()
ENDIF()
IF(WITH_LIBARCHIVE STREQUAL "STATIC")
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)
ENDIF()
FIND_PACKAGE(LibArchive)
IF(NOT DEFINED WITH_LIBARCHIVE)
IF(LibArchive_FOUND)
SET(WITH_LIBARCHIVE_DEFAULT ON)
ELSE()
SET(WITH_LIBARCHIVE_DEFAULT OFF)
ENDIF()
SET(WITH_LIBARCHIVE ${WITH_LIBARCHIVE_DEFAULT} CACHE STRING "Use libarchive for streaming features (ON, OFF or STATIC)" )
ENDIF()
IF(NOT WITH_LIBARCHIVE MATCHES "^(ON|OFF|STATIC)$")
MESSAGE(FATAL_ERROR "Invalid value for WITH_LIBARCHIVE: '${WITH_LIBARCHIVE}'. Use one of ON, OFF or STATIC")
ENDIF()
IF(UNIX)
SET(PIC_FLAG -fPIC)
ENDIF()
IF((NOT WITH_LIBARCHIVE STREQUAL "OFF") AND (NOT LibArchive_FOUND))
IF(CMAKE_VERSION VERSION_LESS "2.8.12")
MESSAGE("libarchive can't be built, old cmake")
ELSE()
# Build a local version
INCLUDE(ExternalProject)
SET(LIBARCHIVE_DIR ${CMAKE_CURRENT_BINARY_DIR}/libarchive)
SET(libarchive_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libarchive)
SET(libarchive_CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DENABLE_ICONV=OFF
-DENABLE_TAR=ON
-DENABLE_OPENSSL=OFF
-DENABLE_TEST=OFF
"-DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} ${PIC_FLAG}"
"-DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO} ${PIC_FLAG}"
"-DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} ${PIC_FLAG}"
"-DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL} ${PIC_FLAG}"
)
IF(WIN32)
SET(libarchive_CMAKE_ARGS ${libarchive_CMAKE_ARGS} -DWINDOWS_VERSION=WIN7 -DCMAKE_DEBUG_POSTFIX=d)
SET(LIBARCHIVE_RELEASE_LIB ${LIBARCHIVE_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}archive_static${CMAKE_STATIC_LIBRARY_SUFFIX})
SET(LIBARCHIVE_DEBUG_LIB ${LIBARCHIVE_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}archive_staticd${CMAKE_STATIC_LIBRARY_SUFFIX})
SET(byproducts ${LIBARCHIVE_RELEASE_LIB} ${LIBARCHIVE_DEBUG_LIB})
ELSE()
SET(LIBARCHIVE_LIB ${LIBARCHIVE_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}archive${CMAKE_STATIC_LIBRARY_SUFFIX})
SET(byproducts ${LIBARCHIVE_LIB})
ENDIF()
IF(CMAKE_VERSION VERSION_GREATER "3.1")
SET(byproducts BUILD_BYPRODUCTS ${byproducts})
ENDIF()
ExternalProject_Add(libarchive
PREFIX ${libarchive_PREFIX}
DOWNLOAD_DIR ${LIBARCHIVE_DIR}
URL http://www.libarchive.org/downloads/libarchive-3.2.2.tar.gz
INSTALL_DIR ${LIBARCHIVE_DIR}
CMAKE_ARGS ${libarchive_CMAKE_ARGS}
${byproducts}
)
ADD_LIBRARY(archive_static STATIC IMPORTED)
ADD_DEPENDENCIES(archive_static libarchive)
IF(WIN32)
SET_PROPERTY(TARGET archive_static PROPERTY IMPORTED_LOCATION_RELWITHDEBINFO ${LIBARCHIVE_RELEASE_LIB})
SET_PROPERTY(TARGET archive_static PROPERTY IMPORTED_LOCATION_RELEASE ${LIBARCHIVE_RELEASE_LIB})
SET_PROPERTY(TARGET archive_static PROPERTY IMPORTED_LOCATION_DEBUG ${LIBARCHIVE_DEBUG_LIB})
SET_PROPERTY(TARGET archive_static PROPERTY IMPORTED_LOCATION_MINSIZEREL ${LIBARCHIVE_RELEASE_LIB})
ELSE()
SET_PROPERTY(TARGET archive_static PROPERTY IMPORTED_LOCATION ${LIBARCHIVE_LIB})
ENDIF()
SET(LibArchive_FOUND ON )
SET(LibArchive_INCLUDE_DIRS ${LIBARCHIVE_DIR}/include )
SET(LibArchive_LIBRARIES archive_static)
IF(WIN32)
SET(LIBARCHIVE_STATIC 1)
ENDIF()
ENDIF()
ENDIF()
IF(WITH_LIBARCHIVE AND LibArchive_FOUND)
ADD_DEFINITIONS(-DHAVE_LIBARCHIVE)
IF(LIBARCHIVE_STATIC)
ADD_DEFINITIONS(-DLIBARCHIVE_STATIC)
ENDIF()
INCLUDE_DIRECTORIES(${LibArchive_INCLUDE_DIRS})
LINK_LIBRARIES(${LibArchive_LIBRARIES})
SET(DS_ARCHIVE_SOURCE ds_archive.c)
ENDIF()
INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/include
@ -154,7 +59,6 @@ MYSQL_ADD_EXECUTABLE(mariabackup
innobackupex.cc
changed_page_bitmap.cc
datasink.c
${DS_ARCHIVE_SOURCE}
ds_buffer.c
ds_compress.c
ds_local.c

View File

@ -450,7 +450,7 @@ datadir_iter_free(datadir_iter_t *it)
/************************************************************************
Holds the state needed to copy single data file. */
struct datafile_cur_t {
os_file_t file;
pfs_os_file_t file;
char rel_path[FN_REFLEN];
char abs_path[FN_REFLEN];
MY_STAT statinfo;
@ -1774,7 +1774,7 @@ copy_back()
const char *ext_list[] = {"backup-my.cnf", "xtrabackup_logfile",
"xtrabackup_binary", "xtrabackup_binlog_info",
"xtrabackup_checkpoints", ".qp", ".pmap", ".tmp",
".xbcrypt", NULL};
NULL};
const char *filename;
char c_tmp;
int i_tmp;
@ -1807,7 +1807,7 @@ copy_back()
filename = base_name(node.filepath);
/* skip .qp and .xbcrypt files */
/* skip .qp files */
if (filename_matches(filename, ext_list)) {
continue;
}
@ -1899,24 +1899,8 @@ decrypt_decompress_file(const char *filepath, uint thread_n)
cmd << IF_WIN("type ","cat ") << filepath;
if (ends_with(filepath, ".xbcrypt") && opt_decrypt) {
cmd << " | xbcrypt --decrypt --encrypt-algo="
<< xtrabackup_encrypt_algo_names[opt_decrypt_algo];
if (xtrabackup_encrypt_key) {
cmd << " --encrypt-key=" << xtrabackup_encrypt_key;
} else {
cmd << " --encrypt-key-file="
<< xtrabackup_encrypt_key_file;
}
dest_filepath[strlen(dest_filepath) - 8] = 0;
message << "decrypting";
needs_action = true;
}
if (opt_decompress
&& (ends_with(filepath, ".qp")
|| (ends_with(filepath, ".qp.xbcrypt")
&& opt_decrypt))) {
&& ends_with(filepath, ".qp")) {
cmd << " | qpress -dio ";
dest_filepath[strlen(dest_filepath) - 3] = 0;
if (needs_action) {
@ -1967,8 +1951,7 @@ decrypt_decompress_thread_func(void *arg)
continue;
}
if (!ends_with(node.filepath, ".qp")
&& !ends_with(node.filepath, ".xbcrypt")) {
if (!ends_with(node.filepath, ".qp")) {
continue;
}

View File

@ -1435,9 +1435,7 @@ write_xtrabackup_info(MYSQL *connection)
"partial = %s\n"
"incremental = %s\n"
"format = %s\n"
"compact = %s\n"
"compressed = %s\n"
"encrypted = %s\n",
"compressed = %s\n",
uuid, /* uuid */
opt_history ? opt_history : "", /* name */
tool_name, /* tool_name */
@ -1455,9 +1453,7 @@ write_xtrabackup_info(MYSQL *connection)
is_partial? "Y" : "N",
xtrabackup_incremental ? "Y" : "N", /* incremental */
xb_stream_name[xtrabackup_stream_fmt], /* format */
"N", /* compact */
xtrabackup_compress ? "compressed" : "N", /* compressed */
xtrabackup_encrypt ? "Y" : "N"); /* encrypted */
xtrabackup_compress ? "compressed" : "N"); /* compressed */
if (!opt_history) {
goto cleanup;
@ -1483,9 +1479,7 @@ write_xtrabackup_info(MYSQL *connection)
"partial ENUM('Y', 'N') DEFAULT NULL,"
"incremental ENUM('Y', 'N') DEFAULT NULL,"
"format ENUM('file', 'tar', 'xbstream') DEFAULT NULL,"
"compact ENUM('Y', 'N') DEFAULT NULL,"
"compressed ENUM('Y', 'N') DEFAULT NULL,"
"encrypted ENUM('Y', 'N') DEFAULT NULL"
"compressed ENUM('Y', 'N') DEFAULT NULL"
") CHARACTER SET utf8 ENGINE=innodb", false);
@ -1495,8 +1489,8 @@ write_xtrabackup_info(MYSQL *connection)
<< "uuid, name, tool_name, tool_command, tool_version,"
<< "ibbackup_version, server_version, start_time, end_time,"
<< "lock_time, binlog_pos, innodb_from_lsn, innodb_to_lsn,"
<< "partial, incremental, format, compact, compressed, "
<< "encrypted) values("
<< "partial, incremental, format, compressed) "
<< "values("
<< escape_and_quote(connection, uuid) << ","
<< escape_and_quote(connection, opt_history) << ","
<< escape_and_quote(connection, tool_name) << ","
@ -1513,9 +1507,7 @@ write_xtrabackup_info(MYSQL *connection)
<< ESCAPE_BOOL(is_partial) << ","
<< ESCAPE_BOOL(xtrabackup_incremental)<< ","
<< escape_and_quote(connection,xb_stream_name[xtrabackup_stream_fmt]) <<","
<< ESCAPE_BOOL(false) << ","
<< ESCAPE_BOOL(xtrabackup_compress) << ","
<< ESCAPE_BOOL(xtrabackup_encrypt) <<")";
<< ESCAPE_BOOL(xtrabackup_compress) << ")";
xb_mysql_query(mysql_connection, oss.str().c_str(), false);
@ -1581,14 +1573,6 @@ char *make_argv(char *buf, size_t len, int argc, char **argv)
if (strncmp(*argv, "--password", strlen("--password")) == 0) {
arg = "--password=...";
}
if (strncmp(*argv, "--encrypt-key",
strlen("--encrypt-key")) == 0) {
arg = "--encrypt-key=...";
}
if (strncmp(*argv, "--encrypt_key",
strlen("--encrypt_key")) == 0) {
arg = "--encrypt_key=...";
}
left-= ut_snprintf(buf + len - left, left,
"%s%c", arg, argc > 1 ? ' ' : 0);
++argv; --argc;

View File

@ -35,7 +35,7 @@ Remove these on the first opportunity, i.e. single-binary XtraBackup. */
/** Single bitmap file information */
struct log_online_bitmap_file_t {
char name[FN_REFLEN]; /*!< Name with full path */
os_file_t file; /*!< Handle to opened file */
pfs_os_file_t file; /*!< Handle to opened file */
ib_uint64_t size; /*!< Size of the file */
ib_uint64_t offset; /*!< Offset of the next read,
or count of already-read bytes

View File

@ -30,4 +30,4 @@ ENDIF()
IF(HAVE_CLMUL_INSTRUCTION)
ADD_DEFINITIONS(-DHAVE_CLMUL_INSTRUCTION)
ENDIF()
ADD_LIBRARY(crc crc_glue.c crc-intel-pclmul.c)
ADD_LIBRARY(crc STATIC crc_glue.c crc-intel-pclmul.c)

View File

@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#include "my_config.h"
#include "crc_glue.h"
#include "crc-intel-pclmul.h"
#include <stdint.h>

View File

@ -1,665 +0,0 @@
/******************************************************
Copyright (c) 2017 Percona LLC and/or its affiliates.
Encryption datasink implementation for XtraBackup.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#include <my_base.h>
#include "common.h"
#include "datasink.h"
#include "xbcrypt.h"
#include "xbcrypt_common.h"
#include "crc_glue.h"
typedef struct {
pthread_t id;
uint num;
pthread_mutex_t ctrl_mutex;
pthread_cond_t ctrl_cond;
pthread_mutex_t data_mutex;
pthread_cond_t data_cond;
my_bool started;
my_bool data_avail;
my_bool cancelled;
my_bool failed;
const uchar *from;
size_t from_len;
uchar *to;
size_t to_len;
size_t to_size;
const uchar *iv;
size_t iv_len;
unsigned long long offset;
my_bool hash_appended;
gcry_cipher_hd_t cipher_handle;
xb_rcrypt_result_t parse_result;
} crypt_thread_ctxt_t;
typedef struct {
crypt_thread_ctxt_t *threads;
uint nthreads;
int encrypt_algo;
size_t chunk_size;
char *encrypt_key;
char *encrypt_key_file;
} ds_decrypt_ctxt_t;
typedef struct {
ds_decrypt_ctxt_t *crypt_ctxt;
size_t bytes_processed;
ds_file_t *dest_file;
uchar *buf;
size_t buf_len;
size_t buf_size;
} ds_decrypt_file_t;
int ds_decrypt_encrypt_threads = 1;
static ds_ctxt_t *decrypt_init(const char *root);
static ds_file_t *decrypt_open(ds_ctxt_t *ctxt, const char *path,
MY_STAT *mystat);
static int decrypt_write(ds_file_t *file, const void *buf, size_t len);
static int decrypt_close(ds_file_t *file);
static void decrypt_deinit(ds_ctxt_t *ctxt);
datasink_t datasink_decrypt = {
&decrypt_init,
&decrypt_open,
&decrypt_write,
&decrypt_close,
&decrypt_deinit
};
static crypt_thread_ctxt_t *create_worker_threads(uint n);
static void destroy_worker_threads(crypt_thread_ctxt_t *threads, uint n);
static void *decrypt_worker_thread_func(void *arg);
static
ds_ctxt_t *
decrypt_init(const char *root)
{
ds_ctxt_t *ctxt;
ds_decrypt_ctxt_t *decrypt_ctxt;
crypt_thread_ctxt_t *threads;
if (xb_crypt_init(NULL)) {
return NULL;
}
/* Create and initialize the worker threads */
threads = create_worker_threads(ds_decrypt_encrypt_threads);
if (threads == NULL) {
msg("decrypt: failed to create worker threads.\n");
return NULL;
}
ctxt = (ds_ctxt_t *) my_malloc(sizeof(ds_ctxt_t) +
sizeof(ds_decrypt_ctxt_t),
MYF(MY_FAE));
decrypt_ctxt = (ds_decrypt_ctxt_t *) (ctxt + 1);
decrypt_ctxt->threads = threads;
decrypt_ctxt->nthreads = ds_decrypt_encrypt_threads;
ctxt->ptr = decrypt_ctxt;
ctxt->root = my_strdup(root, MYF(MY_FAE));
return ctxt;
}
static
ds_file_t *
decrypt_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat)
{
ds_ctxt_t *dest_ctxt;
ds_decrypt_ctxt_t *crypt_ctxt;
ds_decrypt_file_t *crypt_file;
char new_name[FN_REFLEN];
ds_file_t *file;
xb_ad(ctxt->pipe_ctxt != NULL);
dest_ctxt = ctxt->pipe_ctxt;
crypt_ctxt = (ds_decrypt_ctxt_t *) ctxt->ptr;
file = (ds_file_t *) my_malloc(sizeof(ds_file_t) +
sizeof(ds_decrypt_file_t),
MYF(MY_FAE|MY_ZEROFILL));
crypt_file = (ds_decrypt_file_t *) (file + 1);
/* Remove the .xbcrypt extension from the filename */
strncpy(new_name, path, FN_REFLEN);
new_name[strlen(new_name) - 8] = 0;
crypt_file->dest_file = ds_open(dest_ctxt, new_name, mystat);
if (crypt_file->dest_file == NULL) {
msg("decrypt: ds_open(\"%s\") failed.\n", new_name);
goto err;
}
crypt_file->crypt_ctxt = crypt_ctxt;
crypt_file->buf = NULL;
crypt_file->buf_size = 0;
crypt_file->buf_len = 0;
file->ptr = crypt_file;
file->path = crypt_file->dest_file->path;
return file;
err:
if (crypt_file->dest_file) {
ds_close(crypt_file->dest_file);
}
my_free(file);
return NULL;
}
#define CHECK_BUF_SIZE(ptr, size, buf, len) \
if (ptr + size - buf > (ssize_t) len) { \
result = XB_CRYPT_READ_INCOMPLETE; \
goto exit; \
}
static
xb_rcrypt_result_t
parse_xbcrypt_chunk(crypt_thread_ctxt_t *thd, const uchar *buf, size_t len,
size_t *bytes_processed)
{
const uchar *ptr;
uint version;
ulong checksum, checksum_exp;
ulonglong tmp;
xb_rcrypt_result_t result = XB_CRYPT_READ_CHUNK;
*bytes_processed = 0;
ptr = buf;
CHECK_BUF_SIZE(ptr, XB_CRYPT_CHUNK_MAGIC_SIZE, buf, len);
if (memcmp(ptr, XB_CRYPT_CHUNK_MAGIC3,
XB_CRYPT_CHUNK_MAGIC_SIZE) == 0) {
version = 3;
} else if (memcmp(ptr, XB_CRYPT_CHUNK_MAGIC2,
XB_CRYPT_CHUNK_MAGIC_SIZE) == 0) {
version = 2;
} else if (memcmp(ptr, XB_CRYPT_CHUNK_MAGIC1,
XB_CRYPT_CHUNK_MAGIC_SIZE) == 0) {
version = 1;
} else {
msg("%s:%s: wrong chunk magic at offset 0x%llx.\n",
my_progname, __FUNCTION__, thd->offset);
result = XB_CRYPT_READ_ERROR;
goto exit;
}
ptr += XB_CRYPT_CHUNK_MAGIC_SIZE;
thd->offset += XB_CRYPT_CHUNK_MAGIC_SIZE;
CHECK_BUF_SIZE(ptr, 8, buf, len);
tmp = uint8korr(ptr); /* reserved */
ptr += 8;
thd->offset += 8;
CHECK_BUF_SIZE(ptr, 8, buf, len);
tmp = uint8korr(ptr); /* original size */
ptr += 8;
if (tmp > INT_MAX) {
msg("%s:%s: invalid original size at offset 0x%llx.\n",
my_progname, __FUNCTION__, thd->offset);
result = XB_CRYPT_READ_ERROR;
goto exit;
}
thd->offset += 8;
thd->to_len = (size_t)tmp;
if (thd->to_size < thd->to_len + XB_CRYPT_HASH_LEN) {
thd->to = (uchar *) my_realloc(
thd->to,
thd->to_len + XB_CRYPT_HASH_LEN,
MYF(MY_FAE | MY_ALLOW_ZERO_PTR));
thd->to_size = thd->to_len;
}
CHECK_BUF_SIZE(ptr, 8, buf, len);
tmp = uint8korr(ptr); /* encrypted size */
ptr += 8;
if (tmp > INT_MAX) {
msg("%s:%s: invalid encrypted size at offset 0x%llx.\n",
my_progname, __FUNCTION__, thd->offset);
result = XB_CRYPT_READ_ERROR;
goto exit;
}
thd->offset += 8;
thd->from_len = (size_t)tmp;
xb_a(thd->from_len <= thd->to_len + XB_CRYPT_HASH_LEN);
CHECK_BUF_SIZE(ptr, 4, buf, len);
checksum_exp = uint4korr(ptr); /* checksum */
ptr += 4;
thd->offset += 4;
/* iv size */
if (version == 1) {
thd->iv_len = 0;
thd->iv = NULL;
} else {
CHECK_BUF_SIZE(ptr, 8, buf, len);
tmp = uint8korr(ptr);
if (tmp > INT_MAX) {
msg("%s:%s: invalid iv size at offset 0x%llx.\n",
my_progname, __FUNCTION__, thd->offset);
result = XB_CRYPT_READ_ERROR;
goto exit;
}
ptr += 8;
thd->offset += 8;
thd->iv_len = (size_t)tmp;
}
if (thd->iv_len > 0) {
CHECK_BUF_SIZE(ptr, thd->iv_len, buf, len);
thd->iv = ptr;
ptr += thd->iv_len;
}
/* for version euqals 2 we need to read in the iv data but do not init
CTR with it */
if (version == 2) {
thd->iv_len = 0;
thd->iv = 0;
}
if (thd->from_len > 0) {
CHECK_BUF_SIZE(ptr, thd->from_len, buf, len);
thd->from = ptr;
ptr += thd->from_len;
}
xb_ad(thd->from_len <= thd->to_len);
checksum = crc32_iso3309(0, thd->from, thd->from_len);
if (checksum != checksum_exp) {
msg("%s:%s invalid checksum at offset 0x%llx, "
"expected 0x%lx, actual 0x%lx.\n", my_progname,
__FUNCTION__, thd->offset, checksum_exp, checksum);
result = XB_CRYPT_READ_ERROR;
goto exit;
}
thd->offset += thd->from_len;
thd->hash_appended = version > 2;
exit:
*bytes_processed = (size_t) (ptr - buf);
return result;
}
static
int
decrypt_write(ds_file_t *file, const void *buf, size_t len)
{
ds_decrypt_file_t *crypt_file;
ds_decrypt_ctxt_t *crypt_ctxt;
crypt_thread_ctxt_t *threads;
crypt_thread_ctxt_t *thd;
uint nthreads;
uint i;
size_t bytes_processed;
xb_rcrypt_result_t parse_result = XB_CRYPT_READ_CHUNK;
my_bool err = FALSE;
crypt_file = (ds_decrypt_file_t *) file->ptr;
crypt_ctxt = crypt_file->crypt_ctxt;
threads = crypt_ctxt->threads;
nthreads = crypt_ctxt->nthreads;
if (crypt_file->buf_len > 0) {
thd = threads;
pthread_mutex_lock(&thd->ctrl_mutex);
do {
if (parse_result == XB_CRYPT_READ_INCOMPLETE) {
crypt_file->buf_size = crypt_file->buf_size * 2;
crypt_file->buf = (uchar *) my_realloc(
crypt_file->buf,
crypt_file->buf_size,
MYF(MY_FAE|MY_ALLOW_ZERO_PTR));
}
memcpy(crypt_file->buf + crypt_file->buf_len,
buf, MY_MIN(crypt_file->buf_size -
crypt_file->buf_len, len));
parse_result = parse_xbcrypt_chunk(
thd, crypt_file->buf,
crypt_file->buf_size, &bytes_processed);
if (parse_result == XB_CRYPT_READ_ERROR) {
pthread_mutex_unlock(&thd->ctrl_mutex);
return 1;
}
} while (parse_result == XB_CRYPT_READ_INCOMPLETE &&
crypt_file->buf_size < len);
if (parse_result != XB_CRYPT_READ_CHUNK) {
msg("decrypt: incomplete data.\n");
pthread_mutex_unlock(&thd->ctrl_mutex);
return 1;
}
pthread_mutex_lock(&thd->data_mutex);
thd->data_avail = TRUE;
pthread_cond_signal(&thd->data_cond);
pthread_mutex_unlock(&thd->data_mutex);
len -= bytes_processed - crypt_file->buf_len;
buf += bytes_processed - crypt_file->buf_len;
/* reap */
pthread_mutex_lock(&thd->data_mutex);
while (thd->data_avail == TRUE) {
pthread_cond_wait(&thd->data_cond,
&thd->data_mutex);
}
if (thd->failed) {
msg("decrypt: failed to decrypt chunk.\n");
err = TRUE;
}
xb_a(thd->to_len > 0);
if (!err &&
ds_write(crypt_file->dest_file, thd->to, thd->to_len)) {
msg("decrypt: write to destination failed.\n");
err = TRUE;
}
crypt_file->bytes_processed += thd->from_len;
pthread_mutex_unlock(&thd->data_mutex);
pthread_mutex_unlock(&thd->ctrl_mutex);
crypt_file->buf_len = 0;
if (err) {
return 1;
}
}
while (parse_result == XB_CRYPT_READ_CHUNK && len > 0) {
uint max_thread;
for (i = 0; i < nthreads; i++) {
thd = threads + i;
pthread_mutex_lock(&thd->ctrl_mutex);
parse_result = parse_xbcrypt_chunk(
thd, buf, len, &bytes_processed);
if (parse_result == XB_CRYPT_READ_ERROR) {
pthread_mutex_unlock(&thd->ctrl_mutex);
err = TRUE;
break;
}
thd->parse_result = parse_result;
if (parse_result != XB_CRYPT_READ_CHUNK) {
pthread_mutex_unlock(&thd->ctrl_mutex);
break;
}
pthread_mutex_lock(&thd->data_mutex);
thd->data_avail = TRUE;
pthread_cond_signal(&thd->data_cond);
pthread_mutex_unlock(&thd->data_mutex);
len -= bytes_processed;
buf += bytes_processed;
}
max_thread = (i < nthreads) ? i : nthreads - 1;
/* Reap and write decrypted data */
for (i = 0; i <= max_thread; i++) {
thd = threads + i;
if (thd->parse_result != XB_CRYPT_READ_CHUNK) {
break;
}
pthread_mutex_lock(&thd->data_mutex);
while (thd->data_avail == TRUE) {
pthread_cond_wait(&thd->data_cond,
&thd->data_mutex);
}
if (thd->failed) {
msg("decrypt: failed to decrypt chunk.\n");
err = TRUE;
}
xb_a(thd->to_len > 0);
if (!err && ds_write(crypt_file->dest_file, thd->to,
thd->to_len)) {
msg("decrypt: write to destination failed.\n");
err = TRUE;
}
crypt_file->bytes_processed += thd->from_len;
pthread_mutex_unlock(&thd->data_mutex);
pthread_mutex_unlock(&thd->ctrl_mutex);
}
if (err) {
return 1;
}
}
if (parse_result == XB_CRYPT_READ_INCOMPLETE && len > 0) {
crypt_file->buf_len = len;
if (crypt_file->buf_size < len) {
crypt_file->buf = (uchar *) my_realloc(
crypt_file->buf,
crypt_file->buf_len,
MYF(MY_FAE | MY_ALLOW_ZERO_PTR));
crypt_file->buf_size = len;
}
memcpy(crypt_file->buf, buf, len);
}
return 0;
}
static
int
decrypt_close(ds_file_t *file)
{
ds_decrypt_file_t *crypt_file;
ds_file_t *dest_file;
int rc = 0;
crypt_file = (ds_decrypt_file_t *) file->ptr;
dest_file = crypt_file->dest_file;
if (ds_close(dest_file)) {
rc = 1;
}
my_free(crypt_file->buf);
my_free(file);
return rc;
}
static
void
decrypt_deinit(ds_ctxt_t *ctxt)
{
ds_decrypt_ctxt_t *crypt_ctxt;
xb_ad(ctxt->pipe_ctxt != NULL);
crypt_ctxt = (ds_decrypt_ctxt_t *) ctxt->ptr;
destroy_worker_threads(crypt_ctxt->threads, crypt_ctxt->nthreads);
my_free(ctxt->root);
my_free(ctxt);
}
static
crypt_thread_ctxt_t *
create_worker_threads(uint n)
{
crypt_thread_ctxt_t *threads;
uint i;
threads = (crypt_thread_ctxt_t *)
my_malloc(sizeof(crypt_thread_ctxt_t) * n,
MYF(MY_FAE | MY_ZEROFILL));
for (i = 0; i < n; i++) {
crypt_thread_ctxt_t *thd = threads + i;
thd->num = i + 1;
/* Initialize the control mutex and condition var */
if (pthread_mutex_init(&thd->ctrl_mutex, NULL) ||
pthread_cond_init(&thd->ctrl_cond, NULL)) {
goto err;
}
/* Initialize and data mutex and condition var */
if (pthread_mutex_init(&thd->data_mutex, NULL) ||
pthread_cond_init(&thd->data_cond, NULL)) {
goto err;
}
xb_crypt_cipher_open(&thd->cipher_handle);
pthread_mutex_lock(&thd->ctrl_mutex);
if (pthread_create(&thd->id, NULL, decrypt_worker_thread_func,
thd)) {
msg("decrypt: pthread_create() failed: "
"errno = %d\n", errno);
goto err;
}
}
/* Wait for the threads to start */
for (i = 0; i < n; i++) {
crypt_thread_ctxt_t *thd = threads + i;
while (thd->started == FALSE)
pthread_cond_wait(&thd->ctrl_cond, &thd->ctrl_mutex);
pthread_mutex_unlock(&thd->ctrl_mutex);
}
return threads;
err:
return NULL;
}
static
void
destroy_worker_threads(crypt_thread_ctxt_t *threads, uint n)
{
uint i;
for (i = 0; i < n; i++) {
crypt_thread_ctxt_t *thd = threads + i;
pthread_mutex_lock(&thd->data_mutex);
threads[i].cancelled = TRUE;
pthread_cond_signal(&thd->data_cond);
pthread_mutex_unlock(&thd->data_mutex);
pthread_join(thd->id, NULL);
pthread_cond_destroy(&thd->data_cond);
pthread_mutex_destroy(&thd->data_mutex);
pthread_cond_destroy(&thd->ctrl_cond);
pthread_mutex_destroy(&thd->ctrl_mutex);
xb_crypt_cipher_close(thd->cipher_handle);
my_free(thd->to);
}
my_free(threads);
}
static
void *
decrypt_worker_thread_func(void *arg)
{
crypt_thread_ctxt_t *thd = (crypt_thread_ctxt_t *) arg;
pthread_mutex_lock(&thd->ctrl_mutex);
pthread_mutex_lock(&thd->data_mutex);
thd->started = TRUE;
pthread_cond_signal(&thd->ctrl_cond);
pthread_mutex_unlock(&thd->ctrl_mutex);
while (1) {
thd->data_avail = FALSE;
pthread_cond_signal(&thd->data_cond);
while (!thd->data_avail && !thd->cancelled) {
pthread_cond_wait(&thd->data_cond, &thd->data_mutex);
}
if (thd->cancelled)
break;
if (xb_crypt_decrypt(thd->cipher_handle, thd->from,
thd->from_len, thd->to, &thd->to_len,
thd->iv, thd->iv_len,
thd->hash_appended)) {
thd->failed = TRUE;
continue;
}
}
pthread_mutex_unlock(&thd->data_mutex);
return NULL;
}

View File

@ -1,30 +0,0 @@
/******************************************************
Copyright (c) 2017 Percona LLC and/or its affiliates.
Encryption interface for XtraBackup.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#ifndef DS_DECRYPT_H
#define DS_DECRYPT_H
#include "datasink.h"
extern datasink_t datasink_decrypt;
extern int ds_decrypt_encrypt_threads;
#endif

View File

@ -1,446 +0,0 @@
/******************************************************
Copyright (c) 2013 Percona LLC and/or its affiliates.
Encryption datasink implementation for XtraBackup.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#include <my_base.h>
#include "common.h"
#include "datasink.h"
#include "xbcrypt_common.h"
#ifdef HAVE_GRYPT
#include "xbcrypt.h"
#define XB_CRYPT_CHUNK_SIZE ((size_t) (ds_encrypt_encrypt_chunk_size))
typedef struct {
pthread_t id;
uint num;
pthread_mutex_t ctrl_mutex;
pthread_cond_t ctrl_cond;
pthread_mutex_t data_mutex;
pthread_cond_t data_cond;
my_bool started;
my_bool data_avail;
my_bool cancelled;
const uchar *from;
size_t from_len;
uchar *to;
uchar *iv;
size_t to_len;
gcry_cipher_hd_t cipher_handle;
} crypt_thread_ctxt_t;
typedef struct {
crypt_thread_ctxt_t *threads;
uint nthreads;
} ds_encrypt_ctxt_t;
typedef struct {
xb_wcrypt_t *xbcrypt_file;
ds_encrypt_ctxt_t *crypt_ctxt;
size_t bytes_processed;
ds_file_t *dest_file;
} ds_encrypt_file_t;
/* Encryption options */
uint ds_encrypt_encrypt_threads;
ulonglong ds_encrypt_encrypt_chunk_size;
static ds_ctxt_t *encrypt_init(const char *root);
static ds_file_t *encrypt_open(ds_ctxt_t *ctxt, const char *path,
MY_STAT *mystat);
static int encrypt_write(ds_file_t *file, const void *buf, size_t len);
static int encrypt_close(ds_file_t *file);
static void encrypt_deinit(ds_ctxt_t *ctxt);
datasink_t datasink_encrypt = {
&encrypt_init,
&encrypt_open,
&encrypt_write,
&encrypt_close,
&encrypt_deinit
};
static crypt_thread_ctxt_t *create_worker_threads(uint n);
static void destroy_worker_threads(crypt_thread_ctxt_t *threads, uint n);
static void *encrypt_worker_thread_func(void *arg);
static uint encrypt_iv_len = 0;
static
ssize_t
my_xb_crypt_write_callback(void *userdata, const void *buf, size_t len)
{
ds_encrypt_file_t *encrypt_file;
encrypt_file = (ds_encrypt_file_t *) userdata;
xb_ad(encrypt_file != NULL);
xb_ad(encrypt_file->dest_file != NULL);
if (!ds_write(encrypt_file->dest_file, buf, len)) {
return len;
}
return -1;
}
static
ds_ctxt_t *
encrypt_init(const char *root)
{
ds_ctxt_t *ctxt;
ds_encrypt_ctxt_t *encrypt_ctxt;
crypt_thread_ctxt_t *threads;
if (xb_crypt_init(&encrypt_iv_len)) {
return NULL;
}
/* Create and initialize the worker threads */
threads = create_worker_threads(ds_encrypt_encrypt_threads);
if (threads == NULL) {
msg("encrypt: failed to create worker threads.\n");
return NULL;
}
ctxt = (ds_ctxt_t *) my_malloc(sizeof(ds_ctxt_t) +
sizeof(ds_encrypt_ctxt_t),
MYF(MY_FAE));
encrypt_ctxt = (ds_encrypt_ctxt_t *) (ctxt + 1);
encrypt_ctxt->threads = threads;
encrypt_ctxt->nthreads = ds_encrypt_encrypt_threads;
ctxt->ptr = encrypt_ctxt;
ctxt->root = my_strdup(root, MYF(MY_FAE));
return ctxt;
}
static
ds_file_t *
encrypt_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat)
{
ds_ctxt_t *dest_ctxt;
ds_encrypt_ctxt_t *crypt_ctxt;
ds_encrypt_file_t *crypt_file;
char new_name[FN_REFLEN];
ds_file_t *file;
xb_ad(ctxt->pipe_ctxt != NULL);
dest_ctxt = ctxt->pipe_ctxt;
crypt_ctxt = (ds_encrypt_ctxt_t *) ctxt->ptr;
file = (ds_file_t *) my_malloc(sizeof(ds_file_t) +
sizeof(ds_encrypt_file_t),
MYF(MY_FAE|MY_ZEROFILL));
crypt_file = (ds_encrypt_file_t *) (file + 1);
/* Append the .xbcrypt extension to the filename */
fn_format(new_name, path, "", ".xbcrypt", MYF(MY_APPEND_EXT));
crypt_file->dest_file = ds_open(dest_ctxt, new_name, mystat);
if (crypt_file->dest_file == NULL) {
msg("encrypt: ds_open(\"%s\") failed.\n", new_name);
goto err;
}
crypt_file->crypt_ctxt = crypt_ctxt;
crypt_file->xbcrypt_file = xb_crypt_write_open(crypt_file,
my_xb_crypt_write_callback);
if (crypt_file->xbcrypt_file == NULL) {
msg("encrypt: xb_crypt_write_open() failed.\n");
goto err;
}
file->ptr = crypt_file;
file->path = crypt_file->dest_file->path;
return file;
err:
if (crypt_file->dest_file) {
ds_close(crypt_file->dest_file);
}
my_free(file);
return NULL;
}
static
int
encrypt_write(ds_file_t *file, const void *buf, size_t len)
{
ds_encrypt_file_t *crypt_file;
ds_encrypt_ctxt_t *crypt_ctxt;
crypt_thread_ctxt_t *threads;
crypt_thread_ctxt_t *thd;
uint nthreads;
uint i;
const uchar *ptr;
crypt_file = (ds_encrypt_file_t *) file->ptr;
crypt_ctxt = crypt_file->crypt_ctxt;
threads = crypt_ctxt->threads;
nthreads = crypt_ctxt->nthreads;
ptr = (const uchar *) buf;
while (len > 0) {
uint max_thread;
/* Send data to worker threads for encryption */
for (i = 0; i < nthreads; i++) {
size_t chunk_len;
thd = threads + i;
pthread_mutex_lock(&thd->ctrl_mutex);
chunk_len = (len > XB_CRYPT_CHUNK_SIZE) ?
XB_CRYPT_CHUNK_SIZE : len;
thd->from = ptr;
thd->from_len = chunk_len;
pthread_mutex_lock(&thd->data_mutex);
thd->data_avail = TRUE;
pthread_cond_signal(&thd->data_cond);
pthread_mutex_unlock(&thd->data_mutex);
len -= chunk_len;
if (len == 0) {
break;
}
ptr += chunk_len;
}
max_thread = (i < nthreads) ? i : nthreads - 1;
/* Reap and stream the encrypted data */
for (i = 0; i <= max_thread; i++) {
thd = threads + i;
pthread_mutex_lock(&thd->data_mutex);
while (thd->data_avail == TRUE) {
pthread_cond_wait(&thd->data_cond,
&thd->data_mutex);
}
xb_a(threads[i].to_len > 0);
if (xb_crypt_write_chunk(crypt_file->xbcrypt_file,
threads[i].to,
threads[i].from_len +
XB_CRYPT_HASH_LEN,
threads[i].to_len,
threads[i].iv,
encrypt_iv_len)) {
msg("encrypt: write to the destination file "
"failed.\n");
return 1;
}
crypt_file->bytes_processed += threads[i].from_len;
pthread_mutex_unlock(&threads[i].data_mutex);
pthread_mutex_unlock(&threads[i].ctrl_mutex);
}
}
return 0;
}
static
int
encrypt_close(ds_file_t *file)
{
ds_encrypt_file_t *crypt_file;
ds_file_t *dest_file;
int rc = 0;
crypt_file = (ds_encrypt_file_t *) file->ptr;
dest_file = crypt_file->dest_file;
rc = xb_crypt_write_close(crypt_file->xbcrypt_file);
if (ds_close(dest_file)) {
rc = 1;
}
my_free(file);
return rc;
}
static
void
encrypt_deinit(ds_ctxt_t *ctxt)
{
ds_encrypt_ctxt_t *crypt_ctxt;
xb_ad(ctxt->pipe_ctxt != NULL);
crypt_ctxt = (ds_encrypt_ctxt_t *) ctxt->ptr;
destroy_worker_threads(crypt_ctxt->threads, crypt_ctxt->nthreads);
my_free(ctxt->root);
my_free(ctxt);
}
static
crypt_thread_ctxt_t *
create_worker_threads(uint n)
{
crypt_thread_ctxt_t *threads;
uint i;
threads = (crypt_thread_ctxt_t *)
my_malloc(sizeof(crypt_thread_ctxt_t) * n, MYF(MY_FAE));
for (i = 0; i < n; i++) {
crypt_thread_ctxt_t *thd = threads + i;
thd->num = i + 1;
thd->started = FALSE;
thd->cancelled = FALSE;
thd->data_avail = FALSE;
thd->to = (uchar *) my_malloc(XB_CRYPT_CHUNK_SIZE +
XB_CRYPT_HASH_LEN, MYF(MY_FAE));
thd->iv = (uchar *) my_malloc(encrypt_iv_len, MYF(MY_FAE));
/* Initialize the control mutex and condition var */
if (pthread_mutex_init(&thd->ctrl_mutex, NULL) ||
pthread_cond_init(&thd->ctrl_cond, NULL)) {
goto err;
}
/* Initialize and data mutex and condition var */
if (pthread_mutex_init(&thd->data_mutex, NULL) ||
pthread_cond_init(&thd->data_cond, NULL)) {
goto err;
}
if (xb_crypt_cipher_open(&thd->cipher_handle)) {
goto err;
}
pthread_mutex_lock(&thd->ctrl_mutex);
if (pthread_create(&thd->id, NULL, encrypt_worker_thread_func,
thd)) {
msg("encrypt: pthread_create() failed: "
"errno = %d\n", errno);
goto err;
}
}
/* Wait for the threads to start */
for (i = 0; i < n; i++) {
crypt_thread_ctxt_t *thd = threads + i;
while (thd->started == FALSE)
pthread_cond_wait(&thd->ctrl_cond, &thd->ctrl_mutex);
pthread_mutex_unlock(&thd->ctrl_mutex);
}
return threads;
err:
return NULL;
}
static
void
destroy_worker_threads(crypt_thread_ctxt_t *threads, uint n)
{
uint i;
for (i = 0; i < n; i++) {
crypt_thread_ctxt_t *thd = threads + i;
pthread_mutex_lock(&thd->data_mutex);
threads[i].cancelled = TRUE;
pthread_cond_signal(&thd->data_cond);
pthread_mutex_unlock(&thd->data_mutex);
pthread_join(thd->id, NULL);
pthread_cond_destroy(&thd->data_cond);
pthread_mutex_destroy(&thd->data_mutex);
pthread_cond_destroy(&thd->ctrl_cond);
pthread_mutex_destroy(&thd->ctrl_mutex);
xb_crypt_cipher_close(thd->cipher_handle);
my_free(thd->to);
my_free(thd->iv);
}
my_free(threads);
}
static
void *
encrypt_worker_thread_func(void *arg)
{
crypt_thread_ctxt_t *thd = (crypt_thread_ctxt_t *) arg;
pthread_mutex_lock(&thd->ctrl_mutex);
pthread_mutex_lock(&thd->data_mutex);
thd->started = TRUE;
pthread_cond_signal(&thd->ctrl_cond);
pthread_mutex_unlock(&thd->ctrl_mutex);
while (1) {
thd->data_avail = FALSE;
pthread_cond_signal(&thd->data_cond);
while (!thd->data_avail && !thd->cancelled) {
pthread_cond_wait(&thd->data_cond, &thd->data_mutex);
}
if (thd->cancelled)
break;
thd->to_len = thd->from_len;
if (xb_crypt_encrypt(thd->cipher_handle, thd->from,
thd->from_len, thd->to, &thd->to_len,
thd->iv)) {
thd->to_len = 0;
continue;
}
}
pthread_mutex_unlock(&thd->data_mutex);
return NULL;
}
#endif /* HAVE_GCRYPT*/

View File

@ -1,33 +0,0 @@
/******************************************************
Copyright (c) 2013 Percona LLC and/or its affiliates.
Encryption interface for XtraBackup.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#ifndef DS_ENCRYPT_H
#define DS_ENCRYPT_H
#include "datasink.h"
#ifdef HAVE_GCRYPT
extern datasink_t datasink_encrypt;
#endif
/* Encryption options */
extern uint ds_encrypt_encrypt_threads;
extern ulonglong ds_encrypt_encrypt_chunk_size;
#endif

View File

@ -126,7 +126,6 @@ void encryption_plugin_prepare_init(int argc, char **argv)
if (!xb_plugin_load)
{
/* This prevents crashes e.g in --stats with wrong my.cnf*/
finalize_encryption_plugin(0);
return;
}

View File

@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include "read_filt.h"
struct xb_fil_cur_t {
os_file_t file; /*!< source file handle */
pfs_os_file_t file; /*!< source file handle */
fil_node_t* node; /*!< source tablespace node */
char rel_path[FN_REFLEN];
/*!< normalized file path */

View File

@ -101,8 +101,6 @@ char *opt_ibx_login_path = NULL;
ulong opt_ibx_lock_wait_query_type;
ulong opt_ibx_kill_long_query_type;
ulong opt_ibx_decrypt_algo = 0;
uint opt_ibx_kill_long_queries_timeout = 0;
uint opt_ibx_lock_wait_timeout = 0;
uint opt_ibx_lock_wait_threshold = 0;
@ -110,7 +108,6 @@ uint opt_ibx_debug_sleep_before_unlock = 0;
uint opt_ibx_safe_slave_backup_timeout = 0;
const char *opt_ibx_history = NULL;
bool opt_ibx_decrypt = false;
char *opt_ibx_include = NULL;
char *opt_ibx_databases = NULL;
@ -121,15 +118,9 @@ char *ibx_backup_directory = NULL;
/* copy of proxied xtrabackup options */
my_bool ibx_xb_close_files;
my_bool ibx_xtrabackup_compact;
const char *ibx_xtrabackup_compress_alg;
uint ibx_xtrabackup_compress_threads;
ulonglong ibx_xtrabackup_compress_chunk_size;
ulong ibx_xtrabackup_encrypt_algo;
char *ibx_xtrabackup_encrypt_key;
char *ibx_xtrabackup_encrypt_key_file;
uint ibx_xtrabackup_encrypt_threads;
ulonglong ibx_xtrabackup_encrypt_chunk_size;
my_bool ibx_xtrabackup_export;
char *ibx_xtrabackup_extra_lsndir;
char *ibx_xtrabackup_incremental_basedir;
@ -138,8 +129,6 @@ my_bool ibx_xtrabackup_incremental_force_scan;
ulint ibx_xtrabackup_log_copy_interval;
char *ibx_xtrabackup_incremental;
int ibx_xtrabackup_parallel;
my_bool ibx_xtrabackup_rebuild_indexes;
ulint ibx_xtrabackup_rebuild_threads;
char *ibx_xtrabackup_stream_str;
char *ibx_xtrabackup_tables_file;
long ibx_xtrabackup_throttle;
@ -201,7 +190,6 @@ enum innobackupex_options
OPT_NO_VERSION_CHECK,
OPT_NO_BACKUP_LOCKS,
OPT_DATABASES,
OPT_DECRYPT,
OPT_DECOMPRESS,
/* options wich are passed directly to xtrabackup */
@ -210,11 +198,6 @@ enum innobackupex_options
OPT_COMPRESS,
OPT_COMPRESS_THREADS,
OPT_COMPRESS_CHUNK_SIZE,
OPT_ENCRYPT,
OPT_ENCRYPT_KEY,
OPT_ENCRYPT_KEY_FILE,
OPT_ENCRYPT_THREADS,
OPT_ENCRYPT_CHUNK_SIZE,
OPT_EXPORT,
OPT_EXTRA_LSNDIR,
OPT_INCREMENTAL_BASEDIR,
@ -430,12 +413,6 @@ static struct my_option ibx_long_options[] =
(uchar*) &opt_ibx_incremental_history_uuid, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"decrypt", OPT_DECRYPT, "Decrypts all files with the .xbcrypt "
"extension in a backup previously made with --encrypt option.",
&opt_ibx_decrypt_algo, &opt_ibx_decrypt_algo,
&xtrabackup_encrypt_algo_typelib, GET_ENUM, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"ftwrl-wait-query-type", OPT_LOCK_WAIT_QUERY_TYPE,
"This option specifies which types of queries are allowed to complete "
"before innobackupex will issue the global lock. Default is all.",
@ -533,12 +510,6 @@ static struct my_option ibx_long_options[] =
(uchar*) &ibx_xb_close_files, (uchar*) &ibx_xb_close_files, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"compact", OPT_COMPACT, "Create a compact backup with all secondary "
"index pages omitted. This option is passed directly to xtrabackup. "
"See xtrabackup documentation for details.",
(uchar*) &ibx_xtrabackup_compact, (uchar*) &ibx_xtrabackup_compact,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"compress", OPT_COMPRESS, "This option instructs xtrabackup to "
"compress backup copies of InnoDB data files. It is passed directly "
"to the xtrabackup child process. Try 'xtrabackup --help' for more "
@ -560,46 +531,6 @@ static struct my_option ibx_long_options[] =
(uchar*) &ibx_xtrabackup_compress_chunk_size,
0, GET_ULL, REQUIRED_ARG, (1 << 16), 1024, ULONGLONG_MAX, 0, 0, 0},
{"encrypt", OPT_ENCRYPT, "This option instructs xtrabackup to encrypt "
"backup copies of InnoDB data files using the algorithm specified in "
"the ENCRYPTION-ALGORITHM. It is passed directly to the xtrabackup "
"child process. Try 'xtrabackup --help' for more details.",
&ibx_xtrabackup_encrypt_algo, &ibx_xtrabackup_encrypt_algo,
&xtrabackup_encrypt_algo_typelib, GET_ENUM, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"encrypt-key", OPT_ENCRYPT_KEY, "This option instructs xtrabackup to "
"use the given ENCRYPTION-KEY when using the --encrypt or --decrypt "
"options. During backup it is passed directly to the xtrabackup child "
"process. Try 'xtrabackup --help' for more details.",
(uchar*) &ibx_xtrabackup_encrypt_key,
(uchar*) &ibx_xtrabackup_encrypt_key, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"encrypt-key-file", OPT_ENCRYPT_KEY_FILE, "This option instructs "
"xtrabackup to use the encryption key stored in the given "
"ENCRYPTION-KEY-FILE when using the --encrypt or --decrypt options.",
(uchar*) &ibx_xtrabackup_encrypt_key_file,
(uchar*) &ibx_xtrabackup_encrypt_key_file, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"encrypt-threads", OPT_ENCRYPT_THREADS,
"This option specifies the number of worker threads that will be used "
"for parallel encryption. It is passed directly to the xtrabackup "
"child process. Try 'xtrabackup --help' for more details.",
(uchar*) &ibx_xtrabackup_encrypt_threads,
(uchar*) &ibx_xtrabackup_encrypt_threads,
0, GET_UINT, REQUIRED_ARG, 1, 1, UINT_MAX, 0, 0, 0},
{"encrypt-chunk-size", OPT_ENCRYPT_CHUNK_SIZE,
"This option specifies the size of the internal working buffer for "
"each encryption thread, measured in bytes. It is passed directly to "
"the xtrabackup child process. Try 'xtrabackup --help' for more "
"details.",
(uchar*) &ibx_xtrabackup_encrypt_chunk_size,
(uchar*) &ibx_xtrabackup_encrypt_chunk_size,
0, GET_ULL, REQUIRED_ARG, (1 << 16), 1024, ULONGLONG_MAX, 0, 0, 0},
{"export", OPT_EXPORT, "This option is passed directly to xtrabackup's "
"--export option. It enables exporting individual tables for import "
"into another server. See the xtrabackup documentation for details.",
@ -735,8 +666,6 @@ You can download full text of the license on http://www.gnu.org/licenses/gpl-2.0
SYNOPOSIS\n\
\n\
innobackupex [--compress] [--compress-threads=NUMBER-OF-THREADS] [--compress-chunk-size=CHUNK-SIZE]\n\
[--encrypt=ENCRYPTION-ALGORITHM] [--encrypt-threads=NUMBER-OF-THREADS] [--encrypt-chunk-size=CHUNK-SIZE]\n\
[--encrypt-key=LITERAL-ENCRYPTION-KEY] | [--encryption-key-file=MY.KEY]\n\
[--include=REGEXP] [--user=NAME]\n\
[--password=WORD] [--port=PORT] [--socket=SOCKET]\n\
[--no-timestamp] [--ibbackup=IBBACKUP-BINARY]\n\
@ -748,7 +677,7 @@ innobackupex [--compress] [--compress-threads=NUMBER-OF-THREADS] [--compress-chu
[--incremental] [--incremental-basedir]\n\
[--incremental-dir] [--incremental-force-scan] [--incremental-lsn]\n\
[--incremental-history-name=NAME] [--incremental-history-uuid=UUID]\n\
[--close-files] [--compact] \n\
[--close-files]\n\
BACKUP-ROOT-DIR\n\
\n\
innobackupex --apply-log [--use-memory=B]\n\
@ -760,8 +689,7 @@ innobackupex --copy-back [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME]
\n\
innobackupex --move-back [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME] BACKUP-DIR\n\
\n\
innobackupex [--decompress] [--decrypt=ENCRYPTION-ALGORITHM]\n\
[--encrypt-key=LITERAL-ENCRYPTION-KEY] | [--encryption-key-file=MY.KEY]\n\
innobackupex [--decompress]\n\
[--parallel=NUMBER-OF-FORKS] BACKUP-DIR\n\
\n\
DESCRIPTION\n\
@ -798,15 +726,12 @@ it moves files to their original locations rather than copies them. As this\n\
option removes backup files, it must be used with caution. It may be useful in\n\
cases when there is not enough free disk space to copy files.\n\
\n\
The --decompress --decrypt command will decrypt and/or decompress a backup made\n\
with the --compress and/or --encrypt options. When decrypting, the encryption\n\
algorithm and key used when the backup was taken MUST be provided via the\n\
specified options. --decrypt and --decompress may be used together at the same\n\
time to completely normalize a previously compressed and encrypted backup. The\n\
--parallel option will allow multiple files to be decrypted and/or decompressed\n\
The --decompress command will decompress a backup made\n\
with the --compress option. The\n\
--parallel option will allow multiple files to be decompressed\n\
simultaneously. In order to decompress, the qpress utility MUST be installed\n\
and accessable within the path. This process will remove the original\n\
compressed/encrypted files and leave the results in the same location.\n\
compressed files and leave the results in the same location.\n\
\n\
On success the exit code innobackupex is 0. A non-zero exit code \n\
indicates an error.\n");
@ -839,18 +764,8 @@ ibx_get_one_option(int optid,
opt_ibx_history = "";
}
break;
case OPT_DECRYPT:
if (argument == NULL) {
ibx_msg("Missing --decrypt argument, must specify a "
"valid encryption algorithm.\n");
return(1);
}
opt_ibx_decrypt = true;
break;
case OPT_STREAM:
if (!strcasecmp(argument, "tar"))
xtrabackup_stream_fmt = XB_STREAM_FMT_TAR;
else if (!strcasecmp(argument, "xbstream"))
if (!strcasecmp(argument, "xbstream"))
xtrabackup_stream_fmt = XB_STREAM_FMT_XBSTREAM;
else {
ibx_msg("Invalid --stream argument: %s\n", argument);
@ -868,15 +783,6 @@ ibx_get_one_option(int optid,
}
xtrabackup_compress = TRUE;
break;
case OPT_ENCRYPT:
if (argument == NULL)
{
msg("Missing --encrypt argument, must specify a "
"valid encryption algorithm.\n");
return 1;
}
xtrabackup_encrypt = TRUE;
break;
case 'p':
if (argument)
{
@ -930,7 +836,7 @@ ibx_handle_options(int *argc, char ***argv)
ibx_mode = IBX_MODE_COPY_BACK;
} else if (opt_ibx_move_back) {
ibx_mode = IBX_MODE_MOVE_BACK;
} else if (opt_ibx_decrypt || opt_ibx_decompress) {
} else if (opt_ibx_decompress) {
ibx_mode = IBX_MODE_DECRYPT_DECOMPRESS;
} else {
ibx_mode = IBX_MODE_BACKUP;
@ -1008,8 +914,6 @@ ibx_init()
opt_lock_wait_query_type = opt_ibx_lock_wait_query_type;
opt_kill_long_query_type = opt_ibx_kill_long_query_type;
opt_decrypt_algo = opt_ibx_decrypt_algo;
opt_kill_long_queries_timeout = opt_ibx_kill_long_queries_timeout;
opt_lock_wait_timeout = opt_ibx_lock_wait_timeout;
opt_lock_wait_threshold = opt_ibx_lock_wait_threshold;
@ -1017,18 +921,12 @@ ibx_init()
opt_safe_slave_backup_timeout = opt_ibx_safe_slave_backup_timeout;
opt_history = opt_ibx_history;
opt_decrypt = opt_ibx_decrypt;
/* setup xtrabackup options */
xb_close_files = ibx_xb_close_files;
xtrabackup_compress_alg = ibx_xtrabackup_compress_alg;
xtrabackup_compress_threads = ibx_xtrabackup_compress_threads;
xtrabackup_compress_chunk_size = ibx_xtrabackup_compress_chunk_size;
xtrabackup_encrypt_algo = ibx_xtrabackup_encrypt_algo;
xtrabackup_encrypt_key = ibx_xtrabackup_encrypt_key;
xtrabackup_encrypt_key_file = ibx_xtrabackup_encrypt_key_file;
xtrabackup_encrypt_threads = ibx_xtrabackup_encrypt_threads;
xtrabackup_encrypt_chunk_size = ibx_xtrabackup_encrypt_chunk_size;
xtrabackup_export = ibx_xtrabackup_export;
xtrabackup_extra_lsndir = ibx_xtrabackup_extra_lsndir;
xtrabackup_incremental_basedir = ibx_xtrabackup_incremental_basedir;
@ -1109,7 +1007,7 @@ ibx_init()
case IBX_MODE_DECRYPT_DECOMPRESS:
xtrabackup_decrypt_decompress = TRUE;
xtrabackup_target_dir = ibx_position_arg;
run = "decrypt and decompress";
run = "decompress";
break;
default:
ut_error;

View File

@ -23,17 +23,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
extern void os_io_init_simple(void);
extern os_file_t files[1000];
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(
ibool* create_new_db,
bool* create_new_db,
#ifdef UNIV_LOG_ARCHIVE
lsn_t* min_arch_log_no,
lsn_t* max_arch_log_no,
#endif
lsn_t* min_flushed_lsn,
lsn_t* max_flushed_lsn,
#endif
lsn_t* flushed_lsn,
ulint* sum_of_new_sizes)
;
int
@ -45,19 +44,6 @@ dberr_t* err, /*!< out: this is set to DB_ERROR if an error
os_file_dir_t dir, /*!< in: directory stream */
os_file_stat_t* info) /*!< in/out: buffer where the
info is returned */;
buf_block_t* btr_node_ptr_get_child(
const rec_t* node_ptr,/*!< in: node pointer */
dict_index_t* index, /*!< in: index */
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
mtr_t* mtr) /*!< in: mtr */;
buf_block_t*
btr_root_block_get(
/*===============*/
const dict_index_t* index, /*!< in: index tree */
ulint mode, /*!< in: either RW_S_LATCH
or RW_X_LATCH */
mtr_t* mtr) /*!< in: mtr */;
fil_space_t*
fil_space_get_by_name(const char *);
ibool
@ -66,7 +52,6 @@ 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(
/*======================*/

View File

@ -1,696 +0,0 @@
/******************************************************
Copyright (c) 2013 Percona LLC and/or its affiliates.
The xbcrypt utility: decrypt files in the XBCRYPT format.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#include <my_base.h>
#include <my_getopt.h>
#include "common.h"
#include "xbcrypt.h"
#include "xbcrypt_common.h"
#include "crc_glue.h"
#if !defined(GCRYPT_VERSION_NUMBER) || (GCRYPT_VERSION_NUMBER < 0x010600)
GCRY_THREAD_OPTION_PTHREAD_IMPL;
#endif
#define XBCRYPT_VERSION "1.1"
typedef enum {
RUN_MODE_NONE,
RUN_MODE_ENCRYPT,
RUN_MODE_DECRYPT
} run_mode_t;
const char *xbcrypt_encrypt_algo_names[] =
{ "NONE", "AES128", "AES192", "AES256", NullS};
TYPELIB xbcrypt_encrypt_algo_typelib=
{array_elements(xbcrypt_encrypt_algo_names)-1,"",
xbcrypt_encrypt_algo_names, NULL};
static run_mode_t opt_run_mode = RUN_MODE_ENCRYPT;
static char *opt_input_file = NULL;
static char *opt_output_file = NULL;
static ulong opt_encrypt_algo;
static char *opt_encrypt_key_file = NULL;
static void *opt_encrypt_key = NULL;
static ulonglong opt_encrypt_chunk_size = 0;
static my_bool opt_verbose = FALSE;
static uint encrypt_algos[] = { GCRY_CIPHER_NONE,
GCRY_CIPHER_AES128,
GCRY_CIPHER_AES192,
GCRY_CIPHER_AES256 };
static int encrypt_algo = 0;
static int encrypt_mode = GCRY_CIPHER_MODE_CTR;
static uint encrypt_key_len = 0;
static size_t encrypt_iv_len = 0;
static struct my_option my_long_options[] =
{
{"help", '?', "Display this help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"decrypt", 'd', "Decrypt data input to output.",
0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"input", 'i', "Optional input file. If not specified, input"
" will be read from standard input.",
&opt_input_file, &opt_input_file, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"output", 'o', "Optional output file. If not specified, output"
" will be written to standard output.",
&opt_output_file, &opt_output_file, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"encrypt-algo", 'a', "Encryption algorithm.",
&opt_encrypt_algo, &opt_encrypt_algo, &xbcrypt_encrypt_algo_typelib,
GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"encrypt-key", 'k', "Encryption key.",
&opt_encrypt_key, &opt_encrypt_key, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"encrypt-key-file", 'f', "File which contains encryption key.",
&opt_encrypt_key_file, &opt_encrypt_key_file, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"encrypt-chunk-size", 's', "Size of working buffer for encryption in"
" bytes. The default value is 64K.",
&opt_encrypt_chunk_size, &opt_encrypt_chunk_size, 0,
GET_ULL, REQUIRED_ARG, (1 << 16), 1024, ULONGLONG_MAX, 0, 0, 0},
{"verbose", 'v', "Display verbose status output.",
&opt_verbose, &opt_verbose,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static
int
get_options(int *argc, char ***argv);
static
my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument __attribute__((unused)));
static
void
print_version(void);
static
void
usage(void);
static
int
mode_decrypt(File filein, File fileout);
static
int
mode_encrypt(File filein, File fileout);
int
main(int argc, char **argv)
{
#if !defined(GCRYPT_VERSION_NUMBER) || (GCRYPT_VERSION_NUMBER < 0x010600)
gcry_error_t gcry_error;
#endif
File filein = 0;
File fileout = 0;
MY_INIT(argv[0]);
crc_init();
if (get_options(&argc, &argv)) {
goto err;
}
/* Acording to gcrypt docs (and my testing), setting up the threading
callbacks must be done first, so, lets give it a shot */
#if !defined(GCRYPT_VERSION_NUMBER) || (GCRYPT_VERSION_NUMBER < 0x010600)
gcry_error = gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
if (gcry_error) {
msg("%s: unable to set libgcrypt thread cbs - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return 1;
}
#endif
/* Version check should be the very first call because it
makes sure that important subsystems are intialized. */
if (!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) {
const char *gcrypt_version;
gcrypt_version = gcry_check_version(NULL);
/* No other library has already initialized libgcrypt. */
if (!gcrypt_version) {
msg("%s: failed to initialize libgcrypt\n",
my_progname);
return 1;
} else if (opt_verbose) {
msg("%s: using gcrypt %s\n", my_progname,
gcrypt_version);
}
}
gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
/* Determine the algorithm */
encrypt_algo = encrypt_algos[opt_encrypt_algo];
/* Set up the iv length */
encrypt_iv_len = gcry_cipher_get_algo_blklen(encrypt_algo);
/* Now set up the key */
if (opt_encrypt_key == NULL && opt_encrypt_key_file == NULL) {
msg("%s: no encryption key or key file specified.\n",
my_progname);
return 1;
} else if (opt_encrypt_key && opt_encrypt_key_file) {
msg("%s: both encryption key and key file specified.\n",
my_progname);
return 1;
} else if (opt_encrypt_key_file) {
if (!xb_crypt_read_key_file(opt_encrypt_key_file,
&opt_encrypt_key,
&encrypt_key_len)) {
msg("%s: unable to read encryption key file \"%s\".\n",
opt_encrypt_key_file, my_progname);
return 1;
}
} else {
encrypt_key_len = strlen(opt_encrypt_key);
}
if (opt_input_file) {
MY_STAT mystat;
if (opt_verbose)
msg("%s: input file \"%s\".\n", my_progname,
opt_input_file);
if (my_stat(opt_input_file, &mystat, MYF(MY_WME)) == NULL) {
goto err;
}
if (!MY_S_ISREG(mystat.st_mode)) {
msg("%s: \"%s\" is not a regular file, exiting.\n",
my_progname, opt_input_file);
goto err;
}
if ((filein = my_open(opt_input_file, O_RDONLY, MYF(MY_WME)))
< 0) {
msg("%s: failed to open \"%s\".\n", my_progname,
opt_input_file);
goto err;
}
} else {
if (opt_verbose)
msg("%s: input from standard input.\n", my_progname);
filein = fileno(stdin);
}
if (opt_output_file) {
if (opt_verbose)
msg("%s: output file \"%s\".\n", my_progname,
opt_output_file);
if ((fileout = my_create(opt_output_file, 0,
O_WRONLY|O_BINARY|O_EXCL|O_NOFOLLOW,
MYF(MY_WME))) < 0) {
msg("%s: failed to create output file \"%s\".\n",
my_progname, opt_output_file);
goto err;
}
} else {
if (opt_verbose)
msg("%s: output to standard output.\n", my_progname);
fileout = fileno(stdout);
}
if (opt_run_mode == RUN_MODE_DECRYPT
&& mode_decrypt(filein, fileout)) {
goto err;
} else if (opt_run_mode == RUN_MODE_ENCRYPT
&& mode_encrypt(filein, fileout)) {
goto err;
}
if (opt_input_file && filein) {
my_close(filein, MYF(MY_WME));
}
if (opt_output_file && fileout) {
my_close(fileout, MYF(MY_WME));
}
my_cleanup_options(my_long_options);
my_end(0);
return EXIT_SUCCESS;
err:
if (opt_input_file && filein) {
my_close(filein, MYF(MY_WME));
}
if (opt_output_file && fileout) {
my_close(fileout, MYF(MY_WME));
}
my_cleanup_options(my_long_options);
my_end(0);
exit(EXIT_FAILURE);
}
static
size_t
my_xb_crypt_read_callback(void *userdata, void *buf, size_t len)
{
File* file = (File *) userdata;
return xb_read_full(*file, buf, len);
}
static
int
mode_decrypt(File filein, File fileout)
{
xb_rcrypt_t *xbcrypt_file = NULL;
void *chunkbuf = NULL;
size_t chunksize;
size_t originalsize;
void *ivbuf = NULL;
size_t ivsize;
void *decryptbuf = NULL;
size_t decryptbufsize = 0;
ulonglong ttlchunksread = 0;
ulonglong ttlbytesread = 0;
xb_rcrypt_result_t result;
gcry_cipher_hd_t cipher_handle;
gcry_error_t gcry_error;
my_bool hash_appended;
if (encrypt_algo != GCRY_CIPHER_NONE) {
gcry_error = gcry_cipher_open(&cipher_handle,
encrypt_algo,
encrypt_mode, 0);
if (gcry_error) {
msg("%s:decrypt: unable to open libgcrypt"
" cipher - %s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return 1;
}
gcry_error = gcry_cipher_setkey(cipher_handle,
opt_encrypt_key,
encrypt_key_len);
if (gcry_error) {
msg("%s:decrypt: unable to set libgcrypt cipher"
"key - %s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
goto err;
}
}
/* Initialize the xb_crypt format reader */
xbcrypt_file = xb_crypt_read_open(&filein, my_xb_crypt_read_callback);
if (xbcrypt_file == NULL) {
msg("%s:decrypt: xb_crypt_read_open() failed.\n", my_progname);
goto err;
}
/* Walk the encrypted chunks, decrypting them and writing out */
while ((result = xb_crypt_read_chunk(xbcrypt_file, &chunkbuf,
&originalsize, &chunksize,
&ivbuf, &ivsize, &hash_appended))
== XB_CRYPT_READ_CHUNK) {
if (encrypt_algo != GCRY_CIPHER_NONE) {
gcry_error = gcry_cipher_reset(cipher_handle);
if (gcry_error) {
msg("%s:decrypt: unable to reset libgcrypt"
" cipher - %s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
goto err;
}
if (ivsize) {
gcry_error = gcry_cipher_setctr(cipher_handle,
ivbuf,
ivsize);
}
if (gcry_error) {
msg("%s:decrypt: unable to set cipher iv - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
continue;
}
if (decryptbufsize < originalsize) {
decryptbuf = my_realloc(decryptbuf,
originalsize,
MYF(MY_WME | MY_ALLOW_ZERO_PTR));
decryptbufsize = originalsize;
}
/* Try to decrypt it */
gcry_error = gcry_cipher_decrypt(cipher_handle,
decryptbuf,
originalsize,
chunkbuf,
chunksize);
if (gcry_error) {
msg("%s:decrypt: unable to decrypt chunk - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
gcry_cipher_close(cipher_handle);
goto err;
}
} else {
decryptbuf = chunkbuf;
}
if (hash_appended) {
uchar hash[XB_CRYPT_HASH_LEN];
originalsize -= XB_CRYPT_HASH_LEN;
/* ensure that XB_CRYPT_HASH_LEN is the correct length
of XB_CRYPT_HASH hashing algorithm output */
xb_a(gcry_md_get_algo_dlen(XB_CRYPT_HASH) ==
XB_CRYPT_HASH_LEN);
gcry_md_hash_buffer(XB_CRYPT_HASH, hash, decryptbuf,
originalsize);
if (memcmp(hash, (char *) decryptbuf + originalsize,
XB_CRYPT_HASH_LEN) != 0) {
msg("%s:%s invalid plaintext hash. "
"Wrong encrytion key specified?\n",
my_progname, __FUNCTION__);
result = XB_CRYPT_READ_ERROR;
goto err;
}
}
/* Write it out */
if (my_write(fileout, (const uchar *) decryptbuf, originalsize,
MYF(MY_WME | MY_NABP))) {
msg("%s:decrypt: unable to write output chunk.\n",
my_progname);
goto err;
}
ttlchunksread++;
ttlbytesread += chunksize;
if (opt_verbose)
msg("%s:decrypt: %llu chunks read, %llu bytes read\n.",
my_progname, ttlchunksread, ttlbytesread);
}
xb_crypt_read_close(xbcrypt_file);
if (encrypt_algo != GCRY_CIPHER_NONE)
gcry_cipher_close(cipher_handle);
if (decryptbuf && decryptbufsize)
my_free(decryptbuf);
if (opt_verbose)
msg("\n%s:decrypt: done\n", my_progname);
return 0;
err:
if (xbcrypt_file)
xb_crypt_read_close(xbcrypt_file);
if (encrypt_algo != GCRY_CIPHER_NONE)
gcry_cipher_close(cipher_handle);
if (decryptbuf && decryptbufsize)
my_free(decryptbuf);
return 1;
}
static
ssize_t
my_xb_crypt_write_callback(void *userdata, const void *buf, size_t len)
{
File* file = (File *) userdata;
ssize_t ret = my_write(*file, buf, len, MYF(MY_WME));
posix_fadvise(*file, 0, 0, POSIX_FADV_DONTNEED);
return ret;
}
static
int
mode_encrypt(File filein, File fileout)
{
size_t bytesread;
size_t chunkbuflen;
uchar *chunkbuf = NULL;
void *ivbuf = NULL;
size_t encryptbuflen = 0;
size_t encryptedlen = 0;
void *encryptbuf = NULL;
ulonglong ttlchunkswritten = 0;
ulonglong ttlbyteswritten = 0;
xb_wcrypt_t *xbcrypt_file = NULL;
gcry_cipher_hd_t cipher_handle;
gcry_error_t gcry_error;
if (encrypt_algo != GCRY_CIPHER_NONE) {
gcry_error = gcry_cipher_open(&cipher_handle,
encrypt_algo,
encrypt_mode, 0);
if (gcry_error) {
msg("%s:encrypt: unable to open libgcrypt cipher - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return 1;
}
gcry_error = gcry_cipher_setkey(cipher_handle,
opt_encrypt_key,
encrypt_key_len);
if (gcry_error) {
msg("%s:encrypt: unable to set libgcrypt cipher key - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
goto err;
}
}
posix_fadvise(filein, 0, 0, POSIX_FADV_SEQUENTIAL);
xbcrypt_file = xb_crypt_write_open(&fileout,
my_xb_crypt_write_callback);
if (xbcrypt_file == NULL) {
msg("%s:encrypt: xb_crypt_write_open() failed.\n",
my_progname);
goto err;
}
ivbuf = my_malloc(encrypt_iv_len, MYF(MY_FAE));
/* now read in data in chunk size, encrypt and write out */
chunkbuflen = opt_encrypt_chunk_size + XB_CRYPT_HASH_LEN;
chunkbuf = (uchar *) my_malloc(chunkbuflen, MYF(MY_FAE));
while ((bytesread = my_read(filein, chunkbuf, opt_encrypt_chunk_size,
MYF(MY_WME))) > 0) {
size_t origbuflen = bytesread + XB_CRYPT_HASH_LEN;
/* ensure that XB_CRYPT_HASH_LEN is the correct length
of XB_CRYPT_HASH hashing algorithm output */
xb_a(XB_CRYPT_HASH_LEN == gcry_md_get_algo_dlen(XB_CRYPT_HASH));
gcry_md_hash_buffer(XB_CRYPT_HASH, chunkbuf + bytesread,
chunkbuf, bytesread);
if (encrypt_algo != GCRY_CIPHER_NONE) {
gcry_error = gcry_cipher_reset(cipher_handle);
if (gcry_error) {
msg("%s:encrypt: unable to reset cipher - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
goto err;
}
xb_crypt_create_iv(ivbuf, encrypt_iv_len);
gcry_error = gcry_cipher_setctr(cipher_handle,
ivbuf,
encrypt_iv_len);
if (gcry_error) {
msg("%s:encrypt: unable to set cipher iv - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
continue;
}
if (encryptbuflen < origbuflen) {
encryptbuf = my_realloc(encryptbuf, origbuflen,
MYF(MY_WME | MY_ALLOW_ZERO_PTR));
encryptbuflen = origbuflen;
}
gcry_error = gcry_cipher_encrypt(cipher_handle,
encryptbuf,
encryptbuflen,
chunkbuf,
origbuflen);
encryptedlen = origbuflen;
if (gcry_error) {
msg("%s:encrypt: unable to encrypt chunk - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
gcry_cipher_close(cipher_handle);
goto err;
}
} else {
encryptedlen = origbuflen;
encryptbuf = chunkbuf;
}
if (xb_crypt_write_chunk(xbcrypt_file, encryptbuf,
bytesread + XB_CRYPT_HASH_LEN,
encryptedlen, ivbuf, encrypt_iv_len)) {
msg("%s:encrypt: abcrypt_write_chunk() failed.\n",
my_progname);
goto err;
}
ttlchunkswritten++;
ttlbyteswritten += encryptedlen;
if (opt_verbose)
msg("%s:encrypt: %llu chunks written, %llu bytes "
"written\n.", my_progname, ttlchunkswritten,
ttlbyteswritten);
}
my_free(ivbuf);
my_free(chunkbuf);
if (encryptbuf && encryptbuflen)
my_free(encryptbuf);
xb_crypt_write_close(xbcrypt_file);
if (encrypt_algo != GCRY_CIPHER_NONE)
gcry_cipher_close(cipher_handle);
if (opt_verbose)
msg("\n%s:encrypt: done\n", my_progname);
return 0;
err:
if (chunkbuf)
my_free(chunkbuf);
if (encryptbuf && encryptbuflen)
my_free(encryptbuf);
if (xbcrypt_file)
xb_crypt_write_close(xbcrypt_file);
if (encrypt_algo != GCRY_CIPHER_NONE)
gcry_cipher_close(cipher_handle);
return 1;
}
static
int
get_options(int *argc, char ***argv)
{
int ho_error;
if ((ho_error= handle_options(argc, argv, my_long_options,
get_one_option))) {
exit(EXIT_FAILURE);
}
return 0;
}
static
my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument __attribute__((unused)))
{
switch (optid) {
case 'd':
opt_run_mode = RUN_MODE_DECRYPT;
break;
case '?':
usage();
exit(0);
}
return FALSE;
}
static
void
print_version(void)
{
printf("%s Ver %s for %s (%s)\n", my_progname, XBCRYPT_VERSION,
SYSTEM_TYPE, MACHINE_TYPE);
}
static
void
usage(void)
{
print_version();
puts("Copyright (C) 2011 Percona Inc.");
puts("This software comes with ABSOLUTELY NO WARRANTY. "
"This is free software,\nand you are welcome to modify and "
"redistribute it under the GPL license.\n");
puts("Encrypt or decrypt files in the XBCRYPT format.\n");
puts("Usage: ");
printf(" %s [OPTIONS...]"
" # read data from specified input, encrypting or decrypting "
" and writing the result to the specified output.\n",
my_progname);
puts("\nOptions:");
my_print_help(my_long_options);
}

View File

@ -1,79 +0,0 @@
/******************************************************
Copyright (c) 2011 Percona LLC and/or its affiliates.
Encryption interface for XtraBackup.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#ifndef XBCRYPT_H
#define XBCRYPT_H
#include <my_base.h>
#include "common.h"
#define XB_CRYPT_CHUNK_MAGIC1 "XBCRYP01"
#define XB_CRYPT_CHUNK_MAGIC2 "XBCRYP02"
#define XB_CRYPT_CHUNK_MAGIC3 "XBCRYP03" /* must be same size as ^^ */
#define XB_CRYPT_CHUNK_MAGIC_CURRENT XB_CRYPT_CHUNK_MAGIC3
#define XB_CRYPT_CHUNK_MAGIC_SIZE (sizeof(XB_CRYPT_CHUNK_MAGIC1)-1)
#define XB_CRYPT_HASH GCRY_MD_SHA256
#define XB_CRYPT_HASH_LEN 32
/******************************************************************************
Write interface */
typedef struct xb_wcrypt_struct xb_wcrypt_t;
/* Callback on write for i/o, must return # of bytes written or -1 on error */
typedef ssize_t xb_crypt_write_callback(void *userdata,
const void *buf, size_t len);
xb_wcrypt_t *xb_crypt_write_open(void *userdata,
xb_crypt_write_callback *onwrite);
/* Takes buffer, original length, encrypted length iv and iv length, formats
output buffer and calls write callback.
Returns 0 on success, 1 on error */
int xb_crypt_write_chunk(xb_wcrypt_t *crypt, const void *buf, size_t olen,
size_t elen, const void *iv, size_t ivlen);
/* Returns 0 on success, 1 on error */
int xb_crypt_write_close(xb_wcrypt_t *crypt);
/******************************************************************************
Read interface */
typedef struct xb_rcrypt_struct xb_rcrypt_t;
/* Callback on read for i/o, must return # of bytes read or -1 on error */
typedef size_t xb_crypt_read_callback(void *userdata, void *buf, size_t len);
xb_rcrypt_t *xb_crypt_read_open(void *userdata,
xb_crypt_read_callback *onread);
typedef enum {
XB_CRYPT_READ_CHUNK,
XB_CRYPT_READ_INCOMPLETE,
XB_CRYPT_READ_EOF,
XB_CRYPT_READ_ERROR
} xb_rcrypt_result_t;
xb_rcrypt_result_t xb_crypt_read_chunk(xb_rcrypt_t *crypt, void **buf,
size_t *olen, size_t *elen, void **iv,
size_t *ivlen, my_bool *hash_appended);
int xb_crypt_read_close(xb_rcrypt_t *crypt);
#endif

View File

@ -1,328 +0,0 @@
/******************************************************
Copyright (c) 2013, 2017 Percona LLC and/or its affiliates.
Encryption configuration file interface for XtraBackup.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#include <my_base.h>
#include "common.h"
#include "xbcrypt.h"
#include "xbcrypt_common.h"
/* Encryption options */
char *ds_encrypt_key = NULL;
char *ds_encrypt_key_file = NULL;
ulong ds_encrypt_algo;
static uint encrypt_key_len;
static uint encrypt_iv_len;
static const uint encrypt_mode = GCRY_CIPHER_MODE_CTR;
static uint encrypt_algos[] = { GCRY_CIPHER_NONE, GCRY_CIPHER_AES128,
GCRY_CIPHER_AES192, GCRY_CIPHER_AES256 };
static uint encrypt_algo;
#if !defined(GCRYPT_VERSION_NUMBER) || (GCRYPT_VERSION_NUMBER < 0x010600)
GCRY_THREAD_OPTION_PTHREAD_IMPL;
#endif
my_bool
xb_crypt_read_key_file(const char *filename, void** key, uint *keylength)
{
FILE *fp;
if (!(fp = my_fopen(filename, O_RDONLY, MYF(0)))) {
msg("%s:%s: unable to open config file \"%s\", errno(%d)\n",
my_progname, __FUNCTION__, filename, my_errno);
return FALSE;
}
fseek(fp, 0 , SEEK_END);
*keylength = ftell(fp);
rewind(fp);
*key = my_malloc(*keylength, MYF(MY_FAE));
*keylength = fread(*key, 1, *keylength, fp);
my_fclose(fp, MYF(0));
return TRUE;
}
void
xb_crypt_create_iv(void* ivbuf, size_t ivlen)
{
gcry_create_nonce(ivbuf, ivlen);
}
gcry_error_t
xb_crypt_init(uint *iv_len)
{
gcry_error_t gcry_error;
/* Acording to gcrypt docs (and my testing), setting up the threading
callbacks must be done first, so, lets give it a shot */
#if !defined(GCRYPT_VERSION_NUMBER) || (GCRYPT_VERSION_NUMBER < 0x010600)
gcry_error = gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
if (gcry_error) {
msg("encryption: unable to set libgcrypt thread cbs - "
"%s : %s\n",
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return gcry_error;
}
#endif
/* Version check should be the very next call because it
makes sure that important subsystems are intialized. */
if (!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) {
const char *gcrypt_version;
gcrypt_version = gcry_check_version(NULL);
/* No other library has already initialized libgcrypt. */
if (!gcrypt_version) {
msg("encryption: failed to initialize libgcrypt\n");
return 1;
} else {
msg("encryption: using gcrypt %s\n", gcrypt_version);
}
}
/* Disable the gcry secure memory, not dealing with this for now */
gcry_error = gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
if (gcry_error) {
msg("encryption: unable to disable libgcrypt secmem - "
"%s : %s\n",
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return gcry_error;
}
/* Finalize gcry initialization. */
gcry_error = gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
if (gcry_error) {
msg("encryption: unable to finish libgcrypt initialization - "
"%s : %s\n",
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return gcry_error;
}
/* Determine the algorithm */
encrypt_algo = encrypt_algos[ds_encrypt_algo];
/* Set up the iv length */
encrypt_iv_len = gcry_cipher_get_algo_blklen(encrypt_algo);
xb_a(encrypt_iv_len > 0);
if (iv_len != NULL) {
*iv_len = encrypt_iv_len;
}
/* Now set up the key */
if (ds_encrypt_key == NULL &&
ds_encrypt_key_file == NULL) {
msg("encryption: no encryption key or key file specified.\n");
return gcry_error;
} else if (ds_encrypt_key && ds_encrypt_key_file) {
msg("encryption: both encryption key and key file specified.\n");
return gcry_error;
} else if (ds_encrypt_key_file) {
if (!xb_crypt_read_key_file(ds_encrypt_key_file,
(void**)&ds_encrypt_key,
&encrypt_key_len)) {
msg("encryption: unable to read encryption key file"
" \"%s\".\n", ds_encrypt_key_file);
return gcry_error;
}
} else if (ds_encrypt_key) {
encrypt_key_len = strlen(ds_encrypt_key);
} else {
msg("encryption: no encryption key or key file specified.\n");
return gcry_error;
}
return 0;
}
gcry_error_t
xb_crypt_cipher_open(gcry_cipher_hd_t *cipher_handle)
{
if (encrypt_algo != GCRY_CIPHER_NONE) {
gcry_error_t gcry_error;
gcry_error = gcry_cipher_open(cipher_handle,
encrypt_algo,
encrypt_mode, 0);
if (gcry_error) {
msg("encryption: unable to open libgcrypt"
" cipher - %s : %s\n",
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
gcry_cipher_close(*cipher_handle);
return gcry_error;
}
gcry_error = gcry_cipher_setkey(*cipher_handle,
ds_encrypt_key,
encrypt_key_len);
if (gcry_error) {
msg("encryption: unable to set libgcrypt"
" cipher key - %s : %s\n",
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
gcry_cipher_close(*cipher_handle);
return gcry_error;
}
return gcry_error;
}
return 0;
}
void
xb_crypt_cipher_close(gcry_cipher_hd_t cipher_handle)
{
if (encrypt_algo != GCRY_CIPHER_NONE)
gcry_cipher_close(cipher_handle);
}
gcry_error_t
xb_crypt_decrypt(gcry_cipher_hd_t cipher_handle, const uchar *from,
size_t from_len, uchar *to, size_t *to_len,
const uchar *iv, size_t iv_len, my_bool hash_appended)
{
*to_len = from_len;
if (encrypt_algo != GCRY_CIPHER_NONE) {
gcry_error_t gcry_error;
gcry_error = gcry_cipher_reset(cipher_handle);
if (gcry_error) {
msg("%s:encryption: unable to reset libgcrypt"
" cipher - %s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return gcry_error;
}
if (iv_len > 0) {
gcry_error = gcry_cipher_setctr(cipher_handle,
iv, iv_len);
}
if (gcry_error) {
msg("%s:encryption: unable to set cipher iv - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return gcry_error;
}
/* Try to decrypt it */
gcry_error = gcry_cipher_decrypt(cipher_handle, to, *to_len,
from, from_len);
if (gcry_error) {
msg("%s:encryption: unable to decrypt chunk - "
"%s : %s\n", my_progname,
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
gcry_cipher_close(cipher_handle);
return gcry_error;
}
if (hash_appended) {
uchar hash[XB_CRYPT_HASH_LEN];
*to_len -= XB_CRYPT_HASH_LEN;
/* ensure that XB_CRYPT_HASH_LEN is the correct length
of XB_CRYPT_HASH hashing algorithm output */
xb_ad(gcry_md_get_algo_dlen(XB_CRYPT_HASH) ==
XB_CRYPT_HASH_LEN);
gcry_md_hash_buffer(XB_CRYPT_HASH, hash, to,
*to_len);
if (memcmp(hash, (char *) to + *to_len,
XB_CRYPT_HASH_LEN) != 0) {
msg("%s:%s invalid plaintext hash. "
"Wrong encrytion key specified?\n",
my_progname, __FUNCTION__);
return 1;
}
}
} else {
memcpy(to, from, *to_len);
}
return 0;
}
gcry_error_t
xb_crypt_encrypt(gcry_cipher_hd_t cipher_handle, const uchar *from,
size_t from_len, uchar *to, size_t *to_len, uchar *iv)
{
gcry_error_t gcry_error;
/* ensure that XB_CRYPT_HASH_LEN is the correct length
of XB_CRYPT_HASH hashing algorithm output */
xb_ad(gcry_md_get_algo_dlen(XB_CRYPT_HASH) ==
XB_CRYPT_HASH_LEN);
memcpy(to, from, from_len);
gcry_md_hash_buffer(XB_CRYPT_HASH, to + from_len,
from, from_len);
*to_len = from_len;
if (encrypt_algo != GCRY_CIPHER_NONE) {
gcry_error = gcry_cipher_reset(cipher_handle);
if (gcry_error) {
msg("encrypt: unable to reset cipher - "
"%s : %s\n",
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return gcry_error;
}
xb_crypt_create_iv(iv, encrypt_iv_len);
gcry_error = gcry_cipher_setctr(cipher_handle, iv,
encrypt_iv_len);
if (gcry_error) {
msg("encrypt: unable to set cipher ctr - "
"%s : %s\n",
gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return gcry_error;
}
gcry_error = gcry_cipher_encrypt(cipher_handle, to,
*to_len + XB_CRYPT_HASH_LEN,
to,
from_len + XB_CRYPT_HASH_LEN);
if (gcry_error) {
msg("encrypt: unable to encrypt buffer - "
"%s : %s\n", gcry_strsource(gcry_error),
gcry_strerror(gcry_error));
return gcry_error;
}
} else {
memcpy(to, from, from_len + XB_CRYPT_HASH_LEN);
}
*to_len += XB_CRYPT_HASH_LEN;
return 0;
}
#endif

View File

@ -1,64 +0,0 @@
/******************************************************
Copyright (c) 2017 Percona LLC and/or its affiliates.
Encryption datasink implementation for XtraBackup.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#include <my_base.h>
#if HAVE_GCRYPT
#if GCC_VERSION >= 4002
/* Workaround to avoid "gcry_ac_* is deprecated" warnings in gcrypt.h */
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <gcrypt.h>
extern char *ds_encrypt_key;
extern char *ds_encrypt_key_file;
extern int ds_encrypt_threads;
extern ulong ds_encrypt_algo;
/******************************************************************************
Utility interface */
my_bool xb_crypt_read_key_file(const char *filename,
void** key, uint *keylength);
void xb_crypt_create_iv(void* ivbuf, size_t ivlen);
/* Initialize gcrypt and setup encryption key and IV lengths */
gcry_error_t
xb_crypt_init(uint *iv_len);
/* Setup gcrypt cipher */
gcry_error_t
xb_crypt_cipher_open(gcry_cipher_hd_t *cipher_handle);
/* Close gcrypt cipher */
void
xb_crypt_cipher_close(gcry_cipher_hd_t cipher_handle);
/* Decrypt buffer */
gcry_error_t
xb_crypt_decrypt(gcry_cipher_hd_t cipher_handle, const uchar *from,
size_t from_len, uchar *to, size_t *to_len, const uchar *iv,
size_t iv_len, my_bool hash_appended);
/* Encrypt buffer */
gcry_error_t
xb_crypt_encrypt(gcry_cipher_hd_t cipher_handle, const uchar *from,
size_t from_len, uchar *to, size_t *to_len, uchar *iv);
#endif

View File

@ -1,252 +0,0 @@
/******************************************************
Copyright (c) 2013 Percona LLC and/or its affiliates.
The xbcrypt format reader implementation.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#include "xbcrypt.h"
#include "crc_glue.h"
struct xb_rcrypt_struct {
void *userdata;
xb_crypt_read_callback *read;
void *buffer;
size_t bufsize;
void *ivbuffer;
size_t ivbufsize;
ulonglong offset;
};
xb_rcrypt_t *
xb_crypt_read_open(void *userdata, xb_crypt_read_callback *onread)
{
xb_rcrypt_t *crypt;
xb_ad(onread);
crypt = (xb_rcrypt_t *) my_malloc(sizeof(xb_rcrypt_t), MYF(MY_FAE));
crypt->userdata = userdata;
crypt->read = onread;
crypt->buffer = NULL;
crypt->bufsize = 0;
crypt->offset = 0;
crypt->ivbuffer = NULL;
crypt->ivbufsize = 0;
return crypt;
}
xb_rcrypt_result_t
xb_crypt_read_chunk(xb_rcrypt_t *crypt, void **buf, size_t *olen, size_t *elen,
void **iv, size_t *ivlen, my_bool *hash_appended)
{
uchar tmpbuf[XB_CRYPT_CHUNK_MAGIC_SIZE + 8 + 8 + 8 + 4];
uchar *ptr;
ulonglong tmp;
ulong checksum, checksum_exp, version;
size_t bytesread;
xb_rcrypt_result_t result = XB_CRYPT_READ_CHUNK;
if ((bytesread = crypt->read(crypt->userdata, tmpbuf, sizeof(tmpbuf)))
!= sizeof(tmpbuf)) {
if (bytesread == 0) {
result = XB_CRYPT_READ_EOF;
goto err;
} else {
msg("%s:%s: unable to read chunk header data at "
"offset 0x%llx.\n",
my_progname, __FUNCTION__, crypt->offset);
result = XB_CRYPT_READ_ERROR;
goto err;
}
}
ptr = tmpbuf;
if (memcmp(ptr, XB_CRYPT_CHUNK_MAGIC3,
XB_CRYPT_CHUNK_MAGIC_SIZE) == 0) {
version = 3;
} else if (memcmp(ptr, XB_CRYPT_CHUNK_MAGIC2,
XB_CRYPT_CHUNK_MAGIC_SIZE) == 0) {
version = 2;
} else if (memcmp(ptr, XB_CRYPT_CHUNK_MAGIC1,
XB_CRYPT_CHUNK_MAGIC_SIZE) == 0) {
version = 1;
} else {
msg("%s:%s: wrong chunk magic at offset 0x%llx.\n",
my_progname, __FUNCTION__, crypt->offset);
result = XB_CRYPT_READ_ERROR;
goto err;
}
ptr += XB_CRYPT_CHUNK_MAGIC_SIZE;
crypt->offset += XB_CRYPT_CHUNK_MAGIC_SIZE;
tmp = uint8korr(ptr); /* reserved */
ptr += 8;
crypt->offset += 8;
tmp = uint8korr(ptr); /* original size */
ptr += 8;
if (tmp > INT_MAX) {
msg("%s:%s: invalid original size at offset 0x%llx.\n",
my_progname, __FUNCTION__, crypt->offset);
result = XB_CRYPT_READ_ERROR;
goto err;
}
crypt->offset += 8;
*olen = (size_t)tmp;
tmp = uint8korr(ptr); /* encrypted size */
ptr += 8;
if (tmp > INT_MAX) {
msg("%s:%s: invalid encrypted size at offset 0x%llx.\n",
my_progname, __FUNCTION__, crypt->offset);
result = XB_CRYPT_READ_ERROR;
goto err;
}
crypt->offset += 8;
*elen = (size_t)tmp;
checksum_exp = uint4korr(ptr); /* checksum */
ptr += 4;
crypt->offset += 4;
/* iv size */
if (version == 1) {
*ivlen = 0;
*iv = 0;
} else {
if ((bytesread = crypt->read(crypt->userdata, tmpbuf, 8))
!= 8) {
if (bytesread == 0) {
result = XB_CRYPT_READ_EOF;
goto err;
} else {
msg("%s:%s: unable to read chunk iv size at "
"offset 0x%llx.\n",
my_progname, __FUNCTION__, crypt->offset);
result = XB_CRYPT_READ_ERROR;
goto err;
}
}
tmp = uint8korr(tmpbuf);
if (tmp > INT_MAX) {
msg("%s:%s: invalid iv size at offset 0x%llx.\n",
my_progname, __FUNCTION__, crypt->offset);
result = XB_CRYPT_READ_ERROR;
goto err;
}
crypt->offset += 8;
*ivlen = (size_t)tmp;
}
if (*ivlen > crypt->ivbufsize) {
crypt->ivbuffer = my_realloc(crypt->ivbuffer, *ivlen,
MYF(MY_WME | MY_ALLOW_ZERO_PTR));
if (crypt->ivbuffer == NULL) {
msg("%s:%s: failed to increase iv buffer to "
"%llu bytes.\n", my_progname, __FUNCTION__,
(ulonglong)*ivlen);
result = XB_CRYPT_READ_ERROR;
goto err;
}
crypt->ivbufsize = *ivlen;
}
if (*ivlen > 0) {
if (crypt->read(crypt->userdata, crypt->ivbuffer, *ivlen)
!= *ivlen) {
msg("%s:%s: failed to read %lld bytes for chunk iv "
"at offset 0x%llx.\n", my_progname, __FUNCTION__,
(ulonglong)*ivlen, crypt->offset);
result = XB_CRYPT_READ_ERROR;
goto err;
}
*iv = crypt->ivbuffer;
}
/* for version euqals 2 we need to read in the iv data but do not init
CTR with it */
if (version == 2) {
*ivlen = 0;
*iv = 0;
}
if (*olen > crypt->bufsize) {
crypt->buffer = my_realloc(crypt->buffer, *olen,
MYF(MY_WME | MY_ALLOW_ZERO_PTR));
if (crypt->buffer == NULL) {
msg("%s:%s: failed to increase buffer to "
"%llu bytes.\n", my_progname, __FUNCTION__,
(ulonglong)*olen);
result = XB_CRYPT_READ_ERROR;
goto err;
}
crypt->bufsize = *olen;
}
if (*elen > 0) {
if (crypt->read(crypt->userdata, crypt->buffer, *elen)
!= *elen) {
msg("%s:%s: failed to read %lld bytes for chunk payload "
"at offset 0x%llx.\n", my_progname, __FUNCTION__,
(ulonglong)*elen, crypt->offset);
result = XB_CRYPT_READ_ERROR;
goto err;
}
}
checksum = crc32_iso3309(0, crypt->buffer, *elen);
if (checksum != checksum_exp) {
msg("%s:%s invalid checksum at offset 0x%llx, "
"expected 0x%lx, actual 0x%lx.\n", my_progname, __FUNCTION__,
crypt->offset, checksum_exp, checksum);
result = XB_CRYPT_READ_ERROR;
goto err;
}
crypt->offset += *elen;
*buf = crypt->buffer;
*hash_appended = version > 2;
goto exit;
err:
*buf = NULL;
*olen = 0;
*elen = 0;
*ivlen = 0;
*iv = 0;
exit:
return result;
}
int xb_crypt_read_close(xb_rcrypt_t *crypt)
{
if (crypt->buffer)
my_free(crypt->buffer);
if (crypt->ivbuffer)
my_free(crypt->ivbuffer);
my_free(crypt);
return 0;
}

View File

@ -1,105 +0,0 @@
/******************************************************
Copyright (c) 2013 Percona LLC and/or its affiliates.
The xbcrypt format writer implementation.
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; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
#include "xbcrypt.h"
#include "crc_glue.h"
struct xb_wcrypt_struct {
void *userdata;
xb_crypt_write_callback *write;
};
xb_wcrypt_t *
xb_crypt_write_open(void *userdata, xb_crypt_write_callback *onwrite)
{
xb_wcrypt_t *crypt;
xb_ad(onwrite);
crypt = (xb_wcrypt_t *) my_malloc(sizeof(xb_wcrypt_t), MYF(MY_FAE));
crypt->userdata = userdata;
crypt->write = onwrite;
return crypt;
}
int xb_crypt_write_chunk(xb_wcrypt_t *crypt, const void *buf, size_t olen,
size_t elen, const void *iv, size_t ivlen)
{
uchar tmpbuf[XB_CRYPT_CHUNK_MAGIC_SIZE + 8 + 8 + 8 + 4 + 8];
uchar *ptr;
ulong checksum;
xb_ad(olen <= INT_MAX);
if (olen > INT_MAX)
return 0;
xb_ad(elen <= INT_MAX);
if (elen > INT_MAX)
return 0;
xb_ad(ivlen <= INT_MAX);
if (ivlen > INT_MAX)
return 0;
ptr = tmpbuf;
memcpy(ptr, XB_CRYPT_CHUNK_MAGIC_CURRENT, XB_CRYPT_CHUNK_MAGIC_SIZE);
ptr += XB_CRYPT_CHUNK_MAGIC_SIZE;
int8store(ptr, (ulonglong)0); /* reserved */
ptr += 8;
int8store(ptr, (ulonglong)olen); /* original size */
ptr += 8;
int8store(ptr, (ulonglong)elen); /* encrypted (actual) size */
ptr += 8;
checksum = crc32_iso3309(0, buf, elen);
int4store(ptr, checksum); /* checksum */
ptr += 4;
int8store(ptr, (ulonglong)ivlen); /* iv size */
ptr += 8;
xb_ad(ptr <= tmpbuf + sizeof(tmpbuf));
if (crypt->write(crypt->userdata, tmpbuf, ptr-tmpbuf) == -1)
return 1;
if (crypt->write(crypt->userdata, iv, ivlen) == -1)
return 1;
if (crypt->write(crypt->userdata, buf, elen) == -1)
return 1;
return 0;
}
int xb_crypt_write_close(xb_wcrypt_t *crypt)
{
my_free(crypt);
return 0;
}

View File

@ -25,9 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include <my_pthread.h>
#include "common.h"
#include "xbstream.h"
#include "xbcrypt_common.h"
#include "datasink.h"
#include "ds_decrypt.h"
#include "crc_glue.h"
#define XBSTREAM_VERSION "1.0"
@ -41,33 +39,18 @@ typedef enum {
RUN_MODE_EXTRACT
} run_mode_t;
const char *xbstream_encrypt_algo_names[] =
{ "NONE", "AES128", "AES192", "AES256", NullS};
TYPELIB xbstream_encrypt_algo_typelib=
{array_elements(xbstream_encrypt_algo_names)-1,"",
xbstream_encrypt_algo_names, NULL};
/* Need the following definitions to avoid linking with ds_*.o and their link
dependencies */
datasink_t datasink_archive;
datasink_t datasink_xbstream;
datasink_t datasink_compress;
datasink_t datasink_tmpfile;
datasink_t datasink_encrypt;
datasink_t datasink_buffer;
static run_mode_t opt_mode;
static char * opt_directory = NULL;
static my_bool opt_verbose = 0;
static int opt_parallel = 1;
static ulong opt_encrypt_algo;
static char *opt_encrypt_key_file = NULL;
static void *opt_encrypt_key = NULL;
static int opt_encrypt_threads = 1;
enum {
OPT_ENCRYPT_THREADS = 256
};
static struct my_option my_long_options[] =
{
@ -86,20 +69,6 @@ static struct my_option my_long_options[] =
{"parallel", 'p', "Number of worker threads for reading / writing.",
&opt_parallel, &opt_parallel, 0, GET_INT, REQUIRED_ARG,
1, 1, INT_MAX, 0, 0, 0},
{"decrypt", 'd', "Decrypt files ending with .xbcrypt.",
&opt_encrypt_algo, &opt_encrypt_algo, &xbstream_encrypt_algo_typelib,
GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"encrypt-key", 'k', "Encryption key.",
&opt_encrypt_key, &opt_encrypt_key, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"encrypt-key-file", 'f', "File which contains encryption key.",
&opt_encrypt_key_file, &opt_encrypt_key_file, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"encrypt-threads", OPT_ENCRYPT_THREADS,
"Number of threads for parallel data encryption. "
"The default value is 1.",
&opt_encrypt_threads, &opt_encrypt_threads,
0, GET_INT, REQUIRED_ARG, 1, 1, INT_MAX, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@ -108,7 +77,6 @@ typedef struct {
HASH *filehash;
xb_rstream_t *stream;
ds_ctxt_t *ds_ctxt;
ds_ctxt_t *ds_decrypt_ctxt;
pthread_mutex_t *mutex;
} extract_ctxt_t;
@ -348,19 +316,6 @@ err:
return 1;
}
/************************************************************************
Check if string ends with given suffix.
@return true if string ends with given suffix. */
static
my_bool
ends_with(const char *str, const char *suffix)
{
size_t suffix_len = strlen(suffix);
size_t str_len = strlen(str);
return(str_len >= suffix_len
&& strcmp(str + str_len - suffix_len, suffix) == 0);
}
static
file_entry_t *
file_entry_new(extract_ctxt_t *ctxt, const char *path, uint pathlen)
@ -380,11 +335,8 @@ file_entry_new(extract_ctxt_t *ctxt, const char *path, uint pathlen)
}
entry->pathlen = pathlen;
if (ctxt->ds_decrypt_ctxt && ends_with(path, ".xbcrypt")) {
file = ds_open(ctxt->ds_decrypt_ctxt, path, NULL);
} else {
file = ds_open(ctxt->ds_ctxt, path, NULL);
}
file = ds_open(ctxt->ds_ctxt, path, NULL);
if (file == NULL) {
msg("%s: failed to create file.\n", my_progname);
goto err;
@ -534,7 +486,6 @@ mode_extract(int n_threads, int argc __attribute__((unused)),
xb_rstream_t *stream = NULL;
HASH filehash;
ds_ctxt_t *ds_ctxt = NULL;
ds_ctxt_t *ds_decrypt_ctxt = NULL;
extract_ctxt_t ctxt;
int i;
pthread_t *tids = NULL;
@ -574,7 +525,6 @@ mode_extract(int n_threads, int argc __attribute__((unused)),
ctxt.stream = stream;
ctxt.filehash = &filehash;
ctxt.ds_ctxt = ds_ctxt;
ctxt.ds_decrypt_ctxt = ds_decrypt_ctxt;
ctxt.mutex = &mutex;
tids = malloc(sizeof(pthread_t) * n_threads);
@ -604,9 +554,6 @@ exit:
if (ds_ctxt != NULL) {
ds_destroy(ds_ctxt);
}
if (ds_decrypt_ctxt) {
ds_destroy(ds_decrypt_ctxt);
}
xb_stream_read_done(stream);
return ret;

View File

@ -42,7 +42,6 @@ typedef struct xb_wstream_file_struct xb_wstream_file_t;
typedef enum {
XB_STREAM_FMT_NONE,
XB_STREAM_FMT_TAR,
XB_STREAM_FMT_XBSTREAM
} xb_stream_fmt_t;

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include "changed_page_bitmap.h"
#ifdef __WIN__
#define XB_FILE_UNDEFINED NULL
#define XB_FILE_UNDEFINED INVALID_HANDLE_VALUE
#else
#define XB_FILE_UNDEFINED (-1)
#endif
@ -81,7 +81,6 @@ extern char *xtrabackup_tables_exclude;
extern char *xtrabackup_databases_exclude;
extern ibool xtrabackup_compress;
extern ibool xtrabackup_encrypt;
extern my_bool xtrabackup_backup;
extern my_bool xtrabackup_prepare;
@ -92,15 +91,10 @@ extern my_bool xtrabackup_decrypt_decompress;
extern char *innobase_data_file_path;
extern char *innobase_doublewrite_file;
extern char *xtrabackup_encrypt_key;
extern char *xtrabackup_encrypt_key_file;
extern longlong innobase_log_file_size;
extern long innobase_log_files_in_group;
extern longlong innobase_page_size;
extern const char *xtrabackup_encrypt_algo_names[];
extern TYPELIB xtrabackup_encrypt_algo_typelib;
extern int xtrabackup_parallel;
extern my_bool xb_close_files;
@ -113,9 +107,6 @@ extern "C"{
#ifdef __cplusplus
}
#endif
extern ulong xtrabackup_encrypt_algo;
extern uint xtrabackup_encrypt_threads;
extern ulonglong xtrabackup_encrypt_chunk_size;
extern my_bool xtrabackup_export;
extern char *xtrabackup_incremental_basedir;
extern char *xtrabackup_extra_lsndir;
@ -158,8 +149,6 @@ extern TYPELIB query_type_typelib;
extern ulong opt_lock_wait_query_type;
extern ulong opt_kill_long_query_type;
extern ulong opt_decrypt_algo;
extern uint opt_kill_long_queries_timeout;
extern uint opt_lock_wait_timeout;
extern uint opt_lock_wait_threshold;
@ -167,7 +156,6 @@ extern uint opt_debug_sleep_before_unlock;
extern uint opt_safe_slave_backup_timeout;
extern const char *opt_history;
extern my_bool opt_decrypt;
enum binlog_info_enum { BINLOG_INFO_OFF, BINLOG_INFO_LOCKLESS, BINLOG_INFO_ON,
BINLOG_INFO_AUTO};
@ -182,19 +170,10 @@ 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(os_file_t file);
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)

View File

@ -174,6 +174,7 @@ register char **argv[];
break;
case 'V':
version=1;
/* fall through */
case 'I':
case '?':
help=1; /* Help text written */

View File

@ -949,6 +949,12 @@ extern ulonglong my_getcputime(void);
#define hrtime_sec_part(X) ((ulong)((X).val % HRTIME_RESOLUTION))
#define my_time(X) hrtime_to_time(my_hrtime())
#if STACK_DIRECTION < 0
#define available_stack_size(CUR,END) (long) ((char*)(CUR) - (char*)(END))
#else
#define available_stack_size(CUR,END) (long) ((char*)(END) - (char*)(CUR))
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>

View File

@ -12,7 +12,8 @@ enum enum_server_command
COM_UNIMPLEMENTED,
COM_RESET_CONNECTION,
COM_MDB_GAP_BEG,
COM_MDB_GAP_END=250,
COM_MDB_GAP_END=249,
COM_STMT_BULK_EXECUTE=250,
COM_SLAVE_WORKER=251,
COM_SLAVE_IO=252,
COM_SLAVE_SQL=253,

View File

@ -115,7 +115,8 @@ enum enum_server_command
COM_RESET_CONNECTION,
/* don't forget to update const char *command_name[] in sql_parse.cc */
COM_MDB_GAP_BEG,
COM_MDB_GAP_END=250,
COM_MDB_GAP_END=249,
COM_STMT_BULK_EXECUTE=250,
COM_SLAVE_WORKER=251,
COM_SLAVE_IO=252,
COM_SLAVE_SQL=253,
@ -136,6 +137,13 @@ enum enum_indicator_type
STMT_INDICATOR_IGNORE
};
/*
bulk PS flags
*/
#define STMT_BULK_FLAG_CLIENT_SEND_TYPES 128
#define STMT_BULK_FLAG_INSERT_ID_REQUEST 64
/* sql type stored in .frm files for virtual fields */
#define MYSQL_TYPE_VIRTUAL 245
/*
@ -311,7 +319,8 @@ enum enum_indicator_type
CLIENT_SESSION_TRACK |\
CLIENT_DEPRECATE_EOF |\
CLIENT_CONNECT_ATTRS |\
MARIADB_CLIENT_COM_MULTI)
MARIADB_CLIENT_COM_MULTI |\
MARIADB_CLIENT_STMT_BULK_OPERATIONS)
/*
To be added later:

@ -1 +1 @@
Subproject commit 467a193b399dfda41d87368a898e9550d754fa14
Subproject commit ff4bfdf1caf2e0a47382fdbe6d796d0e63ec1062

View File

@ -1404,7 +1404,7 @@ void set_stmt_errmsg(MYSQL_STMT *stmt, NET *net)
DBUG_ASSERT(stmt != 0);
stmt->last_errno= net->last_errno;
if (net->last_error && net->last_error[0])
if (net->last_error[0])
strmov(stmt->last_error, net->last_error);
strmov(stmt->sqlstate, net->sqlstate);
@ -4707,8 +4707,7 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
{
uchar buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */
if ((rc= reset_stmt_handle(stmt, RESET_ALL_BUFFERS | RESET_CLEAR_ERROR)))
return rc;
reset_stmt_handle(stmt, RESET_ALL_BUFFERS | RESET_CLEAR_ERROR);
int4store(buff, stmt->stmt_id);
if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)))

View File

@ -0,0 +1,16 @@
[64k]
innodb-page-size=64K
innodb-buffer-pool-size=24M
[32k]
innodb-page-size=32K
innodb-buffer-pool-size=24M
[16k]
innodb-page-size=16K
[8k]
innodb-page-size=8K
[4k]
innodb-page-size=4K

View File

@ -0,0 +1,4 @@
# The goal of including this file is to enable innodb_page_size combinations
# (see include/innodb_page_size.combinations)
--source include/have_innodb.inc

View File

@ -0,0 +1,8 @@
[16k]
innodb-page-size=16K
[8k]
innodb-page-size=8K
[4k]
innodb-page-size=4K

View File

@ -0,0 +1,4 @@
# The goal of including this file is to enable innodb_page_size combinations
# (see include/innodb_page_size.combinations)
--source include/have_innodb.inc

View File

@ -90,6 +90,7 @@ explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a '
--replace_regex /Duplicate entry '[^']+' for key/Duplicate entry '{ ' for key/
--error ER_DUP_ENTRY
alter table t1 add unique(v);
show warnings;
alter table t1 add key(v);
select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a';
--replace_column 6 # 9 # 10 #

View File

@ -208,6 +208,10 @@ sub mtr_report_test ($) {
{
mtr_report("[ skipped ]");
}
if ( $tinfo->{'warnings'} )
{
mtr_report($tinfo->{'warnings'});
}
}
elsif ($result eq 'MTR_RES_PASSED')
{

View File

@ -2794,15 +2794,26 @@ sub mysql_server_start($) {
}
my $mysqld_basedir= $mysqld->value('basedir');
my $extra_opts= get_extra_opts($mysqld, $tinfo);
if ( $basedir eq $mysqld_basedir )
{
if (! $opt_start_dirty) # If dirty, keep possibly grown system db
{
# Copy datadir from installed system db
my $path= ($opt_parallel == 1) ? "$opt_vardir" : "$opt_vardir/..";
my $install_db= "$path/install.db";
copytree($install_db, $datadir) if -d $install_db;
mtr_error("Failed to copy system db to '$datadir'") unless -d $datadir;
# Some InnoDB options are incompatible with the default bootstrap.
# If they are used, re-bootstrap
if ( $extra_opts and
"@$extra_opts" =~ /--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)/ )
{
mysql_install_db($mysqld, undef, $extra_opts);
}
else {
# Copy datadir from installed system db
my $path= ($opt_parallel == 1) ? "$opt_vardir" : "$opt_vardir/..";
my $install_db= "$path/install.db";
copytree($install_db, $datadir) if -d $install_db;
mtr_error("Failed to copy system db to '$datadir'") unless -d $datadir;
}
}
}
else
@ -2841,7 +2852,6 @@ sub mysql_server_start($) {
if (!$opt_embedded_server)
{
my $extra_opts= get_extra_opts($mysqld, $tinfo);
mysqld_start($mysqld,$extra_opts);
# Save this test case information, so next can examine it
@ -3065,7 +3075,7 @@ sub default_mysqld {
sub mysql_install_db {
my ($mysqld, $datadir)= @_;
my ($mysqld, $datadir, $extra_opts)= @_;
my $install_datadir= $datadir || $mysqld->value('datadir');
my $install_basedir= $mysqld->value('basedir');
@ -3106,6 +3116,13 @@ sub mysql_install_db {
mtr_add_arg($args, $extra_opt);
}
}
# InnoDB options can come not only from the command line, but also
# from option files or combinations
foreach my $extra_opt ( @$extra_opts ) {
if ($extra_opt =~ /--innodb/) {
mtr_add_arg($args, $extra_opt);
}
}
# If DISABLE_GRANT_OPTIONS is defined when the server is compiled (e.g.,
# configure --disable-grant-options), mysqld will not recognize the
@ -3990,12 +4007,13 @@ sub run_testcase ($$) {
{
my $res= $test->exit_status();
if ($res == 0 and $opt_warnings and check_warnings($tinfo) )
if (($res == 0 or $res == 62) and $opt_warnings and check_warnings($tinfo) )
{
# Test case suceeded, but it has produced unexpected
# warnings, continue in $res == 1
$res= 1;
resfile_output($tinfo->{'warnings'}) if $opt_resfile;
# If test case suceeded, but it has produced unexpected
# warnings, continue with $res == 1;
# but if the test was skipped, it should remain skipped
$res= 1 if $res == 0;
resfile_output($tinfo->{'warnings'}) if $opt_resfile;
}
if ( $res == 0 )

View File

@ -184,6 +184,35 @@ CREATE TABLE t1 (a LONGTEXT COLLATE latin1_general_ci);
ALTER TABLE t1 MODIFY a LONGTEXT COLLATE latin1_swedish_ci, ALGORITHM=INPLACE;
ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
DROP TABLE t1;
#
# End of MDEV-8948 ALTER ... INPLACE does work for BINARY, BLOB
#
select @@global.delay_key_write;
@@global.delay_key_write
ON
create table t1 (a int, b int, key(b));
flush tables;
flush status;
show status like 'Feature_delay_key_write';
Variable_name Value
Feature_delay_key_write 0
insert t1 values (1,2),(2,3),(3,4);
show status like 'Feature_delay_key_write';
Variable_name Value
Feature_delay_key_write 0
alter online table t1 delay_key_write=1;
show status like 'Feature_delay_key_write';
Variable_name Value
Feature_delay_key_write 1
flush tables;
insert t1 values (1,2),(2,3),(3,4);
show status like 'Feature_delay_key_write';
Variable_name Value
Feature_delay_key_write 2
alter online table t1 delay_key_write=0;
show status like 'Feature_delay_key_write';
Variable_name Value
Feature_delay_key_write 2
flush tables;
insert t1 values (1,2),(2,3),(3,4);
show status like 'Feature_delay_key_write';
Variable_name Value
Feature_delay_key_write 2
drop table t1;

View File

@ -614,22 +614,24 @@ ANALYZE
},
"block-nl-join": {
"table": {
"table_name": "<subquery2>",
"table_name": "t2",
"access_type": "ALL",
"possible_keys": ["distinct_key"],
"r_loops": 1,
"rows": 2,
"r_rows": 2,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
"r_filtered": 0,
"attached_condition": "<in_optimizer>(t2.b,t2.b in (subquery#2))"
},
"buffer_type": "flat",
"buffer_size": "256Kb",
"join_type": "BNL",
"r_filtered": 100,
"materialized": {
"unique": 1,
"attached_condition": "<in_optimizer>(t2.b,t2.b in (subquery#2))",
"r_filtered": null
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"r_loops": 1,
@ -646,24 +648,7 @@ ANALYZE
}
}
}
},
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"r_loops": 1,
"rows": 2,
"r_rows": 2,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"buffer_type": "incremental",
"buffer_size": "256Kb",
"join_type": "BNL",
"attached_condition": "t2.b = `<subquery2>`.a",
"r_filtered": 0
}
]
}
}
drop table t1,t2;

View File

@ -667,7 +667,7 @@ create table t1 (a int);
create table t1 select * from t1;
ERROR 42S01: Table 't1' already exists
create table t2 union = (t1) select * from t1;
ERROR HY000: 'test.t2' is not BASE TABLE
ERROR HY000: 'test.t2' is not of type 'BASE TABLE'
flush tables with read lock;
unlock tables;
drop table t1;
@ -701,7 +701,7 @@ create database mysqltest;
use mysqltest;
create view v1 as select 'foo' from dual;
create table t1 like v1;
ERROR HY000: 'mysqltest.v1' is not BASE TABLE
ERROR HY000: 'mysqltest.v1' is not of type 'BASE TABLE'
drop view v1;
drop database mysqltest;
create database mysqltest;

View File

@ -507,6 +507,7 @@ select t.a, count(*) from t1,t where t1.a=t.a group by t.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 35 func 1
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
explain
@ -522,6 +523,7 @@ where t1.a=t.a group by t.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 35 func 1
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
# with clause in the specification of a derived table

View File

@ -2916,5 +2916,64 @@ Handler_read_rnd_deleted 0
Handler_read_rnd_next 27
deallocate prepare stmt1;
drop table t1,t2;
#
# Bug mdev-12670: mergeable derived / view with subqueries
# subject to semi-join optimizations
# (actually this is a 5.3 bug.)
#
create table t1 (a int) engine=myisam;
insert into t1 values (5),(3),(2),(7),(2),(5),(1);
create table t2 (b int, index idx(b)) engine=myisam;
insert into t2 values (2),(3),(2),(1),(3),(4);
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
analyze table t1,t2;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
explain select a from t1 where a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 140 Using index; FirstMatch(t1)
explain select * from (select a from t1 where a in (select b from t2)) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 140 Using index; FirstMatch(t1)
create view v1 as select a from t1 where a in (select b from t2);
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 140 Using index; FirstMatch(t1)
drop view v1;
drop table t1,t2;
#
# Bug mdev-12812: mergeable derived / view with subqueries
# NOT subject to semi-join optimizations
#
CREATE TABLE t1 (c1 varchar(3)) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('foo'),('foo');
CREATE TABLE t2 (c2 varchar(3)) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('bar'),('qux'),('foo');
SELECT STRAIGHT_JOIN *
FROM ( SELECT * FROM t1 WHERE c1 IN ( SELECT c2 FROM t2 ) ) AS sq;
c1
foo
foo
EXPLAIN EXTENDED SELECT STRAIGHT_JOIN *
FROM ( SELECT * FROM t1 WHERE c1 IN ( SELECT c2 FROM t2 ) ) AS sq;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select straight_join `test`.`t1`.`c1` AS `c1` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`c1`,<exists>(/* select#3 */ select `test`.`t2`.`c2` from `test`.`t2` where <cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c2`))
DROP TABLE t1, t2;
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;

View File

@ -60,7 +60,7 @@ DROP TABLE export;
CREATE VIEW v1 AS SELECT 1;
CREATE TEMPORARY TABLE t1 (a INT);
FLUSH TABLES v1 FOR EXPORT;
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
FLUSH TABLES t1 FOR EXPORT;
ERROR 42S02: Table 'test.t1' doesn't exist
FLUSH TABLES non_existent FOR EXPORT;

View File

@ -295,16 +295,16 @@ create view v1 as select 1;
create view v2 as select * from t1;
create view v3 as select * from v2;
flush table v1, v2, v3 with read lock;
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
flush table v1 with read lock;
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
flush table v2 with read lock;
ERROR HY000: 'test.v2' is not BASE TABLE
ERROR HY000: 'test.v2' is not of type 'BASE TABLE'
flush table v3 with read lock;
ERROR HY000: 'test.v3' is not BASE TABLE
ERROR HY000: 'test.v3' is not of type 'BASE TABLE'
create temporary table v1 (a int);
flush table v1 with read lock;
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
drop view v1;
create table v1 (a int);
flush table v1 with read lock;

View File

@ -2448,6 +2448,15 @@ DROP TABLE t1;
# End of 10.1 tests
#
#
# MDEV-13064: assertion `n < m_size' fails in Item::split_sum_func2()
#
create table t1 (i int) engine=MyISAM;
insert into t1 value (1),(2);
select count(*)+sleep(0) from t1;
count(*)+sleep(0)
2
drop table t1;
#
# Start of 10.3 tests
#
#

View File

@ -3570,6 +3570,153 @@ t1 CREATE TABLE `t1` (
`c2` bigint(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 AS SELECT
9 AS i1, COALESCE(9) AS c1,
99 AS i2, COALESCE(99) AS c2,
999 AS i3, COALESCE(999) AS c3,
9999 AS i4, COALESCE(9999) AS c4,
99999 AS i5, COALESCE(99999) AS c5,
999999 AS i6, COALESCE(999999) AS c6,
9999999 AS i7, COALESCE(9999999) AS c7,
99999999 AS i8, COALESCE(99999999) AS c8,
999999999 AS i9, COALESCE(999999999) AS c9,
2147483647, COALESCE(2147483647),
2147483648, COALESCE(2147483648),
9999999999 AS i10, COALESCE(9999999999) AS c10,
99999999999 AS i11, COALESCE(99999999999) AS c11,
999999999999 AS i12, COALESCE(999999999999) AS c12,
9999999999999 AS i13, COALESCE(9999999999999) AS c13,
99999999999999 AS i14, COALESCE(99999999999999) AS c14,
999999999999999 AS i15, COALESCE(999999999999999) AS c15,
9999999999999999 AS i16, COALESCE(9999999999999999) AS c16,
99999999999999999 AS i17, COALESCE(99999999999999999) AS c17,
999999999999999999 AS i18, COALESCE(999999999999999999) AS c18,
9223372036854775807, COALESCE(9223372036854775807),
9223372036854775808, COALESCE(9223372036854775808),
9999999999999999999 AS i19, COALESCE(9999999999999999999) AS c19,
18446744073709551615, COALESCE(18446744073709551615),
18446744073709551616, COALESCE(18446744073709551616),
99999999999999999999 AS i20, COALESCE(99999999999999999999) AS c20,
999999999999999999999 AS i21, COALESCE(999999999999999999999) AS c21,
9999999999999999999999 AS i22, COALESCE(9999999999999999999999) AS c22;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`i1` int(1) NOT NULL,
`c1` int(1) NOT NULL,
`i2` int(2) NOT NULL,
`c2` int(2) NOT NULL,
`i3` int(3) NOT NULL,
`c3` int(3) NOT NULL,
`i4` int(4) NOT NULL,
`c4` int(4) NOT NULL,
`i5` int(5) NOT NULL,
`c5` int(5) NOT NULL,
`i6` int(6) NOT NULL,
`c6` int(6) NOT NULL,
`i7` int(7) NOT NULL,
`c7` int(7) NOT NULL,
`i8` int(8) NOT NULL,
`c8` int(8) NOT NULL,
`i9` int(9) NOT NULL,
`c9` int(9) NOT NULL,
`2147483647` bigint(10) NOT NULL,
`COALESCE(2147483647)` bigint(10) NOT NULL,
`2147483648` bigint(10) NOT NULL,
`COALESCE(2147483648)` bigint(10) NOT NULL,
`i10` bigint(10) NOT NULL,
`c10` bigint(10) NOT NULL,
`i11` bigint(11) NOT NULL,
`c11` bigint(11) NOT NULL,
`i12` bigint(12) NOT NULL,
`c12` bigint(12) NOT NULL,
`i13` bigint(13) NOT NULL,
`c13` bigint(13) NOT NULL,
`i14` bigint(14) NOT NULL,
`c14` bigint(14) NOT NULL,
`i15` bigint(15) NOT NULL,
`c15` bigint(15) NOT NULL,
`i16` bigint(16) NOT NULL,
`c16` bigint(16) NOT NULL,
`i17` bigint(17) NOT NULL,
`c17` bigint(17) NOT NULL,
`i18` bigint(18) NOT NULL,
`c18` bigint(18) NOT NULL,
`9223372036854775807` bigint(19) NOT NULL,
`COALESCE(9223372036854775807)` bigint(19) NOT NULL,
`9223372036854775808` bigint(19) unsigned NOT NULL,
`COALESCE(9223372036854775808)` bigint(19) unsigned NOT NULL,
`i19` bigint(19) unsigned NOT NULL,
`c19` bigint(19) unsigned NOT NULL,
`18446744073709551615` bigint(20) unsigned NOT NULL,
`COALESCE(18446744073709551615)` bigint(20) unsigned NOT NULL,
`18446744073709551616` decimal(20,0) NOT NULL,
`COALESCE(18446744073709551616)` decimal(20,0) NOT NULL,
`i20` decimal(20,0) NOT NULL,
`c20` decimal(20,0) NOT NULL,
`i21` decimal(21,0) NOT NULL,
`c21` decimal(21,0) NOT NULL,
`i22` decimal(22,0) NOT NULL,
`c22` decimal(22,0) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM t1;
i1 9
c1 9
i2 99
c2 99
i3 999
c3 999
i4 9999
c4 9999
i5 99999
c5 99999
i6 999999
c6 999999
i7 9999999
c7 9999999
i8 99999999
c8 99999999
i9 999999999
c9 999999999
2147483647 2147483647
COALESCE(2147483647) 2147483647
2147483648 2147483648
COALESCE(2147483648) 2147483648
i10 9999999999
c10 9999999999
i11 99999999999
c11 99999999999
i12 999999999999
c12 999999999999
i13 9999999999999
c13 9999999999999
i14 99999999999999
c14 99999999999999
i15 999999999999999
c15 999999999999999
i16 9999999999999999
c16 9999999999999999
i17 99999999999999999
c17 99999999999999999
i18 999999999999999999
c18 999999999999999999
9223372036854775807 9223372036854775807
COALESCE(9223372036854775807) 9223372036854775807
9223372036854775808 9223372036854775808
COALESCE(9223372036854775808) 9223372036854775808
i19 9999999999999999999
c19 9999999999999999999
18446744073709551615 18446744073709551615
COALESCE(18446744073709551615) 18446744073709551615
18446744073709551616 18446744073709551616
COALESCE(18446744073709551616) 18446744073709551616
i20 99999999999999999999
c20 99999999999999999999
i21 999999999999999999999
c21 999999999999999999999
i22 9999999999999999999999
c22 9999999999999999999999
DROP TABLE t1;
#
# MDEV-9406 CREATE TABLE..SELECT creates different columns for IFNULL() and equivalent COALESCE,CASE,IF
#

View File

@ -880,3 +880,17 @@ SET @regCheck= '\\xE0\\x01';
SELECT CAST(0xE001 AS BINARY) REGEXP @regCheck;
CAST(0xE001 AS BINARY) REGEXP @regCheck
1
# MDEV-12420: Testing recursion overflow
SELECT 1 FROM dual WHERE ('Alpha,Bravo,Charlie,Delta,Echo,Foxtrot,StrataCentral,Golf,Hotel,India,Juliet,Kilo,Lima,Mike,StrataL3,November,Oscar,StrataL2,Sand,P3,P4SwitchTest,Arsys,Poppa,ExtensionMgr,Arp,Quebec,Romeo,StrataApiV2,PtReyes,Sierra,SandAcl,Arrow,Artools,BridgeTest,Tango,SandT,PAlaska,Namespace,Agent,Qos,PatchPanel,ProjectReport,Ark,Gimp,Agent,SliceAgent,Arnet,Bgp,Ale,Tommy,Central,AsicPktTestLib,Hsc,SandL3,Abuild,Pca9555,Standby,ControllerDut,CalSys,SandLib,Sb820,PointV2,BfnLib,Evpn,BfnSdk,Sflow,ManagementActive,AutoTest,GatedTest,Bgp,Sand,xinetd,BfnAgentLib,bf-utils,Hello,BfnState,Eos,Artest,Qos,Scd,ThermoMgr,Uniform,EosUtils,Eb,FanController,Central,BfnL3,BfnL2,tcp_wrappers,Victor,Environment,Route,Failover,Whiskey,Xray,Gimp,BfnFixed,Strata,SoCal,XApi,Msrp,XpProfile,tcpdump,PatchPanel,ArosTest,FhTest,Arbus,XpAcl,MacConc,XpApi,telnet,QosTest,Alpha2,BfnVlan,Stp,VxlanControllerTest,MplsAgent,Bravo2,Lanz,BfnMbb,Intf,XCtrl,Unicast,SandTunnel,L3Unicast,Ipsec,MplsTest,Rsvp,EthIntf,StageMgr,Sol,MplsUtils,Nat,Ira,P4NamespaceDut,Counters,Charlie2,Aqlc,Mlag,Power,OpenFlow,Lag,RestApi,BfdTest,strongs,Sfa,CEosUtils,Adt746,MaintenanceMode,MlagDut,EosImage,IpEth,MultiProtocol,Launcher,Max3179,Snmp,Acl,IpEthTest,PhyEee,bf-syslibs,tacc,XpL2,p4-ar-switch,p4-bf-switch,LdpTest,BfnPhy,Mirroring,Phy6,Ptp' REGEXP '^((?!\b(Strata|StrataApi|StrataApiV2)\b).)*$');
1
Warnings:
Warning 1139 Got error 'pcre_exec: recursion limit of NUM exceeded' from regexp
SELECT REGEXP_INSTR('a_kollision', 'oll');
REGEXP_INSTR('a_kollision', 'oll')
4
SELECT REGEXP_INSTR('a_kollision', '(oll)');
REGEXP_INSTR('a_kollision', '(oll)')
4
SELECT REGEXP_INSTR('a_kollision', 'o([lm])\\1');
REGEXP_INSTR('a_kollision', 'o([lm])\\1')
4

View File

@ -1090,7 +1090,7 @@ t_nn CREATE TABLE `t_nn` (
`c1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW CREATE VIEW mysqltest2.t_nn;
ERROR HY000: 'mysqltest2.t_nn' is not VIEW
ERROR HY000: 'mysqltest2.t_nn' is not of type 'VIEW'
SHOW CREATE VIEW mysqltest2.v_yy;
View Create View character_set_client collation_connection
v_yy CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_yy` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` where `mysqltest2`.`t_nn`.`c1` = 55 latin1 latin1_swedish_ci
@ -1110,7 +1110,7 @@ t_nn CREATE TABLE `t_nn` (
`c1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW CREATE VIEW mysqltest2.t_nn;
ERROR HY000: 'mysqltest2.t_nn' is not VIEW
ERROR HY000: 'mysqltest2.t_nn' is not of type 'VIEW'
DROP VIEW mysqltest2.v_nn;
DROP VIEW mysqltest2.v_yn;
DROP VIEW mysqltest2.v_ny;

View File

@ -1133,5 +1133,78 @@ where index_date_updated= 10 and index_id < 800;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range index_date_updated index_date_updated 13 NULL # Using index condition
drop table t0,t1,t2;
set optimizer_switch=@save_ext_key_optimizer_switch;
SET SESSION STORAGE_ENGINE=DEFAULT;
#
# MDEV-11196: Error:Run-Time Check Failure #2 - Stack around the variable 'key_buff'
# was corrupted, server crashes in opt_sum_query
CREATE TABLE t1 (
pk INT,
f1 VARCHAR(3),
f2 VARCHAR(1024),
PRIMARY KEY (pk),
KEY(f2)
) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC;
INSERT INTO t1 VALUES (1,'foo','abc'),(2,'bar','def');
SELECT MAX(t2.pk) FROM t1 t2 INNER JOIN t1 t3 ON t2.f1 = t3.f1 WHERE t2.pk <= 4;
MAX(t2.pk)
2
drop table t1;
CREATE TABLE t1 (
pk1 INT,
pk2 INT,
f1 VARCHAR(3),
f2 VARCHAR(1021),
PRIMARY KEY (pk1,pk2),
KEY(f2)
) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC;
INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def');
explain format= json
select * from t1 force index(f2) where pk1 <= 5 and pk2 <=5 and f2 = 'abc' and f1 <= '3';
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t1",
"access_type": "range",
"possible_keys": ["f2"],
"key": "f2",
"key_length": "3070",
"used_key_parts": ["f2", "pk1"],
"rows": 1,
"filtered": 100,
"index_condition": "t1.pk1 <= 5 and t1.pk2 <= 5 and t1.f2 = 'abc'",
"attached_condition": "t1.f1 <= '3'"
}
}
}
drop table t1;
CREATE TABLE t1 (
f2 INT,
pk2 INT,
f1 VARCHAR(3),
pk1 VARCHAR(1000),
PRIMARY KEY (pk1,pk2),
KEY k1(pk1,f2)
) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC;
INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def');
explain format= json
select * from t1 force index(k1) where f2 <= 5 and pk2 <=5 and pk1 = 'abc' and f1 <= '3';
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t1",
"access_type": "range",
"possible_keys": ["k1"],
"key": "k1",
"key_length": "3011",
"used_key_parts": ["pk1", "f2", "pk2"],
"rows": 1,
"filtered": 100,
"index_condition": "t1.f2 <= 5 and t1.pk2 <= 5 and t1.pk1 = 'abc'",
"attached_condition": "t1.f1 <= '3'"
}
}
}
drop table t1;

View File

@ -4,7 +4,7 @@ drop table if exists t1;
create table t1 (n int);
create view v1 as select * from t1;
insert delayed into v1 values (1);
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
drop table t1;
drop view v1;
CREATE DATABASE meow;

View File

@ -2337,4 +2337,99 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t1`.`v1` AS `v1`,`test`.`t2`.`i2` AS `i2`,`test`.`t2`.`v2` AS `v2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`v3` AS `v3` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t3`.`v3` = 4 and `test`.`t1`.`i1` = `test`.`t3`.`i3` and `test`.`t2`.`i2` = `test`.`t3`.`i3`
drop table t1,t2,t3;
#
# MDEV-11958: LEFT JOIN with stored routine produces incorrect result
#
CREATE TABLE t (x INT);
INSERT INTO t VALUES(1),(NULL);
CREATE FUNCTION f (val INT, ret INT) RETURNS INT DETERMINISTIC RETURN IFNULL(val, ret);
SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
FROM t t1 LEFT JOIN t t2
ON t1.x = t2.x
WHERE IFNULL(t2.x,0)=0;
x x IFNULL(t2.x,0) f(t2.x,0)
NULL NULL 0 0
explain extended
SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
FROM t t1 LEFT JOIN t t2
ON t1.x = t2.x
WHERE IFNULL(t2.x,0)=0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on(`test`.`t2`.`x` = `test`.`t1`.`x`) where ifnull(`test`.`t2`.`x`,0) = 0
SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
FROM t t1 LEFT JOIN t t2
ON t1.x = t2.x
WHERE f(t2.x,0)=0;
x x IFNULL(t2.x,0) f(t2.x,0)
NULL NULL 0 0
explain extended
SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
FROM t t1 LEFT JOIN t t2
ON t1.x = t2.x
WHERE f(t2.x,0)=0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on(`test`.`t2`.`x` = `test`.`t1`.`x`) where `f`(`test`.`t2`.`x`,0) = 0
drop function f;
drop table t;
CREATE TABLE t1 (
col1 DECIMAL(33,5) NULL DEFAULT NULL,
col2 DECIMAL(33,5) NULL DEFAULT NULL
);
CREATE TABLE t2 (
col1 DECIMAL(33,5) NULL DEFAULT NULL,
col2 DECIMAL(33,5) NULL DEFAULT NULL,
col3 DECIMAL(33,5) NULL DEFAULT NULL
);
INSERT INTO t1 VALUES (2, 1.1), (2, 2.1);
INSERT INTO t2 VALUES (3, 3.1, 4), (1, 1, NULL);
CREATE FUNCTION f1 ( p_num DECIMAL(45,15), p_return DECIMAL(45,15))
RETURNS decimal(33,5)
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY INVOKER
BEGIN
IF p_num IS NULL THEN
RETURN p_return;
ELSE
RETURN p_num;
END IF;
END |
SELECT t1.col1, t2.col1, t2.col3
FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
WHERE IFNULL(t2.col3,0) = 0;
col1 col1 col3
2.00000 NULL NULL
2.00000 NULL NULL
EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3
FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
WHERE IFNULL(t2.col3,0) = 0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`col2` = `test`.`t1`.`col1`) where ifnull(`test`.`t2`.`col3`,0) = 0
SELECT t1.col1, t2.col1, t2.col3
FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
WHERE f1(t2.col3,0) = 0;
col1 col1 col3
2.00000 NULL NULL
2.00000 NULL NULL
EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3
FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
WHERE f1(t2.col3,0) = 0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`col2` = `test`.`t1`.`col1`) where `f1`(`test`.`t2`.`col3`,0) = 0
DROP FUNCTION f1;
DROP TABLE t1,t2;
# end of 5.5 tests
SET optimizer_switch=@save_optimizer_switch;

View File

@ -2348,6 +2348,101 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t1`.`v1` AS `v1`,`test`.`t2`.`i2` AS `i2`,`test`.`t2`.`v2` AS `v2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`v3` AS `v3` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t3`.`v3` = 4 and `test`.`t1`.`i1` = `test`.`t3`.`i3` and `test`.`t2`.`i2` = `test`.`t3`.`i3`
drop table t1,t2,t3;
#
# MDEV-11958: LEFT JOIN with stored routine produces incorrect result
#
CREATE TABLE t (x INT);
INSERT INTO t VALUES(1),(NULL);
CREATE FUNCTION f (val INT, ret INT) RETURNS INT DETERMINISTIC RETURN IFNULL(val, ret);
SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
FROM t t1 LEFT JOIN t t2
ON t1.x = t2.x
WHERE IFNULL(t2.x,0)=0;
x x IFNULL(t2.x,0) f(t2.x,0)
NULL NULL 0 0
explain extended
SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
FROM t t1 LEFT JOIN t t2
ON t1.x = t2.x
WHERE IFNULL(t2.x,0)=0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on(`test`.`t2`.`x` = `test`.`t1`.`x`) where ifnull(`test`.`t2`.`x`,0) = 0
SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
FROM t t1 LEFT JOIN t t2
ON t1.x = t2.x
WHERE f(t2.x,0)=0;
x x IFNULL(t2.x,0) f(t2.x,0)
NULL NULL 0 0
explain extended
SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
FROM t t1 LEFT JOIN t t2
ON t1.x = t2.x
WHERE f(t2.x,0)=0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on(`test`.`t2`.`x` = `test`.`t1`.`x`) where `f`(`test`.`t2`.`x`,0) = 0
drop function f;
drop table t;
CREATE TABLE t1 (
col1 DECIMAL(33,5) NULL DEFAULT NULL,
col2 DECIMAL(33,5) NULL DEFAULT NULL
);
CREATE TABLE t2 (
col1 DECIMAL(33,5) NULL DEFAULT NULL,
col2 DECIMAL(33,5) NULL DEFAULT NULL,
col3 DECIMAL(33,5) NULL DEFAULT NULL
);
INSERT INTO t1 VALUES (2, 1.1), (2, 2.1);
INSERT INTO t2 VALUES (3, 3.1, 4), (1, 1, NULL);
CREATE FUNCTION f1 ( p_num DECIMAL(45,15), p_return DECIMAL(45,15))
RETURNS decimal(33,5)
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY INVOKER
BEGIN
IF p_num IS NULL THEN
RETURN p_return;
ELSE
RETURN p_num;
END IF;
END |
SELECT t1.col1, t2.col1, t2.col3
FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
WHERE IFNULL(t2.col3,0) = 0;
col1 col1 col3
2.00000 NULL NULL
2.00000 NULL NULL
EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3
FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
WHERE IFNULL(t2.col3,0) = 0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`col2` = `test`.`t1`.`col1`) where ifnull(`test`.`t2`.`col3`,0) = 0
SELECT t1.col1, t2.col1, t2.col3
FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
WHERE f1(t2.col3,0) = 0;
col1 col1 col3
2.00000 NULL NULL
2.00000 NULL NULL
EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3
FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
WHERE f1(t2.col3,0) = 0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`col2` = `test`.`t1`.`col1`) where `f1`(`test`.`t2`.`col3`,0) = 0
DROP FUNCTION f1;
DROP TABLE t1,t2;
# end of 5.5 tests
SET optimizer_switch=@save_optimizer_switch;
set join_cache_level=default;
show variables like 'join_cache_level';

View File

@ -425,7 +425,7 @@ c1
bb
cc
Warnings:
Warning 1931 Query execution was interrupted. The query examined at least 18 rows, which exceeds LIMIT ROWS EXAMINED (16). The query result may be incomplete
Warning 1931 Query execution was interrupted. The query examined at least 17 rows, which exceeds LIMIT ROWS EXAMINED (16). The query result may be incomplete
select * from v1 LIMIT ROWS EXAMINED 11;
c1
bb
@ -438,7 +438,8 @@ from (select * from t1
where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 0)) as tmp
LIMIT ROWS EXAMINED 11;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 2 func 1
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
select *
from (select * from t1

View File

@ -1,8 +1,12 @@
set @@global.log_output = 'TABLE';
connect con1,localhost,root,,;
connect con2,localhost,root,,;
connection con1;
set session long_query_time=10;
select get_lock('bug27638', 1);
get_lock('bug27638', 1)
1
connection con2;
set session long_query_time=1;
select get_lock('bug27638', 2);
get_lock('bug27638', 2)
@ -25,7 +29,11 @@ select if (query_time >= '00:01:40', 'OK', 'WRONG') as qt, sql_text from mysql.s
where sql_text = 'select get_lock(\'bug27638\', 101)';
qt sql_text
OK select get_lock('bug27638', 101)
connection con1;
select release_lock('bug27638');
release_lock('bug27638')
1
connection default;
disconnect con1;
disconnect con2;
set @@global.log_output=default;

View File

@ -3049,3 +3049,21 @@ SET DEBUG_SYNC= 'RESET';
disconnect con1;
disconnect con2;
disconnect con3;
#
# MDEV-12620 - set lock_wait_timeout = 1;flush tables with read lock;
# lock not released after timeout
#
CREATE TABLE t1(a INT) ENGINE=InnoDB;
SET debug_sync='open_tables_after_open_and_process_table SIGNAL ready WAIT_FOR go';
SELECT * FROM t1;
connect con1,localhost,root,,;
SET debug_sync='now WAIT_FOR ready';
SET lock_wait_timeout=1;
FLUSH TABLES WITH READ LOCK;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
SET debug_sync='now SIGNAL go';
connection default;
a
SET debug_sync='RESET';
DROP TABLE t1;
disconnect con1;

View File

@ -629,7 +629,7 @@ INSERT INTO t3 VALUES (3), (33);
LOCK TABLES t3 READ;
CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL) ENGINE=MERGE UNION=(t1,t2)
INSERT_METHOD=LAST SELECT * FROM t3;
ERROR HY000: 'test.t4' is not BASE TABLE
ERROR HY000: 'test.t4' is not of type 'BASE TABLE'
SELECT * FROM t4;
ERROR HY000: Table 't4' was not locked with LOCK TABLES
UNLOCK TABLES;
@ -702,11 +702,11 @@ create table t2 (a int);
insert into t1 values (0);
insert into t2 values (1);
create table t3 engine=merge union=(t1, t2) select * from t1;
ERROR HY000: 'test.t3' is not BASE TABLE
ERROR HY000: 'test.t3' is not of type 'BASE TABLE'
create table t3 engine=merge union=(t1, t2) select * from t2;
ERROR HY000: 'test.t3' is not BASE TABLE
ERROR HY000: 'test.t3' is not of type 'BASE TABLE'
create table t3 engine=merge union=(t1, t2) select (select max(a) from t2);
ERROR HY000: 'test.t3' is not BASE TABLE
ERROR HY000: 'test.t3' is not of type 'BASE TABLE'
drop table t1, t2;
create table t1 (
a double(14,4),
@ -1176,7 +1176,7 @@ SHOW CREATE TABLE t3;
ERROR 42S02: Table 'test.t3' doesn't exist
CREATE TABLE t3 ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST
SELECT * FROM t2;
ERROR HY000: 'test.t3' is not BASE TABLE
ERROR HY000: 'test.t3' is not of type 'BASE TABLE'
SHOW CREATE TABLE t3;
ERROR 42S02: Table 'test.t3' doesn't exist
DROP TABLE t1, t2;
@ -3115,11 +3115,11 @@ DROP TABLE m2;
#
CREATE TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
ERROR HY000: 'test.m2' is not BASE TABLE
ERROR HY000: 'test.m2' is not of type 'BASE TABLE'
#
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
ERROR HY000: 'test.m2' is not BASE TABLE
ERROR HY000: 'test.m2' is not of type 'BASE TABLE'
#
CREATE TABLE m2 LIKE m1;
SHOW CREATE TABLE m2;
@ -3519,7 +3519,7 @@ Got one of the listed errors
#
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
ERROR HY000: 'test.m2' is not BASE TABLE
ERROR HY000: 'test.m2' is not of type 'BASE TABLE'
#
CREATE TEMPORARY TABLE m2 LIKE m1;
SHOW CREATE TABLE m2;

View File

@ -1549,6 +1549,9 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 13 const # Using where; Using index
alter table t1 add unique(v);
ERROR 23000: Duplicate entry '{ ' for key 'v_2'
show warnings;
Level Code Message
Error 1062 Duplicate entry 'a' for key 'v_2'
alter table t1 add key(v);
Warnings:
Note 1831 Duplicate index `v_2`. This is deprecated and will be disallowed in a future release

View File

@ -350,6 +350,9 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 13 const # Using where; Using index
alter table t1 add unique(v);
ERROR 23000: Duplicate entry '{ ' for key 'v_2'
show warnings;
Level Code Message
Error 1062 Duplicate entry 'a' for key 'v_2'
alter table t1 add key(v);
Warnings:
Note 1831 Duplicate index `v_2`. This is deprecated and will be disallowed in a future release

View File

@ -1255,6 +1255,9 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 13 const # Using where; Using index
alter table t1 add unique(v);
ERROR 23000: Duplicate entry '{ ' for key 'v_2'
show warnings;
Level Code Message
Error 1062 Duplicate entry 'a' for key 'v_2'
alter table t1 add key(v);
Warnings:
Note 1831 Duplicate index `v_2`. This is deprecated and will be disallowed in a future release

View File

@ -29,3 +29,15 @@ Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1,t2;
disconnect insertConn;
call mtr.add_suppression("Index for table '.*test.t1\\.MYI' is corrupt; try to repair it");
create table t1 (a int, index(a));
lock tables t1 write;
insert t1 values (1),(2),(1);
set @old_dbug=@@debug_dbug;
set debug_dbug='+d,mi_lock_database_failure';
unlock tables;
Warnings:
Error 126 Index for table './test/t1.MYI' is corrupt; try to repair it
Error 1030 Got error 22 "Invalid argument" from storage engine MyISAM
set debug_dbug=@old_dbug;
drop table t1;

View File

@ -1404,7 +1404,7 @@ performance-schema-max-rwlock-instances -1
performance-schema-max-socket-classes 10
performance-schema-max-socket-instances -1
performance-schema-max-stage-classes 150
performance-schema-max-statement-classes 190
performance-schema-max-statement-classes 191
performance-schema-max-table-handles -1
performance-schema-max-table-instances -1
performance-schema-max-thread-classes 50

View File

@ -51,3 +51,50 @@ execute stmt;
execute stmt;
deallocate prepare stmt;
drop table test_data;
create table t1(id int, d date not null, b bool not null default 0, primary key(id,d))
engine=innodb
partition by range columns (d) (
partition p1 values less than ('2016-10-18'),
partition p2 values less than ('2020-10-19'));
insert t1 values (0, '2000-01-02', 0);
insert t1 values (1, '2020-01-02', 10);
alter table t1 add check (b in (0, 1));
ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`#sql-temporary`
alter table t1 add check (b in (0, 10));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) NOT NULL,
`d` date NOT NULL,
`b` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`,`d`),
CONSTRAINT `CONSTRAINT_1` CHECK (`b` in (0,10))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
PARTITION BY RANGE COLUMNS(d)
(PARTITION p1 VALUES LESS THAN ('2016-10-18') ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN ('2020-10-19') ENGINE = InnoDB)
insert t1 values (2, '2020-01-03', 20);
ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1`
drop table t1;
create table t1(id int, d date not null, b bool not null default 0, primary key(id,d))
partition by range columns (d) (
partition p1 values less than ('2016-10-18'),
partition p2 values less than ('2020-10-19'));
insert t1 values (0, '2000-01-02', 0);
insert t1 values (1, '2020-01-02', 10);
alter table t1 add check (b in (0, 1));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) NOT NULL,
`d` date NOT NULL,
`b` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`,`d`),
CONSTRAINT `CONSTRAINT_1` CHECK (`b` in (0,1))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
PARTITION BY RANGE COLUMNS(d)
(PARTITION p1 VALUES LESS THAN ('2016-10-18') ENGINE = MyISAM,
PARTITION p2 VALUES LESS THAN ('2020-10-19') ENGINE = MyISAM)
insert t1 values (2, '2020-01-03', 20);
ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1`
drop table t1;

View File

@ -74,7 +74,7 @@ End of 4.1 tests
create table t1(f1 int);
create view v1 as select * from t1;
alter table v1 rename to v2;
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
drop view v1;
drop table t1;
End of 5.0 tests

View File

@ -4329,57 +4329,57 @@ Table Op Msg_type Msg_text
test.t1 repair status OK
test.t2 repair status OK
test.t3 repair status OK
test.v1 repair Error 'test.v1' is not BASE TABLE
test.v1 repair Error 'test.v1' is not of type 'BASE TABLE'
test.v1 repair status Operation failed
Table Op Msg_type Msg_text
test.t1 optimize status OK
test.t2 optimize status OK
test.t3 optimize status OK
test.v1 optimize Error 'test.v1' is not BASE TABLE
test.v1 optimize Error 'test.v1' is not of type 'BASE TABLE'
test.v1 optimize status Operation failed
Table Op Msg_type Msg_text
test.t1 analyze status Table is already up to date
test.t2 analyze status Table is already up to date
test.t3 analyze status Table is already up to date
test.v1 analyze Error 'test.v1' is not BASE TABLE
test.v1 analyze Error 'test.v1' is not of type 'BASE TABLE'
test.v1 analyze status Operation failed
call bug13012()|
Table Op Msg_type Msg_text
test.t1 repair status OK
test.t2 repair status OK
test.t3 repair status OK
test.v1 repair Error 'test.v1' is not BASE TABLE
test.v1 repair Error 'test.v1' is not of type 'BASE TABLE'
test.v1 repair status Operation failed
Table Op Msg_type Msg_text
test.t1 optimize status OK
test.t2 optimize status OK
test.t3 optimize status OK
test.v1 optimize Error 'test.v1' is not BASE TABLE
test.v1 optimize Error 'test.v1' is not of type 'BASE TABLE'
test.v1 optimize status Operation failed
Table Op Msg_type Msg_text
test.t1 analyze status Table is already up to date
test.t2 analyze status Table is already up to date
test.t3 analyze status Table is already up to date
test.v1 analyze Error 'test.v1' is not BASE TABLE
test.v1 analyze Error 'test.v1' is not of type 'BASE TABLE'
test.v1 analyze status Operation failed
call bug13012()|
Table Op Msg_type Msg_text
test.t1 repair status OK
test.t2 repair status OK
test.t3 repair status OK
test.v1 repair Error 'test.v1' is not BASE TABLE
test.v1 repair Error 'test.v1' is not of type 'BASE TABLE'
test.v1 repair status Operation failed
Table Op Msg_type Msg_text
test.t1 optimize status OK
test.t2 optimize status OK
test.t3 optimize status OK
test.v1 optimize Error 'test.v1' is not BASE TABLE
test.v1 optimize Error 'test.v1' is not of type 'BASE TABLE'
test.v1 optimize status Operation failed
Table Op Msg_type Msg_text
test.t1 analyze status Table is already up to date
test.t2 analyze status Table is already up to date
test.t3 analyze status Table is already up to date
test.v1 analyze Error 'test.v1' is not BASE TABLE
test.v1 analyze Error 'test.v1' is not of type 'BASE TABLE'
test.v1 analyze status Operation failed
drop procedure bug13012|
drop view v1|

View File

@ -576,3 +576,42 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL #
2 DEPENDENT SUBQUERY t2 ref key1 key1 5 test.t1.a # Using where; Using filesort
drop table t1,t2;
#
# mdev-12931: semi-join in ON expression of STRAIGHT_JOIN
# joining a base table and a mergeable derived table
#
CREATE TABLE t1 (f1 int) ENGINE=InnoDB;
INSERT INTO t1 VALUES (3),(2);
CREATE TABLE t2 (f2 int) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(4);
CREATE TABLE t3 (f3 int) ENGINE=InnoDB;
INSERT INTO t3 VALUES (5),(6);
CREATE TABLE t4 (f4 int) ENGINE=InnoDB;
INSERT INTO t4 VALUES (1),(8);
SELECT *
FROM t1
INNER JOIN
( t2 STRAIGHT_JOIN ( SELECT * FROM t3 ) AS sq
ON ( 1 IN ( SELECT f4 FROM t4 ) ) )
ON ( f1 >= f2 );
f1 f2 f3
3 1 5
2 1 5
3 1 6
2 1 6
EXPLAIN EXTENDED
SELECT *
FROM t1
INNER JOIN
( t2 STRAIGHT_JOIN ( SELECT * FROM t3 ) AS sq
ON ( 1 IN ( SELECT f4 FROM t4 ) ) )
ON ( f1 >= f2 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (incremental, BNL join)
3 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` join `test`.`t2` semi join (`test`.`t4`) join `test`.`t3` where `test`.`t4`.`f4` = 1 and `test`.`t1`.`f1` >= `test`.`t2`.`f2`
DROP TABLE t1,t2,t3,t4;

View File

@ -379,6 +379,7 @@ drop table t3, t4, t5;
#
# LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
#
set @optimizer_switch_save= @@optimizer_switch;
create table t1 (c1 char(2) not null, c2 char(2));
create table t2 (c3 char(2), c4 char(2));
insert into t1 values ('a1', 'b1');
@ -400,6 +401,7 @@ id select_type table type possible_keys key key_len ref rows Extra
select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
c1 c2
drop table t1, t2;
set optimizer_switch= @optimizer_switch_save;
#
# MDEV-12673: cost-based choice between materialization and in-to-exists
#
@ -442,3 +444,44 @@ id select_type table type possible_keys key key_len ref rows Extra
2 DEPENDENT SUBQUERY t3 const PRIMARY PRIMARY 4 const 1
2 DEPENDENT SUBQUERY t2 index NULL i2 11 NULL 2 Using where; Using index
DROP TABLE t1,t2,t3;
#
# MDEV-7599: in-to-exists chosen after min/max optimization
#
set @optimizer_switch_save= @@optimizer_switch;
CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT, c INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1,6),(2,4), (8,9);
SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
b c
EXPLAIN EXTENDED SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
2 MATERIALIZED t1 index NULL a 5 NULL 2 100.00 Using index
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where !<expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,`test`.`t2`.`b` in ( <materialize> (/* select#2 */ select min(`test`.`t1`.`a`) from `test`.`t1` join `test`.`t2` where `test`.`t2`.`c` = `test`.`t2`.`b` ), <primary_index_lookup>(`test`.`t2`.`b` in <temporary table> on distinct_key where `test`.`t2`.`b` = `<subquery2>`.`MIN(a)`))))
set optimizer_switch= 'materialization=off';
SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
b c
EXPLAIN EXTENDED SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY t1 index NULL a 5 NULL 2 100.00 Using index
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where !<expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,<exists>(/* select#2 */ select min(`test`.`t1`.`a`) from `test`.`t1` join `test`.`t2` where `test`.`t2`.`c` = `test`.`t2`.`b` having trigcond(<cache>(`test`.`t2`.`b`) = <ref_null_helper>(min(`test`.`t1`.`a`))))))
set optimizer_switch= @optimizer_switch_save;
DROP TABLE t1,t2;
CREATE TABLE t1 (f1 varchar(10)) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('foo'),('bar');
CREATE TABLE t2 (f2 varchar(10), key(f2)) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('baz'),('qux');
CREATE TABLE t3 (f3 varchar(10)) ENGINE=MyISAM;
INSERT INTO t3 VALUES ('abc'),('def');
SELECT * FROM t1
WHERE f1 = ALL( SELECT MAX(t2a.f2)
FROM t2 AS t2a INNER JOIN t2 t2b INNER JOIN t3
ON (f3 = t2b.f2) );
f1
DROP TABLE t1,t2,t3;

View File

@ -1652,9 +1652,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED <derived3> system NULL NULL NULL NULL 1
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
@ -3072,4 +3072,97 @@ project_number
aaa
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
#
# MDEV-12675: subquery subject to semi-join optimizations
# in ON expression of INNER JOIN
#
set @tmp_mdev12675=@@optimizer_switch;
set optimizer_switch=default;
create table t1 (a int) engine=myisam;
insert into t1 values (5),(3),(2),(7),(2),(5),(1);
create table t2 (b int, index idx(b)) engine=myisam;
insert into t2 values (2),(3),(2),(1),(3),(4);
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
analyze table t1,t2;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
explain
select a from t1, t2 where b between 1 and 2 and a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
explain
select a from t1 join t2 on b between 1 and 2 and a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
drop table t1,t2;
set optimizer_switch= @tmp_mdev12675;
#
# MDEV-12817: subquery NOT subject to semi-join optimizations
# in ON expression of INNER JOIN
#
CREATE TABLE t1 (c1 int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (c2 int) ENGINE=MyISAM;
INSERT INTO t2 VALUES (3),(4);
CREATE TABLE t3 (c3 int) ENGINE=MyISAM;
INSERT INTO t3 VALUES (5),(6);
CREATE TABLE t4 (c4 int) ENGINE=MyISAM;
INSERT INTO t4 VALUES (7),(8);
SELECT c1
FROM t1
LEFT JOIN
( t2 INNER JOIN t3 ON ( 1 IN ( SELECT c4 FROM t4 ) ) )
ON (c1 = c3);
c1
1
2
EXPLAIN EXTENDED SELECT c1
FROM t1
LEFT JOIN
( t2 INNER JOIN t3 ON ( 1 IN ( SELECT c4 FROM t4 ) ) )
ON (c1 = c3);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t3`.`c3` = `test`.`t1`.`c1` and <cache>(<in_optimizer>(1,<exists>(/* select#2 */ select `test`.`t4`.`c4` from `test`.`t4` where 1 = `test`.`t4`.`c4`)))) where 1
# mdev-12820
SELECT *
FROM t1
LEFT JOIN
( ( SELECT * FROM t2 WHERE c2 IN ( SELECT c3 FROM t3 ) ) AS sq INNER JOIN t4 )
ON (c1 = c2);
c1 c2 c4
1 NULL NULL
2 NULL NULL
EXPLAIN EXTENDED SELECT *
FROM t1
LEFT JOIN
( ( SELECT * FROM t2 WHERE c2 IN ( SELECT c3 FROM t3 ) ) AS sq INNER JOIN t4 )
ON (c1 = c2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(`test`.`t2`.`c2` = `test`.`t1`.`c1` and <in_optimizer>(`test`.`t1`.`c1`,<exists>(/* select#3 */ select `test`.`t3`.`c3` from `test`.`t3` where <cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))) where 1
DROP TABLE t1,t2,t3,t4;
set optimizer_switch=@subselect_sj_tmp;

View File

@ -1625,3 +1625,26 @@ i1
DROP TABLE t1,t2,t3;
set join_cache_level= @save_join_cache_level;
set optimizer_switch=@save_optimizer_switch;
#
# mdev-7791: materialization of a semi-join subquery +
# RAND() in WHERE
# (materialized table is accessed last)
#
set @save_optimizer_switch=@@optimizer_switch;
set optimizer_switch='materialization=on';
create table t1(i int);
insert into t1 values (1), (2), (3), (7), (9), (10);
create table t2(i int);
insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
select * from t1 where (rand() < 0) and i in (select i from t2);
i
explain extended
select * from t1 where (rand() < 0) and i in (select i from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 100.00
Warnings:
Note 1003 select `test`.`t1`.`i` AS `i` from `test`.`t1` semi join (`test`.`t2`) where rand() < 0
drop table t1,t2;
set optimizer_switch=@save_optimizer_switch;

View File

@ -1665,9 +1665,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED <derived3> system NULL NULL NULL NULL 1
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
@ -3086,6 +3086,99 @@ project_number
aaa
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
#
# MDEV-12675: subquery subject to semi-join optimizations
# in ON expression of INNER JOIN
#
set @tmp_mdev12675=@@optimizer_switch;
set optimizer_switch=default;
create table t1 (a int) engine=myisam;
insert into t1 values (5),(3),(2),(7),(2),(5),(1);
create table t2 (b int, index idx(b)) engine=myisam;
insert into t2 values (2),(3),(2),(1),(3),(4);
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
insert into t2 select b+10 from t2;
analyze table t1,t2;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
explain
select a from t1, t2 where b between 1 and 2 and a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
explain
select a from t1 join t2 on b between 1 and 2 and a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
drop table t1,t2;
set optimizer_switch= @tmp_mdev12675;
#
# MDEV-12817: subquery NOT subject to semi-join optimizations
# in ON expression of INNER JOIN
#
CREATE TABLE t1 (c1 int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (c2 int) ENGINE=MyISAM;
INSERT INTO t2 VALUES (3),(4);
CREATE TABLE t3 (c3 int) ENGINE=MyISAM;
INSERT INTO t3 VALUES (5),(6);
CREATE TABLE t4 (c4 int) ENGINE=MyISAM;
INSERT INTO t4 VALUES (7),(8);
SELECT c1
FROM t1
LEFT JOIN
( t2 INNER JOIN t3 ON ( 1 IN ( SELECT c4 FROM t4 ) ) )
ON (c1 = c3);
c1
1
2
EXPLAIN EXTENDED SELECT c1
FROM t1
LEFT JOIN
( t2 INNER JOIN t3 ON ( 1 IN ( SELECT c4 FROM t4 ) ) )
ON (c1 = c3);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
2 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t3`.`c3` = `test`.`t1`.`c1` and <cache>(<in_optimizer>(1,<exists>(/* select#2 */ select `test`.`t4`.`c4` from `test`.`t4` where 1 = `test`.`t4`.`c4`)))) where 1
# mdev-12820
SELECT *
FROM t1
LEFT JOIN
( ( SELECT * FROM t2 WHERE c2 IN ( SELECT c3 FROM t3 ) ) AS sq INNER JOIN t4 )
ON (c1 = c2);
c1 c2 c4
1 NULL NULL
2 NULL NULL
EXPLAIN EXTENDED SELECT *
FROM t1
LEFT JOIN
( ( SELECT * FROM t2 WHERE c2 IN ( SELECT c3 FROM t3 ) ) AS sq INNER JOIN t4 )
ON (c1 = c2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (incremental, BNL join)
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(`test`.`t2`.`c2` = `test`.`t1`.`c1` and <in_optimizer>(`test`.`t1`.`c1`,<exists>(/* select#3 */ select `test`.`t3`.`c3` from `test`.`t3` where <cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))) where 1
DROP TABLE t1,t2,t3,t4;
set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off

View File

@ -313,7 +313,7 @@ drop trigger trg;
ERROR HY000: Trigger does not exist
create view v1 as select * from t1;
create trigger trg before insert on v1 for each row set @a:=1;
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
drop view v1;
drop table t1;
drop table t3;
@ -2368,6 +2368,16 @@ tr1 1 2016-01-01 10:10:10.33
tr2 2 2016-01-01 10:10:10.99
drop table t1;
set time_zone= @@global.time_zone;
# MDEV-12992: Increasing memory consumption
with each invocation of trigger
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (b INT);
CREATE TRIGGER tr
AFTER UPDATE ON t1 FOR EACH ROW SELECT (SELECT b FROM t2) INTO @x;
# Running 20000 queries
DROP TABLE t1,t2;
#
# Start of 10.3 tests
#

View File

@ -2178,6 +2178,35 @@ WHERE t1_2.b NOT IN ( SELECT 4 UNION ALL SELECT 5 );
a b a b
1 1 1 1
DROP TABLE t1;
# Bug mdev-12788: UNION ALL + impossible having for derived
# with IN subquery in WHERE
#
CREATE TABLE t1 (i int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (pk int PRIMARY KEY) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(2);
SELECT 1, 2
UNION ALL
SELECT i, COUNT(*) FROM (
SELECT * FROM t1 WHERE i IN ( SELECT pk FROM t2 )
) AS sq
GROUP BY i
HAVING i = 10;
1 2
1 2
EXPLAIN EXTENDED SELECT 1, 2
UNION ALL
SELECT i, COUNT(*) FROM (
SELECT * FROM t1 WHERE i IN ( SELECT pk FROM t2 )
) AS sq
GROUP BY i
HAVING i = 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
2 UNION NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
Warnings:
Note 1003 /* select#1 */ select 1 AS `1`,2 AS `2` union all /* select#2 */ select 1 AS `i`,count(0) AS `COUNT(*)` from `test`.`t2` where 1 group by 1 having 0
DROP TABLE t1,t2;
#
# Start of 10.3 tests
#

View File

@ -41,7 +41,7 @@ show create view v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`b` + 1 AS `c` from `t1` latin1 latin1_swedish_ci
show create view t1;
ERROR HY000: 'test.t1' is not VIEW
ERROR HY000: 'test.t1' is not of type 'VIEW'
drop table t1;
select a from v1;
ERROR 42S22: Unknown column 'a' in 'field list'
@ -199,7 +199,7 @@ c d
drop view v100;
ERROR 42S02: Unknown VIEW: 'test.v100'
drop view t1;
ERROR HY000: 'test.t1' is not VIEW
ERROR HY000: 'test.t1' is not of type 'VIEW'
drop table v1;
ERROR 42S02: 'test.v1' is a view
drop view v1,v2;
@ -675,7 +675,7 @@ drop view v1;
create table t1 (col1 int,col2 char(22));
create view v1 as select * from t1;
create index i1 on v1 (col1);
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
drop view v1;
drop table t1;
CREATE VIEW v1 (f1,f2,f3,f4) AS SELECT connection_id(), pi(), current_user(), version();
@ -1061,7 +1061,7 @@ drop table t1,t2,t3;
create table t1 (s1 int);
create view v1 as select * from t1;
handler v1 open as xx;
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
drop view v1;
drop table t1;
create table t1(a int);
@ -2445,28 +2445,28 @@ CREATE TABLE t1(id INT);
CREATE VIEW v1 AS SELECT id FROM t1;
OPTIMIZE TABLE v1;
Table Op Msg_type Msg_text
test.v1 optimize Error 'test.v1' is not BASE TABLE
test.v1 optimize Error 'test.v1' is not of type 'BASE TABLE'
test.v1 optimize status Operation failed
ANALYZE TABLE v1;
Table Op Msg_type Msg_text
test.v1 analyze Error 'test.v1' is not BASE TABLE
test.v1 analyze Error 'test.v1' is not of type 'BASE TABLE'
test.v1 analyze status Operation failed
REPAIR TABLE v1;
Table Op Msg_type Msg_text
test.v1 repair Error 'test.v1' is not BASE TABLE
test.v1 repair Error 'test.v1' is not of type 'BASE TABLE'
test.v1 repair status Operation failed
DROP TABLE t1;
OPTIMIZE TABLE v1;
Table Op Msg_type Msg_text
test.v1 optimize Error 'test.v1' is not BASE TABLE
test.v1 optimize Error 'test.v1' is not of type 'BASE TABLE'
test.v1 optimize status Operation failed
ANALYZE TABLE v1;
Table Op Msg_type Msg_text
test.v1 analyze Error 'test.v1' is not BASE TABLE
test.v1 analyze Error 'test.v1' is not of type 'BASE TABLE'
test.v1 analyze status Operation failed
REPAIR TABLE v1;
Table Op Msg_type Msg_text
test.v1 repair Error 'test.v1' is not BASE TABLE
test.v1 repair Error 'test.v1' is not of type 'BASE TABLE'
test.v1 repair status Operation failed
DROP VIEW v1;
create definer = current_user() sql security invoker view v1 as select 1;
@ -2920,7 +2920,7 @@ Tables_in_test
t1
CREATE VIEW v1 AS SELECT id FROM t1;
DROP VIEW t1,v1;
ERROR HY000: 'test.t1' is not VIEW
ERROR HY000: 'test.t1' is not of type 'VIEW'
SHOW TABLES;
Tables_in_test
t1
@ -3706,7 +3706,7 @@ CREATE TABLE t1(c1 INT);
SELECT * FROM t1;
c1
ALTER ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW t1 (c2) AS SELECT (1);
ERROR HY000: 'test.t1' is not VIEW
ERROR HY000: 'test.t1' is not of type 'VIEW'
DROP TABLE t1;
@ -4011,7 +4011,7 @@ drop procedure p;
CREATE TABLE t1 (a INT);
CREATE VIEW v1 AS SELECT a FROM t1;
ALTER TABLE v1;
ERROR HY000: 'test.v1' is not BASE TABLE
ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
DROP VIEW v1;
DROP TABLE t1;
#
@ -5584,7 +5584,7 @@ create table t1 (a int, b int);
create view v1 as select a+b from t1;
alter table v1 check partition p1;
Table Op Msg_type Msg_text
test.v1 check Error 'test.v1' is not BASE TABLE
test.v1 check Error 'test.v1' is not of type 'BASE TABLE'
test.v1 check status Operation failed
drop view v1;
drop table t1;

View File

@ -0,0 +1,12 @@
create user adm@localhost identified by 'foobar';
grant reload on *.* to adm@localhost;
reset master;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # flush status
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # flush status
drop user adm@localhost;

View File

@ -0,0 +1,12 @@
source include/have_binlog_format_statement.inc;
#
# MDEV-12612 mysqladmin --local flush... to use FLUSH LOCAL
#
create user adm@localhost identified by 'foobar';
grant reload on *.* to adm@localhost;
reset master;
exec $MYSQLADMIN -uadm -pfoobar flush-status;
source include/show_binlog_events.inc;
exec $MYSQLADMIN --local -uadm -pfoobar flush-status;
source include/show_binlog_events.inc;
drop user adm@localhost;

View File

@ -0,0 +1,30 @@
create table t1 (a int not null) engine=csv;
insert t1 values (1),(2);
flush tables;
select * from information_schema.tables where table_schema='test';
TABLE_CATALOG def
TABLE_SCHEMA test
TABLE_NAME t1
TABLE_TYPE BASE TABLE
ENGINE NULL
VERSION NULL
ROW_FORMAT NULL
TABLE_ROWS NULL
AVG_ROW_LENGTH NULL
DATA_LENGTH NULL
MAX_DATA_LENGTH NULL
INDEX_LENGTH NULL
DATA_FREE NULL
AUTO_INCREMENT NULL
CREATE_TIME NULL
UPDATE_TIME NULL
CHECK_TIME NULL
TABLE_COLLATION NULL
CHECKSUM NULL
CREATE_OPTIONS NULL
TABLE_COMMENT File './test/t1.CSM' not found (Errcode: 13 "Permission denied")
Warnings:
Level Warning
Code 29
Message File './test/t1.CSM' not found (Errcode: 13 "Permission denied")
drop table t1;

View File

@ -0,0 +1,19 @@
#
# MDEV-11883 MariaDB crashes with out-of-memory when query information_schema
#
source include/have_csv.inc;
let datadir=`select @@datadir`;
create table t1 (a int not null) engine=csv;
insert t1 values (1),(2);
flush tables;
chmod 0400 $datadir/test/t1.CSM;
chmod 0400 $datadir/test/t1.CSV;
--replace_result $datadir ./
query_vertical select * from information_schema.tables where table_schema='test';
drop table t1;

View File

@ -0,0 +1,38 @@
--- suite/encryption/r/innodb-checksum-algorithm.result
+++ suite/encryption/r/innodb-checksum-algorithm,32k.reject
@@ -13,9 +13,9 @@
SET GLOBAL innodb_default_encryption_key_id=4;
SET GLOBAL innodb_checksum_algorithm=crc32;
create table tce_crc32(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=yes;
+ROW_FORMAT=DYNAMIC encrypted=yes;
create table tc_crc32(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=no;
+ROW_FORMAT=DYNAMIC encrypted=no;
create table te_crc32(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_crc32(a serial, b blob, index(b(10))) engine=innodb
@@ -222,9 +222,9 @@
t_crc32, tpe_crc32, tp_crc32;
SET GLOBAL innodb_checksum_algorithm=innodb;
create table tce_innodb(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=yes;
+ROW_FORMAT=DYNAMIC encrypted=yes;
create table tc_innodb(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=no;
+ROW_FORMAT=DYNAMIC encrypted=no;
create table te_innodb(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_innodb(a serial, b blob, index(b(10))) engine=innodb
@@ -431,9 +431,9 @@
t_innodb, tpe_innodb, tp_innodb;
SET GLOBAL innodb_checksum_algorithm=none;
create table tce_none(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=yes;
+ROW_FORMAT=DYNAMIC encrypted=yes;
create table tc_none(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=no;
+ROW_FORMAT=DYNAMIC encrypted=no;
create table te_none(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_none(a serial, b blob, index(b(10))) engine=innodb

View File

@ -0,0 +1,38 @@
--- suite/encryption/r/innodb-checksum-algorithm.result
+++ suite/encryption/r/innodb-checksum-algorithm,64k.reject
@@ -13,9 +13,9 @@
SET GLOBAL innodb_default_encryption_key_id=4;
SET GLOBAL innodb_checksum_algorithm=crc32;
create table tce_crc32(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=yes;
+ROW_FORMAT=DYNAMIC encrypted=yes;
create table tc_crc32(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=no;
+ROW_FORMAT=DYNAMIC encrypted=no;
create table te_crc32(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_crc32(a serial, b blob, index(b(10))) engine=innodb
@@ -222,9 +222,9 @@
t_crc32, tpe_crc32, tp_crc32;
SET GLOBAL innodb_checksum_algorithm=innodb;
create table tce_innodb(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=yes;
+ROW_FORMAT=DYNAMIC encrypted=yes;
create table tc_innodb(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=no;
+ROW_FORMAT=DYNAMIC encrypted=no;
create table te_innodb(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_innodb(a serial, b blob, index(b(10))) engine=innodb
@@ -431,9 +431,9 @@
t_innodb, tpe_innodb, tp_innodb;
SET GLOBAL innodb_checksum_algorithm=none;
create table tce_none(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=yes;
+ROW_FORMAT=DYNAMIC encrypted=yes;
create table tc_none(a serial, b blob, index(b(10))) engine=innodb
-ROW_FORMAT=COMPRESSED encrypted=no;
+ROW_FORMAT=DYNAMIC encrypted=no;
create table te_none(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_none(a serial, b blob, index(b(10))) engine=innodb

View File

@ -0,0 +1,643 @@
SET @saved_file_per_table = @@global.innodb_file_per_table;
SET @saved_checksum_algorithm = @@global.innodb_checksum_algorithm;
SET @saved_encrypt_tables = @@global.innodb_encrypt_tables;
SET @saved_encryption_threads = @@global.innodb_encryption_threads;
SET @saved_encryption_key_id = @@global.innodb_default_encryption_key_id;
SET GLOBAL innodb_file_per_table = ON;
SET GLOBAL innodb_encrypt_tables = ON;
SET GLOBAL innodb_encryption_threads = 4;
call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_(crc32|none|innodb)\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"(innodb|none|crc32)\"");
SET GLOBAL innodb_checksum_algorithm = innodb;
SET GLOBAL innodb_default_encryption_key_id=4;
SET GLOBAL innodb_checksum_algorithm=crc32;
create table tce_crc32(a serial, b blob, index(b(10))) engine=innodb
ROW_FORMAT=COMPRESSED encrypted=yes;
create table tc_crc32(a serial, b blob, index(b(10))) engine=innodb
ROW_FORMAT=COMPRESSED encrypted=no;
create table te_crc32(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_crc32(a serial, b blob, index(b(10))) engine=innodb
encrypted=no;
create table tpe_crc32(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=yes;
create table tp_crc32(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=no;
begin;
insert into tce_crc32(b) values (repeat('secret',20));
insert into tc_crc32(b) values (repeat('secret',20));
insert into te_crc32(b) values (repeat('secret',20));
insert into t_crc32(b) values (repeat('secret',20));
insert into tpe_crc32(b) values (repeat('secret',20));
insert into tp_crc32(b) values (repeat('secret',20));
commit;
FLUSH TABLES tce_crc32, tc_crc32, te_crc32,
t_crc32, tpe_crc32, tp_crc32 FOR EXPORT;
backup: tce_crc32
backup: tc_crc32
backup: te_crc32
backup: t_crc32
backup: tpe_crc32
backup: tp_crc32
t_crc32.cfg
t_crc32.frm
t_crc32.ibd
tc_crc32.cfg
tc_crc32.frm
tc_crc32.ibd
tce_crc32.cfg
tce_crc32.frm
tce_crc32.ibd
te_crc32.cfg
te_crc32.frm
te_crc32.ibd
tp_crc32.cfg
tp_crc32.frm
tp_crc32.ibd
tpe_crc32.cfg
tpe_crc32.frm
tpe_crc32.ibd
UNLOCK TABLES;
SET GLOBAL innodb_checksum_algorithm=strict_crc32;
ALTER TABLE tce_crc32 DISCARD TABLESPACE;
ALTER TABLE tc_crc32 DISCARD TABLESPACE;
ALTER TABLE te_crc32 DISCARD TABLESPACE;
ALTER TABLE t_crc32 DISCARD TABLESPACE;
ALTER TABLE tpe_crc32 DISCARD TABLESPACE;
ALTER TABLE tp_crc32 DISCARD TABLESPACE;
restore: tce_crc32 .ibd and .cfg files
restore: tc_crc32 .ibd and .cfg files
restore: te_crc32 .ibd and .cfg files
restore: t_crc32 .ibd and .cfg files
restore: tpe_crc32 .ibd and .cfg files
restore: tp_crc32 .ibd and .cfg files
ALTER TABLE tce_crc32 IMPORT TABLESPACE;
update tce_crc32 set b=substr(b,1);
ALTER TABLE tc_crc32 IMPORT TABLESPACE;
update tc_crc32 set b=substr(b,1);
ALTER TABLE te_crc32 IMPORT TABLESPACE;
update te_crc32 set b=substr(b,1);
ALTER TABLE t_crc32 IMPORT TABLESPACE;
update t_crc32 set b=substr(b,1);
ALTER TABLE tpe_crc32 IMPORT TABLESPACE;
update tpe_crc32 set b=substr(b,1);
ALTER TABLE tp_crc32 IMPORT TABLESPACE;
update tp_crc32 set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=crc32;
ALTER TABLE tce_crc32 DISCARD TABLESPACE;
ALTER TABLE tc_crc32 DISCARD TABLESPACE;
ALTER TABLE te_crc32 DISCARD TABLESPACE;
ALTER TABLE t_crc32 DISCARD TABLESPACE;
ALTER TABLE tpe_crc32 DISCARD TABLESPACE;
ALTER TABLE tp_crc32 DISCARD TABLESPACE;
restore: tce_crc32 .ibd and .cfg files
restore: tc_crc32 .ibd and .cfg files
restore: te_crc32 .ibd and .cfg files
restore: t_crc32 .ibd and .cfg files
restore: tpe_crc32 .ibd and .cfg files
restore: tp_crc32 .ibd and .cfg files
ALTER TABLE tce_crc32 IMPORT TABLESPACE;
update tce_crc32 set b=substr(b,1);
ALTER TABLE tc_crc32 IMPORT TABLESPACE;
update tc_crc32 set b=substr(b,1);
ALTER TABLE te_crc32 IMPORT TABLESPACE;
update te_crc32 set b=substr(b,1);
ALTER TABLE t_crc32 IMPORT TABLESPACE;
update t_crc32 set b=substr(b,1);
ALTER TABLE tpe_crc32 IMPORT TABLESPACE;
update tpe_crc32 set b=substr(b,1);
ALTER TABLE tp_crc32 IMPORT TABLESPACE;
update tp_crc32 set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=strict_innodb;
ALTER TABLE tce_crc32 DISCARD TABLESPACE;
ALTER TABLE tc_crc32 DISCARD TABLESPACE;
ALTER TABLE te_crc32 DISCARD TABLESPACE;
ALTER TABLE t_crc32 DISCARD TABLESPACE;
ALTER TABLE tpe_crc32 DISCARD TABLESPACE;
ALTER TABLE tp_crc32 DISCARD TABLESPACE;
restore: tce_crc32 .ibd and .cfg files
restore: tc_crc32 .ibd and .cfg files
restore: te_crc32 .ibd and .cfg files
restore: t_crc32 .ibd and .cfg files
restore: tpe_crc32 .ibd and .cfg files
restore: tp_crc32 .ibd and .cfg files
ALTER TABLE tce_crc32 IMPORT TABLESPACE;
update tce_crc32 set b=substr(b,1);
ALTER TABLE tc_crc32 IMPORT TABLESPACE;
update tc_crc32 set b=substr(b,1);
ALTER TABLE te_crc32 IMPORT TABLESPACE;
update te_crc32 set b=substr(b,1);
ALTER TABLE t_crc32 IMPORT TABLESPACE;
update t_crc32 set b=substr(b,1);
ALTER TABLE tpe_crc32 IMPORT TABLESPACE;
update tpe_crc32 set b=substr(b,1);
ALTER TABLE tp_crc32 IMPORT TABLESPACE;
update tp_crc32 set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=innodb;
ALTER TABLE tce_crc32 DISCARD TABLESPACE;
ALTER TABLE tc_crc32 DISCARD TABLESPACE;
ALTER TABLE te_crc32 DISCARD TABLESPACE;
ALTER TABLE t_crc32 DISCARD TABLESPACE;
ALTER TABLE tpe_crc32 DISCARD TABLESPACE;
ALTER TABLE tp_crc32 DISCARD TABLESPACE;
restore: tce_crc32 .ibd and .cfg files
restore: tc_crc32 .ibd and .cfg files
restore: te_crc32 .ibd and .cfg files
restore: t_crc32 .ibd and .cfg files
restore: tpe_crc32 .ibd and .cfg files
restore: tp_crc32 .ibd and .cfg files
ALTER TABLE tce_crc32 IMPORT TABLESPACE;
update tce_crc32 set b=substr(b,1);
ALTER TABLE tc_crc32 IMPORT TABLESPACE;
update tc_crc32 set b=substr(b,1);
ALTER TABLE te_crc32 IMPORT TABLESPACE;
update te_crc32 set b=substr(b,1);
ALTER TABLE t_crc32 IMPORT TABLESPACE;
update t_crc32 set b=substr(b,1);
ALTER TABLE tpe_crc32 IMPORT TABLESPACE;
update tpe_crc32 set b=substr(b,1);
ALTER TABLE tp_crc32 IMPORT TABLESPACE;
update tp_crc32 set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=strict_none;
ALTER TABLE tce_crc32 DISCARD TABLESPACE;
ALTER TABLE tc_crc32 DISCARD TABLESPACE;
ALTER TABLE te_crc32 DISCARD TABLESPACE;
ALTER TABLE t_crc32 DISCARD TABLESPACE;
ALTER TABLE tpe_crc32 DISCARD TABLESPACE;
ALTER TABLE tp_crc32 DISCARD TABLESPACE;
restore: tce_crc32 .ibd and .cfg files
restore: tc_crc32 .ibd and .cfg files
restore: te_crc32 .ibd and .cfg files
restore: t_crc32 .ibd and .cfg files
restore: tpe_crc32 .ibd and .cfg files
restore: tp_crc32 .ibd and .cfg files
ALTER TABLE tce_crc32 IMPORT TABLESPACE;
update tce_crc32 set b=substr(b,1);
ALTER TABLE tc_crc32 IMPORT TABLESPACE;
update tc_crc32 set b=substr(b,1);
ALTER TABLE te_crc32 IMPORT TABLESPACE;
update te_crc32 set b=substr(b,1);
ALTER TABLE t_crc32 IMPORT TABLESPACE;
update t_crc32 set b=substr(b,1);
ALTER TABLE tpe_crc32 IMPORT TABLESPACE;
update tpe_crc32 set b=substr(b,1);
ALTER TABLE tp_crc32 IMPORT TABLESPACE;
update tp_crc32 set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=none;
ALTER TABLE tce_crc32 DISCARD TABLESPACE;
ALTER TABLE tc_crc32 DISCARD TABLESPACE;
ALTER TABLE te_crc32 DISCARD TABLESPACE;
ALTER TABLE t_crc32 DISCARD TABLESPACE;
ALTER TABLE tpe_crc32 DISCARD TABLESPACE;
ALTER TABLE tp_crc32 DISCARD TABLESPACE;
restore: tce_crc32 .ibd and .cfg files
restore: tc_crc32 .ibd and .cfg files
restore: te_crc32 .ibd and .cfg files
restore: t_crc32 .ibd and .cfg files
restore: tpe_crc32 .ibd and .cfg files
restore: tp_crc32 .ibd and .cfg files
ALTER TABLE tce_crc32 IMPORT TABLESPACE;
update tce_crc32 set b=substr(b,1);
ALTER TABLE tc_crc32 IMPORT TABLESPACE;
update tc_crc32 set b=substr(b,1);
ALTER TABLE te_crc32 IMPORT TABLESPACE;
update te_crc32 set b=substr(b,1);
ALTER TABLE t_crc32 IMPORT TABLESPACE;
update t_crc32 set b=substr(b,1);
ALTER TABLE tpe_crc32 IMPORT TABLESPACE;
update tpe_crc32 set b=substr(b,1);
ALTER TABLE tp_crc32 IMPORT TABLESPACE;
update tp_crc32 set b=substr(b,1);
CHECK TABLE tce_crc32, tc_crc32, te_crc32,
t_crc32, tpe_crc32, tp_crc32;
Table Op Msg_type Msg_text
test.tce_crc32 check status OK
test.tc_crc32 check status OK
test.te_crc32 check status OK
test.t_crc32 check status OK
test.tpe_crc32 check status OK
test.tp_crc32 check status OK
DROP TABLE tce_crc32, tc_crc32, te_crc32,
t_crc32, tpe_crc32, tp_crc32;
SET GLOBAL innodb_checksum_algorithm=innodb;
create table tce_innodb(a serial, b blob, index(b(10))) engine=innodb
ROW_FORMAT=COMPRESSED encrypted=yes;
create table tc_innodb(a serial, b blob, index(b(10))) engine=innodb
ROW_FORMAT=COMPRESSED encrypted=no;
create table te_innodb(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_innodb(a serial, b blob, index(b(10))) engine=innodb
encrypted=no;
create table tpe_innodb(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=yes;
create table tp_innodb(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=no;
begin;
insert into tce_innodb(b) values (repeat('secret',20));
insert into tc_innodb(b) values (repeat('secret',20));
insert into te_innodb(b) values (repeat('secret',20));
insert into t_innodb(b) values (repeat('secret',20));
insert into tpe_innodb(b) values (repeat('secret',20));
insert into tp_innodb(b) values (repeat('secret',20));
commit;
FLUSH TABLES tce_innodb, tc_innodb, te_innodb,
t_innodb, tpe_innodb, tp_innodb FOR EXPORT;
backup: tce_innodb
backup: tc_innodb
backup: te_innodb
backup: t_innodb
backup: tpe_innodb
backup: tp_innodb
t_innodb.cfg
t_innodb.frm
t_innodb.ibd
tc_innodb.cfg
tc_innodb.frm
tc_innodb.ibd
tce_innodb.cfg
tce_innodb.frm
tce_innodb.ibd
te_innodb.cfg
te_innodb.frm
te_innodb.ibd
tp_innodb.cfg
tp_innodb.frm
tp_innodb.ibd
tpe_innodb.cfg
tpe_innodb.frm
tpe_innodb.ibd
UNLOCK TABLES;
SET GLOBAL innodb_checksum_algorithm=strict_crc32;
ALTER TABLE tce_innodb DISCARD TABLESPACE;
ALTER TABLE tc_innodb DISCARD TABLESPACE;
ALTER TABLE te_innodb DISCARD TABLESPACE;
ALTER TABLE t_innodb DISCARD TABLESPACE;
ALTER TABLE tpe_innodb DISCARD TABLESPACE;
ALTER TABLE tp_innodb DISCARD TABLESPACE;
restore: tce_innodb .ibd and .cfg files
restore: tc_innodb .ibd and .cfg files
restore: te_innodb .ibd and .cfg files
restore: t_innodb .ibd and .cfg files
restore: tpe_innodb .ibd and .cfg files
restore: tp_innodb .ibd and .cfg files
ALTER TABLE tce_innodb IMPORT TABLESPACE;
update tce_innodb set b=substr(b,1);
ALTER TABLE tc_innodb IMPORT TABLESPACE;
update tc_innodb set b=substr(b,1);
ALTER TABLE te_innodb IMPORT TABLESPACE;
update te_innodb set b=substr(b,1);
ALTER TABLE t_innodb IMPORT TABLESPACE;
update t_innodb set b=substr(b,1);
ALTER TABLE tpe_innodb IMPORT TABLESPACE;
update tpe_innodb set b=substr(b,1);
ALTER TABLE tp_innodb IMPORT TABLESPACE;
update tp_innodb set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=crc32;
ALTER TABLE tce_innodb DISCARD TABLESPACE;
ALTER TABLE tc_innodb DISCARD TABLESPACE;
ALTER TABLE te_innodb DISCARD TABLESPACE;
ALTER TABLE t_innodb DISCARD TABLESPACE;
ALTER TABLE tpe_innodb DISCARD TABLESPACE;
ALTER TABLE tp_innodb DISCARD TABLESPACE;
restore: tce_innodb .ibd and .cfg files
restore: tc_innodb .ibd and .cfg files
restore: te_innodb .ibd and .cfg files
restore: t_innodb .ibd and .cfg files
restore: tpe_innodb .ibd and .cfg files
restore: tp_innodb .ibd and .cfg files
ALTER TABLE tce_innodb IMPORT TABLESPACE;
update tce_innodb set b=substr(b,1);
ALTER TABLE tc_innodb IMPORT TABLESPACE;
update tc_innodb set b=substr(b,1);
ALTER TABLE te_innodb IMPORT TABLESPACE;
update te_innodb set b=substr(b,1);
ALTER TABLE t_innodb IMPORT TABLESPACE;
update t_innodb set b=substr(b,1);
ALTER TABLE tpe_innodb IMPORT TABLESPACE;
update tpe_innodb set b=substr(b,1);
ALTER TABLE tp_innodb IMPORT TABLESPACE;
update tp_innodb set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=strict_innodb;
ALTER TABLE tce_innodb DISCARD TABLESPACE;
ALTER TABLE tc_innodb DISCARD TABLESPACE;
ALTER TABLE te_innodb DISCARD TABLESPACE;
ALTER TABLE t_innodb DISCARD TABLESPACE;
ALTER TABLE tpe_innodb DISCARD TABLESPACE;
ALTER TABLE tp_innodb DISCARD TABLESPACE;
restore: tce_innodb .ibd and .cfg files
restore: tc_innodb .ibd and .cfg files
restore: te_innodb .ibd and .cfg files
restore: t_innodb .ibd and .cfg files
restore: tpe_innodb .ibd and .cfg files
restore: tp_innodb .ibd and .cfg files
ALTER TABLE tce_innodb IMPORT TABLESPACE;
update tce_innodb set b=substr(b,1);
ALTER TABLE tc_innodb IMPORT TABLESPACE;
update tc_innodb set b=substr(b,1);
ALTER TABLE te_innodb IMPORT TABLESPACE;
update te_innodb set b=substr(b,1);
ALTER TABLE t_innodb IMPORT TABLESPACE;
update t_innodb set b=substr(b,1);
ALTER TABLE tpe_innodb IMPORT TABLESPACE;
update tpe_innodb set b=substr(b,1);
ALTER TABLE tp_innodb IMPORT TABLESPACE;
update tp_innodb set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=innodb;
ALTER TABLE tce_innodb DISCARD TABLESPACE;
ALTER TABLE tc_innodb DISCARD TABLESPACE;
ALTER TABLE te_innodb DISCARD TABLESPACE;
ALTER TABLE t_innodb DISCARD TABLESPACE;
ALTER TABLE tpe_innodb DISCARD TABLESPACE;
ALTER TABLE tp_innodb DISCARD TABLESPACE;
restore: tce_innodb .ibd and .cfg files
restore: tc_innodb .ibd and .cfg files
restore: te_innodb .ibd and .cfg files
restore: t_innodb .ibd and .cfg files
restore: tpe_innodb .ibd and .cfg files
restore: tp_innodb .ibd and .cfg files
ALTER TABLE tce_innodb IMPORT TABLESPACE;
update tce_innodb set b=substr(b,1);
ALTER TABLE tc_innodb IMPORT TABLESPACE;
update tc_innodb set b=substr(b,1);
ALTER TABLE te_innodb IMPORT TABLESPACE;
update te_innodb set b=substr(b,1);
ALTER TABLE t_innodb IMPORT TABLESPACE;
update t_innodb set b=substr(b,1);
ALTER TABLE tpe_innodb IMPORT TABLESPACE;
update tpe_innodb set b=substr(b,1);
ALTER TABLE tp_innodb IMPORT TABLESPACE;
update tp_innodb set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=strict_none;
ALTER TABLE tce_innodb DISCARD TABLESPACE;
ALTER TABLE tc_innodb DISCARD TABLESPACE;
ALTER TABLE te_innodb DISCARD TABLESPACE;
ALTER TABLE t_innodb DISCARD TABLESPACE;
ALTER TABLE tpe_innodb DISCARD TABLESPACE;
ALTER TABLE tp_innodb DISCARD TABLESPACE;
restore: tce_innodb .ibd and .cfg files
restore: tc_innodb .ibd and .cfg files
restore: te_innodb .ibd and .cfg files
restore: t_innodb .ibd and .cfg files
restore: tpe_innodb .ibd and .cfg files
restore: tp_innodb .ibd and .cfg files
ALTER TABLE tce_innodb IMPORT TABLESPACE;
update tce_innodb set b=substr(b,1);
ALTER TABLE tc_innodb IMPORT TABLESPACE;
update tc_innodb set b=substr(b,1);
ALTER TABLE te_innodb IMPORT TABLESPACE;
update te_innodb set b=substr(b,1);
ALTER TABLE t_innodb IMPORT TABLESPACE;
update t_innodb set b=substr(b,1);
ALTER TABLE tpe_innodb IMPORT TABLESPACE;
update tpe_innodb set b=substr(b,1);
ALTER TABLE tp_innodb IMPORT TABLESPACE;
update tp_innodb set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=none;
ALTER TABLE tce_innodb DISCARD TABLESPACE;
ALTER TABLE tc_innodb DISCARD TABLESPACE;
ALTER TABLE te_innodb DISCARD TABLESPACE;
ALTER TABLE t_innodb DISCARD TABLESPACE;
ALTER TABLE tpe_innodb DISCARD TABLESPACE;
ALTER TABLE tp_innodb DISCARD TABLESPACE;
restore: tce_innodb .ibd and .cfg files
restore: tc_innodb .ibd and .cfg files
restore: te_innodb .ibd and .cfg files
restore: t_innodb .ibd and .cfg files
restore: tpe_innodb .ibd and .cfg files
restore: tp_innodb .ibd and .cfg files
ALTER TABLE tce_innodb IMPORT TABLESPACE;
update tce_innodb set b=substr(b,1);
ALTER TABLE tc_innodb IMPORT TABLESPACE;
update tc_innodb set b=substr(b,1);
ALTER TABLE te_innodb IMPORT TABLESPACE;
update te_innodb set b=substr(b,1);
ALTER TABLE t_innodb IMPORT TABLESPACE;
update t_innodb set b=substr(b,1);
ALTER TABLE tpe_innodb IMPORT TABLESPACE;
update tpe_innodb set b=substr(b,1);
ALTER TABLE tp_innodb IMPORT TABLESPACE;
update tp_innodb set b=substr(b,1);
CHECK TABLE tce_innodb, tc_innodb, te_innodb,
t_innodb, tpe_innodb, tp_innodb;
Table Op Msg_type Msg_text
test.tce_innodb check status OK
test.tc_innodb check status OK
test.te_innodb check status OK
test.t_innodb check status OK
test.tpe_innodb check status OK
test.tp_innodb check status OK
DROP TABLE tce_innodb, tc_innodb, te_innodb,
t_innodb, tpe_innodb, tp_innodb;
SET GLOBAL innodb_checksum_algorithm=none;
create table tce_none(a serial, b blob, index(b(10))) engine=innodb
ROW_FORMAT=COMPRESSED encrypted=yes;
create table tc_none(a serial, b blob, index(b(10))) engine=innodb
ROW_FORMAT=COMPRESSED encrypted=no;
create table te_none(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_none(a serial, b blob, index(b(10))) engine=innodb
encrypted=no;
create table tpe_none(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=yes;
create table tp_none(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=no;
begin;
insert into tce_none(b) values (repeat('secret',20));
insert into tc_none(b) values (repeat('secret',20));
insert into te_none(b) values (repeat('secret',20));
insert into t_none(b) values (repeat('secret',20));
insert into tpe_none(b) values (repeat('secret',20));
insert into tp_none(b) values (repeat('secret',20));
commit;
FLUSH TABLES tce_none, tc_none, te_none,
t_none, tpe_none, tp_none FOR EXPORT;
backup: tce_none
backup: tc_none
backup: te_none
backup: t_none
backup: tpe_none
backup: tp_none
t_none.cfg
t_none.frm
t_none.ibd
tc_none.cfg
tc_none.frm
tc_none.ibd
tce_none.cfg
tce_none.frm
tce_none.ibd
te_none.cfg
te_none.frm
te_none.ibd
tp_none.cfg
tp_none.frm
tp_none.ibd
tpe_none.cfg
tpe_none.frm
tpe_none.ibd
UNLOCK TABLES;
SET GLOBAL innodb_checksum_algorithm=strict_crc32;
ALTER TABLE tce_none DISCARD TABLESPACE;
ALTER TABLE tc_none DISCARD TABLESPACE;
ALTER TABLE te_none DISCARD TABLESPACE;
ALTER TABLE t_none DISCARD TABLESPACE;
ALTER TABLE tpe_none DISCARD TABLESPACE;
ALTER TABLE tp_none DISCARD TABLESPACE;
restore: tce_none .ibd and .cfg files
restore: tc_none .ibd and .cfg files
restore: te_none .ibd and .cfg files
restore: t_none .ibd and .cfg files
restore: tpe_none .ibd and .cfg files
restore: tp_none .ibd and .cfg files
ALTER TABLE tce_none IMPORT TABLESPACE;
update tce_none set b=substr(b,1);
ALTER TABLE tc_none IMPORT TABLESPACE;
update tc_none set b=substr(b,1);
ALTER TABLE te_none IMPORT TABLESPACE;
update te_none set b=substr(b,1);
ALTER TABLE t_none IMPORT TABLESPACE;
update t_none set b=substr(b,1);
ALTER TABLE tpe_none IMPORT TABLESPACE;
update tpe_none set b=substr(b,1);
ALTER TABLE tp_none IMPORT TABLESPACE;
update tp_none set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=crc32;
ALTER TABLE tce_none DISCARD TABLESPACE;
ALTER TABLE tc_none DISCARD TABLESPACE;
ALTER TABLE te_none DISCARD TABLESPACE;
ALTER TABLE t_none DISCARD TABLESPACE;
ALTER TABLE tpe_none DISCARD TABLESPACE;
ALTER TABLE tp_none DISCARD TABLESPACE;
restore: tce_none .ibd and .cfg files
restore: tc_none .ibd and .cfg files
restore: te_none .ibd and .cfg files
restore: t_none .ibd and .cfg files
restore: tpe_none .ibd and .cfg files
restore: tp_none .ibd and .cfg files
ALTER TABLE tce_none IMPORT TABLESPACE;
update tce_none set b=substr(b,1);
ALTER TABLE tc_none IMPORT TABLESPACE;
update tc_none set b=substr(b,1);
ALTER TABLE te_none IMPORT TABLESPACE;
update te_none set b=substr(b,1);
ALTER TABLE t_none IMPORT TABLESPACE;
update t_none set b=substr(b,1);
ALTER TABLE tpe_none IMPORT TABLESPACE;
update tpe_none set b=substr(b,1);
ALTER TABLE tp_none IMPORT TABLESPACE;
update tp_none set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=strict_innodb;
ALTER TABLE tce_none DISCARD TABLESPACE;
ALTER TABLE tc_none DISCARD TABLESPACE;
ALTER TABLE te_none DISCARD TABLESPACE;
ALTER TABLE t_none DISCARD TABLESPACE;
ALTER TABLE tpe_none DISCARD TABLESPACE;
ALTER TABLE tp_none DISCARD TABLESPACE;
restore: tce_none .ibd and .cfg files
restore: tc_none .ibd and .cfg files
restore: te_none .ibd and .cfg files
restore: t_none .ibd and .cfg files
restore: tpe_none .ibd and .cfg files
restore: tp_none .ibd and .cfg files
ALTER TABLE tce_none IMPORT TABLESPACE;
update tce_none set b=substr(b,1);
ALTER TABLE tc_none IMPORT TABLESPACE;
update tc_none set b=substr(b,1);
ALTER TABLE te_none IMPORT TABLESPACE;
update te_none set b=substr(b,1);
ALTER TABLE t_none IMPORT TABLESPACE;
update t_none set b=substr(b,1);
ALTER TABLE tpe_none IMPORT TABLESPACE;
update tpe_none set b=substr(b,1);
ALTER TABLE tp_none IMPORT TABLESPACE;
update tp_none set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=innodb;
ALTER TABLE tce_none DISCARD TABLESPACE;
ALTER TABLE tc_none DISCARD TABLESPACE;
ALTER TABLE te_none DISCARD TABLESPACE;
ALTER TABLE t_none DISCARD TABLESPACE;
ALTER TABLE tpe_none DISCARD TABLESPACE;
ALTER TABLE tp_none DISCARD TABLESPACE;
restore: tce_none .ibd and .cfg files
restore: tc_none .ibd and .cfg files
restore: te_none .ibd and .cfg files
restore: t_none .ibd and .cfg files
restore: tpe_none .ibd and .cfg files
restore: tp_none .ibd and .cfg files
ALTER TABLE tce_none IMPORT TABLESPACE;
update tce_none set b=substr(b,1);
ALTER TABLE tc_none IMPORT TABLESPACE;
update tc_none set b=substr(b,1);
ALTER TABLE te_none IMPORT TABLESPACE;
update te_none set b=substr(b,1);
ALTER TABLE t_none IMPORT TABLESPACE;
update t_none set b=substr(b,1);
ALTER TABLE tpe_none IMPORT TABLESPACE;
update tpe_none set b=substr(b,1);
ALTER TABLE tp_none IMPORT TABLESPACE;
update tp_none set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=strict_none;
ALTER TABLE tce_none DISCARD TABLESPACE;
ALTER TABLE tc_none DISCARD TABLESPACE;
ALTER TABLE te_none DISCARD TABLESPACE;
ALTER TABLE t_none DISCARD TABLESPACE;
ALTER TABLE tpe_none DISCARD TABLESPACE;
ALTER TABLE tp_none DISCARD TABLESPACE;
restore: tce_none .ibd and .cfg files
restore: tc_none .ibd and .cfg files
restore: te_none .ibd and .cfg files
restore: t_none .ibd and .cfg files
restore: tpe_none .ibd and .cfg files
restore: tp_none .ibd and .cfg files
ALTER TABLE tce_none IMPORT TABLESPACE;
update tce_none set b=substr(b,1);
ALTER TABLE tc_none IMPORT TABLESPACE;
update tc_none set b=substr(b,1);
ALTER TABLE te_none IMPORT TABLESPACE;
update te_none set b=substr(b,1);
ALTER TABLE t_none IMPORT TABLESPACE;
update t_none set b=substr(b,1);
ALTER TABLE tpe_none IMPORT TABLESPACE;
update tpe_none set b=substr(b,1);
ALTER TABLE tp_none IMPORT TABLESPACE;
update tp_none set b=substr(b,1);
SET GLOBAL innodb_checksum_algorithm=none;
ALTER TABLE tce_none DISCARD TABLESPACE;
ALTER TABLE tc_none DISCARD TABLESPACE;
ALTER TABLE te_none DISCARD TABLESPACE;
ALTER TABLE t_none DISCARD TABLESPACE;
ALTER TABLE tpe_none DISCARD TABLESPACE;
ALTER TABLE tp_none DISCARD TABLESPACE;
restore: tce_none .ibd and .cfg files
restore: tc_none .ibd and .cfg files
restore: te_none .ibd and .cfg files
restore: t_none .ibd and .cfg files
restore: tpe_none .ibd and .cfg files
restore: tp_none .ibd and .cfg files
ALTER TABLE tce_none IMPORT TABLESPACE;
update tce_none set b=substr(b,1);
ALTER TABLE tc_none IMPORT TABLESPACE;
update tc_none set b=substr(b,1);
ALTER TABLE te_none IMPORT TABLESPACE;
update te_none set b=substr(b,1);
ALTER TABLE t_none IMPORT TABLESPACE;
update t_none set b=substr(b,1);
ALTER TABLE tpe_none IMPORT TABLESPACE;
update tpe_none set b=substr(b,1);
ALTER TABLE tp_none IMPORT TABLESPACE;
update tp_none set b=substr(b,1);
CHECK TABLE tce_none, tc_none, te_none,
t_none, tpe_none, tp_none;
Table Op Msg_type Msg_text
test.tce_none check status OK
test.tc_none check status OK
test.te_none check status OK
test.t_none check status OK
test.tpe_none check status OK
test.tp_none check status OK
DROP TABLE tce_none, tc_none, te_none,
t_none, tpe_none, tp_none;
SET GLOBAL innodb_file_per_table = @saved_file_per_table;
SET GLOBAL innodb_checksum_algorithm = @saved_checksum_algorithm;
SET GLOBAL innodb_encrypt_tables = @saved_encrypt_tables;
SET GLOBAL innodb_encryption_threads = @saved_encryption_threads;
SET GLOBAL innodb_default_encryption_key_id = @saved_encryption_key_id;

View File

@ -1,4 +1,5 @@
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
# Restart mysqld --file-key-management-filename=keys2.txt
SET GLOBAL innodb_file_per_table = ON;
set GLOBAL innodb_default_encryption_key_id=4;

View File

@ -0,0 +1,87 @@
create database innodb_test;
use innodb_test;
create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb;
create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact;
create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic;
create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed;
create table innodb_compressed1(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=1;
create table innodb_compressed2(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=2;
create table innodb_compressed4(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=4;
create table innodb_compressed8(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=8;
create table innodb_compressed16(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=16;
create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant;
create table innodb_pagecomp(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes;
create table innodb_pagecomp1(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=1;
create table innodb_pagecomp2(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=2;
create table innodb_pagecomp3(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=3;
create table innodb_pagecomp4(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=4;
create table innodb_pagecomp5(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=5;
create table innodb_pagecomp6(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=6;
create table innodb_pagecomp7(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=7;
create table innodb_pagecomp8(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=8;
create table innodb_pagecomp9(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=9;
create table innodb_datadir1(c1 bigint not null, b char(200)) engine=innodb DATA DIRECTORY='MYSQL_TMP_DIR';
create table innodb_datadir2(c1 bigint not null, b char(200)) engine=innodb row_format=compressed DATA DIRECTORY='MYSQL_TMP_DIR';
create table innodb_datadir3(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes DATA DIRECTORY='MYSQL_TMP_DIR';
begin;
insert into innodb_normal values (1,'secret');
insert into innodb_compact select * from innodb_normal;
insert into innodb_dynamic select * from innodb_normal;
insert into innodb_compressed select * from innodb_normal;
insert into innodb_compressed1 select * from innodb_normal;
insert into innodb_compressed2 select * from innodb_normal;
insert into innodb_compressed4 select * from innodb_normal;
insert into innodb_compressed8 select * from innodb_normal;
insert into innodb_compressed16 select * from innodb_normal;
insert into innodb_redundant select * from innodb_normal;
insert into innodb_pagecomp select * from innodb_normal;
insert into innodb_pagecomp1 select * from innodb_normal;
insert into innodb_pagecomp2 select * from innodb_normal;
insert into innodb_pagecomp3 select * from innodb_normal;
insert into innodb_pagecomp4 select * from innodb_normal;
insert into innodb_pagecomp5 select * from innodb_normal;
insert into innodb_pagecomp6 select * from innodb_normal;
insert into innodb_pagecomp7 select * from innodb_normal;
insert into innodb_pagecomp8 select * from innodb_normal;
insert into innodb_pagecomp9 select * from innodb_normal;
insert into innodb_datadir1 select * from innodb_normal;
insert into innodb_datadir2 select * from innodb_normal;
insert into innodb_datadir3 select * from innodb_normal;
commit;
# Restart server and see how many page 0's are read
# result should be less than actual number of tables
# i.e. < 23 + 3 = 26
show status like 'innodb_pages0_read%';
Variable_name Value
Innodb_pages0_read 26
use innodb_test;
show status like 'innodb_pages0_read%';
Variable_name Value
Innodb_pages0_read 26
use test;
show status like 'innodb_pages0_read%';
Variable_name Value
Innodb_pages0_read 26
set global innodb_encrypt_tables=OFF;
# wait until tables are decrypted
show status like 'innodb_pages0_read%';
Variable_name Value
Innodb_pages0_read 26
use innodb_test;
show status like 'innodb_pages0_read%';
Variable_name Value
Innodb_pages0_read 26
use test;
# restart and see number read page 0
show status like 'innodb_pages0_read%';
Variable_name Value
Innodb_pages0_read 26
use innodb_test;
show status like 'innodb_pages0_read%';
Variable_name Value
Innodb_pages0_read 26
use test;
drop database innodb_test;
show status like 'innodb_pages0_read%';
Variable_name Value
Innodb_pages0_read 26

View File

@ -64,5 +64,4 @@ FOUND 1 /public/ in t7.ibd
FOUND 1 /public/ in t8.ibd
# t9 page compressed expecting NOT FOUND
NOT FOUND /public/ in t9.ibd
use test;
drop database enctests;

View File

@ -0,0 +1,120 @@
-- source include/innodb_page_size.inc
-- source include/have_file_key_management_plugin.inc
SET @saved_file_per_table = @@global.innodb_file_per_table;
SET @saved_checksum_algorithm = @@global.innodb_checksum_algorithm;
SET @saved_encrypt_tables = @@global.innodb_encrypt_tables;
SET @saved_encryption_threads = @@global.innodb_encryption_threads;
SET @saved_encryption_key_id = @@global.innodb_default_encryption_key_id;
SET GLOBAL innodb_file_per_table = ON;
SET GLOBAL innodb_encrypt_tables = ON;
SET GLOBAL innodb_encryption_threads = 4;
call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_(crc32|none|innodb)\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"(innodb|none|crc32)\"");
SET GLOBAL innodb_checksum_algorithm = innodb;
SET GLOBAL innodb_default_encryption_key_id=4;
let MYSQLD_DATADIR =`SELECT @@datadir`;
# ROW_FORMAT=COMPRESSED is unavailable with innodb_page_size=32k or 64k
let $row_format_compressed= `select case when @@global.innodb_page_size>16384
then 'ROW_FORMAT=DYNAMIC' else 'ROW_FORMAT=COMPRESSED' end`;
let $from = 3;
while ($from)
{
dec $from;
let checksum = `select case $from
when 0 then 'none'
when 1 then 'innodb'
when 2 then 'crc32'
end`;
eval SET GLOBAL innodb_checksum_algorithm=$checksum;
eval create table tce_$checksum(a serial, b blob, index(b(10))) engine=innodb
$row_format_compressed encrypted=yes;
eval create table tc_$checksum(a serial, b blob, index(b(10))) engine=innodb
$row_format_compressed encrypted=no;
eval create table te_$checksum(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
eval create table t_$checksum(a serial, b blob, index(b(10))) engine=innodb
encrypted=no;
eval create table tpe_$checksum(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=yes;
eval create table tp_$checksum(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=no;
begin;
eval insert into tce_$checksum(b) values (repeat('secret',20));
eval insert into tc_$checksum(b) values (repeat('secret',20));
eval insert into te_$checksum(b) values (repeat('secret',20));
eval insert into t_$checksum(b) values (repeat('secret',20));
eval insert into tpe_$checksum(b) values (repeat('secret',20));
eval insert into tp_$checksum(b) values (repeat('secret',20));
commit;
eval FLUSH TABLES tce_$checksum, tc_$checksum, te_$checksum,
t_$checksum, tpe_$checksum, tp_$checksum FOR EXPORT;
perl;
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
my @tables = ("tce_", "tc_", "te_", "t_", "tpe_", "tp_");
ib_backup_tablespaces("test", map{ $_ . $ENV{checksum} } @tables);
EOF
--list_files $MYSQLD_DATADIR/test
UNLOCK TABLES;
let $to = 6;
while ($to)
{
dec $to;
let $tocksum = `select case $to
when 0 then 'none'
when 1 then 'strict_none'
when 2 then 'innodb'
when 3 then 'strict_innodb'
when 4 then 'crc32'
when 5 then 'strict_crc32'
end`;
eval SET GLOBAL innodb_checksum_algorithm=$tocksum;
eval ALTER TABLE tce_$checksum DISCARD TABLESPACE;
eval ALTER TABLE tc_$checksum DISCARD TABLESPACE;
eval ALTER TABLE te_$checksum DISCARD TABLESPACE;
eval ALTER TABLE t_$checksum DISCARD TABLESPACE;
eval ALTER TABLE tpe_$checksum DISCARD TABLESPACE;
eval ALTER TABLE tp_$checksum DISCARD TABLESPACE;
perl;
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
my @tables = ("tce_", "tc_", "te_", "t_", "tpe_", "tp_");
ib_restore_tablespaces("test", map{ $_ . $ENV{checksum} } @tables);
EOF
eval ALTER TABLE tce_$checksum IMPORT TABLESPACE;
eval update tce_$checksum set b=substr(b,1);
eval ALTER TABLE tc_$checksum IMPORT TABLESPACE;
eval update tc_$checksum set b=substr(b,1);
eval ALTER TABLE te_$checksum IMPORT TABLESPACE;
eval update te_$checksum set b=substr(b,1);
eval ALTER TABLE t_$checksum IMPORT TABLESPACE;
eval update t_$checksum set b=substr(b,1);
eval ALTER TABLE tpe_$checksum IMPORT TABLESPACE;
eval update tpe_$checksum set b=substr(b,1);
eval ALTER TABLE tp_$checksum IMPORT TABLESPACE;
eval update tp_$checksum set b=substr(b,1);
}
eval CHECK TABLE tce_$checksum, tc_$checksum, te_$checksum,
t_$checksum, tpe_$checksum, tp_$checksum;
eval DROP TABLE tce_$checksum, tc_$checksum, te_$checksum,
t_$checksum, tpe_$checksum, tp_$checksum;
}
SET GLOBAL innodb_file_per_table = @saved_file_per_table;
SET GLOBAL innodb_checksum_algorithm = @saved_checksum_algorithm;
SET GLOBAL innodb_encrypt_tables = @saved_encrypt_tables;
SET GLOBAL innodb_encryption_threads = @saved_encryption_threads;
SET GLOBAL innodb_default_encryption_key_id = @saved_encryption_key_id;

View File

@ -0,0 +1,12 @@
[crc32]
loose-innodb-tablespaces-encryption
loose-innodb-encrypt-tables=on
loose-innodb-encryption-threads=4
max_allowed_packet=64K
loose-innodb-checksum-algorithm=crc32
[none]
loose-innodb-tablespaces-encryption
loose-innodb-encrypt-tables=on
loose-innodb-encryption-threads=4
max_allowed_packet=64K
loose-innodb-checksum-algorithm=none

View File

@ -1,4 +0,0 @@
--innodb-tablespaces-encryption
--innodb-encrypt-tables=on
--innodb-encryption-threads=2
--max_allowed_packet=64K

View File

@ -1,10 +1,11 @@
-- source include/have_innodb.inc
-- source include/innodb_page_size_small.inc
-- source include/have_file_key_management_plugin.inc
# embedded does not support restart
-- source include/not_embedded.inc
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]");
--echo # Restart mysqld --file-key-management-filename=keys2.txt
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt

View File

@ -0,0 +1,5 @@
--innodb-encrypt-tables=ON
--innodb-encrypt-log=ON
--innodb-encryption-rotate-key-age=15
--innodb-encryption-threads=4
--innodb-tablespaces-encryption

View File

@ -0,0 +1,92 @@
-- source include/have_innodb.inc
-- source include/have_file_key_management_plugin.inc
-- source include/not_embedded.inc
create database innodb_test;
use innodb_test;
create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb;
create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact;
create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic;
create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed;
create table innodb_compressed1(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=1;
create table innodb_compressed2(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=2;
create table innodb_compressed4(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=4;
create table innodb_compressed8(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=8;
create table innodb_compressed16(c1 bigint not null, b char(200)) engine=innodb row_format=compressed key_block_size=16;
create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant;
create table innodb_pagecomp(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes;
create table innodb_pagecomp1(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=1;
create table innodb_pagecomp2(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=2;
create table innodb_pagecomp3(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=3;
create table innodb_pagecomp4(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=4;
create table innodb_pagecomp5(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=5;
create table innodb_pagecomp6(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=6;
create table innodb_pagecomp7(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=7;
create table innodb_pagecomp8(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=8;
create table innodb_pagecomp9(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes page_compression_level=9;
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
eval create table innodb_datadir1(c1 bigint not null, b char(200)) engine=innodb DATA DIRECTORY='$MYSQL_TMP_DIR';
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
eval create table innodb_datadir2(c1 bigint not null, b char(200)) engine=innodb row_format=compressed DATA DIRECTORY='$MYSQL_TMP_DIR';
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
eval create table innodb_datadir3(c1 bigint not null, b char(200)) engine=innodb page_compressed=yes DATA DIRECTORY='$MYSQL_TMP_DIR';
begin;
insert into innodb_normal values (1,'secret');
insert into innodb_compact select * from innodb_normal;
insert into innodb_dynamic select * from innodb_normal;
insert into innodb_compressed select * from innodb_normal;
insert into innodb_compressed1 select * from innodb_normal;
insert into innodb_compressed2 select * from innodb_normal;
insert into innodb_compressed4 select * from innodb_normal;
insert into innodb_compressed8 select * from innodb_normal;
insert into innodb_compressed16 select * from innodb_normal;
insert into innodb_redundant select * from innodb_normal;
insert into innodb_pagecomp select * from innodb_normal;
insert into innodb_pagecomp1 select * from innodb_normal;
insert into innodb_pagecomp2 select * from innodb_normal;
insert into innodb_pagecomp3 select * from innodb_normal;
insert into innodb_pagecomp4 select * from innodb_normal;
insert into innodb_pagecomp5 select * from innodb_normal;
insert into innodb_pagecomp6 select * from innodb_normal;
insert into innodb_pagecomp7 select * from innodb_normal;
insert into innodb_pagecomp8 select * from innodb_normal;
insert into innodb_pagecomp9 select * from innodb_normal;
insert into innodb_datadir1 select * from innodb_normal;
insert into innodb_datadir2 select * from innodb_normal;
insert into innodb_datadir3 select * from innodb_normal;
commit;
--echo # Restart server and see how many page 0's are read
--source include/restart_mysqld.inc
--echo # result should be less than actual number of tables
--echo # i.e. < 23 + 3 = 26
show status like 'innodb_pages0_read%';
use innodb_test;
show status like 'innodb_pages0_read%';
use test;
show status like 'innodb_pages0_read%';
set global innodb_encrypt_tables=OFF;
--echo # wait until tables are decrypted
--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0
--source include/wait_condition.inc
show status like 'innodb_pages0_read%';
use innodb_test;
show status like 'innodb_pages0_read%';
use test;
--echo # restart and see number read page 0
-- source include/restart_mysqld.inc
show status like 'innodb_pages0_read%';
use innodb_test;
show status like 'innodb_pages0_read%';
use test;
drop database innodb_test;
show status like 'innodb_pages0_read%';

View File

@ -80,5 +80,4 @@ SET GLOBAL innodb_encrypt_tables=ON;
-- source include/start_mysqld.inc
use test;
drop database enctests;

Some files were not shown because too many files have changed in this diff Show More