Bug #51023 Mysql server crashes on SIGHUP and destroys InnoDB files
Submitted: 9 Feb 2010 12:12 Modified: 10 Jan 2011 16:41
Reporter: Vsevolod Volkov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: General Severity:S1 (Critical)
Version:5.1.35-5.1.52 OS:FreeBSD (7.2-RELEASE, 8.0-RELEASE, 8.1-RELEASE)
Assigned to: Davi Arnaut CPU Architecture:Any
Tags: crash, HUP, ibd, innodb

[9 Feb 2010 12:12] Vsevolod Volkov
Description:
Mysql server sometimes crashes and destroys one or more (usualy 2) .ibd files. Configuration of server contains 'innodb_file_per_table' statement. There are about 800 databases at the server (~29000 MyISAM tables, ~2500 InnoBD tables).
Every hour mysql server get SIGHUP to rotate logs. Server sometimes (usualy once per week) crashes on SIGHUP. The beginning of one or more .ibd files contains log-error messages like this:

---------------------------------------------------------------

Status information:

Current dir: /db/mysql/
Running threads: 0  Stack size: 196608
Current locks:
lock: 0x3c210b44:

lock: 0x3c211044:
.....
[ binary data ]
---------------------------------------------------------------

It looks like mysql server mixed file handles up. Modification time of corrupted .ibd files often is older than time of crash. So, I guess that appearing of corrupted files causes server crash.

The problem appears after upgrading from mysql-5.0.83 to 5.1.35 and currently actual with mysql-5.1.42. The same problem was found at some other servers with similar configuration.

How to repeat:
- start dump of all databases (it takes about 25 minutes at my server);
- run the following command at the same time:
while sleep 5; do kill -HUP `cat /path/to/pid_file.pid`; done
[9 Feb 2010 12:45] Valeriy Kravchuk
Do you use MySQL server built from ports or binaries from MySQL site/mirror?
[9 Feb 2010 12:55] Vsevolod Volkov
Mysql built from port. Architecture is i386. Configure arguments (from config.log):
./configure
        --localstatedir=/var/db/mysql
        --without-debug --without-readline
        --without-libedit
        --with-libwrap
        --with-low-memory
        --with-comment="FreeBSD port: mysql-server-5.1.42"
        --enable-thread-safe-client
        --with-charset=koi8u
        --with-extra-charsets=all
        --with-plugins=max-no-ndb
        --enable-assembler
        --with-named-thread-libs=-pthread
        --with-embedded-server
        --prefix=/usr/local
        --mandir=/usr/local/man
        --infodir=/usr/local/info/
        --build=i386-portbld-freebsd8.0
[10 Feb 2010 20:44] Valeriy Kravchuk
Please, send your my.cnf file content and messages from the error log of MySQL server (if any) from that period when SIGHUP led to .ibd files corruption.
[11 Feb 2010 8:28] Vsevolod Volkov
my.cnf file

Attachment: my.cnf (application/octet-stream, text), 5.00 KiB.

[11 Feb 2010 8:46] Vsevolod Volkov
The cnf file is modified my-large.cnf from the port.
Now I have no error log contents after crash. But I could wait for the next crash or reproduce it if you need it immediately.
Also I guess the problem may depend on a number of opened files by mysql server. Usualy the number is 600...800. But sometimes it can be more than 1000. Backup of all databases causes higher load of mysql server and slower queries causes increasing of opened handles.
[19 Feb 2010 15:01] Vsevolod Volkov
Two days ago I've upgraded to mysql-5.1.43 and switched from built-in InnoDB to plugin. Today mysql server destroyed one InnoDB table.
[19 Feb 2010 15:02] Vsevolod Volkov
The beginning of errors.log just after crash.

Attachment: errors.log (application/octet-stream, text), 23.38 KiB.

[19 Feb 2010 15:05] Vsevolod Volkov
Corrupted .ibd file:

Attachment: wp_posts.ibd (application/octet-stream, text), 3.34 KiB.

[23 Feb 2010 11:02] Susanne Ebrecht
Please check output from your mysqld user of 

