WL#3951: MyISAM: Additional Error Logs for Data Corruption

Affects: Server-5.5   —   Status: Complete

When data corruption occurs, it is needed to log more information that can be 
used to locate the cause of corruption.

The following information is from BUG#28414:

When a myisam table becomes corrupted, mysql usually writes something like this 
to error log:

070514  9:43:48 [ERROR] mysqld-debug: Incorrect key file for 
table '.\test\t1.MYI'; try to repair it

However, this is not enough information to identify the source of these 
corruptions.

Some errors where we need the information are: 134, 127, 124, 126

Some ideas that could appear in error logs:

1) current running query which caused/found the corruption
2) current threads reading/writing from that table can be printed
3) the function/source code file in which the error originate can be printed.
4) dump the current processlist?
5) ... other ideas?

These information should be included in the release version of mysql.

A complete solution could be a combination of error logs and utilities for 
analyzing the corrupted file(s).
When table currption is detected, in addition to current error message we will 
provide following information:
- list of threads (and queries) accessing a table;
- thread_id of a thread that detected corruption;
- source file name and line number where this corruption was detected;
- optional extra information (string).

An example of error report:
Got an error from thread_id=2, mi_dynrec.c:368
Delete link crashed
thread_id=2, query=INSERT INTO t1 VALUES(1)
thread_id=3, query=SELECT * FROM t1
We will implement new function for reporting extra information:

void _mi_report_crashed(MI_INFO *file, const char *message,
                        const char *sfile, uint sline);
file - MI_INFO object;
message - optional error string;
sfile - name of source file;
sline - line number in source file.

_mi_report_crashed() will be called from mi_mark_crashed() macro.

To report threads (+ queries) accessing current table, we need to maintain list 
of threads accessing current table. Extra elements will be added to MI_INFO and 
MYISAM_SHARE structures. MI_INFO will be extended with LIST element, that will 
hold a pointer to THD object accessing a table. MYISAM_SHARE will be extended 
with LIST (list of threads accessing a table).

For every call to ha_myisam::external_lock(F_[RD|WR|EXTRA_]LCK) - add current 
thread to the list.

For every call to ha_myisam::external_lock(F_UNLCK) - remove current thread 
from the list.

The same must be done for merge tables in ha_myisammrg::external_lock().

All operations with the list must be protected by myisam share intern_lock.

As INSERT DELAYED doesn't preserve query string, we have no chance to report 
query string. Instead we will just report that it is delayed insert thread.

Some system temporary tables do not get locked by external_lock() method. For 
these tables we will only report source file name and line number.