//Write a chunk of bytes to a file
size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
{
size_t writtenbytes;
size_t sum_written= 0;
const size_t initial_count= Count;
for (;;)
{
//...
#ifdef _WIN32
writtenbytes= my_win_write(Filedes, Buffer, Count);
#else
writtenbytes= write(Filedes, Buffer, Count); //writtenbytes为实际写入的字节数
//...
if (writtenbytes == Count) //判断实际写入的字节数与要求写入的字节数是否相符
{
//写入正常则直接break跳出循环,正常结束.
sum_written+= writtenbytes;
break;
}
//...
}
//...
if (MyFlags & (MY_NABP | MY_FNABP))
{
if (sum_written == initial_count) //写入正常走这个逻辑,返回0代表成功
DBUG_RETURN(0);
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) //写入过程报错走这个逻辑
{
char errbuf[MYSYS_STRERROR_SIZE];
my_error(EE_WRITE, MYF(0), my_filename(Filedes),
my_errno(), my_strerror(errbuf, sizeof(errbuf), my_errno())); //打印错误信息
}
DBUG_RETURN(MY_FILE_ERROR); //返回错误
}
//...
}
/*
源码如上,MySQL最终会走Linux内核方法write(Filedes, Buffer, Count)来刷新binlog缓冲至磁盘文件中。
1.Filedes为文件号(对应/proc/mysqld_pid/fd下的文件编号)
2.Buffer为指向所需写入缓冲的指针。
3.Count为所需要写入的字节数。
my: fd: 51 Buffer: 0x7f24c49e9e30 Count: 27
由于/data/tmp磁盘已满,无法写入Count所需的字节数,导致writtenbytes!=Count,然后引起了后续一系列的代码报错,最终诱发binlog_error_action->MySQL Crash.
*/