summaryrefslogtreecommitdiff
path: root/extra/mariabackup/backup_mysql.cc
diff options
context:
space:
mode:
Diffstat (limited to 'extra/mariabackup/backup_mysql.cc')
-rw-r--r--extra/mariabackup/backup_mysql.cc170
1 files changed, 138 insertions, 32 deletions
diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc
index 824b8b6d5f3..d953cb23b3d 100644
--- a/extra/mariabackup/backup_mysql.cc
+++ b/extra/mariabackup/backup_mysql.cc
@@ -1337,25 +1337,12 @@ cleanup:
Flush and copy the current binary log file into the backup,
if GTID is enabled */
bool
-write_current_binlog_file(MYSQL *connection)
+write_current_binlog_file(MYSQL *connection, bool write_binlogs)
{
- char *executed_gtid_set = NULL;
char *gtid_binlog_state = NULL;
- char *log_bin_file = NULL;
char *log_bin_dir = NULL;
- bool gtid_exists;
+ bool gtid_exists = false;
bool result = true;
- char filepath[FN_REFLEN];
-
- mysql_variable status[] = {
- {"Executed_Gtid_Set", &executed_gtid_set},
- {NULL, NULL}
- };
-
- mysql_variable status_after_flush[] = {
- {"File", &log_bin_file},
- {NULL, NULL}
- };
mysql_variable vars[] = {
{"gtid_binlog_state", &gtid_binlog_state},
@@ -1363,13 +1350,36 @@ write_current_binlog_file(MYSQL *connection)
{NULL, NULL}
};
- read_mysql_variables(connection, "SHOW MASTER STATUS", status, false);
read_mysql_variables(connection, "SHOW VARIABLES", vars, true);
- gtid_exists = (executed_gtid_set && *executed_gtid_set)
- || (gtid_binlog_state && *gtid_binlog_state);
+ if (!write_binlogs) {
+
+ char *executed_gtid_set = NULL;
+
+ mysql_variable status[] = {
+ {"Executed_Gtid_Set", &executed_gtid_set},
+ {NULL, NULL}
+ };
+
+ read_mysql_variables(connection, "SHOW MASTER STATUS", status, false);
+
+ gtid_exists = (executed_gtid_set && *executed_gtid_set)
+ || (gtid_binlog_state && *gtid_binlog_state);
+
+ free_mysql_variables(status);
+
+ }
+
+ if (write_binlogs || gtid_exists) {
+
+ char *log_bin_file = NULL;
+ char filepath[FN_REFLEN];
+
+ mysql_variable status_after_flush[] = {
+ {"File", &log_bin_file},
+ {NULL, NULL}
+ };
- if (gtid_exists) {
size_t log_bin_dir_length;
lock_binlog_maybe(connection);
@@ -1405,14 +1415,31 @@ write_current_binlog_file(MYSQL *connection)
goto cleanup;
}
- snprintf(filepath, sizeof(filepath), "%s%c%s",
- log_bin_dir, FN_LIBCHAR, log_bin_file);
- result = copy_file(ds_data, filepath, log_bin_file, 0);
- }
+ MYSQL_RES *mysql_result;
+ MYSQL_ROW row;
+
+ mysql_result = xb_mysql_query(connection, "SHOW BINARY LOGS", true);
+
+ ut_ad(mysql_num_fields(mysql_result) >= 2);
+
+ while ((row = mysql_fetch_row(mysql_result))) {
+ const char *binlog_name = row[0];
+ snprintf(filepath, sizeof(filepath), "%s%c%s",
+ log_bin_dir, FN_LIBCHAR, binlog_name);
+ if (file_exists(filepath)) {
+ result = copy_file(ds_data, filepath, binlog_name, 0);
+ if (!result) break;
+ }
+ }
+ mysql_free_result(mysql_result);
+
+ write_binlog_info(connection, log_bin_dir);
cleanup:
- free_mysql_variables(status_after_flush);
- free_mysql_variables(status);
+ free_mysql_variables(status_after_flush);
+
+ }
+
free_mysql_variables(vars);
return(result);
@@ -1423,7 +1450,7 @@ cleanup:
Retrieves MySQL binlog position and
saves it in a file. It also prints it to stdout. */
bool
-write_binlog_info(MYSQL *connection)
+write_binlog_info(MYSQL *connection, char *log_bin_dir)
{
char *filename = NULL;
char *position = NULL;
@@ -1431,9 +1458,16 @@ write_binlog_info(MYSQL *connection)
char *gtid_current_pos = NULL;
char *gtid_executed = NULL;
char *gtid = NULL;
+ char *buffer;
+ char *buf;
+ int total;
+ int position_length;
+ int bytes;
bool result;
bool mysql_gtid;
bool mariadb_gtid;
+ bool with_gtid;
+ MYSQL_ROW_OFFSET start;
mysql_variable status[] = {
{"File", &filename},
@@ -1461,24 +1495,96 @@ write_binlog_info(MYSQL *connection)
mysql_gtid = ((gtid_mode != NULL) && (strcmp(gtid_mode, "ON") == 0));
mariadb_gtid = (gtid_current_pos != NULL);
+ with_gtid = mariadb_gtid || mysql_gtid;
+
gtid = (gtid_executed != NULL ? gtid_executed : gtid_current_pos);
- if (mariadb_gtid || mysql_gtid) {
+ if (with_gtid) {
ut_a(asprintf(&mysql_binlog_position,
"filename '%s', position '%s', "
"GTID of the last change '%s'",
filename, position, gtid) != -1);
- result = backup_file_printf(XTRABACKUP_BINLOG_INFO,
- "%s\t%s\t%s\n", filename, position,
- gtid);
} else {
ut_a(asprintf(&mysql_binlog_position,
"filename '%s', position '%s'",
filename, position) != -1);
- result = backup_file_printf(XTRABACKUP_BINLOG_INFO,
- "%s\t%s\n", filename, position);
}
+ MYSQL_RES *mysql_result;
+ MYSQL_ROW row;
+
+ mysql_result = xb_mysql_query(connection, "SHOW BINARY LOGS", true);
+
+ ut_ad(mysql_num_fields(mysql_result) >= 2);
+ start = mysql_row_tell(mysql_result);
+
+ position_length = strlen(position) + 2;
+ if (with_gtid) {
+ position_length += strlen(gtid) + 1;
+ }
+
+ total = strlen(filename) + position_length + 1;
+ while ((row = mysql_fetch_row(mysql_result))) {
+ const char *binlog_name = row[0];
+ if (strcmp(binlog_name, filename) == 0) {
+ continue;
+ }
+ total += strlen(binlog_name) + position_length;
+ }
+
+ buffer = static_cast<char*>(malloc(total));
+ if (!buffer) {
+ msg("Failed to allocate memory for temporary buffer");
+ result = false;
+ goto cleanup2;
+ }
+
+ mysql_row_seek(mysql_result, start);
+
+ buf = buffer;
+ while ((row = mysql_fetch_row(mysql_result))) {
+ const char *binlog_name = row[0];
+ if (strcmp(binlog_name, filename) == 0) {
+ continue;
+ }
+ char filepath[FN_REFLEN];
+ snprintf(filepath, sizeof(filepath), "%s%c%s",
+ log_bin_dir, FN_LIBCHAR, binlog_name);
+ if (file_exists(filepath)) {
+ if (with_gtid) {
+ bytes = snprintf(buf, total, "%s\t%s\t%s\n", binlog_name, position, gtid);
+ } else {
+ bytes = snprintf(buf, total, "%s\t%s\n", binlog_name, position);
+ }
+ if (bytes <= 0) {
+ msg("Buffer overflow in write_binlog_info");
+ result = false;
+ goto cleanup3;
+ }
+ buf += bytes;
+ total -= bytes;
+ }
+ }
+
+ if (with_gtid) {
+ bytes = snprintf(buf, total, "%s\t%s\t%s\n", filename, position, gtid);
+ } else {
+ bytes = snprintf(buf, total, "%s\t%s\n", filename, position);
+ }
+ if (bytes <= 0) {
+ msg("Buffer overflow in write_binlog_info");
+ result = false;
+ goto cleanup3;
+ }
+
+ result = backup_file_printf(XTRABACKUP_BINLOG_INFO, "%s", buffer);
+
+cleanup3:
+ free(buffer);
+
+cleanup2:
+ mysql_free_result(mysql_result);
+
cleanup:
free_mysql_variables(status);
free_mysql_variables(vars);