Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Defend against disk I/O errors that happen during an sqlite3OsSeek(). (CVS 2679) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
461e3a0a27ff083b0bae10c9880e3b41 |
User & Date: | drh 2005-09-09 01:32:06.000 |
Context
2005-09-09
| ||
01:33 | Infrastructure for the DISTINCT keyword in aggregate functions. But it does not work yet. If you try to use it you get an error message. (CVS 2680) (check-in: 4d62e36fe3 user: drh tags: trunk) | |
01:32 | Defend against disk I/O errors that happen during an sqlite3OsSeek(). (CVS 2679) (check-in: 461e3a0a27 user: drh tags: trunk) | |
2005-09-08
| ||
20:37 | SUM returns NULL when it has no inputs. Ticket #1413. (CVS 2678) (check-in: 6281859425 user: drh tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
768 769 770 771 772 773 774 775 776 777 778 779 780 781 | /* ** Move the read/write pointer in a file. */ int sqlite3OsSeek(OsFile *id, i64 offset){ assert( id->isOpen ); SEEK(offset/1024 + 1); lseek(id->h, offset, SEEK_SET); return SQLITE_OK; } #ifdef SQLITE_TEST /* ** Count the number of fullsyncs and normal syncs. This is used to test | > > > | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 | /* ** Move the read/write pointer in a file. */ int sqlite3OsSeek(OsFile *id, i64 offset){ assert( id->isOpen ); SEEK(offset/1024 + 1); #ifdef SQLITE_TEST if( offset ) SimulateDiskfullError #endif lseek(id->h, offset, SEEK_SET); return SQLITE_OK; } #ifdef SQLITE_TEST /* ** Count the number of fullsyncs and normal syncs. This is used to test |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
469 470 471 472 473 474 475 476 477 478 479 480 481 482 | ** Move the read/write pointer in a file. */ int sqlite3OsSeek(OsFile *id, i64 offset){ LONG upperBits = offset>>32; LONG lowerBits = offset & 0xffffffff; DWORD rc; assert( id->isOpen ); SEEK(offset/1024 + 1); rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN); TRACE3("SEEK %d %lld\n", id->h, offset); return SQLITE_OK; } /* | > > > | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 | ** Move the read/write pointer in a file. */ int sqlite3OsSeek(OsFile *id, i64 offset){ LONG upperBits = offset>>32; LONG lowerBits = offset & 0xffffffff; DWORD rc; assert( id->isOpen ); #ifdef SQLITE_TEST if( offset ) SimulateDiskfullError #endif SEEK(offset/1024 + 1); rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN); TRACE3("SEEK %d %lld\n", id->h, offset); return SQLITE_OK; } /* |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.212 2005/09/09 01:32:06 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
653 654 655 656 657 658 659 | rc = write32bits(&pPager->jfd, pPager->sectorSize); } /* The journal header has been written successfully. Seek the journal ** file descriptor to the end of the journal header sector. */ if( rc==SQLITE_OK ){ | | > | > | 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 | rc = write32bits(&pPager->jfd, pPager->sectorSize); } /* The journal header has been written successfully. Seek the journal ** file descriptor to the end of the journal header sector. */ if( rc==SQLITE_OK ){ rc = sqlite3OsSeek(&pPager->jfd, pPager->journalOff-1); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(&pPager->jfd, "\000", 1); } } return rc; } /* ** The journal file must be open when this is called. A journal header file ** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal |
︙ | ︙ | |||
1034 1035 1036 1037 1038 1039 1040 | ** page content is in the main journal either because the page is not in ** cache or else it is marked as needSync==0. */ pPg = pager_lookup(pPager, pgno); assert( pPager->state>=PAGER_EXCLUSIVE || pPg!=0 ); TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno); if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){ | | > | > | 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 | ** page content is in the main journal either because the page is not in ** cache or else it is marked as needSync==0. */ pPg = pager_lookup(pPager, pgno); assert( pPager->state>=PAGER_EXCLUSIVE || pPg!=0 ); TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno); if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){ rc = sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize); } if( pPg ) pPg->dirty = 0; } if( pPg ){ /* No page should ever be explicitly rolled back that is in use, except ** for page 1 which is held in use in order to keep the lock on the ** database active. However such a page may be rolled back as a result ** of an internal error resulting in an automatic call to |
︙ | ︙ | |||
1164 1165 1166 1167 1168 1169 1170 | static int pager_reload_cache(Pager *pPager){ PgHdr *pPg; int rc = SQLITE_OK; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ char zBuf[SQLITE_MAX_PAGE_SIZE]; if( !pPg->dirty ) continue; if( (int)pPg->pgno <= pPager->origDbSize ){ | | > | > | 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 | static int pager_reload_cache(Pager *pPager){ PgHdr *pPg; int rc = SQLITE_OK; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ char zBuf[SQLITE_MAX_PAGE_SIZE]; if( !pPg->dirty ) continue; if( (int)pPg->pgno <= pPager->origDbSize ){ rc = sqlite3OsSeek(&pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1)); if( rc==SQLITE_OK ){ rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize); } TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno); if( rc ) break; CODEC(pPager, zBuf, pPg->pgno, 2); }else{ memset(zBuf, 0, pPager->pageSize); } if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){ |
︙ | ︙ | |||
2120 2121 2122 2123 2124 2125 2126 | ** it as a candidate for rollback. */ if( pPager->fullSync ){ TRACE2("SYNC journal of %d\n", PAGERID(pPager)); rc = sqlite3OsSync(&pPager->jfd, 0); if( rc!=0 ) return rc; } | > | > | > | 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 | ** it as a candidate for rollback. */ if( pPager->fullSync ){ TRACE2("SYNC journal of %d\n", PAGERID(pPager)); rc = sqlite3OsSync(&pPager->jfd, 0); if( rc!=0 ) return rc; } rc = sqlite3OsSeek(&pPager->jfd, pPager->journalHdr + sizeof(aJournalMagic)); if( rc ) return rc; rc = write32bits(&pPager->jfd, pPager->nRec); if( rc ) return rc; rc = sqlite3OsSeek(&pPager->jfd, pPager->journalOff); if( rc ) return rc; } TRACE2("SYNC journal of %d\n", PAGERID(pPager)); rc = sqlite3OsSync(&pPager->jfd, pPager->fullSync); if( rc!=0 ) return rc; pPager->journalStarted = 1; } pPager->needSync = 0; |
︙ | ︙ | |||
2192 2193 2194 2195 2196 2197 2198 | rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ return rc; } while( pList ){ assert( pList->dirty ); | | > | 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 | rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ return rc; } while( pList ){ assert( pList->dirty ); rc = sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize); if( rc ) return rc; /* If there are dirty pages in the page cache with page numbers greater ** than Pager.dbSize, this means sqlite3pager_truncate() was called to ** make the file smaller (presumably by auto-vacuum code). Do not write ** any such pages to the file. */ if( pList->pgno<=pPager->dbSize ){ CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); |
︙ | ︙ | |||
2502 2503 2504 2505 2506 2507 2508 | return rc; } if( sqlite3pager_pagecount(pPager)<(int)pgno ){ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); }else{ int rc; assert( MEMDB==0 ); | | > | > | 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 | return rc; } if( sqlite3pager_pagecount(pPager)<(int)pgno ){ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); }else{ int rc; assert( MEMDB==0 ); rc = sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); if( rc==SQLITE_OK ){ rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize); } TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno); CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3); if( rc!=SQLITE_OK ){ i64 fileSize; if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK || fileSize>=pgno*pPager->pageSize ){ sqlite3pager_unref(PGHDR_TO_DATA(pPg)); |
︙ | ︙ |