Navigation Menu

Skip to content

Commit

Permalink
MDEV-26773 MariaBackup backup does not work with compression providers
Browse files Browse the repository at this point in the history
make mariabackup to load not only encryption but also provider plugins.
  • Loading branch information
vuvova committed Oct 27, 2021
1 parent a010959 commit b91acd4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 50 deletions.
107 changes: 58 additions & 49 deletions extra/mariabackup/encryption_plugin.cc
Expand Up @@ -39,6 +39,7 @@ std::vector<std::string> backup_plugins_args;
const char *QUERY_PLUGIN =
"SELECT plugin_name, plugin_library, @@plugin_dir"
" FROM information_schema.plugins WHERE plugin_type='ENCRYPTION'"
" OR (plugin_type = 'DAEMON' AND plugin_name LIKE 'provider\\_%')"
" AND plugin_status='ACTIVE'";

std::string encryption_plugin_config;
Expand Down Expand Up @@ -85,74 +86,82 @@ void encryption_plugin_backup_init(MYSQL *mysql)
MYSQL_ROW row;
std::ostringstream oss;
char *argv[PLUGIN_MAX_ARGS];
char show_query[1024] = "";
std::string plugin_load;
int argc;

result = xb_mysql_query(mysql, QUERY_PLUGIN, true, true);
row = mysql_fetch_row(result);
if (!row)
while ((row = mysql_fetch_row(result)))
{
mysql_free_result(result);
return;
}

char *name= row[0];
char *library= row[1];
char *dir= row[2];
char *name= row[0];
char *library= row[1];
char *dir= row[2];

if (!plugin_load.length())
{
#ifdef _WIN32
for (char *p = dir; *p; p++)
if (*p == '\\') *p = '/';
for (char *p = dir; *p; p++)
if (*p == '\\') *p = '/';
#endif
strncpy(opt_plugin_dir, dir, FN_REFLEN - 1);
opt_plugin_dir[FN_REFLEN - 1] = '\0';
oss << "plugin_dir=" << '"' << dir << '"' << std::endl;
}

std::string plugin_load(name);
if (library)
{
/* Remove shared library suffixes, in case we'll prepare on different OS.*/
const char *extensions[] = { ".dll", ".so", 0 };
for (size_t i = 0; extensions[i]; i++)
plugin_load += std::string(";") + name;

if (library)
{
const char *ext = extensions[i];
if (ends_with(library, ext))
library[strlen(library) - strlen(ext)] = 0;
/* Remove shared library suffixes, in case we'll prepare on different OS.*/
const char *extensions[] = { ".dll", ".so", 0 };
for (size_t i = 0; extensions[i]; i++)
{
const char *ext = extensions[i];
if (ends_with(library, ext))
library[strlen(library) - strlen(ext)] = 0;
}
plugin_load += std::string("=") + library;
}
plugin_load += std::string("=") + library;
}

oss << "plugin_load=" << plugin_load << std::endl;
if (strncmp(name, "provider_", 9) == 0)
continue;

/* Required to load the plugin later.*/
add_to_plugin_load_list(plugin_load.c_str());
strncpy(opt_plugin_dir, dir, FN_REFLEN - 1);
opt_plugin_dir[FN_REFLEN - 1] = '\0';
/* Read plugin variables. */
snprintf(show_query, sizeof(show_query), "SHOW variables like '%s_%%'", name);
}
mysql_free_result(result);
if (!plugin_load.length())
return;

oss << "plugin_dir=" << '"' << dir << '"' << std::endl;
oss << "plugin_load=" << plugin_load.c_str() + 1 << std::endl;

/* Required to load the plugin later.*/
add_to_plugin_load_list(plugin_load.c_str() + 1);

/* Read plugin variables. */
char query[1024];
snprintf(query, 1024, "SHOW variables like '%s_%%'", name);
mysql_free_result(result);

result = xb_mysql_query(mysql, query, true, true);
while ((row = mysql_fetch_row(result)))
if (*show_query)
{
std::string arg("--");
arg += row[0];
arg += "=";
arg += row[1];
backup_plugins_args.push_back(arg);
oss << row[0] << "=" << row[1] << std::endl;
}
result = xb_mysql_query(mysql, show_query, true, true);
while ((row = mysql_fetch_row(result)))
{
std::string arg("--");
arg += row[0];
arg += "=";
arg += row[1];
backup_plugins_args.push_back(arg);
oss << row[0] << "=" << row[1] << std::endl;
}

mysql_free_result(result);
mysql_free_result(result);

/* Check whether to encrypt logs. */
result = xb_mysql_query(mysql, "select @@innodb_encrypt_log", true, true);
row = mysql_fetch_row(result);
srv_encrypt_log = (row != 0 && row[0][0] == '1');
oss << "innodb_encrypt_log=" << row[0] << std::endl;
/* Check whether to encrypt logs. */
result = xb_mysql_query(mysql, "select @@innodb_encrypt_log", true, true);
row = mysql_fetch_row(result);
srv_encrypt_log = (row != 0 && row[0][0] == '1');
oss << "innodb_encrypt_log=" << row[0] << std::endl;

mysql_free_result(result);
mysql_free_result(result);
}

encryption_plugin_config = oss.str();

Expand Down Expand Up @@ -198,7 +207,7 @@ void encryption_plugin_prepare_init(int argc, char **argv)
opt_plugin_dir[FN_REFLEN - 1] = '\0';
}

char **new_argv = new char *[argc + 1];
char **new_argv = new char *[argc + 2];
new_argv[0] = XTRABACKUP_EXE;
memcpy(&new_argv[1], argv, argc*sizeof(char *));

Expand Down
2 changes: 1 addition & 1 deletion extra/mariabackup/xtrabackup.cc
Expand Up @@ -1553,7 +1553,7 @@ struct my_option xb_server_options[] =
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},

{"plugin-dir", OPT_PLUGIN_DIR,
"Server plugin directory. Used to load encryption plugin during 'prepare' phase."
"Server plugin directory. Used to load plugins during 'prepare' phase."
"Has no effect in the 'backup' phase (plugin directory during backup is the same as server's)",
&xb_plugin_dir, &xb_plugin_dir,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
Expand Down
Expand Up @@ -12,6 +12,7 @@ a left(b, 9) length(b)
0 abcabcabc 300
1 defdefdef 3000
2 ghighighi 30000
# restart
# xtrabackup backup
# xtrabackup prepare;
# shutdown server
Expand Down
Expand Up @@ -17,6 +17,8 @@ insert t1 (a, b) values (1, repeat("def", 1000));
insert t1 (a, b) values (2, repeat("ghi", 10000));
select a, left(b, 9), length(b) from t1;

--source include/restart_mysqld.inc

--echo # xtrabackup backup
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;

Expand Down

0 comments on commit b91acd4

Please sign in to comment.