1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

Modifications to malloc5.test to account for the fact that sqlite3_release_memory() no longer reclaims dirty pages. (CVS 5625)

FossilOrigin-Name: b01c65b065c62e3dd71e88866a953668b5e2f25f
This commit is contained in:
danielk1977
2008-08-27 16:38:56 +00:00
parent 8af6906348
commit 468c82bc50
4 changed files with 78 additions and 88 deletions

View File

@@ -1,5 +1,5 @@
C Clear\sthe\s$result\svariable\sprior\sto\susing\sit\sin\scorrupt2.test.\s(CVS\s5624) C Modifications\sto\smalloc5.test\sto\saccount\sfor\sthe\sfact\sthat\ssqlite3_release_memory()\sno\slonger\sreclaims\sdirty\spages.\s(CVS\s5625)
D 2008-08-27T16:14:21 D 2008-08-27T16:38:57
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 689e14735f862a5553bceef206d8c13e29504e44 F Makefile.in 689e14735f862a5553bceef206d8c13e29504e44
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -137,7 +137,7 @@ F src/os_win.c aefe9ee26430678a19a058a874e4e2bd91398142
F src/pager.c a38742815a6b2238d0b91d1dd64bda50d6ee95fc F src/pager.c a38742815a6b2238d0b91d1dd64bda50d6ee95fc
F src/pager.h 914103bb62dbcc3d8e9f14baec812d027264d457 F src/pager.h 914103bb62dbcc3d8e9f14baec812d027264d457
F src/parse.y d0f76d2cb8d6883d5600dc20beb961a6022b94b8 F src/parse.y d0f76d2cb8d6883d5600dc20beb961a6022b94b8
F src/pcache.c 94050f68015c883813e39cd222b21d7728ad1203 F src/pcache.c 3d9d933bb22f10956ab78d83798d88ca9a147e86
F src/pcache.h 7a50b77f06c220ff7696be1a9f2a17c9e6ddc486 F src/pcache.h 7a50b77f06c220ff7696be1a9f2a17c9e6ddc486
F src/pragma.c f5b271b090af7fcedd308d7c5807a5503f7a853d F src/pragma.c f5b271b090af7fcedd308d7c5807a5503f7a853d
F src/prepare.c c197041e0c4770672cda75e6bfe10242f885e510 F src/prepare.c c197041e0c4770672cda75e6bfe10242f885e510
@@ -401,7 +401,7 @@ F test/main.test 8d77c161757ef7d96eaff0413daa7120c3b316fe
F test/malloc.test 69f5bb5a13b24edb1322fc1f42894f9d2f6446b1 F test/malloc.test 69f5bb5a13b24edb1322fc1f42894f9d2f6446b1
F test/malloc3.test 094f8195fe8e409bd4da0f1d769f7745faec62c8 F test/malloc3.test 094f8195fe8e409bd4da0f1d769f7745faec62c8
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261 F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test 8b18857f37c1c409b914789934aeb1346b778b3a F test/malloc5.test c8d0f7673337e8a29afa558735ae937a0d629751
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151 F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
@@ -623,7 +623,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P d4438251dd66c4168e09eb421a8c2081228357dd P 12f2d24f88e55d170dd7750e7904ff14e84e820e
R c758c0690635db76a5c5bb3d1f9c5535 R b53ac5363faaa116cc8b7dfcfecb5950
U drh U danielk1977
Z c69b32c45298adb6ff9560d2f547e841 Z c5747597064276f7a0eeb73c949573eb

View File

