diff --git a/src/box/sql/malloc.c b/src/box/sql/malloc.c index f5612bf49cd8..c3fc50b40f76 100644 --- a/src/box/sql/malloc.c +++ b/src/box/sql/malloc.c @@ -120,26 +120,6 @@ sql_sized_realloc(void *pPrior, int nByte) return (void *)p; } -/* - * Attempt to release up to n bytes of non-essential memory currently - * held by sql. An example of non-essential memory is memory used to - * cache database pages that are not currently in use. - */ -int -sql_release_memory(int n) -{ -#ifdef SQL_ENABLE_MEMORY_MANAGEMENT - return sqlPcacheReleaseMemory(n); -#else - /* IMPLEMENTATION-OF: R-34391-24921 The sql_release_memory() routine - * is a no-op returning zero if sql is not compiled with - * SQL_ENABLE_MEMORY_MANAGEMENT. - */ - UNUSED_PARAMETER(n); - return 0; -#endif -} - /* * An instance of the following object records the location of * each unused scratch buffer. @@ -148,39 +128,12 @@ typedef struct ScratchFreeslot { struct ScratchFreeslot *pNext; /* Next unused scratch buffer */ } ScratchFreeslot; -/* - * State information local to the memory allocation subsystem. - */ -static SQL_WSD struct Mem0Global { - sql_int64 alarmThreshold; /* The soft heap limit */ - - /* - * Pointers to the end of sqlGlobalConfig.pScratch memory - * (so that a range test can be used to determine if an allocation - * being freed came from pScratch) and a pointer to the list of - * unused scratch allocations. - */ - void *pScratchEnd; - ScratchFreeslot *pScratchFree; - u32 nScratchFree; - - /* - * True if heap is nearly "full" where "full" is defined by the - * sql_soft_heap_limit() setting. - */ - int nearlyFull; -} mem0 = { -0, 0, 0, 0, 0}; - -#define mem0 GLOBAL(struct Mem0Global, mem0) - /* * Initialize the memory allocation subsystem. */ void sqlMallocInit(void) { - memset(&mem0, 0, sizeof(mem0)); if (sqlGlobalConfig.pScratch && sqlGlobalConfig.szScratch >= 100 && sqlGlobalConfig.nScratch > 0) { int i, n, sz; @@ -189,16 +142,12 @@ sqlMallocInit(void) sqlGlobalConfig.szScratch = sz; pSlot = (ScratchFreeslot *) sqlGlobalConfig.pScratch; n = sqlGlobalConfig.nScratch; - mem0.pScratchFree = pSlot; - mem0.nScratchFree = n; for (i = 0; i < n - 1; i++) { pSlot->pNext = (ScratchFreeslot *) (sz + (char *)pSlot); pSlot = pSlot->pNext; } pSlot->pNext = 0; - mem0.pScratchEnd = (void *)&pSlot[1]; } else { - mem0.pScratchEnd = 0; sqlGlobalConfig.pScratch = 0; sqlGlobalConfig.szScratch = 0; sqlGlobalConfig.nScratch = 0; @@ -210,37 +159,6 @@ sqlMallocInit(void) } } -/* - * Return true if the heap is currently under memory pressure - in other - * words if the amount of heap used is close to the limit set by - * sql_soft_heap_limit(). - */ -int -sqlHeapNearlyFull(void) -{ - return mem0.nearlyFull; -} - -/* - * Deinitialize the memory allocation subsystem. - */ -void -sqlMallocEnd(void) -{ - memset(&mem0, 0, sizeof(mem0)); -} - -/* - * Trigger the alarm - */ -static void -sqlMallocAlarm(int nByte) -{ - if (mem0.alarmThreshold <= 0) - return; - sql_release_memory(nByte); -} - /* * Do a memory allocation with statistics and alarms. Assume the * lock is already held. @@ -252,23 +170,7 @@ mallocWithAlarm(int n, void **pp) void *p; nFull = ROUND8(n); sqlStatusHighwater(SQL_STATUS_MALLOC_SIZE, n); - if (mem0.alarmThreshold > 0) { - sql_int64 nUsed = - sqlStatusValue(SQL_STATUS_MEMORY_USED); - if (nUsed >= mem0.alarmThreshold - nFull) { - mem0.nearlyFull = 1; - sqlMallocAlarm(nFull); - } else { - mem0.nearlyFull = 0; - } - } p = sql_sized_malloc(nFull); -#ifdef SQL_ENABLE_MEMORY_MANAGEMENT - if (p == 0 && mem0.alarmThreshold > 0) { - sqlMallocAlarm(nFull); - p = sql_sized_malloc(nFull); - } -#endif if (p) { nFull = sqlMallocSize(p); sqlStatusUp(SQL_STATUS_MEMORY_USED, nFull); @@ -320,101 +222,6 @@ sql_malloc64(sql_uint64 n) return sqlMalloc(n); } -/* - * Each thread may only have a single outstanding allocation from - * xScratchMalloc(). We verify this constraint in the single-threaded - * case by setting scratchAllocOut to 1 when an allocation - * is outstanding clearing it when the allocation is freed. - */ -#if !defined(NDEBUG) -static int scratchAllocOut = 0; -#endif - -/* - * Allocate memory that is to be used and released right away. - * This routine is similar to alloca() in that it is not intended - * for situations where the memory might be held long-term. This - * routine is intended to get memory to old large transient data - * structures that would not normally fit on the stack of an - * embedded processor. - */ -void * -sqlScratchMalloc(int n) -{ - void *p; - assert(n > 0); - - sqlStatusHighwater(SQL_STATUS_SCRATCH_SIZE, n); - if (mem0.nScratchFree && sqlGlobalConfig.szScratch >= n) { - p = mem0.pScratchFree; - mem0.pScratchFree = mem0.pScratchFree->pNext; - mem0.nScratchFree--; - sqlStatusUp(SQL_STATUS_SCRATCH_USED, 1); - } else { - p = sqlMalloc(n); - if (sqlGlobalConfig.bMemstat && p) { - sqlStatusUp(SQL_STATUS_SCRATCH_OVERFLOW, - sqlMallocSize(p)); - } - } - -#if !defined(NDEBUG) - /* EVIDENCE-OF: R-12970-05880 sql will not use more than one scratch - * buffers per thread. - * - * This can only be checked in single-threaded mode. - */ - assert(scratchAllocOut == 0); - if (p) - scratchAllocOut++; -#endif - - return p; -} - -void -sqlScratchFree(void *p) -{ - if (p) { - -#if !defined(NDEBUG) - /* Verify that no more than two scratch allocation per thread - * is outstanding at one time. (This is only checked in the - * single-threaded case since checking in the multi-threaded case - * would be much more complicated.) - */ - assert(scratchAllocOut >= 1 && scratchAllocOut <= 2); - scratchAllocOut--; -#endif - - if (SQL_WITHIN - (p, sqlGlobalConfig.pScratch, mem0.pScratchEnd)) { - /* Release memory from the SQL_CONFIG_SCRATCH allocation */ - ScratchFreeslot *pSlot; - pSlot = (ScratchFreeslot *) p; - pSlot->pNext = mem0.pScratchFree; - mem0.pScratchFree = pSlot; - mem0.nScratchFree++; - assert(mem0.nScratchFree <= - (u32) sqlGlobalConfig.nScratch); - sqlStatusDown(SQL_STATUS_SCRATCH_USED, 1); - } else { - /* Release memory back to the heap */ - if (sqlGlobalConfig.bMemstat) { - int iSize = sqlMallocSize(p); - sqlStatusDown - (SQL_STATUS_SCRATCH_OVERFLOW, iSize); - sqlStatusDown(SQL_STATUS_MEMORY_USED, - iSize); - sqlStatusDown(SQL_STATUS_MALLOC_COUNT, - 1); - sql_sized_free(p); - } else - sql_sized_free(p); - } - } -} - /* * Return the size of a memory allocation previously obtained from * sqlMalloc() or sql_malloc(). @@ -432,12 +239,6 @@ sqlDbMallocSize(void *p) return sql_sized_sizeof(p); } -sql_uint64 -sql_msize(void *p) -{ - return p ? sql_sized_sizeof(p) : 0; -} - /* * Free memory previously obtained from sqlMalloc(). */ @@ -489,7 +290,7 @@ sqlDbFree(sql * db, void *p) void * sqlRealloc(void *pOld, u64 nBytes) { - int nOld, nNew, nDiff; + int nOld, nNew; void *pNew; if (pOld == 0) { return sqlMalloc(nBytes); /* IMP: R-04300-56712 */ @@ -508,17 +309,7 @@ sqlRealloc(void *pOld, u64 nBytes) pNew = pOld; } else if (sqlGlobalConfig.bMemstat) { sqlStatusHighwater(SQL_STATUS_MALLOC_SIZE, (int)nBytes); - nDiff = nNew - nOld; - if (nDiff > 0 - && sqlStatusValue(SQL_STATUS_MEMORY_USED) >= - mem0.alarmThreshold - nDiff) { - sqlMallocAlarm(nDiff); - } pNew = sql_sized_realloc(pOld, nNew); - if (pNew == 0 && mem0.alarmThreshold > 0) { - sqlMallocAlarm((int)nBytes); - pNew = sql_sized_realloc(pOld, nNew); - } if (pNew) { nNew = sqlMallocSize(pNew); sqlStatusUp(SQL_STATUS_MEMORY_USED, nNew - nOld); @@ -530,18 +321,6 @@ sqlRealloc(void *pOld, u64 nBytes) return pNew; } -/* - * The public interface to sqlRealloc. Make sure that the memory - * subsystem is initialized prior to invoking sqlRealloc. - */ -void * -sql_realloc(void *pOld, int n) -{ - if (n < 0) - n = 0; /* IMP: R-26507-47431 */ - return sqlRealloc(pOld, n); -} - void * sql_realloc64(void *pOld, sql_uint64 n) { @@ -716,16 +495,6 @@ sqlDbStrNDup(sql * db, const char *z, u64 n) return zNew; } -/* - * Free any prior content in *pz and replace it with a copy of zNew. - */ -void -sqlSetString(char **pz, sql * db, const char *zNew) -{ - sqlDbFree(db, *pz); - *pz = sqlDbStrDup(db, zNew); -} - /* * Call this routine to record the fact that an OOM (out-of-memory) error * has happened. This routine will set db->mallocFailed, and also @@ -758,16 +527,6 @@ sqlOomClear(sql * db) } } -/* - * Take actions at the end of an API call to indicate an OOM error - */ -static SQL_NOINLINE int -apiOomError(sql * db) -{ - sqlOomClear(db); - return -1; -} - /* * This function must be called before exiting any API function (i.e. * returning control to the user) that has called sql_malloc or @@ -781,7 +540,8 @@ sqlApiExit(sql * db, int rc) { assert(db != 0); if (db->mallocFailed) { - return apiOomError(db); + sqlOomClear(db); + return -1; } return rc; } diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index 3825a2b78152..27e57cc81fb3 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -368,18 +368,12 @@ sql_malloc(int); void * sql_malloc64(sql_uint64); -void * -sql_realloc(void *, int); - void * sql_realloc64(void *, sql_uint64); void sql_free(void *); -sql_uint64 -sql_msize(void *); - int sql_stricmp(const char *, const char *); @@ -1447,11 +1441,7 @@ struct sql { * than being distinct from one another. */ #define SQL_MAGIC_OPEN 0xa029a697 /* Database is open */ -#define SQL_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */ -#define SQL_MAGIC_SICK 0x4b771290 /* Error and awaiting close */ #define SQL_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ -#define SQL_MAGIC_ERROR 0xb5357930 /* An sql_MISUSE error occurred */ -#define SQL_MAGIC_ZOMBIE 0x64cffc7f /* Close with last statement close */ /** * SQL type definition. Now it is an alias to type, but in @@ -2925,7 +2915,6 @@ unsigned sqlStrlen30(const char *); #define sqlStrNICmp sql_strnicmp void sqlMallocInit(void); -void sqlMallocEnd(void); void *sqlMalloc(u64); void *sqlMallocZero(u64); void *sqlDbMallocZero(sql *, u64); @@ -2939,15 +2928,12 @@ void *sqlDbRealloc(sql *, void *, u64); void sqlDbFree(sql *, void *); int sqlMallocSize(void *); int sqlDbMallocSize(void *); -void *sqlScratchMalloc(int); -void sqlScratchFree(void *); void *sqlPageMalloc(int); void sqlPageFree(void *); void sqlMemSetDefault(void); #ifndef SQL_UNTESTABLE void sqlBenignMallocHooks(void (*)(void), void (*)(void)); #endif -int sqlHeapNearlyFull(void); /* * On systems with ample stack space and that support alloca(), make @@ -2967,7 +2953,6 @@ int sqlHeapNearlyFull(void); #define sqlStackFree(D,P) sqlDbFree(D,P) #endif -sql_int64 sqlStatusValue(int); void sqlStatusUp(int, int); void sqlStatusDown(int, int); void sqlStatusHighwater(int, int); @@ -3003,7 +2988,6 @@ void sqlTreeViewSelect(TreeView *, const Select *, u8); void sqlTreeViewWith(TreeView *, const With *); #endif -void sqlSetString(char **, sql *, const char *); void sqlDequote(char *); /** diff --git a/src/box/sql/status.c b/src/box/sql/status.c index d6de484f3696..9e56836c13ee 100644 --- a/src/box/sql/status.c +++ b/src/box/sql/status.c @@ -61,18 +61,6 @@ static SQL_WSD struct sqlStatType { #define wsdStatInit #define wsdStat sqlStat -/* - * Return the current value of a status parameter. - */ -sql_int64 -sqlStatusValue(int op) -{ - wsdStatInit; - assert(op >= 0 && op < ArraySize(wsdStat.nowValue)); - - return wsdStat.nowValue[op]; -} - /* * Add N to the value of a status record. * @@ -125,140 +113,3 @@ sqlStatusHighwater(int op, int X) wsdStat.mxValue[op] = newValue; } } - -/* - * Query status information for a single database connection - */ -int -sql_db_status(sql * db, /* The database connection whose status is desired */ - int op, /* Status verb */ - int *pCurrent, /* Write current value here */ - int *pHighwater, /* Write high-water mark here */ - int resetFlag /* Reset high-water mark if true */ - ) -{ - int rc = 0; /* Return code */ - switch (op) { - case SQL_DBSTATUS_LOOKASIDE_USED:{ - *pCurrent = db->lookaside.nOut; - *pHighwater = db->lookaside.mxOut; - if (resetFlag) { - db->lookaside.mxOut = db->lookaside.nOut; - } - break; - } - - case SQL_DBSTATUS_LOOKASIDE_HIT: - case SQL_DBSTATUS_LOOKASIDE_MISS_SIZE: - case SQL_DBSTATUS_LOOKASIDE_MISS_FULL:{ - testcase(op == SQL_DBSTATUS_LOOKASIDE_HIT); - testcase(op == SQL_DBSTATUS_LOOKASIDE_MISS_SIZE); - testcase(op == SQL_DBSTATUS_LOOKASIDE_MISS_FULL); - assert((op - SQL_DBSTATUS_LOOKASIDE_HIT) >= 0); - assert((op - SQL_DBSTATUS_LOOKASIDE_HIT) < 3); - *pCurrent = 0; - *pHighwater = - db->lookaside.anStat[op - - SQL_DBSTATUS_LOOKASIDE_HIT]; - if (resetFlag) { - db->lookaside.anStat[op - - SQL_DBSTATUS_LOOKASIDE_HIT] - = 0; - } - break; - } - - /* - * Return an approximation for the amount of memory currently used - * by all pagers associated with the given database connection. The - * highwater mark is meaningless and is returned as zero. - */ - case SQL_DBSTATUS_CACHE_USED_SHARED: - case SQL_DBSTATUS_CACHE_USED:{ - int totalUsed = 0; - *pCurrent = totalUsed; - *pHighwater = 0; - break; - } - - /* - * *pCurrent gets an accurate estimate of the amount of memory used - * to store the schema for database. *pHighwater is set to zero. - */ - case SQL_DBSTATUS_SCHEMA_USED:{ - int nByte = 0; /* Used to accumulate return value */ - - *pHighwater = 0; - *pCurrent = nByte; - break; - } - - /* - * *pCurrent gets an accurate estimate of the amount of memory used - * to store all prepared statements. - * *pHighwater is set to zero. - */ - case SQL_DBSTATUS_STMT_USED:{ - struct Vdbe *pVdbe; /* Used to iterate through VMs */ - int nByte = 0; /* Used to accumulate return value */ - - db->pnBytesFreed = &nByte; - for (pVdbe = db->pVdbe; pVdbe; pVdbe = pVdbe->pNext) { - sqlVdbeClearObject(db, pVdbe); - sqlDbFree(db, pVdbe); - } - db->pnBytesFreed = 0; - - *pHighwater = 0; /* IMP: R-64479-57858 - */ - *pCurrent = nByte; - - break; - } - - /* - * Set *pCurrent to the total cache hits or misses encountered by all - * pagers the database handle is connected to. *pHighwater is always set - * to zero. - */ - case SQL_DBSTATUS_CACHE_HIT: - case SQL_DBSTATUS_CACHE_MISS: - case SQL_DBSTATUS_CACHE_WRITE:{ - int nRet = 0; - assert(SQL_DBSTATUS_CACHE_MISS == - SQL_DBSTATUS_CACHE_HIT + 1); - assert(SQL_DBSTATUS_CACHE_WRITE == - SQL_DBSTATUS_CACHE_HIT + 2); - - *pHighwater = 0; /* IMP: R-42420-56072 - */ - /* IMP: R-54100-20147 */ - /* IMP: R-29431-39229 */ - *pCurrent = nRet; - break; - } - - /* Set *pCurrent to non-zero if there are unresolved deferred foreign - * key constraints. Set *pCurrent to zero if all foreign key constraints - * have been satisfied. The *pHighwater is always set to zero. - */ - case SQL_DBSTATUS_DEFERRED_FKS:{ - *pHighwater = 0; /* IMP: R-11967-56545 - */ - const struct txn *ptxn = in_txn(); - - if (!ptxn || !ptxn->psql_txn) { - *pCurrent = 0; - break; - } - const struct sql_txn *psql_txn = ptxn->psql_txn; - *pCurrent = psql_txn->fk_deferred_count > 0; - break; - } - - default:{ - rc = -1; - } - } - return rc; -} diff --git a/src/box/sql/tokenize.c b/src/box/sql/tokenize.c index ea364de5be0f..32e4fd6d280b 100644 --- a/src/box/sql/tokenize.c +++ b/src/box/sql/tokenize.c @@ -514,11 +514,6 @@ sqlRunParser(Parse * pParse, const char *zSql) } } pParse->zTail = &zSql[i]; -#ifdef YYTRACKMAXSTACKDEPTH - sqlStatusHighwater(SQL_STATUS_PARSER_STACK, - sqlParserStackPeak(pEngine) - ); -#endif /* YYDEBUG */ sqlParserFree(pEngine, sql_free); if (db->mallocFailed) pParse->is_aborted = true; diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 420463755ba4..153402686d3d 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -226,10 +226,6 @@ allocateCursor( * different sized allocations. Memory cells provide growable * allocations. * - * * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can - * be freed lazily via the sql_release_memory() API. This - * minimizes the number of malloc calls made by the system. - * * The memory cell for cursor 0 is aMem[0]. The rest are allocated from * the top of the register space. Cursor 1 is at Mem[p->nMem-1]. * Cursor 2 is at Mem[p->nMem-2]. And so forth. diff --git a/src/box/sql/vdbesort.c b/src/box/sql/vdbesort.c index 7caf13b04d6f..0af9d0ca43cc 100644 --- a/src/box/sql/vdbesort.c +++ b/src/box/sql/vdbesort.c @@ -1778,9 +1778,6 @@ sqlVdbeSorterWrite(const VdbeCursor * pCsr, /* Sorter cursor */ * * * The total memory allocated for the in-memory list is greater * than (page-size * cache-size), or - * - * * The total memory allocated for the in-memory list is greater - * than (page-size * 10) and sqlHeapNearlyFull() returns true. */ nReq = pVal->n + sizeof(SorterRecord); nPMA = pVal->n + sqlVarintLen(pVal->n); @@ -1789,10 +1786,7 @@ sqlVdbeSorterWrite(const VdbeCursor * pCsr, /* Sorter cursor */ bFlush = pSorter->iMemory && (pSorter->iMemory + nReq) > pSorter->mxPmaSize; } else { - bFlush = ((pSorter->list.szPMA > pSorter->mxPmaSize) - || (pSorter->list.szPMA > pSorter->mnPmaSize - && sqlHeapNearlyFull()) - ); + bFlush = ((pSorter->list.szPMA > pSorter->mxPmaSize)); } if (bFlush) { rc = vdbeSorterFlushPMA(pSorter);