Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Performance optimization to the lookaside-memory disabling mechanism. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
17ce1c49cb0ed6fdd8c7c33431bc2afa |
User & Date: | drh 2019-10-05 14:39:36.293 |
Context
2019-10-05
| ||
15:28 | Reorder two comparisons for a small performance gain in OP_Transaction. (check-in: d7667f6560 user: drh tags: trunk) | |
14:39 | Performance optimization to the lookaside-memory disabling mechanism. (check-in: 17ce1c49cb user: drh tags: trunk) | |
2019-10-04
| ||
15:03 | Version 3.30.0 (check-in: c20a353364 user: drh tags: trunk, release, version-3.30.0) | |
Changes
Changes to src/analyze.c.
︙ | ︙ | |||
1850 1851 1852 1853 1854 1855 1856 | Index *pIdx = sqliteHashData(i); if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); } /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT4 if( rc==SQLITE_OK ){ | | | | 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 | Index *pIdx = sqliteHashData(i); if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); } /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT4 if( rc==SQLITE_OK ){ DisableLookaside; rc = loadStat4(db, sInfo.zDatabase); EnableLookaside; } for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3_free(pIdx->aiRowEst); pIdx->aiRowEst = 0; } #endif |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
2443 2444 2445 2446 2447 2448 2449 | #ifndef SQLITE_OMIT_ALTERTABLE u8 eParseMode = pParse->eParseMode; pParse->eParseMode = PARSE_MODE_NORMAL; #endif n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; | | | 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 | #ifndef SQLITE_OMIT_ALTERTABLE u8 eParseMode = pParse->eParseMode; pParse->eParseMode = PARSE_MODE_NORMAL; #endif n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; DisableLookaside; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; db->xAuth = 0; pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); db->xAuth = xAuth; #else pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); |
︙ | ︙ | |||
2485 2486 2487 2488 2489 2490 2491 | assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); }else{ pTable->nCol = 0; nErr++; } sqlite3DeleteTable(db, pSelTab); sqlite3SelectDelete(db, pSel); | | | 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 | assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); }else{ pTable->nCol = 0; nErr++; } sqlite3DeleteTable(db, pSelTab); sqlite3SelectDelete(db, pSel); EnableLookaside; #ifndef SQLITE_OMIT_ALTERTABLE pParse->eParseMode = eParseMode; #endif } else { nErr++; } pTable->pSchema->schemaFlags |= DB_UnresetViews; |
︙ | ︙ |
Changes to src/fkey.c.
︙ | ︙ | |||
1295 1296 1297 1298 1299 1300 1301 | pWhere, 0, 0, 0, 0, 0 ); pWhere = 0; } /* Disable lookaside memory allocation */ | | | 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 | pWhere, 0, 0, 0, 0, 0 ); pWhere = 0; } /* Disable lookaside memory allocation */ DisableLookaside; pTrigger = (Trigger *)sqlite3DbMallocZero(db, sizeof(Trigger) + /* struct Trigger */ sizeof(TriggerStep) + /* Single step in trigger program */ nFrom + 1 /* Space for pStep->zTarget */ ); if( pTrigger ){ |
︙ | ︙ | |||
1317 1318 1319 1320 1321 1322 1323 | if( pWhen ){ pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0); pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); } } /* Re-enable the lookaside buffer, if it was disabled earlier. */ | | | 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 | if( pWhen ){ pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0); pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); } } /* Re-enable the lookaside buffer, if it was disabled earlier. */ EnableLookaside; sqlite3ExprDelete(db, pWhere); sqlite3ExprDelete(db, pWhen); sqlite3ExprListDelete(db, pList); sqlite3SelectDelete(db, pSelect); if( db->mallocFailed==1 ){ fkTriggerDelete(db, pTrigger); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | }else{ pStart = pBuf; } db->lookaside.pStart = pStart; db->lookaside.pInit = 0; db->lookaside.pFree = 0; db->lookaside.sz = (u16)sz; if( pStart ){ int i; LookasideSlot *p; assert( sz > (int)sizeof(LookasideSlot*) ); db->lookaside.nSlot = cnt; p = (LookasideSlot*)pStart; for(i=cnt-1; i>=0; i--){ p->pNext = db->lookaside.pInit; db->lookaside.pInit = p; p = (LookasideSlot*)&((u8*)p)[sz]; } db->lookaside.pEnd = p; db->lookaside.bDisable = 0; db->lookaside.bMalloced = pBuf==0 ?1:0; }else{ db->lookaside.pStart = db; db->lookaside.pEnd = db; db->lookaside.bDisable = 1; db->lookaside.bMalloced = 0; db->lookaside.nSlot = 0; } #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; } | > > | 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 | }else{ pStart = pBuf; } db->lookaside.pStart = pStart; db->lookaside.pInit = 0; db->lookaside.pFree = 0; db->lookaside.sz = (u16)sz; db->lookaside.szTrue = (u16)sz; if( pStart ){ int i; LookasideSlot *p; assert( sz > (int)sizeof(LookasideSlot*) ); db->lookaside.nSlot = cnt; p = (LookasideSlot*)pStart; for(i=cnt-1; i>=0; i--){ p->pNext = db->lookaside.pInit; db->lookaside.pInit = p; p = (LookasideSlot*)&((u8*)p)[sz]; } db->lookaside.pEnd = p; db->lookaside.bDisable = 0; db->lookaside.bMalloced = pBuf==0 ?1:0; }else{ db->lookaside.pStart = db; db->lookaside.pEnd = db; db->lookaside.bDisable = 1; db->lookaside.sz = 0; db->lookaside.bMalloced = 0; db->lookaside.nSlot = 0; } #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; } |
︙ | ︙ | |||
3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 | } sqlite3_mutex_enter(db->mutex); db->errMask = 0xff; db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; db->lookaside.bDisable = 1; assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; db->autoCommit = 1; db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; | > | 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 | } sqlite3_mutex_enter(db->mutex); db->errMask = 0xff; db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; db->lookaside.bDisable = 1; db->lookaside.sz = 0; assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; db->autoCommit = 1; db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; |
︙ | ︙ |
Changes to src/malloc.c.
︙ | ︙ | |||
294 295 296 297 298 299 300 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); } #endif return sqlite3GlobalConfig.m.xSize(p); }else{ assert( sqlite3_mutex_held(db->mutex) ); | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); } #endif return sqlite3GlobalConfig.m.xSize(p); }else{ assert( sqlite3_mutex_held(db->mutex) ); return db->lookaside.szTrue; } } sqlite3_uint64 sqlite3_msize(void *p){ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); return p ? sqlite3GlobalConfig.m.xSize(p) : 0; } |
︙ | ︙ | |||
346 347 348 349 350 351 352 | measureAllocationSize(db, p); return; } if( isLookaside(db, p) ){ LookasideSlot *pBuf = (LookasideSlot*)p; #ifdef SQLITE_DEBUG /* Trash all content in the buffer being freed */ | | | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | measureAllocationSize(db, p); return; } if( isLookaside(db, p) ){ LookasideSlot *pBuf = (LookasideSlot*)p; #ifdef SQLITE_DEBUG /* Trash all content in the buffer being freed */ memset(p, 0xaa, db->lookaside.szTrue); #endif pBuf->pNext = db->lookaside.pFree; db->lookaside.pFree = pBuf; return; } } assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
︙ | ︙ | |||
506 507 508 509 510 511 512 | } void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ #ifndef SQLITE_OMIT_LOOKASIDE LookasideSlot *pBuf; assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); | > | | < > | | | | | | | | | | | < < < | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 | } void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ #ifndef SQLITE_OMIT_LOOKASIDE LookasideSlot *pBuf; assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); if( n>db->lookaside.sz ){ if( db->lookaside.bDisable ){ return db->mallocFailed ? 0 : dbMallocRawFinish(db, n); } db->lookaside.anStat[1]++; }else if( (pBuf = db->lookaside.pFree)!=0 ){ db->lookaside.pFree = pBuf->pNext; db->lookaside.anStat[0]++; return (void*)pBuf; }else if( (pBuf = db->lookaside.pInit)!=0 ){ db->lookaside.pInit = pBuf->pNext; db->lookaside.anStat[0]++; return (void*)pBuf; }else{ db->lookaside.anStat[2]++; } #else assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); if( db->mallocFailed ){ return 0; |
︙ | ︙ | |||
546 547 548 549 550 551 552 | ** Resize the block of memory pointed to by p to n bytes. If the ** resize fails, set the mallocFailed flag in the connection object. */ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ assert( db!=0 ); if( p==0 ) return sqlite3DbMallocRawNN(db, n); assert( sqlite3_mutex_held(db->mutex) ); | | | | 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 | ** Resize the block of memory pointed to by p to n bytes. If the ** resize fails, set the mallocFailed flag in the connection object. */ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ assert( db!=0 ); if( p==0 ) return sqlite3DbMallocRawNN(db, n); assert( sqlite3_mutex_held(db->mutex) ); if( isLookaside(db,p) && n<=db->lookaside.szTrue ) return p; return dbReallocFinish(db, p, n); } static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ void *pNew = 0; assert( db!=0 ); assert( p!=0 ); if( db->mallocFailed==0 ){ if( isLookaside(db, p) ){ pNew = sqlite3DbMallocRawNN(db, n); if( pNew ){ memcpy(pNew, p, db->lookaside.szTrue); sqlite3DbFree(db, p); } }else{ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); pNew = sqlite3_realloc64(p, n); |
︙ | ︙ | |||
656 657 658 659 660 661 662 | */ void sqlite3OomFault(sqlite3 *db){ if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ db->mallocFailed = 1; if( db->nVdbeExec>0 ){ db->u1.isInterrupted = 1; } | | | | 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 | */ void sqlite3OomFault(sqlite3 *db){ if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ db->mallocFailed = 1; if( db->nVdbeExec>0 ){ db->u1.isInterrupted = 1; } DisableLookaside; if( db->pParse ){ db->pParse->rc = SQLITE_NOMEM_BKPT; } } } /* ** This routine reactivates the memory allocator and clears the ** db->mallocFailed flag as necessary. ** ** The memory allocator is not restarted if there are running ** VDBEs. */ void sqlite3OomClear(sqlite3 *db){ if( db->mallocFailed && db->nVdbeExec==0 ){ db->mallocFailed = 0; db->u1.isInterrupted = 0; assert( db->lookaside.bDisable>0 ); EnableLookaside; } } /* ** Take actions at the end of an API call to indicate an OOM error */ static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
102 103 104 105 106 107 108 109 | struct FrameBound { int eType; Expr *pExpr; }; /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. */ static void disableLookaside(Parse *pParse){ pParse->disableLookaside++; | > | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | struct FrameBound { int eType; Expr *pExpr; }; /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. */ static void disableLookaside(Parse *pParse){ sqlite3 *db = pParse->db; pParse->disableLookaside++; DisableLookaside; } } // end %include // Input is a single SQL command input ::= cmdlist. cmdlist ::= cmdlist ecmd. |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
523 524 525 526 527 528 529 530 531 532 533 534 535 536 | void sqlite3ParserReset(Parse *pParse){ sqlite3 *db = pParse->db; sqlite3DbFree(db, pParse->aLabel); sqlite3ExprListDelete(db, pParse->pConstExpr); if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; } pParse->disableLookaside = 0; } /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ | > | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 | void sqlite3ParserReset(Parse *pParse){ sqlite3 *db = pParse->db; sqlite3DbFree(db, pParse->aLabel); sqlite3ExprListDelete(db, pParse->pConstExpr); if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; } pParse->disableLookaside = 0; } /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ |
︙ | ︙ | |||
556 557 558 559 560 561 562 | assert( sqlite3_mutex_held(db->mutex) ); /* For a long-term use prepared statement avoid the use of ** lookaside memory. */ if( prepFlags & SQLITE_PREPARE_PERSISTENT ){ sParse.disableLookaside++; | | | 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 | assert( sqlite3_mutex_held(db->mutex) ); /* For a long-term use prepared statement avoid the use of ** lookaside memory. */ if( prepFlags & SQLITE_PREPARE_PERSISTENT ){ sParse.disableLookaside++; DisableLookaside; } sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0; /* Check to verify that it is possible to get a read lock on all ** database schemas. The inability to get a read lock indicates that ** some other database connection is holding a write-lock, which in ** turn means that the other connection has made uncommitted changes |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 | ** ** Lookaside allocations are only allowed for objects that are associated ** with a particular database connection. Hence, schema information cannot ** be stored in lookaside because in shared cache mode the schema information ** is shared by multiple database connections. Therefore, while parsing ** schema information, the Lookaside.bEnabled flag is cleared so that ** lookaside allocations are not used to construct the schema objects. */ struct Lookaside { u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ u32 nSlot; /* Number of lookaside slots allocated */ u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ LookasideSlot *pInit; /* List of buffers not previously used */ LookasideSlot *pFree; /* List of available buffers */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ }; struct LookasideSlot { LookasideSlot *pNext; /* Next buffer in the list of free buffers */ }; /* ** A hash table for built-in function definitions. (Application-defined ** functions use a regular table table from hash.h.) ** ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots. ** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH() | > > > > > > > > > > > | 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 | ** ** Lookaside allocations are only allowed for objects that are associated ** with a particular database connection. Hence, schema information cannot ** be stored in lookaside because in shared cache mode the schema information ** is shared by multiple database connections. Therefore, while parsing ** schema information, the Lookaside.bEnabled flag is cleared so that ** lookaside allocations are not used to construct the schema objects. ** ** New lookaside allocations are only allowed if bDisable==0. When ** bDisable is greater than zero, sz is set to zero which effectively ** disables lookaside without adding a new test for the bDisable flag ** in a performance-critical path. sz should be set by to szTrue whenever ** bDisable changes back to zero. */ struct Lookaside { u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ u16 szTrue; /* True value of sz, even if disabled */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ u32 nSlot; /* Number of lookaside slots allocated */ u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ LookasideSlot *pInit; /* List of buffers not previously used */ LookasideSlot *pFree; /* List of available buffers */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ }; struct LookasideSlot { LookasideSlot *pNext; /* Next buffer in the list of free buffers */ }; #define DisableLookaside db->lookaside.bDisable++;db->lookaside.sz=0 #define EnableLookaside db->lookaside.bDisable--;\ db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue /* ** A hash table for built-in function definitions. (Application-defined ** functions use a regular table table from hash.h.) ** ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots. ** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH() |
︙ | ︙ |