Some days ago we found very interesting bug report with my friend: http://bugs.mysql.com/bug.php?id=71879
Problem is that, if a client moves binlog files to the other folder, stops MySQL server, update in the config file bin_log and bin_log_index values for a new path and starts server again, then the result of SHOW BINARY LOG command will be wrong:
mysql> show binary logs; +-------------------------+-----------+ | Log_name | File_size | +-------------------------+-----------+ | cluster-repo-bin.000001 | 120 | | cluster-repo-bin.000002 | 0 | | cluster-repo-bin.000003 | 0 | | cluster-repo-bin.000004 | 0 | | cluster-repo-bin.000005 | 0 | | cluster-repo-bin.000006 | 120 | +-------------------------+-----------+
As you see, the size of some binlog files are zero. So why? 😮
If you dive into the mysql internals, you can see these lines of codes in the sql/rpl_master.cc:
/* The file ends with EOF or empty line */
while ((length=my_b_gets(index_file, fname, sizeof(fname))) > 1)
{
int dir_len;
ulonglong file_length= 0; // Length if open fails
fname[–length] = ‘\0’; // remove the newline
….
As you see, my_b_gets function reads index file of binlogs and assigns a real path of binlogs to the fname char array. When we debugged fname we detected that fname contains unreal path to the binlog files (for ex: ./mysql-bin.000001). For this reason the size calculator can’t give us real size of binlog files. To resolve this problem we added a few lines of code to correct the real path of files:
// bug fix for http://bugs.mysql.com/bug.php?id=71879
// if bin file path starts with ./ then we will prepend to it full path of binlog directory
if(fname[0] == ‘.’ && fname[1] == ‘/’)
{
std::string ofname(fname);
// get the new folder path of binlog files and assign to the bin_log_value variable.
std::string bin_log_value(mysql_bin_log.get_name());
// corrects the path of binlog file
std::size_t lpos = bin_log_value.find_last_of(“/”);
std::string dir_path = bin_log_value.substr(0, lpos);
std::string full_path = dir_path + ofname.substr(1, ofname.length());
strcpy(fname, full_path.c_str());
}