Description:
Running MySQL Distrib 3.23.54, on i32 using Win2000 NTFS. This is
where I see the error:
E:\mysql\data\test>myisamchk -O key_buffer=512M -O sort_buffer=512M -O
read_buffer=64M -O write_buffer=64M -r -S -a rsecpossqs
- recovering (with keycache) MyISAM-table 'rsecpossqs.MYI'
Data records: 54822847
myisamchk: warning: Can't change size of indexfile, error: 22
myisamchk: error: 22 for record at pos 4294967232
MyISAM-table 'rsecpossqs' is not fixed because of errors
Try fixing it by using the --safe-recover (-o) or the --force (-f) option
And this is about 4 hours after starting the command; right after myisamchk
runs through counting up the rows.
The table is the standard size, no adjustments have been made to the
AVG_ROW_LENGTH and MAX_ROWS yet. File sizes are:
4,294,967,268 rsecpossqs.MYD
4,383,221,760 rsecpossqs.MYI
at the moment. Should be cut in half after the optimize because of deletes.
Will be looking at merge tables later, but I need this working in the
mean-time.
Output from myisamchk -dv rsecpossqs.myi
MyISAM file: rsecpossqs.myi
Record format: Packed
Character set: latin1 (8)
File-version: 1
Creation time: 2002-10-18 22:39:44
Recover time: 2002-10-19 23:38:27
Status: changed
Data records: 54822847 Deleted blocks: 40358029
Datafile parts: 95419877 Deleted data: 1772432408
Datafile pointer (bytes): 4 Keyfile pointer (bytes): 4
Datafile length: 4294967268 Keyfile length: 4383221760
Max datafile length: 4294967294 Max keyfile length: 4398046510079
Recordlength: 101
table description:
Key Start Len Index Type Rec/key Root
Blocksize
1 2 4 multip. long 0 1628417024 1024
2 99 3 multip. uint24 0 2517115904 1024
3 95 4 multip. long 0 2130399232 1024
4 31 64 multip. char packed stripped 0 1526540288 1024
5 14 16 multip. char packed stripped 0 1576935424 1024
I did some cursory looks through the source code, I've found the following:
my_chsize is being called from the mi_repair function.
Prototype for my_chsize is:
int my_chsize(File fd, my_off_t newlength, myf MyFlags);
my_off_t is a cast of unsigned __int64
inside my_chsize the function chsize is called with a prototype of:
int chsize(int, long);
basicly converting the __int64 into a long.
I'm guessing that the chsize function is a standard c function?
How to repeat:
Create a table with an index ~> 4GB on Windows.
Suggested fix:
The problem is the chsize function which only supports long integer for file
size. I changed the config-win.h line 232 #define HAVE_CHSIZE to #undef
HAVE_CHSIZE so that the code no longer uses the chsize function. The other
code which is implemented instead seems to correctly use __int64
all the way through, as far as I can tell (being a neophyte C programmer).
When I made the change and recompiled the myisamchk program, the execution
seems to complete successfully (although I do not know if it breaks
something else).