$ ulimit -a

Check if open files are limited to 1024 or so.
[23 Feb 2010 11:33] Vsevolod Volkov
mysql@server:~> ulimit -a
socket buffer size       (bytes, -b) unlimited
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) 524288
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 11095
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 65536
cpu time               (seconds, -t) unlimited
max user processes              (-u) 5547
virtual memory          (kbytes, -v) unlimited
swap size               (kbytes, -w) unlimited
mysql@server:~> sysctl kern.maxfilesperproc
kern.maxfilesperproc: 11095

Probably, mysql server reaches the FD_SETSIZE limit (1024 by default).
[20 Mar 2010 11:01] Vsevolod Volkov
The same problem with mysql 5.1.44.
[28 Mar 2010 6:49] Vsevolod Volkov
The same problem with mysql 5.1.45.
[20 May 2010 9:22] Vsevolod Volkov
The same problem with mysql 5.1.46.
[2 Jun 2010 21:02] Sveta Smirnova
Thank you for the feedback.

Verified as described.

To repeat:

1. Create PHP script:

<?php

for ($i=1; $i < 801; $i ++) {
	echo "create database db_$i;\n";
	for ($j=1; $j < 10; $j ++) {
		echo "create table db_$i.t_$j(f1 int not null auto_increment primary key, f2 text) engine=innodb;\n";
		for ($k = 1; $k < 1000; $k ++) {
			echo "insert into db_$i.t_$j (f2) values(md5($k));\n";
		}
	}
}

?>

2. Start mysqld with options provided.

3. Use it to create database/tables:

php bug51023.php | mysql

4. In one session run:

 while  ./bin/mysqldump -uroot -S /tmp/mysql_ssmirnova.sock --all-databases>/dev/null; do echo 1; done

5. In another:

while sleep 1; do kill -HUP `cat /home/sveta/build/mysql-5.1.47/data/bsd60.pid`; done

6. Wait crash. I had to wait for about 6 hours.
[28 Jul 2010 8:05] Vsevolod Volkov
The same problem with mysql 5.1.48.
[3 Aug 2010 7:03] Vsevolod Volkov
The same problem with mysql 5.1.49.
[3 Sep 2010 10:53] Vsevolod Volkov
The same problem with mysql 5.1.50.
[1 Dec 2010 8:38] Vsevolod Volkov
The same problem with mysql 5.1.52.
[6 Dec 2010 9:06] Vasil Dimov
The data that has been printed into .ibd files comes from sql/sql_test.cc:

