[MDEV-12144] Signal 6 crash corrupts ibd files Created: 2017-02-27 Updated: 2017-07-15 Resolved: 2017-07-15 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB |
| Affects Version/s: | 10.0.28, 10.0.29, 10.0.30 |
| Fix Version/s: | 10.1.26, 5.5.57, 10.0.32, 10.2.8 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Edward Hicks | Assignee: | Sergei Golubchik |
| Resolution: | Fixed | Votes: | 2 |
| Labels: | contribution, corruption, crash, foundation, innodb | ||
| Environment: |
RHEL6, x86_64, VMWare, wheezy |
||
| Attachments: |
|
| Description |
|
3 times now in the last 6 months or so we've had a random signal 6 crash corrupt a single ibd file by actually overwriting the top it with the error message. (which I assume was meant for the log file instead) I've attached the corrupted file as an example. I've confirmed this occurs in 10.0.28 and 10.0.29. Here's the error data from the correct log file:
|
| Comments |
| Comment by Marko Mäkelä [ 2017-02-28 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
It looks like the file optometrydb/page_manager_handlers.ibd must have been overwritten with some ASCII text: In the past (while I worked as a MySQL developer) I have suspected that maybe if the mysqld process is started without file descriptor 2 (stderr) being assigned, it is possible that a data file gets opened as file descriptor 2. Then, when some code attempts to report something to stderr, it would overwrite the data file that happens to be associated with file descriptor 2. This hypothesis should be fairly easy to test by an invocation similar to the following:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Daniel Black [ 2017-02-28 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
flush [error] log, will reopen the file descriptor but not necessary the same one will come back. Maybe. Another thread could open a file which becomes FD 2. LOCK_error_log isn't held in reopen_fstreams for stderr. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Edward Hicks [ 2017-02-28 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I'm not sure what you mean by "the start of the file" - what is attached is the entire file as copied from the data directory before I started on recovery. Just run it through less and you see this at the top:
And then the rest is binary through the EOF. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2017-03-18 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
eshicks4, sorry that I overlooked the file attachment. Can you share more details? Do you have a server error log from immediately before the crash? How many InnoDB files do you have, and have you configured innodb_open_files or table_cache (or table_open_cache)? These parameters affect the fil_system->max_n_open and the fil_system->LRU (closing of rarely accessed data files) in InnoDB. danblack has a promising-looking hypothesis. Maybe fil_node_open_file() in InnoDB opened a data file at a very unfortunate moment as file descriptor 2 (STDERR_FILENO) which happened to be available at that point of time. Side note: All of the output that corrupted the .ibd file was written by the server core, not InnoDB. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Daniel Black [ 2017-03-19 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
fdmain.c - an approach using dup2 to ensure that stdout(or another fd) isn't closed - generating a race condition but still redirecting it to another object.
Note 1: during testing I fclose(stdout) after dup2 and the fprintf(stdout..) generated a segfault which seems closer like this bug report. looking at freopen is seems the syscalls are quite similar anyway.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2017-03-20 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There indeed are a few calls to freopen(), mostly during the server initialization. I tested starting mysqld with all of stdin, stdout, stderr closed, and my_freopen() is being called by reopen_fstreams() and init_server_components() before the InnoDB storage engine is initialized:
At this startup, we have fileno(srv_monitor_file)==1 (STDOUT_FILENO) and fileno(srv_dict_tmpfile)==2 (STDERR_FILENO). A possible solution for this startup problem could be to allocate a dummy file to the STDERR_FILENO before starting up storage engines, or refuse startup outright if STDERR_FILENO is not open. I will for now assume that the standard error stream was properly open during the startup. Like danblack pointed out, flush_error_log() is calling redirect_std_streams(), which calls freopen() via my_freopen(). Assuming that the main() function of storage/mroonga/vendor/groonga/src/groonga.c is not compiled in, flush_error_log() seems to be the only caller of freopen() while the server is running. The only caller of flush_error_log() is reload_acl_and_cache(), when REFRESH_LOG or REFRESH_ERROR_LOG are set. The callers that use one of those flags are:
The calls to fdopen() seem to be OK. The function mysqld_main() is calling close(stdin), which seems OK. On a normal startup (without all of stdin, stdout, stderr being open), there is no call to close() with the argument STDOUT_FILENO or STDERR_FILENO. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Edward Hicks [ 2017-03-21 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There is nothing in the error logs for days leading up to the crash. I am now noticing that 1:25AM is when we kick off the nightly backup of the primary database. (around 570 databases) Having crashed only 7 seconds after the script was kicked off it looks like a pretty good candidate for the triggering event. The first thing the backup script does is build a config file (not sure why - not my script) and then executes 'show databases' to get a list:
The generated config file only includes is a [client] section with password, port, and optional socket. It then creates a directory for each database (excluding binlog, relay, innodb, and information_schema) and places into it 2 SQL files:
Afterward it tars everything up. I don't have innodb_open_files but I do have a fair amount of customizations to make it production-level responsive and as VM-friendly as is possible for a DBMS:
If you need anything else then let me know. Thanks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Jean Weisbuch [ 2017-03-28 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The same just happened to me on 10.0.29 using Debian Wheezy packages from MariaDB. Here is what i have on my error log :
And at the beginning of the idb file :
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Michael Widenius [ 2017-03-28 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
What is intersting in Jean's log is that the ibfile contains half of the crash, but the stack trace continues I noticed that on windows, we call reopen_fstreams after innodb is opened, which could in theory cause some issues if innodb crashed in a background thread during this reopen. Unfortunately this doesn't explain this crash as Jean's crash is not on windows. How atomic is writing to stderr if freopen() is called ? One FreeBSD we did have a bug like this a long time ago when freopen was not thread safe and another thread could get the same file descriptor as used by stderr: This bug happens apparently on wheezy. Wonder on which other OS this problem has appeared? Regards, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Jean Weisbuch [ 2017-03-28 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Some additional notes on my crash : The server is on an OpenVZ container running kernel 2.6.32-openvz-042stab116.2-amd64 (Jun 24 2016), the server was up since the 17/02 and there are 4 OpenVZ container containing each a MariaDB server on this server. On the error log backlog there is a similar crash that happened on the 17/02 on the same query but with all the log on the error log :
Configuration :
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Edward Hicks [ 2017-03-28 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Ours is:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Edward Hicks [ 2017-03-29 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
We had another event last night which was triggered by the disk running out of free space. The crash was therefore not a surprise; however, in the process another ibd file was corrupted. You can add 10.0.30 to the list of affected versions. Unfortunately I cannot attach it this time as it holds potentially sensitive info; however, this time the top of the overwritten file only contained the string "pure virtual method called".
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Jean Weisbuch [ 2017-07-06 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Any news on this, is it still not possible to upgrade to 10.0.31? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2017-07-14 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
mysqld_safe starts mysqld with with "1" and "2" file descriptors closed. This was introduced in https://github.com/MariaDB/server/commit/7497ebf8a49bfe30bb4110f2ac20a30f804b7946 This means that descriptors "1" and "2" are free for use for any file. But then signal handler writes it's messages to a hardcoded file descriptor STDERR_FILENO (which is "2"). In both reports InnoDB data file header was overrider exactly with signal handler messages. I'm reassigning to serg and raising priority to critical, since it causes data loss. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2017-07-14 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Please also note that early server error messages (before freopen(stderr)) may also go to undesired location. |