Re: [ADMIN] ERROR: could not read block - Mailing list pgsql-hackers
From | Qingqing Zhou |
---|---|
Subject | Re: [ADMIN] ERROR: could not read block |
Date | |
Msg-id | Pine.LNX.4.58.0511301959540.12750@eon.cs Whole thread Raw |
Responses |
Re: [ADMIN] ERROR: could not read block
Re: [ADMIN] ERROR: could not read block |
List | pgsql-hackers |
I come up with a patch to fix server-side problem. The basic idea is to convert ERROR_NO_SYSTEM_RESOURCES to EINTR and add code to do retry unless a new error encountered or successfully done. I tweak the FileRead() logic on "returnCode <= 0" a little bit by separating it to "<0" and "==0" parts. This is because if our read passed EOF, read() will not set errno which may cause a dead loop if a previous read() is interrupted. For windows, I set a one second waiting time - this should be ok since the problem is very rare. If the error is permenate, you can always SIGINT the process since the waiting is done by pg_usleep(). Regards, Qingqing --- Index: src/backend/storage/file/fd.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/storage/file/fd.c,v retrieving revision 1.122 diff -c -r1.122 fd.c *** src/backend/storage/file/fd.c 22 Nov 2005 18:17:20 -0000 1.122 --- src/backend/storage/file/fd.c 1 Dec 2005 01:09:59 -0000 *************** *** 1009,1019 **** if (returnCode < 0) return returnCode; ! returnCode = read(VfdCache[file].fd, buffer, amount); ! if (returnCode > 0) ! VfdCache[file].seekPos += returnCode; ! else ! VfdCache[file].seekPos = FileUnknownPos; return returnCode; } --- 1009,1052 ---- if (returnCode < 0) return returnCode; ! for (;;) ! { ! returnCode = read(VfdCache[file].fd, buffer, amount); ! ! if (returnCode > 0) ! VfdCache[file].seekPos += returnCode; ! else if (returnCode == 0) ! VfdCache[file].seekPos = FileUnknownPos; ! else ! { ! #ifdef WIN32 ! DWORD error = GetLastError(); ! ! switch (error) ! { ! /* ! * Since we are using buffered IO now, so windows may run ! * out of kernel buffer and return a "Insufficient system ! * resources" error. Retry to solve it. ! */ ! case ERROR_NO_SYSTEM_RESOURCES: ! pg_usleep(1000); ! errno = EINTR; ! break; ! default: ! _dosmaperr(error); ! Assert(errno != EINTR); ! } ! #endif ! /* Ok if interrupted and retry */ ! if (errno == EINTR) ! continue; ! ! VfdCache[file].seekPos = FileUnknownPos; ! } ! ! break; ! } return returnCode; } *************** *** 1033,1049 **** if (returnCode < 0) return returnCode; ! errno = 0; ! returnCode = write(VfdCache[file].fd, buffer, amount); ! /* if write didn't set errno, assume problem is no disk space */ ! if (returnCode != amount && errno == 0) ! errno = ENOSPC; ! if (returnCode > 0) ! VfdCache[file].seekPos += returnCode; ! else ! VfdCache[file].seekPos = FileUnknownPos; return returnCode; } --- 1066,1108 ---- if (returnCode < 0) return returnCode; ! for (;;) ! { ! errno = 0; ! returnCode = write(VfdCache[file].fd, buffer, amount); ! /* if write didn't set errno, assume problem is no disk space */ ! if (returnCode != amount && errno == 0) ! errno = ENOSPC; ! if (returnCode > 0) ! VfdCache[file].seekPos += returnCode; ! else ! { ! #ifdef WIN32 ! DWORD error = GetLastError(); ! ! switch (error) ! { ! /* see comments in FileRead() */ ! case ERROR_NO_SYSTEM_RESOURCES: ! pg_usleep(1000); ! errno = EINTR; ! break; ! default: ! _dosmaperr(error); ! Assert(errno != EINTR); ! } ! #endif ! /* Ok if interrupted and retry */ ! if (errno == EINTR) ! continue; ! ! VfdCache[file].seekPos = FileUnknownPos; ! } ! ! break; ! } return returnCode; }
pgsql-hackers by date: