The following bug has been logged online:
Bug reference: 4162
Logged by: Javier
Email address: elpochodelagente@gmail.com
PostgreSQL version: 8.3.1
Operating system: Windows XP SP2
Description: Hotbackup recovery doesn't work in windows
Details:
I've found that the hotbackup recovery process as described in
http://www.postgresql.org/docs/8.3/interactive/continuous-archiving.html
fails in windows.
The cause can be found in
static XLogRecord *
ReadRecord(XLogRecPtr *RecPtr, int emode);
The problem is the following: When postgres tryies to recover, it looks for
WAL files in incremental order until it reaches a file while doesn't exist.
The variable readFile is assigned a file descriptor for the next WAL file to
be recovered, which is obtained by procedure XLogReadFile. When postgres
reaches a WAL file that doesn't exist, XLogReadFile returns -1.
Now, after getting readFile value, the following code is executed:
if (readFile < 0)
goto next_record_is_invalid;
label next_record_is_invalid is followed by
next_record_is_invalid:;
close(readFile);
in POSIX version of close() it would just fail because the descriptor is
invalid. In microsoft implementation (close() included from io.h), the
application crashes (it doesn't even raise an exception, while debugging a
message appears saying "Microsoft Visual Studio C Runtime Library has
detected a fatal error in testclose.exe.").
The bug may be fixed by testing readFile before close:
next_record_is_invalid:;
if (readFile >= 0)
close(readFile);
To reproduce bug you can try making a base backup in windows and then trying
to recover.
I discovered all this by attaching to postgres.exe process at start with
visual studio 2005, the debugging symbols where invaluable. Then I tested
this minimal code just to check in a new project.
#include "stdafx.h"
#include <io.h>
int _tmain(int argc, _TCHAR* argv[])
{
close(-1);
return 0;
}
it crashes the same way.