Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the undocumented and experimental I/O tracing interface. This interface is likely to change and may be completely abandoned in the near future. (CVS 3665) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
007ca283892a66dd8b9e0dfece4f75d0 |
User & Date: | drh 2007-02-28 04:47:27.000 |
Context
2007-02-28
| ||
06:14 | Work around incompatibilities in the windows printf() routine within the new I/O tracing logic. (CVS 3666) (check-in: ceb3a07f55 user: drh tags: trunk) | |
04:47 | Add the undocumented and experimental I/O tracing interface. This interface is likely to change and may be completely abandoned in the near future. (CVS 3665) (check-in: 007ca28389 user: drh tags: trunk) | |
2007-02-27
| ||
02:01 | Improvements to OS layer tracing on the unix backend. (CVS 3664) (check-in: 3ad96dbe09 user: drh tags: trunk) | |
Changes
Changes to src/main.c.
︙ | |||
10 11 12 13 14 15 16 | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | - + + + + + + + + + | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** |
︙ |
Changes to src/pager.c.
︙ | |||
14 15 16 17 18 19 20 | 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. ** |
︙ | |||
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | + + | /* The random check-hash initialiser */ sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); /* The initial database size */ put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize); /* The assumed sector size for this process */ put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, sizeof(zHeader))) rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader)); /* The journal header has been written successfully. Seek the journal ** file descriptor to the end of the journal header sector. */ if( rc==SQLITE_OK ){ IOTRACE(("JTAIL %p %lld\n", pPager, pPager->journalOff-1)) rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff-1); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->jfd, "\000", 1); } } return rc; } |
︙ | |||
857 858 859 860 861 862 863 864 865 866 867 868 869 870 | 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 | + | ** processes or threads might change the file. So make sure all of ** our internal cache is invalidated. */ static void pager_unlock(Pager *pPager){ if( !MEMDB ){ sqlite3OsUnlock(pPager->fd, NO_LOCK); pPager->dbSize = -1; IOTRACE(("UNLOCK %p\n", pPager)) } pPager->state = PAGER_UNLOCK; assert( pPager->pAll==0 ); } /* |
︙ | |||
1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 | 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 | + | sqlite3OsClose(&fd); sqliteFree(zFullPathname); sqliteFree(pPager); return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc); } TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname); IOTRACE(("OPEN %p %s\n", pPager, zFullPathname)) pPager->zFilename = (char*)&pPager[1]; pPager->zDirectory = &pPager->zFilename[nameLen+1]; pPager->zJournal = &pPager->zDirectory[nameLen+1]; strcpy(pPager->zFilename, zFullPathname); strcpy(pPager->zDirectory, zFullPathname); for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){} |
︙ | |||
1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 | 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 | + | int sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){ int rc = SQLITE_OK; memset(pDest, 0, N); if( MEMDB==0 ){ disable_simulated_io_errors(); sqlite3OsSeek(pPager->fd, 0); enable_simulated_io_errors(); IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) rc = sqlite3OsRead(pPager->fd, pDest, N); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } } return rc; } |
︙ | |||
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 | 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 | + | rc = SQLITE_OK; }else{ do { rc = sqlite3OsLock(pPager->fd, locktype); }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) ); if( rc==SQLITE_OK ){ pPager->state = locktype; IOTRACE(("LOCK %p %d\n", pPager, locktype)) } } return rc; } /* ** Truncate the file to the number of pages specified. |
︙ | |||
2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 | 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 | + | #endif disable_simulated_io_errors(); pPager->errCode = 0; pager_reset(pPager); enable_simulated_io_errors(); TRACE2("CLOSE %d\n", PAGERID(pPager)); IOTRACE(("CLOSE %p\n", pPager)) assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); if( pPager->journalOpen ){ sqlite3OsClose(&pPager->jfd); } sqliteFree(pPager->aInJournal); if( pPager->stmtOpen ){ sqlite3OsClose(&pPager->stfd); |
︙ | |||
2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 | 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 | + + + + | /* Write the nRec value into the journal file header. If in ** full-synchronous mode, sync the journal first. This ensures that ** all data has really hit the disk before nRec is updated to mark ** it as a candidate for rollback. */ if( pPager->fullSync ){ TRACE2("SYNC journal of %d\n", PAGERID(pPager)); IOTRACE(("JSYNC %p\n", pPager)) rc = sqlite3OsSync(pPager->jfd, 0); if( rc!=0 ) return rc; } rc = sqlite3OsSeek(pPager->jfd, pPager->journalHdr + sizeof(aJournalMagic)); if( rc ) return rc; IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr + sizeof(aJournalMagic), 4)) 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)); IOTRACE(("JSYNC %d\n", pPager)) rc = sqlite3OsSync(pPager->jfd, pPager->full_fsync); if( rc!=0 ) return rc; pPager->journalStarted = 1; } pPager->needSync = 0; /* Erase the needSync flag from every page. |
︙ | |||
2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 | 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 | + | ** 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 ){ char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno); IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno)) rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize); TEST_INCR(pPager->nWrite); } #ifndef NDEBUG else{ TRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno); } |
︙ | |||
2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 | 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 | + | }else{ 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); } IOTRACE(("PGIN %p %d\n", pPager, pgno)) TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno); CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3); if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ pPg->pgno = 0; sqlite3pager_unref(PGHDR_TO_DATA(pPg)); return rc; }else{ |
︙ | |||
3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 | 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 | + + | pEnd = pData2 + pPager->pageSize; pData2 -= 4; saved = *(u32*)pEnd; put32bits(pEnd, cksum); szPg = pPager->pageSize+8; put32bits(pData2, pPg->pgno); rc = sqlite3OsWrite(pPager->jfd, pData2, szPg); IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, pPager->journalOff, szPg)) pPager->journalOff += szPg; TRACE4("JOURNAL %d page %d needSync=%d\n", PAGERID(pPager), pPg->pgno, pPg->needSync); *(u32*)pEnd = saved; /* An error has occured writing to the journal file. The ** transaction will be rolled back by the layer above. |
︙ | |||
3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 | 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 | + | ** gets written at least once so that the disk file will be the correct ** size. If you do not write this page and the size of the file ** on the disk ends up being too small, that can lead to database ** corruption during the next transaction. */ }else{ TRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager)); IOTRACE(("CLEAN %p %d\n", pPager, pgno)) makeClean(pPg); #ifdef SQLITE_CHECK_PAGES pPg->pageHash = pager_pagehash(pPg); #endif } } } |
︙ | |||
3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 | 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 | + | pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); pPg->inJournal = 1; if( pPager->stmtInUse ){ pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); page_add_to_stmt_list(pPg); } TRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager)); IOTRACE(("GARBAGE %p %d\n", pPager, pPg->pgno)) } if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); assert( pPager->aInStmt!=0 ); pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); page_add_to_stmt_list(pPg); } |
︙ | |||
3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 | 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 | + | rc = pager_write_pagelist(pPg); if( rc!=SQLITE_OK ) goto sync_exit; /* Sync the database file. */ if( !pPager->noSync ){ rc = sqlite3OsSync(pPager->fd, 0); } IOTRACE(("DBSYNC %p\n", pPager)) pPager->state = PAGER_SYNCED; }else if( MEMDB && nTrunc!=0 ){ rc = sqlite3pager_truncate(pPager, nTrunc); } sync_exit: |
︙ | |||
3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 | 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 | + | int h; Pgno needSyncPgno = 0; assert( pPg->nRef>0 ); TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", PAGERID(pPager), pPg->pgno, pPg->needSync, pgno); IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) if( pPg->needSync ){ needSyncPgno = pPg->pgno; assert( pPg->inJournal ); assert( pPg->dirty ); assert( pPager->needSync ); } |
︙ |
Changes to src/shell.c.
︙ | |||
8 9 10 11 12 13 14 | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | - + + | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** |
︙ | |||
92 93 94 95 96 97 98 99 100 101 102 103 104 105 | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | + + + + + + + + + + + + + + + + + + + | /* ** Prompt strings. Initialized in main. Settable with ** .prompt main continue */ static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ /* ** Write I/O traces to the following stream. */ static FILE *iotrace = 0; /* ** This routine works like printf in that its first argument is a ** format string and subsequent arguments are values to be substituted ** in place of % fields. The result of formatting this string ** is written to iotrace. */ static void iotracePrintf(const char *zFormat, ...){ va_list ap; if( iotrace==0 ) return; va_start(ap, zFormat); vfprintf(iotrace, zFormat, ap); va_end(ap); } /* ** Determines if a string is a number of not. */ static int isNumber(const char *z, int *realnum){ if( *z=='-' || *z=='+' ) z++; |
︙ | |||
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 | 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 | + + + + + + + + + + + + + + + + + + + + | "ORDER BY 1", callback, &data, &zErrMsg ); zShellStatic = 0; if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } }else if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ extern void (*sqlite3_io_trace)(const char*, ...); if( iotrace && iotrace!=stdout ) fclose(iotrace); iotrace = 0; if( nArg<2 ){ sqlite3_io_trace = 0; }else if( strcmp(azArg[1], "-")==0 ){ sqlite3_io_trace = iotracePrintf; iotrace = stdout; }else{ iotrace = fopen(azArg[1], "w"); if( iotrace==0 ){ fprintf(stderr, "cannot open \"%s\"\n", azArg[1]); sqlite3_io_trace = 0; }else{ sqlite3_io_trace = iotracePrintf; } } }else #ifndef SQLITE_OMIT_LOAD_EXTENSION if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){ const char *zFile, *zProc; char *zErrMsg = 0; |
︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | - + | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** |
︙ | |||
1893 1894 1895 1896 1897 1898 1899 1900 | 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 | + + + + + + + + + + + + | void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); int sqlite3Reprepare(Vdbe*); #ifdef SQLITE_SSE #include "sseInt.h" #endif /* ** If the SQLITE_ENABLE IOTRACE exists then the global variable ** sqlite3_io_trace is a pointer to a printf-like routine used to ** print I/O tracing messages. */ #ifdef SQLITE_ENABLE_IOTRACE # define IOTRACE(A) if( sqlite3_io_trace ){ sqlite3_io_trace A; } #else # define IOTRACE(A) #endif extern void (*sqlite3_io_trace)(const char*,...); #endif |