@@ -1 +1 @@
12f2d24f88e55d170dd7750e7904ff14e84e820e b01c65b065c62e3dd71e88866a953668b5e2f25f

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** This file implements that page cache. ** This file implements that page cache.
** **
** @(#) $Id: pcache.c,v 1.17 2008/08/27 15:16:34 danielk1977 Exp $ ** @(#) $Id: pcache.c,v 1.18 2008/08/27 16:38:57 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -553,7 +553,7 @@ static int pcacheRecycleOrAlloc(PCache *pCache, PgHdr **ppPage){
} }
/* If the global page limit has been reached, try to recycle a page. */ /* If the global page limit has been reached, try to recycle a page. */
if( pcache.nCurrentPage>=pcache.nMaxPage ){ if( pCache->bPurgeable && pcache.nCurrentPage>=pcache.nMaxPage ){
p = pcacheRecyclePage(); p = pcacheRecyclePage();
} }
@@ -620,7 +620,7 @@ void sqlite3PcacheOpen(
p->xStress = xStress; p->xStress = xStress;
p->pStress = pStress; p->pStress = pStress;
p->nMax = 100; p->nMax = 100;
p->nMin = 20; p->nMin = 10;
pcacheEnterGlobal(); pcacheEnterGlobal();
if( bPurgeable ){ if( bPurgeable ){

View File

@@ -12,13 +12,13 @@
# This file contains test cases focused on the two memory-management APIs, # This file contains test cases focused on the two memory-management APIs,
# sqlite3_soft_heap_limit() and sqlite3_release_memory(). # sqlite3_soft_heap_limit() and sqlite3_release_memory().
# #
# $Id: malloc5.test,v 1.19 2008/08/21 15:54:01 danielk1977 Exp $ # Prior to version 3.6.2, calling sqlite3_release_memory() or exceeding
# the configured soft heap limit could cause sqlite to upgrade database
#--------------------------------------------------------------------------- # locks and flush dirty pages to the file system. As of 3.6.2, this is
# NOTES ON EXPECTED BEHAVIOUR # no longer the case. In version 3.6.2, sqlite3_release_memory() only
# reclaims clean pages. This test file has been updated accordingly.
# #
#--------------------------------------------------------------------------- # $Id: malloc5.test,v 1.20 2008/08/27 16:38:57 danielk1977 Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -44,35 +44,38 @@ sqlite3 db test.db
do_test malloc5-1.1 { do_test malloc5-1.1 {
# Simplest possible test. Call sqlite3_release_memory when there is exactly # Simplest possible test. Call sqlite3_release_memory when there is exactly
# one unused page in a single pager cache. This test case set's the # one unused page in a single pager cache. The page cannot be freed, as
# value of the ::pgalloc variable, which is used in subsequent tests. # it is dirty. So sqlite3_release_memory() returns 0.
# #
# Note: Even though executing this statement on an empty database
# modifies 2 pages (the root of sqlite_master and the new root page),
# the sqlite_master root (page 1) is never freed because the btree layer
# retains a reference to it for the entire transaction.
execsql { execsql {
PRAGMA auto_vacuum=OFF; PRAGMA auto_vacuum=OFF;
BEGIN; BEGIN;
CREATE TABLE abc(a, b, c); CREATE TABLE abc(a, b, c);
} }
sqlite3_release_memory
} {0}
do_test malloc5-1.2 {
# Test that the transaction started in the above test is still active.
# The lock on the database file should not have been upgraded (this was
# not the case before version 3.6.2).
#
sqlite3 db2 test.db
execsql { SELECT * FROM sqlite_master } db2
} {}
do_test malloc5-1.3 {
# Call [sqlite3_release_memory] when there is exactly one unused page
# in the cache belonging to db2.
#
set ::pgalloc [sqlite3_release_memory] set ::pgalloc [sqlite3_release_memory]
expr $::pgalloc > 0 expr $::pgalloc > 0
} {1} } {1}
do_test malloc5-1.2 {
# Test that the transaction started in the above test is still active. do_test malloc5-1.4 {
# Because the page freed had been written to, freeing it required a # Commit the transaction and open a new one. Read 1 page into the cache.
# journal sync and exclusive lock on the database file. Test the file # Because the page is not dirty, it is eligible for collection even
# appears to be locked. # before the transaction is concluded.
sqlite3 db2 test.db #
catchsql {
SELECT * FROM abc;
} db2
} {1 {database is locked}}
do_test malloc5-1.3 {
# Again call [sqlite3_release_memory] when there is exactly one unused page
# in the cache. The same amount of memory is required, but no journal-sync
# or exclusive lock should be established.
execsql { execsql {
COMMIT; COMMIT;
BEGIN; BEGIN;
@@ -80,43 +83,44 @@ do_test malloc5-1.3 {
} }
sqlite3_release_memory sqlite3_release_memory
} $::pgalloc } $::pgalloc
do_test malloc5-1.4 {
# Database should not be locked this time.
catchsql {
SELECT * FROM abc;
} db2
} {0 {}}
do_test malloc5-1.5 { do_test malloc5-1.5 {
# Conclude the transaction opened in the previous [do_test] block. This
# causes another page (page 1) to become eligible for recycling.
#
execsql { COMMIT }
sqlite3_release_memory
} $::pgalloc
do_test malloc5-1.6 {
# Manipulate the cache so that it contains two unused pages. One requires # Manipulate the cache so that it contains two unused pages. One requires
# a journal-sync to free, the other does not. # a journal-sync to free, the other does not.
db2 close db2 close
execsql { execsql {
BEGIN;
SELECT * FROM abc; SELECT * FROM abc;
CREATE TABLE def(d, e, f); CREATE TABLE def(d, e, f);
} }
sqlite3_release_memory 500 sqlite3_release_memory 500
} $::pgalloc } $::pgalloc
do_test malloc5-1.6 {
# Database should not be locked this time. The above test case only
# requested 500 bytes of memory, which can be obtained by freeing the page
# that does not require an fsync().
sqlite3 db2 test.db
catchsql {
SELECT * FROM abc;
} db2
} {0 {}}
do_test malloc5-1.7 { do_test malloc5-1.7 {
# Release another 500 bytes of memory. This time we require a sync(), # Database should not be locked this time.
# so the database file will be locked afterwards. sqlite3 db2 test.db
catchsql { SELECT * FROM abc } db2
} {0 {}}
do_test malloc5-1.8 {
# Try to release another block of memory. This will fail as the only
# pages currently in the cache are dirty (page 3) or pinned (page 1).
db2 close db2 close
sqlite3_release_memory 500 sqlite3_release_memory 500
} $::pgalloc } 0
do_test malloc5-1.8 { do_test malloc5-1.8 {
# Database is still not locked.
#
sqlite3 db2 test.db sqlite3 db2 test.db
catchsql { catchsql { SELECT * FROM abc } db2
SELECT * FROM abc; } {0 {}}
} db2
} {1 {database is locked}}
do_test malloc5-1.9 { do_test malloc5-1.9 {
execsql { execsql {
COMMIT; COMMIT;
@@ -138,6 +142,7 @@ do_test malloc5-2.2 {
# Halfway through the query call sqlite3_release_memory(). The goal of this # Halfway through the query call sqlite3_release_memory(). The goal of this
# test is to make sure we don't free pages that are in use (specifically, # test is to make sure we don't free pages that are in use (specifically,
# the root of table abc). # the root of table abc).
sqlite3_release_memory
set nRelease 0 set nRelease 0
execsql { execsql {
BEGIN; BEGIN;
@@ -200,45 +205,28 @@ do_test malloc5-4.1 {
execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');" execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');"
} }
execsql {COMMIT;} execsql {COMMIT;}
sqlite3_release_memory
sqlite3_memory_highwater 1
execsql {SELECT * FROM abc}
set nMaxBytes [sqlite3_memory_highwater 1] set nMaxBytes [sqlite3_memory_highwater 1]
puts -nonewline " (Highwater mark: $nMaxBytes) " puts -nonewline " (Highwater mark: $nMaxBytes) "
expr $nMaxBytes > 1000000 expr $nMaxBytes > 1000000
} {1} } {1}
do_test malloc5-4.2 { do_test malloc5-4.2 {
sqlite3_release_memory sqlite3_release_memory
sqlite3_soft_heap_limit 110000 sqlite3_soft_heap_limit 100000
sqlite3_memory_highwater 1 sqlite3_memory_highwater 1
execsql {BEGIN;} execsql {SELECT * FROM abc}
for {set i 0} {$i < 10000} {incr i} {
execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');"
}
execsql {COMMIT;}
set nMaxBytes [sqlite3_memory_highwater 1] set nMaxBytes [sqlite3_memory_highwater 1]
puts -nonewline " (Highwater mark: $nMaxBytes) " puts -nonewline " (Highwater mark: $nMaxBytes) "
expr $nMaxBytes <= 100000
# We used to test ($nMaxBytes<100000), because the soft-heap-limit is
# 100000 bytes. But if an allocation that will exceed the
# soft-heap-limit is requested from within the only pager instance in
# the system, then there is no way to free memory and the limit has to
# be exceeded. An exception is memory allocated to store actual page
# data (the code contains a special case for this).
#
# This is not a problem because all allocations apart from those
# used to store cached page data are both small and transient.
#
# Summary: the actual high-water mark for memory usage may be slightly
# higher than the soft-heap-limit. The specific allocations that cause
# the problem are the calls to sqlite3_malloc() inserted into selected
# sqlite3OsXXX() functions in test builds.
#
expr $nMaxBytes <= 110100
} {1} } {1}
do_test malloc5-4.3 { do_test malloc5-4.3 {
# Check that the content of table abc is at least roughly as expected. # Check that the content of table abc is at least roughly as expected.
execsql { execsql {
SELECT count(*), sum(a), sum(b) FROM abc; SELECT count(*), sum(a), sum(b) FROM abc;
} }
} [list 20000 [expr int(20000.0 * 4999.5)] [expr int(20000.0 * 4999.5)]] } [list 10000 [expr int(10000.0 * 4999.5)] [expr int(10000.0 * 4999.5)]]
# Restore the soft heap limit. # Restore the soft heap limit.
sqlite3_soft_heap_limit $::soft_limit sqlite3_soft_heap_limit $::soft_limit
@@ -326,6 +314,7 @@ do_test malloc5-6.1.2 {
} {10 10} } {10 10}
do_test malloc5-6.2.1 { do_test malloc5-6.2.1 {
breakpoint
execsql {SELECT * FROM abc} db2 execsql {SELECT * FROM abc} db2
execsql {SELECT * FROM abc} db execsql {SELECT * FROM abc} db
expr [nPage db] + [nPage db2] expr [nPage db] + [nPage db2]
@@ -382,16 +371,17 @@ do_test malloc5-6.3.4 {
} {0 3} } {0 3}
do_test malloc5-6.3.5 { do_test malloc5-6.3.5 {
# But if we are really insistent, SQLite will consent to call sync() # But if we are really insistent, SQLite will consent to call sync()
# if there is no other option. # if there is no other option. UPDATE: As of 3.6.2, SQLite will not
# call sync() in this scenario. So no further memory can be reclaimed.
sqlite3_release_memory 1000 sqlite3_release_memory 1000
list [nPage db] [nPage db2] list [nPage db] [nPage db2]
} {0 2} } {0 3}
do_test malloc5-6.3.6 { do_test malloc5-6.3.6 {
# The referenced page (page 1 of the db2 cache) will not be freed no # The referenced page (page 1 of the db2 cache) will not be freed no
# matter how much memory we ask for: # matter how much memory we ask for:
sqlite3_release_memory 31459 sqlite3_release_memory 31459
list [nPage db] [nPage db2] list [nPage db] [nPage db2]
} {0 1} } {0 3}
db2 close db2 close