Skip to content

Commit

Permalink
Make mysqlbinlog find-gtid-position accept gtid sets
Browse files Browse the repository at this point in the history
Summary:
mysqlbinlog --find-gtid-position='gtid_set' outputs
the latest binlog file name whose previous gtid set is a
subset of the input gtid_set. mysqlbinlog errors out if
no such binlog is found.

Test Plan:
mtr test

Run mysqlbinlog --find-gtid-position and no error messages were logged.

Reviewers: jtolmer

Reviewed By: jtolmer
  • Loading branch information
santoshbanda authored and jtolmer committed Jan 5, 2016
1 parent 2d9ecc4 commit cf3889b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
45 changes: 34 additions & 11 deletions client/mysqlbinlog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1747,7 +1747,9 @@ static struct my_option my_long_options[] =
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"find-gtid-position", OPT_FIND_GTID_POSITION,
"Prints binlog file name and starting position of Gtid_log_event "
"corresponding to the given gtid. This requires index-file option.",
"corresponding to the given gtid. If the input string is a gtid set, "
"mysqlbinlog prints latest binlog file name whose previous gtid set "
"is a subset of the input gtid set. This requires index-file option.",
&opt_find_gtid_str, &opt_find_gtid_str, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"index-file", OPT_INDEX_FILE, "Path to the index file, required "
Expand Down Expand Up @@ -3316,25 +3318,42 @@ static Exit_status start_gtid_dump(char *gtid_string, bool find_position)
DBUG_ENTER("start_gtid_dump");
Exit_status retval = OK_CONTINUE;
Sid_map sid_map = NULL;
bool searching_gtid_set = false;
my_off_t pos = BIN_LOG_HEADER_SIZE;
Gtid gtid;
Gtid_set gtid_set(&sid_map);
std::map<std::string, std::string>::reverse_iterator rit;
std::map<std::string, std::string>::iterator it, last_log_it;
it = previous_gtid_set_map.end();
last_log_it = --previous_gtid_set_map.end();

Gtid_set previous_gtid_set(&sid_map);
if (gtid.parse(&sid_map, gtid_string) != RETURN_STATUS_OK)
if (!find_position || Gtid::is_valid(gtid_string))
{
error("Couldn't find position of a malformed Gtid %s", gtid_string);
DBUG_RETURN(ERROR_STOP);
if (gtid.parse(&sid_map, gtid_string) != RETURN_STATUS_OK)
{
error("Couldn't find position of a malformed Gtid %s", gtid_string);
DBUG_RETURN(ERROR_STOP);
}
}
else
{
// Check if the value given to find-gtid-position is gtid set.
if (gtid_set.add_gtid_text(gtid_string) != RETURN_STATUS_OK)
{
error("Couldn't find position of a malformed Gtid %s", gtid_string);
DBUG_RETURN(ERROR_STOP);
}
searching_gtid_set = true;
}

for (rit = previous_gtid_set_map.rbegin();
rit != previous_gtid_set_map.rend(); ++rit)
{
previous_gtid_set.add_gtid_encoding((const uchar*)rit->second.c_str(),
rit->second.length());
if (!previous_gtid_set.contains_gtid(gtid))
if (searching_gtid_set ? previous_gtid_set.is_subset(&gtid_set) :
!previous_gtid_set.contains_gtid(gtid))
{
it = previous_gtid_set_map.find(rit->first.c_str());
break;
Expand All @@ -3348,19 +3367,23 @@ static Exit_status start_gtid_dump(char *gtid_string, bool find_position)
DBUG_RETURN(ERROR_STOP);
}

my_off_t pos = find_gtid_pos_in_log(it->first.c_str(), gtid, &sid_map);
if (pos == 0)
if (!searching_gtid_set)
{
error("Request gtid is not in executed set and so cannot be "
"found in binary logs");
DBUG_RETURN(ERROR_STOP);
pos = find_gtid_pos_in_log(it->first.c_str(), gtid, &sid_map);
if (pos == 0)
{
error("Request gtid is not in executed set and so cannot be "
"found in binary logs");
DBUG_RETURN(ERROR_STOP);
}
}

if (find_position)
{
int dir_len = dirname_length(it->first.c_str());
fprintf(result_file, "Log_name: %s\n", it->first.c_str() + dir_len);
fprintf(result_file, "Position: %llu", pos);
if (!searching_gtid_set)
fprintf(result_file, "Position: %llu", pos);
DBUG_RETURN(OK_CONTINUE);
}

Expand Down
4 changes: 4 additions & 0 deletions mysql-test/r/mysqlbinlog_gtid.result
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ FLUSH LOGS;
insert into t1 values(3);
insert into t1 values(4);
FLUSH LOGS;
Log_name: master-bin.000002

Log_name: master-bin.000003

** Reading from local binlog **
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
Expand Down
10 changes: 10 additions & 0 deletions mysql-test/t/mysqlbinlog_gtid.test
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ FLUSH LOGS;
-- let $MASTER_UUID = `SELECT @@SERVER_UUID;`
-- let $MYSQLD_DATADIR = `select @@datadir;`

-- exec $MYSQL_BINLOG --index-file=$MYSQLD_DATADIR/master-bin.index --find-gtid-position=$MASTER_UUID:1-4
-- echo

-- exec $MYSQL_BINLOG --index-file=$MYSQLD_DATADIR/master-bin.index --find-gtid-position=$MASTER_UUID:1-6
-- echo

-- echo ** Reading from local binlog **
-- replace_result $MASTER_UUID uuid
-- exec $MYSQL_BINLOG --force-if-open --short_form --index-file=$MYSQLD_DATADIR/master-bin.index --start-gtid=$MASTER_UUID:3
Expand Down Expand Up @@ -50,4 +56,8 @@ PURGE BINARY LOGS TO 'master-bin.000002';
-- error 1
-- exec $MYSQL_BINLOG --short-form --read-from-remote-master=BINLOG-DUMP-GTID --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --start-gtid=$MASTER_UUID:1 --to-last-log

# Purged Gtid Set
-- error 1
-- exec $MYSQL_BINLOG --index-file=$MYSQLD_DATADIR/master-bin.index --find-gtid-position=$MASTER_UUID:1-2

drop table t1;

0 comments on commit cf3889b

Please sign in to comment.