void mysql_print_status()
{
  char current_dir[FN_REFLEN];
  STATUS_VAR tmp;

  calc_sum_of_all_status(&tmp);
  printf("\nStatus information:\n\n");
  VOID(my_getwd(current_dir, sizeof(current_dir),MYF(0)));
  printf("Current dir: %s\n", current_dir);
  printf("Running threads: %d  Stack size: %ld\n", thread_count,
         (long) my_thread_stack_size);
  thr_print_locks();                            // Write some debug info
...

So somehow file descriptor 1 (stdout) gets associated with .ibd files.
[6 Dec 2010 11:20] Vasil Dimov
Hmm, the mysqld error log file http://bugs.mysql.com/file.php?id=14076&text=1 contains:

"pure virtual method called"
[6 Dec 2010 12:14] Vasil Dimov
Vsevolod,

you say:

"Every hour mysql server get SIGHUP to rotate logs."

but from your my.cnf I see that you do not have binlog enabled. What logs do you rotate?

I assume that by "mysql server" you mean the mysqld process.

Thanks!
[6 Dec 2010 12:42] Vsevolod Volkov
> What logs do you rotate?
slow.log
> I assume that by "mysql server" you mean the mysqld process.
Right.
[6 Dec 2010 15:11] Vasil Dimov
I said "somehow file descriptor 1 (stdout) gets associated with .ibd files" but this may not be entirely true. When --error-log=/path/to/file is used, then stdout and stderr are redirected to /path/to/file using freopen(3). This is done each time SIGHUP is received by mysqld, see sql/mysqld.cc:

signal_hand()
  reload_acl_and_cache()
    flush_error_log()
      redirect_std_streams()
        reopen_fstreams()
          freopen(log_error_file, "a+", stdout)
          freopen(log_error_file, "a+", stderr)
[6 Dec 2010 17:29] Vasil Dimov
I tried what Sveta suggested (steps 1-6) and got interesting results:

(sending SIGHUP to mysqld every second)

$ while ./bin/mysqldump --all-databases > /dev/null; do date ; done
Mon Dec  6 15:55:15 EET 2010
mysqldump: Couldn't execute 'show fields from `t_9`': Table '/var/tmp/#sql96d9_3_2f7b' is marked as crashed and should be repaired (1194)
$

mysqld did not exit but I found binary data at the end of error.log!

Vsevolod, do you sometimes see binary stuff written to your error.log?

What happens is that the following two tasks are run in parallel:
* each second: freopen() for stdout and stderr
* open lots of files (caused by mysqldump dumping lots of innodb tables).

I wrote this simple program which does the above two tasks:

--- cut ---
#include <sys/types.h>
#include <sys/uio.h>

#include <errno.h>
#include <fcntl.h>
#include <pthread.h>    
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>     

FILE*	l;

void*
openmany(void* p)
{
	int			fds[1500];
	unsigned long long	i, j;
	char			filename[100];

	for (i = 0; ; i++) {
		for (j = 0; j < 1500; j++) {

			snprintf(filename, sizeof(filename),
				 "/tmp/ib%04llu", j);
			fds[j] = open(filename, O_RDWR | O_CREAT, 0644);
			fprintf(l, "open(): %s: %d\n", filename, fds[j]);
			if (fds[j] == -1) {
				fprintf(l, "open(): %s: %s\n", filename,
					strerror(errno));
				exit(1);
			}
			write(fds[j], "ABCABCABC", 9);
		}

		for (j = 0; j < 1500; j++) {
			int	ret;

			ret = close(fds[j]);

			fprintf(l, "close(): %d: %d\n", fds[j], ret);

			if (ret == -1) {
				fprintf(l, "error: close(%d): %s\n", fds[j],
				       strerror(errno));
				exit(1);
			}
		}
	}
}

void*
reopenstd(void* p)
{
	unsigned long long i;

	for (i = 0; ; i++) {
		freopen("/tmp/std_redirected", "a+", stdout);
		freopen("/tmp/std_redirected", "a+", stderr);
		printf("XXXXXXXXXXX %llu\n", i);
	}

	return(NULL);
}

int
main(int argc, char **argv, char **envp)
{
	pthread_t	t1;
	pthread_t	t2;
	void*		ret;

	l = fopen("/tmp/log", "w");
	if (l == NULL) {
		fprintf(stderr, "error: fopen(): /tmp/log: %s\n",
			strerror(errno));
		exit(1);
	}

	pthread_create(&t1, NULL, reopenstd, NULL);
	pthread_create(&t2, NULL, openmany, NULL);

	pthread_join(t1, &ret);
	pthread_join(t2, &ret);

	fclose(l);

	return(0);
}
--- cut ---

It quits immediately and the result is that
* /tmp/std_redirected contains ABCABCABC
* /tmp/log contains:
...
open(): /tmp/ib0175: 179
open(): /tmp/ib0176: 180
open(): /tmp/ib0177: 1
open(): /tmp/ib0178: 182
open(): /tmp/ib0179: 183
...
open(): /tmp/ib0215: 219
open(): /tmp/ib0216: 186
open(): /tmp/ib0217: 1
open(): /tmp/ib0218: 221
open(): /tmp/ib0219: 222
...
close(): 180: 0
close(): 1: 0
close(): 182: 0
...
close(): 219: 0
close(): 186: 0
close(): 1: -1
error: close(1): Bad file descriptor

Which is self explanatory - open() has returned a few times fd=1 when asked to open different files (from /tmp/ib0000 to /tmp/ib1500).

I think the reason for this is that freopen() closes stdout (here open() from the other thread is called and returns the first free fd which is 1) and then opens /tmp/std_redirecred and associates stdout with it.
[6 Dec 2010 17:42] Vasil Dimov
The simple prog from my previous comment does not mix the files under Linux, i.e. this problem does not exist on Linux.

The source of freopen(3) on FreeBSD:

src/lib/libc/stdio/freopen.c:

/*
 * Re-direct an existing, open (probably) file to some other file.
 * ANSI is written such that the original file gets closed if at
 * all possible, no matter what.
 */
FILE *
freopen(file, mode, fp)
	const char * __restrict file;
	const char * __restrict mode;
	FILE *fp;
{
	int f;
	int dflags, flags, isopen, oflags, sverrno, wantfd;

	if ((flags = __sflags(mode, &oflags)) == 0) {
		sverrno = errno;
		(void) fclose(fp);
		errno = sverrno;
		return (NULL);
	}

	FLOCKFILE(fp);

	if (!__sdidinit)
		__sinit();

	/*
	 * If the filename is a NULL pointer, the caller is asking us to
	 * re-open the same file with a different mode. We allow this only
	 * if the modes are compatible.
	 */
	if (file == NULL) {
		/* See comment below regarding freopen() of closed files. */
		if (fp->_flags == 0) {
			FUNLOCKFILE(fp);
			errno = EINVAL;
			return (NULL);
		}
		if ((dflags = _fcntl(fp->_file, F_GETFL)) < 0) {
			sverrno = errno;
			fclose(fp);
			FUNLOCKFILE(fp);
			errno = sverrno;
			return (NULL);
		}
		if ((dflags & O_ACCMODE) != O_RDWR && (dflags & O_ACCMODE) !=
		    (oflags & O_ACCMODE)) {
			fclose(fp);
			FUNLOCKFILE(fp);
			errno = EINVAL;
			return (NULL);
		}
		if (fp->_flags & __SWR)
			(void) __sflush(fp);
		if ((oflags ^ dflags) & O_APPEND) {
			dflags &= ~O_APPEND;
			dflags |= oflags & O_APPEND;
			if (_fcntl(fp->_file, F_SETFL, dflags) < 0) {
				sverrno = errno;
				fclose(fp);
				FUNLOCKFILE(fp);
				errno = sverrno;
				return (NULL);
			}
		}
		if (oflags & O_TRUNC)
			(void) ftruncate(fp->_file, (off_t)0);
		if (!(oflags & O_APPEND))
			(void) _sseek(fp, (fpos_t)0, SEEK_SET);
		f = fp->_file;
		isopen = 0;
		wantfd = -1;
		goto finish;
	}

	/*
	 * There are actually programs that depend on being able to "freopen"
	 * descriptors that weren't originally open.  Keep this from breaking.
	 * Remember whether the stream was open to begin with, and which file
	 * descriptor (if any) was associated with it.  If it was attached to
	 * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
	 * should work.  This is unnecessary if it was not a Unix file.
	 */
	if (fp->_flags == 0) {
		fp->_flags = __SEOF;	/* hold on to it */
		isopen = 0;
		wantfd = -1;
	} else {
		/* flush the stream; ANSI doesn't require this. */
		if (fp->_flags & __SWR)
			(void) __sflush(fp);
		/* if close is NULL, closing is a no-op, hence pointless */
		isopen = fp->_close != NULL;
		if ((wantfd = fp->_file) < 0 && isopen) {
			(void) (*fp->_close)(fp->_cookie);
			isopen = 0;
		}
	}

	/* Get a new descriptor to refer to the new file. */
	f = _open(file, oflags, DEFFILEMODE);
	if (f < 0 && isopen) {
		/* If out of fd's close the old one and try again. */
		if (errno == ENFILE || errno == EMFILE) {
			(void) (*fp->_close)(fp->_cookie);
			isopen = 0;
			f = _open(file, oflags, DEFFILEMODE);
		}
	}
	sverrno = errno;

finish:
	/*
	 * Finish closing fp.  Even if the open succeeded above, we cannot
	 * keep fp->_base: it may be the wrong size.  This loses the effect
	 * of any setbuffer calls, but stdio has always done this before.
	 */
	if (isopen)
		(void) (*fp->_close)(fp->_cookie);
	if (fp->_flags & __SMBF)
		free((char *)fp->_bf._base);
	fp->_w = 0;
	fp->_r = 0;
	fp->_p = NULL;
	fp->_bf._base = NULL;
	fp->_bf._size = 0;
	fp->_lbfsize = 0;
	if (HASUB(fp))
		FREEUB(fp);
	fp->_ub._size = 0;
	if (HASLB(fp))
		FREELB(fp);
	fp->_lb._size = 0;
	fp->_orientation = 0;
	memset(&fp->_mbstate, 0, sizeof(mbstate_t));

	if (f < 0) {			/* did not get it after all */
		fp->_flags = 0;		/* set it free */
		FUNLOCKFILE(fp);
		errno = sverrno;	/* restore in case _close clobbered */
		return (NULL);
	}

	/*
	 * If reopening something that was open before on a real file, try
	 * to maintain the descriptor.  Various C library routines (perror)
	 * assume stderr is always fd STDERR_FILENO, even if being freopen'd.
	 */
	if (wantfd >= 0 && f != wantfd) {
		if (_dup2(f, wantfd) >= 0) {
			(void)_close(f);
			f = wantfd;
		}
	}

	/*
	 * File descriptors are a full int, but _file is only a short.
	 * If we get a valid file descriptor that is greater than
	 * SHRT_MAX, then the fd will get sign-extended into an
	 * invalid file descriptor.  Handle this case by failing the
	 * open.
	 */
	if (f > SHRT_MAX) {
		fp->_flags = 0;		/* set it free */
		FUNLOCKFILE(fp);
		errno = EMFILE;
		return (NULL);
	}

	fp->_flags = flags;
	fp->_file = f;
	fp->_cookie = fp;
	fp->_read = __sread;
	fp->_write = __swrite;
	fp->_seek = __sseek;
	fp->_close = __sclose;
	/*
	 * When opening in append mode, even though we use O_APPEND,
	 * we need to seek to the end so that ftell() gets the right
	 * answer.  If the user then alters the seek pointer, or
	 * the file extends, this will fail, but there is not much
	 * we can do about this.  (We could set __SAPP and check in
	 * fseek and ftell.)
	 */
	if (oflags & O_APPEND)
		(void) _sseek(fp, (fpos_t)0, SEEK_END);
	FUNLOCKFILE(fp);
	return (fp);
}

http://svn.freebsd.org/viewvc/base/stable/8/lib/libc/stdio/freopen.c?revision=196045&view=...
[7 Dec 2010 7:22] Vsevolod Volkov
Probably, this is due to freopen() in FreeBSD isn't thread-safe:
http://www.freebsd.org/cgi/query-pr.cgi?pr=threads/79887
[8 Dec 2010 11:12] Davi Arnaut
While we work on a fix, the recommend workaround is to avoid having the log files flush: do not send a SIGHUP or a FLUSH LOGS to the server. SIGHUP is usually sent by logrotate like programs.
[8 Dec 2010 12:25] Vasil Dimov
Experimental patch

Attachment: bug51023-1.diff (application/octet-stream, text), 5.20 KiB.

[8 Dec 2010 12:30] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/126311

3666 Vasil Dimov	2010-12-08
      Fix Bug#51023 Mysql server crashes on SIGHUP and destroys InnoDB files
      
      Emulate freopen() on FreeBSD. This patch assumes we can assign to stdout
      like "FILE* f; ...; stdout = f;"
[8 Dec 2010 12:34] Vasil Dimov
Here is an experimental patch to fix this bug: http://bugs.mysql.com/file.php?id=16366

Vsevolod, can you try if it fixes the problem for you? If you are using mysql from ports it would be something like:

cd /usr/ports/databases/mysql51-server
make patch
cd work/mysql*
patch -p0 < /path/to/bug51023-1.diff
cd ../..
make
make install, or instead of make install you can just copy mysqld from work/mysql*/sql/mysqld over your installed mysqld assuming they are the same version (e.g. 5.1.53).

Thanks!
[8 Dec 2010 13:22] Vsevolod Volkov
The patch has been applied. I will watch.
[14 Dec 2010 16:11] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/126800

3669 Vasil Dimov	2010-12-14
      Fix Bug#51023 Mysql server crashes on SIGHUP and destroys InnoDB files
      
      The freopen(3) function is not thread-safe on FreeBSD. What this means is
      that if another thread calls open(2) during freopen() is executing that
      another thread's fd returned by open(2) may get re-associated with the
      file being passed to freopen(3).
      
      http://bugs.mysql.com/51023
      http://www.freebsd.org/cgi/query-pr.cgi?pr=79887
[15 Dec 2010 12:01] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/126923

3521 Davi Arnaut	2010-12-15
      Bug#51023: Mysql server crashes on SIGHUP and destroys InnoDB files
      
      From a user perspective, the problem is that a FLUSH LOGS or SIGHUP
      signal could end up associating the stdout and stderr to random
      files. In the case of this bug report, the streams would end up
      associated to InnoDB ibd files.
      
      The freopen(3) function is not thread-safe on FreeBSD. What this
      means is that if another thread calls open(2) during freopen()
      is executing that another thread's fd returned by open(2) may get
      re-associated with the file being passed to freopen(3). See FreeBSD
      PR number 79887 for reference:
      
        http://www.freebsd.org/cgi/query-pr.cgi?pr=79887
      
      This problem is worked around by substituting a internal hook within
      the FILE structure. This avoids the loss of atomicity by not having
      the original fd closed before its duplicated.
      
      Patch based on the original work by Vasil Dimov.
     @ include/my_sys.h
        Export my_freopen.
     @ mysys/my_fopen.c
        Add a my_freopen abstraction to workaround bugs in specific OSes.
     @ sql/log.cc
        Move freopen abstraction code over to mysys.
        The streams are now only reopened for writing.
[15 Dec 2010 12:20] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/126926

3521 Davi Arnaut	2010-12-15
      Bug#51023: Mysql server crashes on SIGHUP and destroys InnoDB files
      
      From a user perspective, the problem is that a FLUSH LOGS or SIGHUP
      signal could end up associating the stdout and stderr to random
      files. In the case of this bug report, the streams would end up
      associated to InnoDB ibd files.
      
      The freopen(3) function is not thread-safe on FreeBSD. What this
      means is that if another thread calls open(2) during freopen()
      is executing that another thread's fd returned by open(2) may get
      re-associated with the file being passed to freopen(3). See FreeBSD
      PR number 79887 for reference:
      
        http://www.freebsd.org/cgi/query-pr.cgi?pr=79887
      
      This problem is worked around by substituting a internal hook within
      the FILE structure. This avoids the loss of atomicity by not having
      the original fd closed before its duplicated.
      
      Patch based on the original work by Vasil Dimov.
     @ include/my_sys.h
        Export my_freopen.
     @ mysys/my_fopen.c
        Add a my_freopen abstraction to workaround bugs in specific OSes.
     @ sql/log.cc
        Move freopen abstraction code over to mysys.
        The streams are now only reopened for writing.
[15 Dec 2010 13:26] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/126934

3521 Davi Arnaut	2010-12-15
      Bug#51023: Mysql server crashes on SIGHUP and destroys InnoDB files
      
      From a user perspective, the problem is that a FLUSH LOGS or SIGHUP
      signal could end up associating the stdout and stderr to random
      files. In the case of this bug report, the streams would end up
      associated to InnoDB ibd files.
      
      The freopen(3) function is not thread-safe on FreeBSD. What this
      means is that if another thread calls open(2) during freopen()
      is executing that another thread's fd returned by open(2) may get
      re-associated with the file being passed to freopen(3). See FreeBSD
      PR number 79887 for reference:
      
        http://www.freebsd.org/cgi/query-pr.cgi?pr=79887
      
      This problem is worked around by substituting a internal hook within
      the FILE structure. This avoids the loss of atomicity by not having
      the original fd closed before its duplicated.
      
      Patch based on the original work by Vasil Dimov.
     @ include/my_sys.h
        Export my_freopen.
     @ mysys/my_fopen.c
        Add a my_freopen abstraction to workaround bugs in specific OSes.
     @ sql/log.cc
        Move freopen abstraction code over to mysys.
        The streams are now only reopened for writing.
[4 Jan 2011 15:54] Vasil Dimov
http://lists.mysql.com/commits/126934 looks fine
[7 Jan 2011 18:33] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/128194

3536 Davi Arnaut	2011-01-07
      Bug#51023: Mysql server crashes on SIGHUP and destroys InnoDB files
      
      From a user perspective, the problem is that a FLUSH LOGS or SIGHUP
      signal could end up associating the stdout and stderr to random
      files. In the case of this bug report, the streams would end up
      associated to InnoDB ibd files.
      
      The freopen(3) function is not thread-safe on FreeBSD. What this
      means is that if another thread calls open(2) during freopen()
      is executing that another thread's fd returned by open(2) may get
      re-associated with the file being passed to freopen(3). See FreeBSD
      PR number 79887 for reference:
      
        http://www.freebsd.org/cgi/query-pr.cgi?pr=79887
      
      This problem is worked around by substituting a internal hook within
      the FILE structure. This avoids the loss of atomicity by not having
      the original fd closed before its duplicated.
      
      Patch based on the original work by Vasil Dimov.
     @ include/my_sys.h
        Export my_freopen.
     @ mysys/my_fopen.c
        Add a my_freopen abstraction to workaround bugs in specific OSes.
        Add a prototype for getosreldate() as older FreeBSD versions did
        not define one.
     @ sql/log.cc
        Move freopen abstraction code over to mysys.
        The streams are now only reopened for writing.
[7 Jan 2011 18:37] Bugs System
Pushed into mysql-5.1 5.1.55 (revid:davi.arnaut@oracle.com-20110107183336-kp8niwm2hz3wb4c3) (version source revid:davi.arnaut@oracle.com-20110107183336-kp8niwm2hz3wb4c3) (merge vers: 5.1.55) (pib:24)
[7 Jan 2011 19:28] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/128197

3537 Davi Arnaut	2011-01-07
      Bug#51023: Mysql server crashes on SIGHUP and destroys InnoDB files
      
      WIN32 compilation fixes: define ETIMEDOUT only if not available and
      fix typos and add a missing parameter.
[7 Jan 2011 19:29] Bugs System
Pushed into mysql-5.1 5.1.55 (revid:davi.arnaut@oracle.com-20110107192806-rmvvxwhk10sy0219) (version source revid:davi.arnaut@oracle.com-20110107192806-rmvvxwhk10sy0219) (merge vers: 5.1.55) (pib:24)
[7 Jan 2011 21:14] Bugs System
Pushed into mysql-trunk 5.6.2 (revid:davi.arnaut@oracle.com-20110107195411-btoz25nczquv47wj) (version source revid:davi.arnaut@oracle.com-20110107195411-btoz25nczquv47wj) (merge vers: 5.6.2) (pib:24)
[7 Jan 2011 21:14] Bugs System
Pushed into mysql-5.5 5.5.9 (revid:davi.arnaut@oracle.com-20110107193241-hg6qmwb5emsn4l8v) (version source revid:davi.arnaut@oracle.com-20110107193052-lz1fwwakvlso6enn) (merge vers: 5.5.9) (pib:24)
[10 Jan 2011 16:41] Paul DuBois
Noted in 5.1.55, 5.5.9, 5.6.2 changelogs.

On FreeBSD, if mysqld was killed with a SIGHUP signal, it could
corrupt InnoDB .ibd files.
[16 Aug 2017 8:53] MySQL Verification Team
another problem with freopen has been avoided in the fix for:
BUG 26447825 - MYSQLD COMPLETELY SILENT EVEN IN FAILURE IF LOG-ERROR IS NOT WRITABLE