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:
16
manifest
16
manifest
@@ -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
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
12f2d24f88e55d170dd7750e7904ff14e84e820e
|
b01c65b065c62e3dd71e88866a953668b5e2f25f
|
||||||
@@ -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 ){
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user