Merge bb-10.2-ext into 10.3
This commit is contained in:
commit
1e3886ae80
@ -39,8 +39,4 @@ else
|
|||||||
fi
|
fi
|
||||||
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
|
set +v +x
|
||||||
|
24
.travis.yml
24
.travis.yml
@ -42,13 +42,33 @@ matrix:
|
|||||||
compiler: gcc
|
compiler: gcc
|
||||||
script:
|
script:
|
||||||
- ${CC} --version ; ${CXX} --version
|
- ${CC} --version ; ${CXX} --version
|
||||||
# Just for disabling hotcopy tests for now
|
|
||||||
- source .travis.compiler.sh
|
- source .travis.compiler.sh
|
||||||
# https://github.com/travis-ci/travis-ci/issues/7062 - /run/shm isn't writable or executable
|
# https://github.com/travis-ci/travis-ci/issues/7062 - /run/shm isn't writable or executable
|
||||||
# in trusty containers
|
# in trusty containers
|
||||||
- export MTR_MEM=/tmp
|
- export MTR_MEM=/tmp
|
||||||
- env DEB_BUILD_OPTIONS="parallel=6" debian/autobake-deb.sh;
|
- env DEB_BUILD_OPTIONS="parallel=6" debian/autobake-deb.sh;
|
||||||
- ccache --show-stats
|
- 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
|
# Matrix include for coverity
|
||||||
# - env:
|
# - env:
|
||||||
@ -108,6 +128,7 @@ addons:
|
|||||||
- libaio-dev
|
- libaio-dev
|
||||||
- libboost-dev
|
- libboost-dev
|
||||||
- libcurl3-dev
|
- libcurl3-dev
|
||||||
|
- libdbd-mysql
|
||||||
- libjudy-dev
|
- libjudy-dev
|
||||||
- libncurses5-dev
|
- libncurses5-dev
|
||||||
- libpam0g-dev
|
- libpam0g-dev
|
||||||
@ -128,6 +149,7 @@ addons:
|
|||||||
- liblzma-dev
|
- liblzma-dev
|
||||||
- libzmq-dev
|
- libzmq-dev
|
||||||
- libdistro-info-perl
|
- libdistro-info-perl
|
||||||
|
- uuid-dev
|
||||||
- devscripts # implicit for any build on Ubuntu
|
- devscripts # implicit for any build on Ubuntu
|
||||||
|
|
||||||
# libsystemd-daemon-dev # https://github.com/travis-ci/apt-package-whitelist/issues/3882
|
# libsystemd-daemon-dev # https://github.com/travis-ci/apt-package-whitelist/issues/3882
|
||||||
|
@ -3059,7 +3059,6 @@ static int com_server_help(String *buffer __attribute__((unused)),
|
|||||||
{
|
{
|
||||||
unsigned int num_fields= mysql_num_fields(result);
|
unsigned int num_fields= mysql_num_fields(result);
|
||||||
my_ulonglong num_rows= mysql_num_rows(result);
|
my_ulonglong num_rows= mysql_num_rows(result);
|
||||||
mysql_fetch_fields(result);
|
|
||||||
if (num_fields==3 && num_rows==1)
|
if (num_fields==3 && num_rows==1)
|
||||||
{
|
{
|
||||||
if (!(cur= mysql_fetch_row(result)))
|
if (!(cur= mysql_fetch_row(result)))
|
||||||
|
@ -1130,7 +1130,7 @@ static int check_version_match(void)
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char self_name[FN_REFLEN];
|
char self_name[FN_REFLEN + 1];
|
||||||
|
|
||||||
MY_INIT(argv[0]);
|
MY_INIT(argv[0]);
|
||||||
|
|
||||||
@ -1138,7 +1138,7 @@ int main(int argc, char **argv)
|
|||||||
if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
|
if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
strncpy(self_name, argv[0], FN_REFLEN);
|
strmake_buf(self_name, argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init_dynamic_string(&ds_args, "", 512, 256) ||
|
if (init_dynamic_string(&ds_args, "", 512, 256) ||
|
||||||
|
@ -47,6 +47,7 @@ static uint opt_count_iterations= 0, my_end_arg;
|
|||||||
static ulong opt_connect_timeout, opt_shutdown_timeout;
|
static ulong opt_connect_timeout, opt_shutdown_timeout;
|
||||||
static char * unix_port=0;
|
static char * unix_port=0;
|
||||||
static char *opt_plugin_dir= 0, *opt_default_auth= 0;
|
static char *opt_plugin_dir= 0, *opt_default_auth= 0;
|
||||||
|
static bool sql_log_bin_off= false;
|
||||||
|
|
||||||
#ifdef HAVE_SMEM
|
#ifdef HAVE_SMEM
|
||||||
static char *shared_memory_base_name=0;
|
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
|
@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)
|
static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
const char *status;
|
const char *status;
|
||||||
/*
|
/*
|
||||||
MySQL documentation relies on the fact that mysqladmin will
|
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;
|
struct my_rnd_struct rand_st;
|
||||||
char buff[FN_REFLEN + 20];
|
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--)
|
for (; argc > 0 ; argv++,argc--)
|
||||||
{
|
{
|
||||||
int command;
|
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);
|
my_printf_error(0, "Too few arguments to create", error_flags);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (maybe_disable_binlog(mysql))
|
||||||
|
return -1;
|
||||||
sprintf(buff,"create database `%.*s`",FN_REFLEN,argv[1]);
|
sprintf(buff,"create database `%.*s`",FN_REFLEN,argv[1]);
|
||||||
if (mysql_query(mysql,buff))
|
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);
|
my_printf_error(0, "Too few arguments to drop", error_flags);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (maybe_disable_binlog(mysql))
|
||||||
|
return -1;
|
||||||
if (drop_db(mysql,argv[1]))
|
if (drop_db(mysql,argv[1]))
|
||||||
return -1;
|
return -1;
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
@ -707,7 +727,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_PRIVILEGES:
|
case ADMIN_FLUSH_PRIVILEGES:
|
||||||
case ADMIN_RELOAD:
|
case ADMIN_RELOAD:
|
||||||
if (mysql_query(mysql,"flush privileges"))
|
if (flush(mysql, "privileges"))
|
||||||
{
|
{
|
||||||
my_printf_error(0, "reload failed; error: '%s'", error_flags,
|
my_printf_error(0, "reload failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -911,7 +931,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_LOGS:
|
case ADMIN_FLUSH_LOGS:
|
||||||
{
|
{
|
||||||
if (mysql_query(mysql,"flush logs"))
|
if (flush(mysql, "logs"))
|
||||||
{
|
{
|
||||||
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -921,7 +941,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_BINARY_LOG:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -931,7 +951,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_ENGINE_LOG:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -941,7 +961,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_ERROR_LOG:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -951,7 +971,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_GENERAL_LOG:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -961,7 +981,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_RELAY_LOG:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -971,7 +991,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_SLOW_LOG:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -981,7 +1001,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_HOSTS:
|
case ADMIN_FLUSH_HOSTS:
|
||||||
{
|
{
|
||||||
if (mysql_query(mysql,"flush hosts"))
|
if (flush(mysql, "hosts"))
|
||||||
{
|
{
|
||||||
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -991,7 +1011,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_TABLES:
|
case ADMIN_FLUSH_TABLES:
|
||||||
{
|
{
|
||||||
if (mysql_query(mysql,"flush tables"))
|
if (flush(mysql, "tables"))
|
||||||
{
|
{
|
||||||
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -1001,7 +1021,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_STATUS:
|
case ADMIN_FLUSH_STATUS:
|
||||||
{
|
{
|
||||||
if (mysql_query(mysql,"flush status"))
|
if (flush(mysql, "status"))
|
||||||
{
|
{
|
||||||
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -1011,7 +1031,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_TABLE_STATISTICS:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -1021,7 +1041,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_INDEX_STATISTICS:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -1031,7 +1051,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_USER_STATISTICS:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -1041,7 +1061,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_USER_RESOURCES:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -1051,7 +1071,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_CLIENT_STATISTICS:
|
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,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -1061,9 +1081,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_ALL_STATISTICS:
|
case ADMIN_FLUSH_ALL_STATISTICS:
|
||||||
{
|
{
|
||||||
if (mysql_query(mysql,
|
if (flush(mysql, "table_statistics,index_statistics,"
|
||||||
"flush table_statistics,index_statistics,"
|
"user_statistics,client_statistics"))
|
||||||
"user_statistics,client_statistics"))
|
|
||||||
{
|
{
|
||||||
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -1073,9 +1092,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
}
|
}
|
||||||
case ADMIN_FLUSH_ALL_STATUS:
|
case ADMIN_FLUSH_ALL_STATUS:
|
||||||
{
|
{
|
||||||
if (mysql_query(mysql,
|
if (flush(mysql, "status,table_statistics,index_statistics,"
|
||||||
"flush status,table_statistics,index_statistics,"
|
"user_statistics,client_statistics"))
|
||||||
"user_statistics,client_statistics"))
|
|
||||||
{
|
{
|
||||||
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
my_printf_error(0, "flush failed; error: '%s'", error_flags,
|
||||||
mysql_error(mysql));
|
mysql_error(mysql));
|
||||||
@ -1093,6 +1111,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
start_time=time((time_t*) 0);
|
start_time=time((time_t*) 0);
|
||||||
my_rnd_init(&rand_st,(ulong) start_time,(ulong) start_time/2);
|
my_rnd_init(&rand_st,(ulong) start_time,(ulong) start_time/2);
|
||||||
|
|
||||||
|
if (maybe_disable_binlog(mysql))
|
||||||
|
return -1;
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
{
|
{
|
||||||
my_printf_error(0, "Too few arguments to change password", error_flags);
|
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)
|
if (strcmp(typed_password, verified) != 0)
|
||||||
{
|
{
|
||||||
my_printf_error(0,"Passwords don't match",MYF(ME_BELL));
|
my_printf_error(0,"Passwords don't match",MYF(ME_BELL));
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto password_done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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'",
|
my_printf_error(0, "Could not determine old_passwords setting from server; error: '%s'",
|
||||||
error_flags, mysql_error(mysql));
|
error_flags, mysql_error(mysql));
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto password_done;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1144,7 +1166,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
"Could not get old_passwords setting from "
|
"Could not get old_passwords setting from "
|
||||||
"server; error: '%s'",
|
"server; error: '%s'",
|
||||||
error_flags, mysql_error(mysql));
|
error_flags, mysql_error(mysql));
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto password_done;
|
||||||
}
|
}
|
||||||
if (!mysql_num_rows(res))
|
if (!mysql_num_rows(res))
|
||||||
old= 1;
|
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'",
|
my_printf_error(0, "Can't turn off logging; error: '%s'",
|
||||||
error_flags, mysql_error(mysql));
|
error_flags, mysql_error(mysql));
|
||||||
return -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (mysql_query(mysql,buff))
|
if (mysql_query(mysql,buff))
|
||||||
{
|
{
|
||||||
if (mysql_errno(mysql)!=1290)
|
if (mysql_errno(mysql)!=1290)
|
||||||
{
|
{
|
||||||
my_printf_error(0,"unable to change password; error: '%s'",
|
my_printf_error(0,"unable to change password; error: '%s'",
|
||||||
error_flags, mysql_error(mysql));
|
error_flags, mysql_error(mysql));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1191,9 +1214,10 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
" --skip-grant-tables).\n"
|
" --skip-grant-tables).\n"
|
||||||
"Use: \"mysqladmin flush-privileges password '*'\""
|
"Use: \"mysqladmin flush-privileges password '*'\""
|
||||||
" instead", error_flags);
|
" instead", error_flags);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
password_done:
|
||||||
/* free up memory from prompted password */
|
/* free up memory from prompted password */
|
||||||
if (typed_password != argv[1])
|
if (typed_password != argv[1])
|
||||||
{
|
{
|
||||||
@ -1300,7 +1324,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags);
|
||||||
|
|
||||||
size_t tlen = strlen(logname);
|
size_t tlen = strlen(logname);
|
||||||
if (tlen > UINT_MAX)
|
if (tlen > sizeof(buf) - 10)
|
||||||
{
|
{
|
||||||
error("Log name too long.");
|
error("Log name too long.");
|
||||||
DBUG_RETURN(ERROR_STOP);
|
DBUG_RETURN(ERROR_STOP);
|
||||||
|
@ -2174,6 +2174,7 @@ static void print_xml_comment(FILE *xml_file, size_t len,
|
|||||||
case '-':
|
case '-':
|
||||||
if (*(comment_string + 1) == '-') /* Only one hyphen allowed. */
|
if (*(comment_string + 1) == '-') /* Only one hyphen allowed. */
|
||||||
break;
|
break;
|
||||||
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
fputc(*comment_string, xml_file);
|
fputc(*comment_string, xml_file);
|
||||||
break;
|
break;
|
||||||
@ -2850,6 +2851,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
|||||||
|
|
||||||
my_free(scv_buff);
|
my_free(scv_buff);
|
||||||
|
|
||||||
|
if (path)
|
||||||
|
my_fclose(sql_file, MYF(MY_WME));
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -5940,8 +5943,7 @@ static my_bool get_view_structure(char *table, char* db)
|
|||||||
dynstr_free(&ds_view);
|
dynstr_free(&ds_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_character_set_results(mysql, default_charset))
|
switch_character_set_results(mysql, default_charset);
|
||||||
DBUG_RETURN(1);
|
|
||||||
|
|
||||||
/* If a separate .sql file was opened, close it now */
|
/* If a separate .sql file was opened, close it now */
|
||||||
if (sql_file != md_result_file)
|
if (sql_file != md_result_file)
|
||||||
|
@ -1720,13 +1720,12 @@ void log_msg(const char *fmt, ...)
|
|||||||
int cat_file(DYNAMIC_STRING* ds, const char* filename)
|
int cat_file(DYNAMIC_STRING* ds, const char* filename)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
size_t len;
|
int len;
|
||||||
char buff[16384];
|
char buff[16384];
|
||||||
|
|
||||||
if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0)
|
if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
while((len= my_read(fd, (uchar*)&buff,
|
while((len= (int)my_read(fd, (uchar*)&buff, sizeof(buff)-1, MYF(0))) > 0)
|
||||||
sizeof(buff)-1, MYF(0))) > 0)
|
|
||||||
{
|
{
|
||||||
char *p= buff, *start= buff,*end=buff+len;
|
char *p= buff, *start= buff,*end=buff+len;
|
||||||
while (p < end)
|
while (p < end)
|
||||||
|
@ -41,4 +41,3 @@ SET(WSREP_PROC_INFO ${WITH_WSREP})
|
|||||||
IF(WITH_WSREP)
|
IF(WITH_WSREP)
|
||||||
SET(WSREP_PATCH_VERSION "wsrep_${WSREP_VERSION}")
|
SET(WSREP_PATCH_VERSION "wsrep_${WSREP_VERSION}")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
@ -575,21 +575,4 @@
|
|||||||
#define __STDC_FORMAT_MACROS
|
#define __STDC_FORMAT_MACROS
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
@ -82,7 +82,7 @@ uintmax_t cur_page_num;
|
|||||||
/* Skip the checksum verification. */
|
/* Skip the checksum verification. */
|
||||||
static bool no_check;
|
static bool no_check;
|
||||||
/* Enabled for strict checksum verification. */
|
/* Enabled for strict checksum verification. */
|
||||||
bool strict_verify = 0;
|
bool strict_verify;
|
||||||
/* Enabled for rewrite checksum. */
|
/* Enabled for rewrite checksum. */
|
||||||
static bool do_write;
|
static bool do_write;
|
||||||
/* Mismatches count allowed (0 by default). */
|
/* 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");
|
fprintf(fil_out, "page_no\tdata_size\tn_recs\n");
|
||||||
while (it_page != index.leaves.end()) {
|
while (it_page != index.leaves.end()) {
|
||||||
const per_page_stats& stat = it_page->second;
|
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;
|
page_no = stat.right_page_no;
|
||||||
it_page = index.leaves.find(page_no);
|
it_page = index.leaves.find(page_no);
|
||||||
}
|
}
|
||||||
@ -315,12 +316,15 @@ void defrag_analysis(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (index.leaf_pages) {
|
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,
|
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(
|
void print_leaf_stats(
|
||||||
|
@ -27,101 +27,6 @@ IF(NOT WIN32)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
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(
|
INCLUDE_DIRECTORIES(
|
||||||
${CMAKE_SOURCE_DIR}/include
|
${CMAKE_SOURCE_DIR}/include
|
||||||
@ -154,7 +59,6 @@ MYSQL_ADD_EXECUTABLE(mariabackup
|
|||||||
innobackupex.cc
|
innobackupex.cc
|
||||||
changed_page_bitmap.cc
|
changed_page_bitmap.cc
|
||||||
datasink.c
|
datasink.c
|
||||||
${DS_ARCHIVE_SOURCE}
|
|
||||||
ds_buffer.c
|
ds_buffer.c
|
||||||
ds_compress.c
|
ds_compress.c
|
||||||
ds_local.c
|
ds_local.c
|
||||||
|
@ -450,7 +450,7 @@ datadir_iter_free(datadir_iter_t *it)
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
Holds the state needed to copy single data file. */
|
Holds the state needed to copy single data file. */
|
||||||
struct datafile_cur_t {
|
struct datafile_cur_t {
|
||||||
os_file_t file;
|
pfs_os_file_t file;
|
||||||
char rel_path[FN_REFLEN];
|
char rel_path[FN_REFLEN];
|
||||||
char abs_path[FN_REFLEN];
|
char abs_path[FN_REFLEN];
|
||||||
MY_STAT statinfo;
|
MY_STAT statinfo;
|
||||||
@ -1774,7 +1774,7 @@ copy_back()
|
|||||||
const char *ext_list[] = {"backup-my.cnf", "xtrabackup_logfile",
|
const char *ext_list[] = {"backup-my.cnf", "xtrabackup_logfile",
|
||||||
"xtrabackup_binary", "xtrabackup_binlog_info",
|
"xtrabackup_binary", "xtrabackup_binlog_info",
|
||||||
"xtrabackup_checkpoints", ".qp", ".pmap", ".tmp",
|
"xtrabackup_checkpoints", ".qp", ".pmap", ".tmp",
|
||||||
".xbcrypt", NULL};
|
NULL};
|
||||||
const char *filename;
|
const char *filename;
|
||||||
char c_tmp;
|
char c_tmp;
|
||||||
int i_tmp;
|
int i_tmp;
|
||||||
@ -1807,7 +1807,7 @@ copy_back()
|
|||||||
|
|
||||||
filename = base_name(node.filepath);
|
filename = base_name(node.filepath);
|
||||||
|
|
||||||
/* skip .qp and .xbcrypt files */
|
/* skip .qp files */
|
||||||
if (filename_matches(filename, ext_list)) {
|
if (filename_matches(filename, ext_list)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1899,24 +1899,8 @@ decrypt_decompress_file(const char *filepath, uint thread_n)
|
|||||||
|
|
||||||
cmd << IF_WIN("type ","cat ") << filepath;
|
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
|
if (opt_decompress
|
||||||
&& (ends_with(filepath, ".qp")
|
&& ends_with(filepath, ".qp")) {
|
||||||
|| (ends_with(filepath, ".qp.xbcrypt")
|
|
||||||
&& opt_decrypt))) {
|
|
||||||
cmd << " | qpress -dio ";
|
cmd << " | qpress -dio ";
|
||||||
dest_filepath[strlen(dest_filepath) - 3] = 0;
|
dest_filepath[strlen(dest_filepath) - 3] = 0;
|
||||||
if (needs_action) {
|
if (needs_action) {
|
||||||
@ -1967,8 +1951,7 @@ decrypt_decompress_thread_func(void *arg)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ends_with(node.filepath, ".qp")
|
if (!ends_with(node.filepath, ".qp")) {
|
||||||
&& !ends_with(node.filepath, ".xbcrypt")) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1435,9 +1435,7 @@ write_xtrabackup_info(MYSQL *connection)
|
|||||||
"partial = %s\n"
|
"partial = %s\n"
|
||||||
"incremental = %s\n"
|
"incremental = %s\n"
|
||||||
"format = %s\n"
|
"format = %s\n"
|
||||||
"compact = %s\n"
|
"compressed = %s\n",
|
||||||
"compressed = %s\n"
|
|
||||||
"encrypted = %s\n",
|
|
||||||
uuid, /* uuid */
|
uuid, /* uuid */
|
||||||
opt_history ? opt_history : "", /* name */
|
opt_history ? opt_history : "", /* name */
|
||||||
tool_name, /* tool_name */
|
tool_name, /* tool_name */
|
||||||
@ -1455,9 +1453,7 @@ write_xtrabackup_info(MYSQL *connection)
|
|||||||
is_partial? "Y" : "N",
|
is_partial? "Y" : "N",
|
||||||
xtrabackup_incremental ? "Y" : "N", /* incremental */
|
xtrabackup_incremental ? "Y" : "N", /* incremental */
|
||||||
xb_stream_name[xtrabackup_stream_fmt], /* format */
|
xb_stream_name[xtrabackup_stream_fmt], /* format */
|
||||||
"N", /* compact */
|
xtrabackup_compress ? "compressed" : "N"); /* compressed */
|
||||||
xtrabackup_compress ? "compressed" : "N", /* compressed */
|
|
||||||
xtrabackup_encrypt ? "Y" : "N"); /* encrypted */
|
|
||||||
|
|
||||||
if (!opt_history) {
|
if (!opt_history) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -1483,9 +1479,7 @@ write_xtrabackup_info(MYSQL *connection)
|
|||||||
"partial ENUM('Y', 'N') DEFAULT NULL,"
|
"partial ENUM('Y', 'N') DEFAULT NULL,"
|
||||||
"incremental ENUM('Y', 'N') DEFAULT NULL,"
|
"incremental ENUM('Y', 'N') DEFAULT NULL,"
|
||||||
"format ENUM('file', 'tar', 'xbstream') DEFAULT NULL,"
|
"format ENUM('file', 'tar', 'xbstream') DEFAULT NULL,"
|
||||||
"compact ENUM('Y', 'N') DEFAULT NULL,"
|
"compressed ENUM('Y', 'N') DEFAULT NULL"
|
||||||
"compressed ENUM('Y', 'N') DEFAULT NULL,"
|
|
||||||
"encrypted ENUM('Y', 'N') DEFAULT NULL"
|
|
||||||
") CHARACTER SET utf8 ENGINE=innodb", false);
|
") CHARACTER SET utf8 ENGINE=innodb", false);
|
||||||
|
|
||||||
|
|
||||||
@ -1495,8 +1489,8 @@ write_xtrabackup_info(MYSQL *connection)
|
|||||||
<< "uuid, name, tool_name, tool_command, tool_version,"
|
<< "uuid, name, tool_name, tool_command, tool_version,"
|
||||||
<< "ibbackup_version, server_version, start_time, end_time,"
|
<< "ibbackup_version, server_version, start_time, end_time,"
|
||||||
<< "lock_time, binlog_pos, innodb_from_lsn, innodb_to_lsn,"
|
<< "lock_time, binlog_pos, innodb_from_lsn, innodb_to_lsn,"
|
||||||
<< "partial, incremental, format, compact, compressed, "
|
<< "partial, incremental, format, compressed) "
|
||||||
<< "encrypted) values("
|
<< "values("
|
||||||
<< escape_and_quote(connection, uuid) << ","
|
<< escape_and_quote(connection, uuid) << ","
|
||||||
<< escape_and_quote(connection, opt_history) << ","
|
<< escape_and_quote(connection, opt_history) << ","
|
||||||
<< escape_and_quote(connection, tool_name) << ","
|
<< escape_and_quote(connection, tool_name) << ","
|
||||||
@ -1513,9 +1507,7 @@ write_xtrabackup_info(MYSQL *connection)
|
|||||||
<< ESCAPE_BOOL(is_partial) << ","
|
<< ESCAPE_BOOL(is_partial) << ","
|
||||||
<< ESCAPE_BOOL(xtrabackup_incremental)<< ","
|
<< ESCAPE_BOOL(xtrabackup_incremental)<< ","
|
||||||
<< escape_and_quote(connection,xb_stream_name[xtrabackup_stream_fmt]) <<","
|
<< escape_and_quote(connection,xb_stream_name[xtrabackup_stream_fmt]) <<","
|
||||||
<< ESCAPE_BOOL(false) << ","
|
<< ESCAPE_BOOL(xtrabackup_compress) << ")";
|
||||||
<< ESCAPE_BOOL(xtrabackup_compress) << ","
|
|
||||||
<< ESCAPE_BOOL(xtrabackup_encrypt) <<")";
|
|
||||||
|
|
||||||
xb_mysql_query(mysql_connection, oss.str().c_str(), false);
|
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) {
|
if (strncmp(*argv, "--password", strlen("--password")) == 0) {
|
||||||
arg = "--password=...";
|
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,
|
left-= ut_snprintf(buf + len - left, left,
|
||||||
"%s%c", arg, argc > 1 ? ' ' : 0);
|
"%s%c", arg, argc > 1 ? ' ' : 0);
|
||||||
++argv; --argc;
|
++argv; --argc;
|
||||||
|
@ -35,7 +35,7 @@ Remove these on the first opportunity, i.e. single-binary XtraBackup. */
|
|||||||
/** Single bitmap file information */
|
/** Single bitmap file information */
|
||||||
struct log_online_bitmap_file_t {
|
struct log_online_bitmap_file_t {
|
||||||
char name[FN_REFLEN]; /*!< Name with full path */
|
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 size; /*!< Size of the file */
|
||||||
ib_uint64_t offset; /*!< Offset of the next read,
|
ib_uint64_t offset; /*!< Offset of the next read,
|
||||||
or count of already-read bytes
|
or count of already-read bytes
|
||||||
|
@ -30,4 +30,4 @@ ENDIF()
|
|||||||
IF(HAVE_CLMUL_INSTRUCTION)
|
IF(HAVE_CLMUL_INSTRUCTION)
|
||||||
ADD_DEFINITIONS(-DHAVE_CLMUL_INSTRUCTION)
|
ADD_DEFINITIONS(-DHAVE_CLMUL_INSTRUCTION)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ADD_LIBRARY(crc crc_glue.c crc-intel-pclmul.c)
|
ADD_LIBRARY(crc STATIC crc_glue.c crc-intel-pclmul.c)
|
||||||
|
@ -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
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
*******************************************************/
|
*******************************************************/
|
||||||
|
#include "my_config.h"
|
||||||
#include "crc_glue.h"
|
#include "crc_glue.h"
|
||||||
#include "crc-intel-pclmul.h"
|
#include "crc-intel-pclmul.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -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
|
|
@ -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*/
|
|
@ -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
|
|
@ -126,7 +126,6 @@ void encryption_plugin_prepare_init(int argc, char **argv)
|
|||||||
|
|
||||||
if (!xb_plugin_load)
|
if (!xb_plugin_load)
|
||||||
{
|
{
|
||||||
/* This prevents crashes e.g in --stats with wrong my.cnf*/
|
|
||||||
finalize_encryption_plugin(0);
|
finalize_encryption_plugin(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|||||||
#include "read_filt.h"
|
#include "read_filt.h"
|
||||||
|
|
||||||
struct xb_fil_cur_t {
|
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 */
|
fil_node_t* node; /*!< source tablespace node */
|
||||||
char rel_path[FN_REFLEN];
|
char rel_path[FN_REFLEN];
|
||||||
/*!< normalized file path */
|
/*!< normalized file path */
|
||||||
|
@ -101,8 +101,6 @@ char *opt_ibx_login_path = NULL;
|
|||||||
ulong opt_ibx_lock_wait_query_type;
|
ulong opt_ibx_lock_wait_query_type;
|
||||||
ulong opt_ibx_kill_long_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_kill_long_queries_timeout = 0;
|
||||||
uint opt_ibx_lock_wait_timeout = 0;
|
uint opt_ibx_lock_wait_timeout = 0;
|
||||||
uint opt_ibx_lock_wait_threshold = 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;
|
uint opt_ibx_safe_slave_backup_timeout = 0;
|
||||||
|
|
||||||
const char *opt_ibx_history = NULL;
|
const char *opt_ibx_history = NULL;
|
||||||
bool opt_ibx_decrypt = false;
|
|
||||||
|
|
||||||
char *opt_ibx_include = NULL;
|
char *opt_ibx_include = NULL;
|
||||||
char *opt_ibx_databases = NULL;
|
char *opt_ibx_databases = NULL;
|
||||||
@ -121,15 +118,9 @@ char *ibx_backup_directory = NULL;
|
|||||||
|
|
||||||
/* copy of proxied xtrabackup options */
|
/* copy of proxied xtrabackup options */
|
||||||
my_bool ibx_xb_close_files;
|
my_bool ibx_xb_close_files;
|
||||||
my_bool ibx_xtrabackup_compact;
|
|
||||||
const char *ibx_xtrabackup_compress_alg;
|
const char *ibx_xtrabackup_compress_alg;
|
||||||
uint ibx_xtrabackup_compress_threads;
|
uint ibx_xtrabackup_compress_threads;
|
||||||
ulonglong ibx_xtrabackup_compress_chunk_size;
|
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;
|
my_bool ibx_xtrabackup_export;
|
||||||
char *ibx_xtrabackup_extra_lsndir;
|
char *ibx_xtrabackup_extra_lsndir;
|
||||||
char *ibx_xtrabackup_incremental_basedir;
|
char *ibx_xtrabackup_incremental_basedir;
|
||||||
@ -138,8 +129,6 @@ my_bool ibx_xtrabackup_incremental_force_scan;
|
|||||||
ulint ibx_xtrabackup_log_copy_interval;
|
ulint ibx_xtrabackup_log_copy_interval;
|
||||||
char *ibx_xtrabackup_incremental;
|
char *ibx_xtrabackup_incremental;
|
||||||
int ibx_xtrabackup_parallel;
|
int ibx_xtrabackup_parallel;
|
||||||
my_bool ibx_xtrabackup_rebuild_indexes;
|
|
||||||
ulint ibx_xtrabackup_rebuild_threads;
|
|
||||||
char *ibx_xtrabackup_stream_str;
|
char *ibx_xtrabackup_stream_str;
|
||||||
char *ibx_xtrabackup_tables_file;
|
char *ibx_xtrabackup_tables_file;
|
||||||
long ibx_xtrabackup_throttle;
|
long ibx_xtrabackup_throttle;
|
||||||
@ -201,7 +190,6 @@ enum innobackupex_options
|
|||||||
OPT_NO_VERSION_CHECK,
|
OPT_NO_VERSION_CHECK,
|
||||||
OPT_NO_BACKUP_LOCKS,
|
OPT_NO_BACKUP_LOCKS,
|
||||||
OPT_DATABASES,
|
OPT_DATABASES,
|
||||||
OPT_DECRYPT,
|
|
||||||
OPT_DECOMPRESS,
|
OPT_DECOMPRESS,
|
||||||
|
|
||||||
/* options wich are passed directly to xtrabackup */
|
/* options wich are passed directly to xtrabackup */
|
||||||
@ -210,11 +198,6 @@ enum innobackupex_options
|
|||||||
OPT_COMPRESS,
|
OPT_COMPRESS,
|
||||||
OPT_COMPRESS_THREADS,
|
OPT_COMPRESS_THREADS,
|
||||||
OPT_COMPRESS_CHUNK_SIZE,
|
OPT_COMPRESS_CHUNK_SIZE,
|
||||||
OPT_ENCRYPT,
|
|
||||||
OPT_ENCRYPT_KEY,
|
|
||||||
OPT_ENCRYPT_KEY_FILE,
|
|
||||||
OPT_ENCRYPT_THREADS,
|
|
||||||
OPT_ENCRYPT_CHUNK_SIZE,
|
|
||||||
OPT_EXPORT,
|
OPT_EXPORT,
|
||||||
OPT_EXTRA_LSNDIR,
|
OPT_EXTRA_LSNDIR,
|
||||||
OPT_INCREMENTAL_BASEDIR,
|
OPT_INCREMENTAL_BASEDIR,
|
||||||
@ -430,12 +413,6 @@ static struct my_option ibx_long_options[] =
|
|||||||
(uchar*) &opt_ibx_incremental_history_uuid, 0, GET_STR,
|
(uchar*) &opt_ibx_incremental_history_uuid, 0, GET_STR,
|
||||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
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,
|
{"ftwrl-wait-query-type", OPT_LOCK_WAIT_QUERY_TYPE,
|
||||||
"This option specifies which types of queries are allowed to complete "
|
"This option specifies which types of queries are allowed to complete "
|
||||||
"before innobackupex will issue the global lock. Default is all.",
|
"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,
|
(uchar*) &ibx_xb_close_files, (uchar*) &ibx_xb_close_files, 0,
|
||||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 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", OPT_COMPRESS, "This option instructs xtrabackup to "
|
||||||
"compress backup copies of InnoDB data files. It is passed directly "
|
"compress backup copies of InnoDB data files. It is passed directly "
|
||||||
"to the xtrabackup child process. Try 'xtrabackup --help' for more "
|
"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,
|
(uchar*) &ibx_xtrabackup_compress_chunk_size,
|
||||||
0, GET_ULL, REQUIRED_ARG, (1 << 16), 1024, ULONGLONG_MAX, 0, 0, 0},
|
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", OPT_EXPORT, "This option is passed directly to xtrabackup's "
|
||||||
"--export option. It enables exporting individual tables for import "
|
"--export option. It enables exporting individual tables for import "
|
||||||
"into another server. See the xtrabackup documentation for details.",
|
"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\
|
SYNOPOSIS\n\
|
||||||
\n\
|
\n\
|
||||||
innobackupex [--compress] [--compress-threads=NUMBER-OF-THREADS] [--compress-chunk-size=CHUNK-SIZE]\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\
|
[--include=REGEXP] [--user=NAME]\n\
|
||||||
[--password=WORD] [--port=PORT] [--socket=SOCKET]\n\
|
[--password=WORD] [--port=PORT] [--socket=SOCKET]\n\
|
||||||
[--no-timestamp] [--ibbackup=IBBACKUP-BINARY]\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] [--incremental-basedir]\n\
|
||||||
[--incremental-dir] [--incremental-force-scan] [--incremental-lsn]\n\
|
[--incremental-dir] [--incremental-force-scan] [--incremental-lsn]\n\
|
||||||
[--incremental-history-name=NAME] [--incremental-history-uuid=UUID]\n\
|
[--incremental-history-name=NAME] [--incremental-history-uuid=UUID]\n\
|
||||||
[--close-files] [--compact] \n\
|
[--close-files]\n\
|
||||||
BACKUP-ROOT-DIR\n\
|
BACKUP-ROOT-DIR\n\
|
||||||
\n\
|
\n\
|
||||||
innobackupex --apply-log [--use-memory=B]\n\
|
innobackupex --apply-log [--use-memory=B]\n\
|
||||||
@ -760,8 +689,7 @@ innobackupex --copy-back [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME]
|
|||||||
\n\
|
\n\
|
||||||
innobackupex --move-back [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME] BACKUP-DIR\n\
|
innobackupex --move-back [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME] BACKUP-DIR\n\
|
||||||
\n\
|
\n\
|
||||||
innobackupex [--decompress] [--decrypt=ENCRYPTION-ALGORITHM]\n\
|
innobackupex [--decompress]\n\
|
||||||
[--encrypt-key=LITERAL-ENCRYPTION-KEY] | [--encryption-key-file=MY.KEY]\n\
|
|
||||||
[--parallel=NUMBER-OF-FORKS] BACKUP-DIR\n\
|
[--parallel=NUMBER-OF-FORKS] BACKUP-DIR\n\
|
||||||
\n\
|
\n\
|
||||||
DESCRIPTION\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\
|
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\
|
cases when there is not enough free disk space to copy files.\n\
|
||||||
\n\
|
\n\
|
||||||
The --decompress --decrypt command will decrypt and/or decompress a backup made\n\
|
The --decompress command will decompress a backup made\n\
|
||||||
with the --compress and/or --encrypt options. When decrypting, the encryption\n\
|
with the --compress option. The\n\
|
||||||
algorithm and key used when the backup was taken MUST be provided via the\n\
|
--parallel option will allow multiple files to be decompressed\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\
|
|
||||||
simultaneously. In order to decompress, the qpress utility MUST be installed\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\
|
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\
|
\n\
|
||||||
On success the exit code innobackupex is 0. A non-zero exit code \n\
|
On success the exit code innobackupex is 0. A non-zero exit code \n\
|
||||||
indicates an error.\n");
|
indicates an error.\n");
|
||||||
@ -839,18 +764,8 @@ ibx_get_one_option(int optid,
|
|||||||
opt_ibx_history = "";
|
opt_ibx_history = "";
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case OPT_STREAM:
|
||||||
if (!strcasecmp(argument, "tar"))
|
if (!strcasecmp(argument, "xbstream"))
|
||||||
xtrabackup_stream_fmt = XB_STREAM_FMT_TAR;
|
|
||||||
else if (!strcasecmp(argument, "xbstream"))
|
|
||||||
xtrabackup_stream_fmt = XB_STREAM_FMT_XBSTREAM;
|
xtrabackup_stream_fmt = XB_STREAM_FMT_XBSTREAM;
|
||||||
else {
|
else {
|
||||||
ibx_msg("Invalid --stream argument: %s\n", argument);
|
ibx_msg("Invalid --stream argument: %s\n", argument);
|
||||||
@ -868,15 +783,6 @@ ibx_get_one_option(int optid,
|
|||||||
}
|
}
|
||||||
xtrabackup_compress = TRUE;
|
xtrabackup_compress = TRUE;
|
||||||
break;
|
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':
|
case 'p':
|
||||||
if (argument)
|
if (argument)
|
||||||
{
|
{
|
||||||
@ -930,7 +836,7 @@ ibx_handle_options(int *argc, char ***argv)
|
|||||||
ibx_mode = IBX_MODE_COPY_BACK;
|
ibx_mode = IBX_MODE_COPY_BACK;
|
||||||
} else if (opt_ibx_move_back) {
|
} else if (opt_ibx_move_back) {
|
||||||
ibx_mode = IBX_MODE_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;
|
ibx_mode = IBX_MODE_DECRYPT_DECOMPRESS;
|
||||||
} else {
|
} else {
|
||||||
ibx_mode = IBX_MODE_BACKUP;
|
ibx_mode = IBX_MODE_BACKUP;
|
||||||
@ -1008,8 +914,6 @@ ibx_init()
|
|||||||
opt_lock_wait_query_type = opt_ibx_lock_wait_query_type;
|
opt_lock_wait_query_type = opt_ibx_lock_wait_query_type;
|
||||||
opt_kill_long_query_type = opt_ibx_kill_long_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_kill_long_queries_timeout = opt_ibx_kill_long_queries_timeout;
|
||||||
opt_lock_wait_timeout = opt_ibx_lock_wait_timeout;
|
opt_lock_wait_timeout = opt_ibx_lock_wait_timeout;
|
||||||
opt_lock_wait_threshold = opt_ibx_lock_wait_threshold;
|
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_safe_slave_backup_timeout = opt_ibx_safe_slave_backup_timeout;
|
||||||
|
|
||||||
opt_history = opt_ibx_history;
|
opt_history = opt_ibx_history;
|
||||||
opt_decrypt = opt_ibx_decrypt;
|
|
||||||
|
|
||||||
/* setup xtrabackup options */
|
/* setup xtrabackup options */
|
||||||
xb_close_files = ibx_xb_close_files;
|
xb_close_files = ibx_xb_close_files;
|
||||||
xtrabackup_compress_alg = ibx_xtrabackup_compress_alg;
|
xtrabackup_compress_alg = ibx_xtrabackup_compress_alg;
|
||||||
xtrabackup_compress_threads = ibx_xtrabackup_compress_threads;
|
xtrabackup_compress_threads = ibx_xtrabackup_compress_threads;
|
||||||
xtrabackup_compress_chunk_size = ibx_xtrabackup_compress_chunk_size;
|
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_export = ibx_xtrabackup_export;
|
||||||
xtrabackup_extra_lsndir = ibx_xtrabackup_extra_lsndir;
|
xtrabackup_extra_lsndir = ibx_xtrabackup_extra_lsndir;
|
||||||
xtrabackup_incremental_basedir = ibx_xtrabackup_incremental_basedir;
|
xtrabackup_incremental_basedir = ibx_xtrabackup_incremental_basedir;
|
||||||
@ -1109,7 +1007,7 @@ ibx_init()
|
|||||||
case IBX_MODE_DECRYPT_DECOMPRESS:
|
case IBX_MODE_DECRYPT_DECOMPRESS:
|
||||||
xtrabackup_decrypt_decompress = TRUE;
|
xtrabackup_decrypt_decompress = TRUE;
|
||||||
xtrabackup_target_dir = ibx_position_arg;
|
xtrabackup_target_dir = ibx_position_arg;
|
||||||
run = "decrypt and decompress";
|
run = "decompress";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ut_error;
|
ut_error;
|
||||||
|
@ -23,17 +23,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|||||||
|
|
||||||
|
|
||||||
extern void os_io_init_simple(void);
|
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 const char *innodb_checksum_algorithm_names[];
|
||||||
extern TYPELIB innodb_checksum_algorithm_typelib;
|
extern TYPELIB innodb_checksum_algorithm_typelib;
|
||||||
extern dberr_t open_or_create_data_files(
|
extern dberr_t open_or_create_data_files(
|
||||||
ibool* create_new_db,
|
bool* create_new_db,
|
||||||
#ifdef UNIV_LOG_ARCHIVE
|
#ifdef UNIV_LOG_ARCHIVE
|
||||||
lsn_t* min_arch_log_no,
|
lsn_t* min_arch_log_no,
|
||||||
lsn_t* max_arch_log_no,
|
lsn_t* max_arch_log_no,
|
||||||
#endif
|
#endif
|
||||||
lsn_t* min_flushed_lsn,
|
lsn_t* flushed_lsn,
|
||||||
lsn_t* max_flushed_lsn,
|
|
||||||
ulint* sum_of_new_sizes)
|
ulint* sum_of_new_sizes)
|
||||||
;
|
;
|
||||||
int
|
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_dir_t dir, /*!< in: directory stream */
|
||||||
os_file_stat_t* info) /*!< in/out: buffer where the
|
os_file_stat_t* info) /*!< in/out: buffer where the
|
||||||
info is returned */;
|
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_t*
|
||||||
fil_space_get_by_name(const char *);
|
fil_space_get_by_name(const char *);
|
||||||
ibool
|
ibool
|
||||||
@ -66,7 +52,6 @@ void
|
|||||||
innodb_log_checksum_func_update(
|
innodb_log_checksum_func_update(
|
||||||
/*============================*/
|
/*============================*/
|
||||||
ulint algorithm) /*!< in: algorithm */;
|
ulint algorithm) /*!< in: algorithm */;
|
||||||
dberr_t recv_find_max_checkpoint(log_group_t** max_group, ulint* max_field);
|
|
||||||
dberr_t
|
dberr_t
|
||||||
srv_undo_tablespaces_init(
|
srv_undo_tablespaces_init(
|
||||||
/*======================*/
|
/*======================*/
|
||||||
|
@ -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);
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -25,9 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|||||||
#include <my_pthread.h>
|
#include <my_pthread.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "xbstream.h"
|
#include "xbstream.h"
|
||||||
#include "xbcrypt_common.h"
|
|
||||||
#include "datasink.h"
|
#include "datasink.h"
|
||||||
#include "ds_decrypt.h"
|
|
||||||
#include "crc_glue.h"
|
#include "crc_glue.h"
|
||||||
|
|
||||||
#define XBSTREAM_VERSION "1.0"
|
#define XBSTREAM_VERSION "1.0"
|
||||||
@ -41,33 +39,18 @@ typedef enum {
|
|||||||
RUN_MODE_EXTRACT
|
RUN_MODE_EXTRACT
|
||||||
} run_mode_t;
|
} 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
|
/* Need the following definitions to avoid linking with ds_*.o and their link
|
||||||
dependencies */
|
dependencies */
|
||||||
datasink_t datasink_archive;
|
datasink_t datasink_archive;
|
||||||
datasink_t datasink_xbstream;
|
datasink_t datasink_xbstream;
|
||||||
datasink_t datasink_compress;
|
datasink_t datasink_compress;
|
||||||
datasink_t datasink_tmpfile;
|
datasink_t datasink_tmpfile;
|
||||||
datasink_t datasink_encrypt;
|
|
||||||
datasink_t datasink_buffer;
|
datasink_t datasink_buffer;
|
||||||
|
|
||||||
static run_mode_t opt_mode;
|
static run_mode_t opt_mode;
|
||||||
static char * opt_directory = NULL;
|
static char * opt_directory = NULL;
|
||||||
static my_bool opt_verbose = 0;
|
static my_bool opt_verbose = 0;
|
||||||
static int opt_parallel = 1;
|
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[] =
|
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.",
|
{"parallel", 'p', "Number of worker threads for reading / writing.",
|
||||||
&opt_parallel, &opt_parallel, 0, GET_INT, REQUIRED_ARG,
|
&opt_parallel, &opt_parallel, 0, GET_INT, REQUIRED_ARG,
|
||||||
1, 1, INT_MAX, 0, 0, 0},
|
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}
|
{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;
|
HASH *filehash;
|
||||||
xb_rstream_t *stream;
|
xb_rstream_t *stream;
|
||||||
ds_ctxt_t *ds_ctxt;
|
ds_ctxt_t *ds_ctxt;
|
||||||
ds_ctxt_t *ds_decrypt_ctxt;
|
|
||||||
pthread_mutex_t *mutex;
|
pthread_mutex_t *mutex;
|
||||||
} extract_ctxt_t;
|
} extract_ctxt_t;
|
||||||
|
|
||||||
@ -348,19 +316,6 @@ err:
|
|||||||
return 1;
|
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
|
static
|
||||||
file_entry_t *
|
file_entry_t *
|
||||||
file_entry_new(extract_ctxt_t *ctxt, const char *path, uint pathlen)
|
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;
|
entry->pathlen = pathlen;
|
||||||
|
|
||||||
if (ctxt->ds_decrypt_ctxt && ends_with(path, ".xbcrypt")) {
|
file = ds_open(ctxt->ds_ctxt, path, NULL);
|
||||||
file = ds_open(ctxt->ds_decrypt_ctxt, path, NULL);
|
|
||||||
} else {
|
|
||||||
file = ds_open(ctxt->ds_ctxt, path, NULL);
|
|
||||||
}
|
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
msg("%s: failed to create file.\n", my_progname);
|
msg("%s: failed to create file.\n", my_progname);
|
||||||
goto err;
|
goto err;
|
||||||
@ -534,7 +486,6 @@ mode_extract(int n_threads, int argc __attribute__((unused)),
|
|||||||
xb_rstream_t *stream = NULL;
|
xb_rstream_t *stream = NULL;
|
||||||
HASH filehash;
|
HASH filehash;
|
||||||
ds_ctxt_t *ds_ctxt = NULL;
|
ds_ctxt_t *ds_ctxt = NULL;
|
||||||
ds_ctxt_t *ds_decrypt_ctxt = NULL;
|
|
||||||
extract_ctxt_t ctxt;
|
extract_ctxt_t ctxt;
|
||||||
int i;
|
int i;
|
||||||
pthread_t *tids = NULL;
|
pthread_t *tids = NULL;
|
||||||
@ -574,7 +525,6 @@ mode_extract(int n_threads, int argc __attribute__((unused)),
|
|||||||
ctxt.stream = stream;
|
ctxt.stream = stream;
|
||||||
ctxt.filehash = &filehash;
|
ctxt.filehash = &filehash;
|
||||||
ctxt.ds_ctxt = ds_ctxt;
|
ctxt.ds_ctxt = ds_ctxt;
|
||||||
ctxt.ds_decrypt_ctxt = ds_decrypt_ctxt;
|
|
||||||
ctxt.mutex = &mutex;
|
ctxt.mutex = &mutex;
|
||||||
|
|
||||||
tids = malloc(sizeof(pthread_t) * n_threads);
|
tids = malloc(sizeof(pthread_t) * n_threads);
|
||||||
@ -604,9 +554,6 @@ exit:
|
|||||||
if (ds_ctxt != NULL) {
|
if (ds_ctxt != NULL) {
|
||||||
ds_destroy(ds_ctxt);
|
ds_destroy(ds_ctxt);
|
||||||
}
|
}
|
||||||
if (ds_decrypt_ctxt) {
|
|
||||||
ds_destroy(ds_decrypt_ctxt);
|
|
||||||
}
|
|
||||||
xb_stream_read_done(stream);
|
xb_stream_read_done(stream);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -42,7 +42,6 @@ typedef struct xb_wstream_file_struct xb_wstream_file_t;
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XB_STREAM_FMT_NONE,
|
XB_STREAM_FMT_NONE,
|
||||||
XB_STREAM_FMT_TAR,
|
|
||||||
XB_STREAM_FMT_XBSTREAM
|
XB_STREAM_FMT_XBSTREAM
|
||||||
} xb_stream_fmt_t;
|
} xb_stream_fmt_t;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|||||||
#include "changed_page_bitmap.h"
|
#include "changed_page_bitmap.h"
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
#define XB_FILE_UNDEFINED NULL
|
#define XB_FILE_UNDEFINED INVALID_HANDLE_VALUE
|
||||||
#else
|
#else
|
||||||
#define XB_FILE_UNDEFINED (-1)
|
#define XB_FILE_UNDEFINED (-1)
|
||||||
#endif
|
#endif
|
||||||
@ -81,7 +81,6 @@ extern char *xtrabackup_tables_exclude;
|
|||||||
extern char *xtrabackup_databases_exclude;
|
extern char *xtrabackup_databases_exclude;
|
||||||
|
|
||||||
extern ibool xtrabackup_compress;
|
extern ibool xtrabackup_compress;
|
||||||
extern ibool xtrabackup_encrypt;
|
|
||||||
|
|
||||||
extern my_bool xtrabackup_backup;
|
extern my_bool xtrabackup_backup;
|
||||||
extern my_bool xtrabackup_prepare;
|
extern my_bool xtrabackup_prepare;
|
||||||
@ -92,15 +91,10 @@ extern my_bool xtrabackup_decrypt_decompress;
|
|||||||
|
|
||||||
extern char *innobase_data_file_path;
|
extern char *innobase_data_file_path;
|
||||||
extern char *innobase_doublewrite_file;
|
extern char *innobase_doublewrite_file;
|
||||||
extern char *xtrabackup_encrypt_key;
|
|
||||||
extern char *xtrabackup_encrypt_key_file;
|
|
||||||
extern longlong innobase_log_file_size;
|
extern longlong innobase_log_file_size;
|
||||||
extern long innobase_log_files_in_group;
|
extern long innobase_log_files_in_group;
|
||||||
extern longlong innobase_page_size;
|
extern longlong innobase_page_size;
|
||||||
|
|
||||||
extern const char *xtrabackup_encrypt_algo_names[];
|
|
||||||
extern TYPELIB xtrabackup_encrypt_algo_typelib;
|
|
||||||
|
|
||||||
extern int xtrabackup_parallel;
|
extern int xtrabackup_parallel;
|
||||||
|
|
||||||
extern my_bool xb_close_files;
|
extern my_bool xb_close_files;
|
||||||
@ -113,9 +107,6 @@ extern "C"{
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
extern ulong xtrabackup_encrypt_algo;
|
|
||||||
extern uint xtrabackup_encrypt_threads;
|
|
||||||
extern ulonglong xtrabackup_encrypt_chunk_size;
|
|
||||||
extern my_bool xtrabackup_export;
|
extern my_bool xtrabackup_export;
|
||||||
extern char *xtrabackup_incremental_basedir;
|
extern char *xtrabackup_incremental_basedir;
|
||||||
extern char *xtrabackup_extra_lsndir;
|
extern char *xtrabackup_extra_lsndir;
|
||||||
@ -158,8 +149,6 @@ extern TYPELIB query_type_typelib;
|
|||||||
extern ulong opt_lock_wait_query_type;
|
extern ulong opt_lock_wait_query_type;
|
||||||
extern ulong opt_kill_long_query_type;
|
extern ulong opt_kill_long_query_type;
|
||||||
|
|
||||||
extern ulong opt_decrypt_algo;
|
|
||||||
|
|
||||||
extern uint opt_kill_long_queries_timeout;
|
extern uint opt_kill_long_queries_timeout;
|
||||||
extern uint opt_lock_wait_timeout;
|
extern uint opt_lock_wait_timeout;
|
||||||
extern uint opt_lock_wait_threshold;
|
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 uint opt_safe_slave_backup_timeout;
|
||||||
|
|
||||||
extern const char *opt_history;
|
extern const char *opt_history;
|
||||||
extern my_bool opt_decrypt;
|
|
||||||
|
|
||||||
enum binlog_info_enum { BINLOG_INFO_OFF, BINLOG_INFO_LOCKLESS, BINLOG_INFO_ON,
|
enum binlog_info_enum { BINLOG_INFO_OFF, BINLOG_INFO_LOCKLESS, BINLOG_INFO_ON,
|
||||||
BINLOG_INFO_AUTO};
|
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);
|
fil_node_t *datafiles_iter_next(datafiles_iter_t *it);
|
||||||
void datafiles_iter_free(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
|
Reads the space flags from a given data file and returns the compressed
|
||||||
page size, or 0 if the space is not 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)
|
Checks if a table specified as a name in the form "database/name" (InnoDB 5.6)
|
||||||
|
@ -174,6 +174,7 @@ register char **argv[];
|
|||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
version=1;
|
version=1;
|
||||||
|
/* fall through */
|
||||||
case 'I':
|
case 'I':
|
||||||
case '?':
|
case '?':
|
||||||
help=1; /* Help text written */
|
help=1; /* Help text written */
|
||||||
|
@ -949,6 +949,12 @@ extern ulonglong my_getcputime(void);
|
|||||||
#define hrtime_sec_part(X) ((ulong)((X).val % HRTIME_RESOLUTION))
|
#define hrtime_sec_part(X) ((ulong)((X).val % HRTIME_RESOLUTION))
|
||||||
#define my_time(X) hrtime_to_time(my_hrtime())
|
#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
|
#ifdef HAVE_SYS_MMAN_H
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ enum enum_server_command
|
|||||||
COM_UNIMPLEMENTED,
|
COM_UNIMPLEMENTED,
|
||||||
COM_RESET_CONNECTION,
|
COM_RESET_CONNECTION,
|
||||||
COM_MDB_GAP_BEG,
|
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_WORKER=251,
|
||||||
COM_SLAVE_IO=252,
|
COM_SLAVE_IO=252,
|
||||||
COM_SLAVE_SQL=253,
|
COM_SLAVE_SQL=253,
|
||||||
|
@ -115,7 +115,8 @@ enum enum_server_command
|
|||||||
COM_RESET_CONNECTION,
|
COM_RESET_CONNECTION,
|
||||||
/* don't forget to update const char *command_name[] in sql_parse.cc */
|
/* don't forget to update const char *command_name[] in sql_parse.cc */
|
||||||
COM_MDB_GAP_BEG,
|
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_WORKER=251,
|
||||||
COM_SLAVE_IO=252,
|
COM_SLAVE_IO=252,
|
||||||
COM_SLAVE_SQL=253,
|
COM_SLAVE_SQL=253,
|
||||||
@ -136,6 +137,13 @@ enum enum_indicator_type
|
|||||||
STMT_INDICATOR_IGNORE
|
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 */
|
/* sql type stored in .frm files for virtual fields */
|
||||||
#define MYSQL_TYPE_VIRTUAL 245
|
#define MYSQL_TYPE_VIRTUAL 245
|
||||||
/*
|
/*
|
||||||
@ -311,7 +319,8 @@ enum enum_indicator_type
|
|||||||
CLIENT_SESSION_TRACK |\
|
CLIENT_SESSION_TRACK |\
|
||||||
CLIENT_DEPRECATE_EOF |\
|
CLIENT_DEPRECATE_EOF |\
|
||||||
CLIENT_CONNECT_ATTRS |\
|
CLIENT_CONNECT_ATTRS |\
|
||||||
MARIADB_CLIENT_COM_MULTI)
|
MARIADB_CLIENT_COM_MULTI |\
|
||||||
|
MARIADB_CLIENT_STMT_BULK_OPERATIONS)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
To be added later:
|
To be added later:
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 467a193b399dfda41d87368a898e9550d754fa14
|
Subproject commit ff4bfdf1caf2e0a47382fdbe6d796d0e63ec1062
|
@ -1404,7 +1404,7 @@ void set_stmt_errmsg(MYSQL_STMT *stmt, NET *net)
|
|||||||
DBUG_ASSERT(stmt != 0);
|
DBUG_ASSERT(stmt != 0);
|
||||||
|
|
||||||
stmt->last_errno= net->last_errno;
|
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->last_error, net->last_error);
|
||||||
strmov(stmt->sqlstate, net->sqlstate);
|
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 */
|
uchar buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */
|
||||||
|
|
||||||
if ((rc= reset_stmt_handle(stmt, RESET_ALL_BUFFERS | RESET_CLEAR_ERROR)))
|
reset_stmt_handle(stmt, RESET_ALL_BUFFERS | RESET_CLEAR_ERROR);
|
||||||
return rc;
|
|
||||||
|
|
||||||
int4store(buff, stmt->stmt_id);
|
int4store(buff, stmt->stmt_id);
|
||||||
if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)))
|
if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)))
|
||||||
|
16
mysql-test/include/innodb_page_size.combinations
Normal file
16
mysql-test/include/innodb_page_size.combinations
Normal 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
|
4
mysql-test/include/innodb_page_size.inc
Normal file
4
mysql-test/include/innodb_page_size.inc
Normal 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
|
8
mysql-test/include/innodb_page_size_small.combinations
Normal file
8
mysql-test/include/innodb_page_size_small.combinations
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[16k]
|
||||||
|
innodb-page-size=16K
|
||||||
|
|
||||||
|
[8k]
|
||||||
|
innodb-page-size=8K
|
||||||
|
|
||||||
|
[4k]
|
||||||
|
innodb-page-size=4K
|
4
mysql-test/include/innodb_page_size_small.inc
Normal file
4
mysql-test/include/innodb_page_size_small.inc
Normal 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
|
@ -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/
|
--replace_regex /Duplicate entry '[^']+' for key/Duplicate entry '{ ' for key/
|
||||||
--error ER_DUP_ENTRY
|
--error ER_DUP_ENTRY
|
||||||
alter table t1 add unique(v);
|
alter table t1 add unique(v);
|
||||||
|
show warnings;
|
||||||
alter table t1 add key(v);
|
alter table t1 add key(v);
|
||||||
select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a';
|
select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a';
|
||||||
--replace_column 6 # 9 # 10 #
|
--replace_column 6 # 9 # 10 #
|
||||||
|
@ -208,6 +208,10 @@ sub mtr_report_test ($) {
|
|||||||
{
|
{
|
||||||
mtr_report("[ skipped ]");
|
mtr_report("[ skipped ]");
|
||||||
}
|
}
|
||||||
|
if ( $tinfo->{'warnings'} )
|
||||||
|
{
|
||||||
|
mtr_report($tinfo->{'warnings'});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elsif ($result eq 'MTR_RES_PASSED')
|
elsif ($result eq 'MTR_RES_PASSED')
|
||||||
{
|
{
|
||||||
|
@ -2794,15 +2794,26 @@ sub mysql_server_start($) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $mysqld_basedir= $mysqld->value('basedir');
|
my $mysqld_basedir= $mysqld->value('basedir');
|
||||||
|
my $extra_opts= get_extra_opts($mysqld, $tinfo);
|
||||||
|
|
||||||
if ( $basedir eq $mysqld_basedir )
|
if ( $basedir eq $mysqld_basedir )
|
||||||
{
|
{
|
||||||
if (! $opt_start_dirty) # If dirty, keep possibly grown system db
|
if (! $opt_start_dirty) # If dirty, keep possibly grown system db
|
||||||
{
|
{
|
||||||
# Copy datadir from installed system db
|
# Some InnoDB options are incompatible with the default bootstrap.
|
||||||
my $path= ($opt_parallel == 1) ? "$opt_vardir" : "$opt_vardir/..";
|
# If they are used, re-bootstrap
|
||||||
my $install_db= "$path/install.db";
|
if ( $extra_opts and
|
||||||
copytree($install_db, $datadir) if -d $install_db;
|
"@$extra_opts" =~ /--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)/ )
|
||||||
mtr_error("Failed to copy system db to '$datadir'") unless -d $datadir;
|
{
|
||||||
|
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
|
else
|
||||||
@ -2841,7 +2852,6 @@ sub mysql_server_start($) {
|
|||||||
|
|
||||||
if (!$opt_embedded_server)
|
if (!$opt_embedded_server)
|
||||||
{
|
{
|
||||||
my $extra_opts= get_extra_opts($mysqld, $tinfo);
|
|
||||||
mysqld_start($mysqld,$extra_opts);
|
mysqld_start($mysqld,$extra_opts);
|
||||||
|
|
||||||
# Save this test case information, so next can examine it
|
# Save this test case information, so next can examine it
|
||||||
@ -3065,7 +3075,7 @@ sub default_mysqld {
|
|||||||
|
|
||||||
|
|
||||||
sub mysql_install_db {
|
sub mysql_install_db {
|
||||||
my ($mysqld, $datadir)= @_;
|
my ($mysqld, $datadir, $extra_opts)= @_;
|
||||||
|
|
||||||
my $install_datadir= $datadir || $mysqld->value('datadir');
|
my $install_datadir= $datadir || $mysqld->value('datadir');
|
||||||
my $install_basedir= $mysqld->value('basedir');
|
my $install_basedir= $mysqld->value('basedir');
|
||||||
@ -3106,6 +3116,13 @@ sub mysql_install_db {
|
|||||||
mtr_add_arg($args, $extra_opt);
|
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.,
|
# If DISABLE_GRANT_OPTIONS is defined when the server is compiled (e.g.,
|
||||||
# configure --disable-grant-options), mysqld will not recognize the
|
# configure --disable-grant-options), mysqld will not recognize the
|
||||||
@ -3990,12 +4007,13 @@ sub run_testcase ($$) {
|
|||||||
{
|
{
|
||||||
my $res= $test->exit_status();
|
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
|
# If test case suceeded, but it has produced unexpected
|
||||||
# warnings, continue in $res == 1
|
# warnings, continue with $res == 1;
|
||||||
$res= 1;
|
# but if the test was skipped, it should remain skipped
|
||||||
resfile_output($tinfo->{'warnings'}) if $opt_resfile;
|
$res= 1 if $res == 0;
|
||||||
|
resfile_output($tinfo->{'warnings'}) if $opt_resfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $res == 0 )
|
if ( $res == 0 )
|
||||||
|
@ -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;
|
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
|
ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
select @@global.delay_key_write;
|
||||||
# End of MDEV-8948 ALTER ... INPLACE does work for BINARY, BLOB
|
@@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;
|
||||||
|
@ -614,22 +614,24 @@ ANALYZE
|
|||||||
},
|
},
|
||||||
"block-nl-join": {
|
"block-nl-join": {
|
||||||
"table": {
|
"table": {
|
||||||
"table_name": "<subquery2>",
|
"table_name": "t2",
|
||||||
"access_type": "ALL",
|
"access_type": "ALL",
|
||||||
"possible_keys": ["distinct_key"],
|
|
||||||
"r_loops": 1,
|
"r_loops": 1,
|
||||||
"rows": 2,
|
"rows": 2,
|
||||||
"r_rows": 2,
|
"r_rows": 2,
|
||||||
"r_total_time_ms": "REPLACED",
|
"r_total_time_ms": "REPLACED",
|
||||||
"filtered": 100,
|
"filtered": 100,
|
||||||
"r_filtered": 100
|
"r_filtered": 0,
|
||||||
|
"attached_condition": "<in_optimizer>(t2.b,t2.b in (subquery#2))"
|
||||||
},
|
},
|
||||||
"buffer_type": "flat",
|
"buffer_type": "flat",
|
||||||
"buffer_size": "256Kb",
|
"buffer_size": "256Kb",
|
||||||
"join_type": "BNL",
|
"join_type": "BNL",
|
||||||
"r_filtered": 100,
|
"attached_condition": "<in_optimizer>(t2.b,t2.b in (subquery#2))",
|
||||||
"materialized": {
|
"r_filtered": null
|
||||||
"unique": 1,
|
},
|
||||||
|
"subqueries": [
|
||||||
|
{
|
||||||
"query_block": {
|
"query_block": {
|
||||||
"select_id": 2,
|
"select_id": 2,
|
||||||
"r_loops": 1,
|
"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;
|
drop table t1,t2;
|
||||||
|
@ -667,7 +667,7 @@ create table t1 (a int);
|
|||||||
create table t1 select * from t1;
|
create table t1 select * from t1;
|
||||||
ERROR 42S01: Table 't1' already exists
|
ERROR 42S01: Table 't1' already exists
|
||||||
create table t2 union = (t1) select * from t1;
|
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;
|
flush tables with read lock;
|
||||||
unlock tables;
|
unlock tables;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
@ -701,7 +701,7 @@ create database mysqltest;
|
|||||||
use mysqltest;
|
use mysqltest;
|
||||||
create view v1 as select 'foo' from dual;
|
create view v1 as select 'foo' from dual;
|
||||||
create table t1 like v1;
|
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 view v1;
|
||||||
drop database mysqltest;
|
drop database mysqltest;
|
||||||
create database mysqltest;
|
create database mysqltest;
|
||||||
|
@ -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
|
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 temporary; Using filesort
|
||||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
|
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 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)
|
3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
|
||||||
explain
|
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
|
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 temporary; Using filesort
|
||||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
|
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 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)
|
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
|
# with clause in the specification of a derived table
|
||||||
|
@ -2916,5 +2916,64 @@ Handler_read_rnd_deleted 0
|
|||||||
Handler_read_rnd_next 27
|
Handler_read_rnd_next 27
|
||||||
deallocate prepare stmt1;
|
deallocate prepare stmt1;
|
||||||
drop table t1,t2;
|
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 optimizer_switch=@exit_optimizer_switch;
|
||||||
set join_cache_level=@exit_join_cache_level;
|
set join_cache_level=@exit_join_cache_level;
|
||||||
|
@ -60,7 +60,7 @@ DROP TABLE export;
|
|||||||
CREATE VIEW v1 AS SELECT 1;
|
CREATE VIEW v1 AS SELECT 1;
|
||||||
CREATE TEMPORARY TABLE t1 (a INT);
|
CREATE TEMPORARY TABLE t1 (a INT);
|
||||||
FLUSH TABLES v1 FOR EXPORT;
|
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;
|
FLUSH TABLES t1 FOR EXPORT;
|
||||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||||
FLUSH TABLES non_existent FOR EXPORT;
|
FLUSH TABLES non_existent FOR EXPORT;
|
||||||
|
@ -295,16 +295,16 @@ create view v1 as select 1;
|
|||||||
create view v2 as select * from t1;
|
create view v2 as select * from t1;
|
||||||
create view v3 as select * from v2;
|
create view v3 as select * from v2;
|
||||||
flush table v1, v2, v3 with read lock;
|
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;
|
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;
|
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;
|
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);
|
create temporary table v1 (a int);
|
||||||
flush table v1 with read lock;
|
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;
|
drop view v1;
|
||||||
create table v1 (a int);
|
create table v1 (a int);
|
||||||
flush table v1 with read lock;
|
flush table v1 with read lock;
|
||||||
|
@ -2448,6 +2448,15 @@ DROP TABLE t1;
|
|||||||
# End of 10.1 tests
|
# 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
|
# Start of 10.3 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -3570,6 +3570,153 @@ t1 CREATE TABLE `t1` (
|
|||||||
`c2` bigint(11) NOT NULL
|
`c2` bigint(11) NOT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
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
|
# MDEV-9406 CREATE TABLE..SELECT creates different columns for IFNULL() and equivalent COALESCE,CASE,IF
|
||||||
#
|
#
|
||||||
|
@ -880,3 +880,17 @@ SET @regCheck= '\\xE0\\x01';
|
|||||||
SELECT CAST(0xE001 AS BINARY) REGEXP @regCheck;
|
SELECT CAST(0xE001 AS BINARY) REGEXP @regCheck;
|
||||||
CAST(0xE001 AS BINARY) REGEXP @regCheck
|
CAST(0xE001 AS BINARY) REGEXP @regCheck
|
||||||
1
|
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
|
||||||
|
@ -1090,7 +1090,7 @@ t_nn CREATE TABLE `t_nn` (
|
|||||||
`c1` int(11) DEFAULT NULL
|
`c1` int(11) DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
SHOW CREATE VIEW mysqltest2.t_nn;
|
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;
|
SHOW CREATE VIEW mysqltest2.v_yy;
|
||||||
View Create View character_set_client collation_connection
|
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
|
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
|
`c1` int(11) DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
SHOW CREATE VIEW mysqltest2.t_nn;
|
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_nn;
|
||||||
DROP VIEW mysqltest2.v_yn;
|
DROP VIEW mysqltest2.v_yn;
|
||||||
DROP VIEW mysqltest2.v_ny;
|
DROP VIEW mysqltest2.v_ny;
|
||||||
|
@ -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
|
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
|
1 SIMPLE t2 range index_date_updated index_date_updated 13 NULL # Using index condition
|
||||||
drop table t0,t1,t2;
|
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;
|
||||||
|
@ -4,7 +4,7 @@ drop table if exists t1;
|
|||||||
create table t1 (n int);
|
create table t1 (n int);
|
||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
insert delayed into v1 values (1);
|
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 table t1;
|
||||||
drop view v1;
|
drop view v1;
|
||||||
CREATE DATABASE meow;
|
CREATE DATABASE meow;
|
||||||
|
@ -2337,4 +2337,99 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||||||
Warnings:
|
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`
|
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;
|
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;
|
SET optimizer_switch=@save_optimizer_switch;
|
||||||
|
@ -2348,6 +2348,101 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||||||
Warnings:
|
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`
|
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;
|
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 optimizer_switch=@save_optimizer_switch;
|
||||||
set join_cache_level=default;
|
set join_cache_level=default;
|
||||||
show variables like 'join_cache_level';
|
show variables like 'join_cache_level';
|
||||||
|
@ -425,7 +425,7 @@ c1
|
|||||||
bb
|
bb
|
||||||
cc
|
cc
|
||||||
Warnings:
|
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;
|
select * from v1 LIMIT ROWS EXAMINED 11;
|
||||||
c1
|
c1
|
||||||
bb
|
bb
|
||||||
@ -438,7 +438,8 @@ from (select * from t1
|
|||||||
where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 0)) as tmp
|
where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 0)) as tmp
|
||||||
LIMIT ROWS EXAMINED 11;
|
LIMIT ROWS EXAMINED 11;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
|
||||||
select *
|
select *
|
||||||
from (select * from t1
|
from (select * from t1
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
set @@global.log_output = 'TABLE';
|
set @@global.log_output = 'TABLE';
|
||||||
|
connect con1,localhost,root,,;
|
||||||
|
connect con2,localhost,root,,;
|
||||||
|
connection con1;
|
||||||
set session long_query_time=10;
|
set session long_query_time=10;
|
||||||
select get_lock('bug27638', 1);
|
select get_lock('bug27638', 1);
|
||||||
get_lock('bug27638', 1)
|
get_lock('bug27638', 1)
|
||||||
1
|
1
|
||||||
|
connection con2;
|
||||||
set session long_query_time=1;
|
set session long_query_time=1;
|
||||||
select get_lock('bug27638', 2);
|
select get_lock('bug27638', 2);
|
||||||
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)';
|
where sql_text = 'select get_lock(\'bug27638\', 101)';
|
||||||
qt sql_text
|
qt sql_text
|
||||||
OK select get_lock('bug27638', 101)
|
OK select get_lock('bug27638', 101)
|
||||||
|
connection con1;
|
||||||
select release_lock('bug27638');
|
select release_lock('bug27638');
|
||||||
release_lock('bug27638')
|
release_lock('bug27638')
|
||||||
1
|
1
|
||||||
|
connection default;
|
||||||
|
disconnect con1;
|
||||||
|
disconnect con2;
|
||||||
set @@global.log_output=default;
|
set @@global.log_output=default;
|
||||||
|
@ -3049,3 +3049,21 @@ SET DEBUG_SYNC= 'RESET';
|
|||||||
disconnect con1;
|
disconnect con1;
|
||||||
disconnect con2;
|
disconnect con2;
|
||||||
disconnect con3;
|
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;
|
||||||
|
@ -629,7 +629,7 @@ INSERT INTO t3 VALUES (3), (33);
|
|||||||
LOCK TABLES t3 READ;
|
LOCK TABLES t3 READ;
|
||||||
CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL) ENGINE=MERGE UNION=(t1,t2)
|
CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL) ENGINE=MERGE UNION=(t1,t2)
|
||||||
INSERT_METHOD=LAST SELECT * FROM t3;
|
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;
|
SELECT * FROM t4;
|
||||||
ERROR HY000: Table 't4' was not locked with LOCK TABLES
|
ERROR HY000: Table 't4' was not locked with LOCK TABLES
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
@ -702,11 +702,11 @@ create table t2 (a int);
|
|||||||
insert into t1 values (0);
|
insert into t1 values (0);
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
create table t3 engine=merge union=(t1, t2) select * from t1;
|
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;
|
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);
|
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;
|
drop table t1, t2;
|
||||||
create table t1 (
|
create table t1 (
|
||||||
a double(14,4),
|
a double(14,4),
|
||||||
@ -1176,7 +1176,7 @@ SHOW CREATE TABLE t3;
|
|||||||
ERROR 42S02: Table 'test.t3' doesn't exist
|
ERROR 42S02: Table 'test.t3' doesn't exist
|
||||||
CREATE TABLE t3 ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST
|
CREATE TABLE t3 ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST
|
||||||
SELECT * FROM t2;
|
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;
|
SHOW CREATE TABLE t3;
|
||||||
ERROR 42S02: Table 'test.t3' doesn't exist
|
ERROR 42S02: Table 'test.t3' doesn't exist
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
@ -3115,11 +3115,11 @@ DROP TABLE m2;
|
|||||||
#
|
#
|
||||||
CREATE TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
|
CREATE TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
|
||||||
INSERT_METHOD=LAST SELECT * FROM m1;
|
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)
|
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
|
||||||
INSERT_METHOD=LAST SELECT * FROM m1;
|
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;
|
CREATE TABLE m2 LIKE m1;
|
||||||
SHOW CREATE TABLE m2;
|
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)
|
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
|
||||||
INSERT_METHOD=LAST SELECT * FROM m1;
|
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;
|
CREATE TEMPORARY TABLE m2 LIKE m1;
|
||||||
SHOW CREATE TABLE m2;
|
SHOW CREATE TABLE m2;
|
||||||
|
@ -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
|
1 SIMPLE t1 ref v v 13 const # Using where; Using index
|
||||||
alter table t1 add unique(v);
|
alter table t1 add unique(v);
|
||||||
ERROR 23000: Duplicate entry '{ ' for key 'v_2'
|
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);
|
alter table t1 add key(v);
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1831 Duplicate index `v_2`. This is deprecated and will be disallowed in a future release
|
Note 1831 Duplicate index `v_2`. This is deprecated and will be disallowed in a future release
|
||||||
|
@ -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
|
1 SIMPLE t1 ref v v 13 const # Using where; Using index
|
||||||
alter table t1 add unique(v);
|
alter table t1 add unique(v);
|
||||||
ERROR 23000: Duplicate entry '{ ' for key 'v_2'
|
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);
|
alter table t1 add key(v);
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1831 Duplicate index `v_2`. This is deprecated and will be disallowed in a future release
|
Note 1831 Duplicate index `v_2`. This is deprecated and will be disallowed in a future release
|
||||||
|
@ -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
|
1 SIMPLE t1 ref v v 13 const # Using where; Using index
|
||||||
alter table t1 add unique(v);
|
alter table t1 add unique(v);
|
||||||
ERROR 23000: Duplicate entry '{ ' for key 'v_2'
|
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);
|
alter table t1 add key(v);
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1831 Duplicate index `v_2`. This is deprecated and will be disallowed in a future release
|
Note 1831 Duplicate index `v_2`. This is deprecated and will be disallowed in a future release
|
||||||
|
@ -29,3 +29,15 @@ Table Op Msg_type Msg_text
|
|||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
disconnect insertConn;
|
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;
|
||||||
|
@ -1404,7 +1404,7 @@ performance-schema-max-rwlock-instances -1
|
|||||||
performance-schema-max-socket-classes 10
|
performance-schema-max-socket-classes 10
|
||||||
performance-schema-max-socket-instances -1
|
performance-schema-max-socket-instances -1
|
||||||
performance-schema-max-stage-classes 150
|
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-handles -1
|
||||||
performance-schema-max-table-instances -1
|
performance-schema-max-table-instances -1
|
||||||
performance-schema-max-thread-classes 50
|
performance-schema-max-thread-classes 50
|
||||||
|
@ -51,3 +51,50 @@ execute stmt;
|
|||||||
execute stmt;
|
execute stmt;
|
||||||
deallocate prepare stmt;
|
deallocate prepare stmt;
|
||||||
drop table test_data;
|
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;
|
||||||
|
@ -74,7 +74,7 @@ End of 4.1 tests
|
|||||||
create table t1(f1 int);
|
create table t1(f1 int);
|
||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
alter table v1 rename to v2;
|
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 view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -4329,57 +4329,57 @@ Table Op Msg_type Msg_text
|
|||||||
test.t1 repair status OK
|
test.t1 repair status OK
|
||||||
test.t2 repair status OK
|
test.t2 repair status OK
|
||||||
test.t3 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
|
test.v1 repair status Operation failed
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 optimize status OK
|
test.t1 optimize status OK
|
||||||
test.t2 optimize status OK
|
test.t2 optimize status OK
|
||||||
test.t3 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
|
test.v1 optimize status Operation failed
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 analyze status Table is already up to date
|
test.t1 analyze status Table is already up to date
|
||||||
test.t2 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.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
|
test.v1 analyze status Operation failed
|
||||||
call bug13012()|
|
call bug13012()|
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 repair status OK
|
test.t1 repair status OK
|
||||||
test.t2 repair status OK
|
test.t2 repair status OK
|
||||||
test.t3 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
|
test.v1 repair status Operation failed
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 optimize status OK
|
test.t1 optimize status OK
|
||||||
test.t2 optimize status OK
|
test.t2 optimize status OK
|
||||||
test.t3 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
|
test.v1 optimize status Operation failed
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 analyze status Table is already up to date
|
test.t1 analyze status Table is already up to date
|
||||||
test.t2 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.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
|
test.v1 analyze status Operation failed
|
||||||
call bug13012()|
|
call bug13012()|
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 repair status OK
|
test.t1 repair status OK
|
||||||
test.t2 repair status OK
|
test.t2 repair status OK
|
||||||
test.t3 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
|
test.v1 repair status Operation failed
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 optimize status OK
|
test.t1 optimize status OK
|
||||||
test.t2 optimize status OK
|
test.t2 optimize status OK
|
||||||
test.t3 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
|
test.v1 optimize status Operation failed
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 analyze status Table is already up to date
|
test.t1 analyze status Table is already up to date
|
||||||
test.t2 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.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
|
test.v1 analyze status Operation failed
|
||||||
drop procedure bug13012|
|
drop procedure bug13012|
|
||||||
drop view v1|
|
drop view v1|
|
||||||
|
@ -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 #
|
1 PRIMARY t1 ALL NULL NULL NULL NULL #
|
||||||
2 DEPENDENT SUBQUERY t2 ref key1 key1 5 test.t1.a # Using where; Using filesort
|
2 DEPENDENT SUBQUERY t2 ref key1 key1 5 test.t1.a # Using where; Using filesort
|
||||||
drop table t1,t2;
|
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;
|
||||||
|
@ -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
|
# 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 t1 (c1 char(2) not null, c2 char(2));
|
||||||
create table t2 (c3 char(2), c4 char(2));
|
create table t2 (c3 char(2), c4 char(2));
|
||||||
insert into t1 values ('a1', 'b1');
|
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);
|
select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
|
||||||
c1 c2
|
c1 c2
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
set optimizer_switch= @optimizer_switch_save;
|
||||||
#
|
#
|
||||||
# MDEV-12673: cost-based choice between materialization and in-to-exists
|
# 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 t3 const PRIMARY PRIMARY 4 const 1
|
||||||
2 DEPENDENT SUBQUERY t2 index NULL i2 11 NULL 2 Using where; Using index
|
2 DEPENDENT SUBQUERY t2 index NULL i2 11 NULL 2 Using where; Using index
|
||||||
DROP TABLE t1,t2,t3;
|
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;
|
||||||
|
@ -1652,9 +1652,9 @@ CREATE VIEW v1 AS SELECT 1;
|
|||||||
EXPLAIN
|
EXPLAIN
|
||||||
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
|
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
|
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 t1 ALL NULL NULL NULL NULL 2
|
||||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
|
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
|
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);
|
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
|
||||||
a a
|
a a
|
||||||
@ -3072,4 +3072,97 @@ project_number
|
|||||||
aaa
|
aaa
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
set optimizer_switch= @tmp_mdev6859;
|
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;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
|
@ -1625,3 +1625,26 @@ i1
|
|||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
set join_cache_level= @save_join_cache_level;
|
set join_cache_level= @save_join_cache_level;
|
||||||
set optimizer_switch=@save_optimizer_switch;
|
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;
|
||||||
|
@ -1665,9 +1665,9 @@ CREATE VIEW v1 AS SELECT 1;
|
|||||||
EXPLAIN
|
EXPLAIN
|
||||||
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
|
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
|
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 t1 ALL NULL NULL NULL NULL 2
|
||||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
|
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
|
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);
|
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
|
||||||
a a
|
a a
|
||||||
@ -3086,6 +3086,99 @@ project_number
|
|||||||
aaa
|
aaa
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
set optimizer_switch= @tmp_mdev6859;
|
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;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
#
|
#
|
||||||
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
|
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
|
||||||
|
@ -313,7 +313,7 @@ drop trigger trg;
|
|||||||
ERROR HY000: Trigger does not exist
|
ERROR HY000: Trigger does not exist
|
||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
create trigger trg before insert on v1 for each row set @a:=1;
|
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 view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
drop table t3;
|
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
|
tr2 2 2016-01-01 10:10:10.99
|
||||||
drop table t1;
|
drop table t1;
|
||||||
set time_zone= @@global.time_zone;
|
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
|
# Start of 10.3 tests
|
||||||
#
|
#
|
||||||
|
@ -2178,6 +2178,35 @@ WHERE t1_2.b NOT IN ( SELECT 4 UNION ALL SELECT 5 );
|
|||||||
a b a b
|
a b a b
|
||||||
1 1 1 1
|
1 1 1 1
|
||||||
DROP TABLE t1;
|
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
|
# Start of 10.3 tests
|
||||||
#
|
#
|
||||||
|
@ -41,7 +41,7 @@ show create view v1;
|
|||||||
View Create View character_set_client collation_connection
|
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
|
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;
|
show create view t1;
|
||||||
ERROR HY000: 'test.t1' is not VIEW
|
ERROR HY000: 'test.t1' is not of type 'VIEW'
|
||||||
drop table t1;
|
drop table t1;
|
||||||
select a from v1;
|
select a from v1;
|
||||||
ERROR 42S22: Unknown column 'a' in 'field list'
|
ERROR 42S22: Unknown column 'a' in 'field list'
|
||||||
@ -199,7 +199,7 @@ c d
|
|||||||
drop view v100;
|
drop view v100;
|
||||||
ERROR 42S02: Unknown VIEW: 'test.v100'
|
ERROR 42S02: Unknown VIEW: 'test.v100'
|
||||||
drop view t1;
|
drop view t1;
|
||||||
ERROR HY000: 'test.t1' is not VIEW
|
ERROR HY000: 'test.t1' is not of type 'VIEW'
|
||||||
drop table v1;
|
drop table v1;
|
||||||
ERROR 42S02: 'test.v1' is a view
|
ERROR 42S02: 'test.v1' is a view
|
||||||
drop view v1,v2;
|
drop view v1,v2;
|
||||||
@ -675,7 +675,7 @@ drop view v1;
|
|||||||
create table t1 (col1 int,col2 char(22));
|
create table t1 (col1 int,col2 char(22));
|
||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
create index i1 on v1 (col1);
|
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 view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE VIEW v1 (f1,f2,f3,f4) AS SELECT connection_id(), pi(), current_user(), version();
|
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 table t1 (s1 int);
|
||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
handler v1 open as xx;
|
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 view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1(a int);
|
create table t1(a int);
|
||||||
@ -2445,28 +2445,28 @@ CREATE TABLE t1(id INT);
|
|||||||
CREATE VIEW v1 AS SELECT id FROM t1;
|
CREATE VIEW v1 AS SELECT id FROM t1;
|
||||||
OPTIMIZE TABLE v1;
|
OPTIMIZE TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
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
|
test.v1 optimize status Operation failed
|
||||||
ANALYZE TABLE v1;
|
ANALYZE TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
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
|
test.v1 analyze status Operation failed
|
||||||
REPAIR TABLE v1;
|
REPAIR TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
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
|
test.v1 repair status Operation failed
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
OPTIMIZE TABLE v1;
|
OPTIMIZE TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
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
|
test.v1 optimize status Operation failed
|
||||||
ANALYZE TABLE v1;
|
ANALYZE TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
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
|
test.v1 analyze status Operation failed
|
||||||
REPAIR TABLE v1;
|
REPAIR TABLE v1;
|
||||||
Table Op Msg_type Msg_text
|
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
|
test.v1 repair status Operation failed
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
create definer = current_user() sql security invoker view v1 as select 1;
|
create definer = current_user() sql security invoker view v1 as select 1;
|
||||||
@ -2920,7 +2920,7 @@ Tables_in_test
|
|||||||
t1
|
t1
|
||||||
CREATE VIEW v1 AS SELECT id FROM t1;
|
CREATE VIEW v1 AS SELECT id FROM t1;
|
||||||
DROP VIEW t1,v1;
|
DROP VIEW t1,v1;
|
||||||
ERROR HY000: 'test.t1' is not VIEW
|
ERROR HY000: 'test.t1' is not of type 'VIEW'
|
||||||
SHOW TABLES;
|
SHOW TABLES;
|
||||||
Tables_in_test
|
Tables_in_test
|
||||||
t1
|
t1
|
||||||
@ -3706,7 +3706,7 @@ CREATE TABLE t1(c1 INT);
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
c1
|
c1
|
||||||
ALTER ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW t1 (c2) AS SELECT (1);
|
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;
|
DROP TABLE t1;
|
||||||
|
|
||||||
@ -4011,7 +4011,7 @@ drop procedure p;
|
|||||||
CREATE TABLE t1 (a INT);
|
CREATE TABLE t1 (a INT);
|
||||||
CREATE VIEW v1 AS SELECT a FROM t1;
|
CREATE VIEW v1 AS SELECT a FROM t1;
|
||||||
ALTER TABLE v1;
|
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 VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
@ -5584,7 +5584,7 @@ create table t1 (a int, b int);
|
|||||||
create view v1 as select a+b from t1;
|
create view v1 as select a+b from t1;
|
||||||
alter table v1 check partition p1;
|
alter table v1 check partition p1;
|
||||||
Table Op Msg_type Msg_text
|
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
|
test.v1 check status Operation failed
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
12
mysql-test/suite/binlog/r/mysqladmin.result
Normal file
12
mysql-test/suite/binlog/r/mysqladmin.result
Normal 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;
|
12
mysql-test/suite/binlog/t/mysqladmin.test
Normal file
12
mysql-test/suite/binlog/t/mysqladmin.test
Normal 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;
|
30
mysql-test/suite/csv/read_only.result
Normal file
30
mysql-test/suite/csv/read_only.result
Normal 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;
|
19
mysql-test/suite/csv/read_only.test
Normal file
19
mysql-test/suite/csv/read_only.test
Normal 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;
|
||||||
|
|
@ -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
|
@ -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
|
643
mysql-test/suite/encryption/r/innodb-checksum-algorithm.result
Normal file
643
mysql-test/suite/encryption/r/innodb-checksum-algorithm.result
Normal 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;
|
@ -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: 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
|
# Restart mysqld --file-key-management-filename=keys2.txt
|
||||||
SET GLOBAL innodb_file_per_table = ON;
|
SET GLOBAL innodb_file_per_table = ON;
|
||||||
set GLOBAL innodb_default_encryption_key_id=4;
|
set GLOBAL innodb_default_encryption_key_id=4;
|
||||||
|
87
mysql-test/suite/encryption/r/innodb-first-page-read.result
Normal file
87
mysql-test/suite/encryption/r/innodb-first-page-read.result
Normal 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
|
@ -64,5 +64,4 @@ FOUND 1 /public/ in t7.ibd
|
|||||||
FOUND 1 /public/ in t8.ibd
|
FOUND 1 /public/ in t8.ibd
|
||||||
# t9 page compressed expecting NOT FOUND
|
# t9 page compressed expecting NOT FOUND
|
||||||
NOT FOUND /public/ in t9.ibd
|
NOT FOUND /public/ in t9.ibd
|
||||||
use test;
|
|
||||||
drop database enctests;
|
drop database enctests;
|
||||||
|
120
mysql-test/suite/encryption/t/innodb-checksum-algorithm.test
Normal file
120
mysql-test/suite/encryption/t/innodb-checksum-algorithm.test
Normal 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;
|
@ -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
|
@ -1,4 +0,0 @@
|
|||||||
--innodb-tablespaces-encryption
|
|
||||||
--innodb-encrypt-tables=on
|
|
||||||
--innodb-encryption-threads=2
|
|
||||||
--max_allowed_packet=64K
|
|
@ -1,10 +1,11 @@
|
|||||||
-- source include/have_innodb.inc
|
-- source include/innodb_page_size_small.inc
|
||||||
-- source include/have_file_key_management_plugin.inc
|
-- source include/have_file_key_management_plugin.inc
|
||||||
|
|
||||||
# embedded does not support restart
|
# embedded does not support restart
|
||||||
-- source include/not_embedded.inc
|
-- 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: 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
|
--echo # Restart mysqld --file-key-management-filename=keys2.txt
|
||||||
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
|
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
|
||||||
|
5
mysql-test/suite/encryption/t/innodb-first-page-read.opt
Normal file
5
mysql-test/suite/encryption/t/innodb-first-page-read.opt
Normal 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
|
92
mysql-test/suite/encryption/t/innodb-first-page-read.test
Normal file
92
mysql-test/suite/encryption/t/innodb-first-page-read.test
Normal 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%';
|
@ -80,5 +80,4 @@ SET GLOBAL innodb_encrypt_tables=ON;
|
|||||||
|
|
||||||
-- source include/start_mysqld.inc
|
-- source include/start_mysqld.inc
|
||||||
|
|
||||||
use test;
|
|
||||||
drop database enctests;
|
drop database enctests;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user