Hi all,

On Sun, Jan 15, 2017 at 5:50 PM, Richard Hipp <d...@sqlite.org> wrote:
> On 1/15/17, Kim Gräsman <kim.gras...@gmail.com> wrote:
>>
>> 1) If I configure a global SQLite heap with SQLITE_CONFIG_HEAP, won't
>> I just trade malloc heap fragmentation for SQLite private heap
>> fragmentation? Or does SQLite's fragmentation-prevention strategy work
>> well even in the face of multiple page sizes and connections?
>
> As described in the document that you read
> (https://www.sqlite.org/malloc.html), if you keep your memory usage
> below the Robson limit, then fragmentation will never be a problem.
> Guaranteed.
>
> If you exceed the Robson limit, it is theoretically possible that
> fragmentation could cause problems.  But in practice, we don't
> normally have issues.
>
>>
>> 2) What happens if the configured heap is depleted?
>
> You get SQLITE_NOMEM errors.  Use sqlite3_memory_used() to monitor
> your memory utilization and raise alarms if it gets too high.  And/or
> call sqlite3_db_release_memory() to try to free up memory from caches
> if you start to run low.

I've now worked through our application to be able to use
SQLITE_CONFIG_HEAP. I thought I'd share some observations:

- With SQLITE_CONFIG_HEAP, different page sizes between connections
are no longer a problem -- they are allocated from the same arena, but
can co-exist nicely. That said, we've gone to the same page size for
all connections/databases to keep the maths easier
- Prepared statements were an unexpected problem. We had unbounded
statement caches with a large number of statements, hogging memory
from SQLite's private heap. The total size requirement in extreme
situations came to almost 20MB. By turning the statement caches into
LRU caches and limiting their size in bytes, we could cap the maximum
number of bytes used for cached statements and use that number to
forecast heap size requirements.
- We've set the minimum allocation size to 32. This led to higher
memory usage compared to malloc, because small allocations were
rounded up, e.g. for statements.
- We recompiled SQLite with SQLITE_DEFAULT_PAGE_SIZE=<our default> and
SQLITE_DEFAULT_CACHE_SIZE=128. This means any ad-hoc connection that
doesn't explicitly specify page/cache size will play well with the
system at large. It may be slow by default, but can be trivially sped
up by issuing "PRAGMA cache_size=n" after making system-wide
adjustments to heap size, to cover for the additional memory pressure.
- Besides forecast for scratch, page cache, lookaside and cached
statements, I've added 4MB, arbitrarily, for general-purpose
allocations
- We use sqlite3_soft_heap_limit64 to get softer handling of heap
depletion. I've set the soft heap limit to (heapsize - 1MB), to give
SQLite ample room for small "soft" overruns. On the assumption that
individual allocations typically aren't larger than 1MB.

Unfortunately, we're getting occasional out-of-memory errors on
statement execution.

I've started looking into `.stats` in the sqlite3 shell, and am
thinking about the pulling out the memory statistics inside our
application to try and understand where memory is going. Any idea what
I might look out for?

I have a nagging suspicion that the tempdb is allocated from the
private heap (we've set pragma temp_store=memory) -- what are the
characteristics of that database? Can I forecast how large it will be?

Many thanks,
- Kim
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to