| OLD | NEW |
| 1 # 2005 November 30 | 1 # 2005 November 30 |
| 2 # | 2 # |
| 3 # The author disclaims copyright to this source code. In place of | 3 # The author disclaims copyright to this source code. In place of |
| 4 # a legal notice, here is a blessing: | 4 # a legal notice, here is a blessing: |
| 5 # | 5 # |
| 6 # May you do good and not evil. | 6 # May you do good and not evil. |
| 7 # May you find forgiveness for yourself and forgive others. | 7 # May you find forgiveness for yourself and forgive others. |
| 8 # May you share freely, never taking more than you give. | 8 # May you share freely, never taking more than you give. |
| 9 # | 9 # |
| 10 #*********************************************************************** | 10 #*********************************************************************** |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 finish_test | 32 finish_test |
| 33 return | 33 return |
| 34 } | 34 } |
| 35 | 35 |
| 36 # Skip these tests if OMIT_MEMORY_MANAGEMENT was defined at compile time. | 36 # Skip these tests if OMIT_MEMORY_MANAGEMENT was defined at compile time. |
| 37 ifcapable !memorymanage { | 37 ifcapable !memorymanage { |
| 38 finish_test | 38 finish_test |
| 39 return | 39 return |
| 40 } | 40 } |
| 41 | 41 |
| 42 test_set_config_pagecache 0 100 |
| 43 |
| 42 sqlite3_soft_heap_limit 0 | 44 sqlite3_soft_heap_limit 0 |
| 43 sqlite3 db test.db | 45 sqlite3 db test.db |
| 46 db eval {PRAGMA cache_size=1} |
| 44 | 47 |
| 45 do_test malloc5-1.1 { | 48 do_test malloc5-1.1 { |
| 46 # Simplest possible test. Call sqlite3_release_memory when there is exactly | 49 # Simplest possible test. Call sqlite3_release_memory when there is exactly |
| 47 # one unused page in a single pager cache. The page cannot be freed, as | 50 # one unused page in a single pager cache. The page cannot be freed, as |
| 48 # it is dirty. So sqlite3_release_memory() returns 0. | 51 # it is dirty. So sqlite3_release_memory() returns 0. |
| 49 # | 52 # |
| 50 execsql { | 53 execsql { |
| 51 PRAGMA auto_vacuum=OFF; | 54 PRAGMA auto_vacuum=OFF; |
| 52 BEGIN; | 55 BEGIN; |
| 53 CREATE TABLE abc(a, b, c); | 56 CREATE TABLE abc(a, b, c); |
| 54 } | 57 } |
| 55 sqlite3_release_memory | 58 sqlite3_release_memory |
| 56 } {0} | 59 } {0} |
| 57 | 60 |
| 58 do_test malloc5-1.2 { | 61 do_test malloc5-1.2 { |
| 59 # Test that the transaction started in the above test is still active. | 62 # Test that the transaction started in the above test is still active. |
| 60 # The lock on the database file should not have been upgraded (this was | 63 # The lock on the database file should not have been upgraded (this was |
| 61 # not the case before version 3.6.2). | 64 # not the case before version 3.6.2). |
| 62 # | 65 # |
| 63 sqlite3 db2 test.db | 66 sqlite3 db2 test.db |
| 64 execsql { SELECT * FROM sqlite_master } db2 | 67 execsql {PRAGMA cache_size=2; SELECT * FROM sqlite_master } db2 |
| 65 } {} | 68 } {} |
| 66 do_test malloc5-1.3 { | 69 do_test malloc5-1.3 { |
| 67 # Call [sqlite3_release_memory] when there is exactly one unused page | 70 # Call [sqlite3_release_memory] when there is exactly one unused page |
| 68 # in the cache belonging to db2. | 71 # in the cache belonging to db2. |
| 69 # | 72 # |
| 70 set ::pgalloc [sqlite3_release_memory] | 73 set ::pgalloc [sqlite3_release_memory] |
| 71 expr $::pgalloc > 0 | 74 } {0} |
| 72 } {1} | 75 |
| 76 # The sizes of memory allocations from system malloc() might vary, |
| 77 # depending on the memory allocator algorithms used. The following |
| 78 # routine is designed to support answers that fall within a range |
| 79 # of values while also supplying easy-to-understand "expected" values |
| 80 # when errors occur. |
| 81 # |
| 82 proc value_in_range {target x args} { |
| 83 set v [lindex $args 0] |
| 84 if {$v!=""} { |
| 85 if {$v<$target*$x} {return $v} |
| 86 if {$v>$target/$x} {return $v} |
| 87 } |
| 88 return "number between [expr {int($target*$x)}] and [expr {int($target/$x)}]" |
| 89 } |
| 90 set mrange 0.98 ;# plus or minus 2% |
| 91 |
| 73 | 92 |
| 74 do_test malloc5-1.4 { | 93 do_test malloc5-1.4 { |
| 75 # Commit the transaction and open a new one. Read 1 page into the cache. | 94 # Commit the transaction and open a new one. Read 1 page into the cache. |
| 76 # Because the page is not dirty, it is eligible for collection even | 95 # Because the page is not dirty, it is eligible for collection even |
| 77 # before the transaction is concluded. | 96 # before the transaction is concluded. |
| 78 # | 97 # |
| 79 execsql { | 98 execsql { |
| 80 COMMIT; | 99 COMMIT; |
| 81 BEGIN; | 100 BEGIN; |
| 82 SELECT * FROM abc; | 101 SELECT * FROM abc; |
| 83 } | 102 } |
| 84 sqlite3_release_memory | 103 value_in_range $::pgalloc $::mrange [sqlite3_release_memory] |
| 85 } $::pgalloc | 104 } [value_in_range $::pgalloc $::mrange] |
| 86 | 105 |
| 87 do_test malloc5-1.5 { | 106 do_test malloc5-1.5 { |
| 88 # Conclude the transaction opened in the previous [do_test] block. This | 107 # Conclude the transaction opened in the previous [do_test] block. This |
| 89 # causes another page (page 1) to become eligible for recycling. | 108 # causes another page (page 1) to become eligible for recycling. |
| 90 # | 109 # |
| 91 execsql { COMMIT } | 110 execsql { COMMIT } |
| 92 sqlite3_release_memory | 111 value_in_range $::pgalloc $::mrange [sqlite3_release_memory] |
| 93 } $::pgalloc | 112 } [value_in_range $::pgalloc $::mrange] |
| 94 | 113 |
| 95 do_test malloc5-1.6 { | 114 do_test malloc5-1.6 { |
| 96 # Manipulate the cache so that it contains two unused pages. One requires | 115 # Manipulate the cache so that it contains two unused pages. One requires |
| 97 # a journal-sync to free, the other does not. | 116 # a journal-sync to free, the other does not. |
| 98 db2 close | 117 db2 close |
| 99 execsql { | 118 execsql { |
| 100 BEGIN; | 119 BEGIN; |
| 101 SELECT * FROM abc; | 120 SELECT * FROM abc; |
| 102 CREATE TABLE def(d, e, f); | 121 CREATE TABLE def(d, e, f); |
| 103 } | 122 } |
| 104 sqlite3_release_memory 500 | 123 value_in_range $::pgalloc $::mrange [sqlite3_release_memory 500] |
| 105 } $::pgalloc | 124 } [value_in_range $::pgalloc $::mrange] |
| 106 | 125 |
| 107 do_test malloc5-1.7 { | 126 do_test malloc5-1.7 { |
| 108 # Database should not be locked this time. | 127 # Database should not be locked this time. |
| 109 sqlite3 db2 test.db | 128 sqlite3 db2 test.db |
| 110 catchsql { SELECT * FROM abc } db2 | 129 catchsql { SELECT * FROM abc } db2 |
| 111 } {0 {}} | 130 } {0 {}} |
| 112 do_test malloc5-1.8 { | 131 do_test malloc5-1.8 { |
| 113 # Try to release another block of memory. This will fail as the only | 132 # Try to release another block of memory. This will fail as the only |
| 114 # pages currently in the cache are dirty (page 3) or pinned (page 1). | 133 # pages currently in the cache are dirty (page 3) or pinned (page 1). |
| 115 db2 close | 134 db2 close |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 # called. | 184 # called. |
| 166 execsql { | 185 execsql { |
| 167 BEGIN; | 186 BEGIN; |
| 168 SELECT * FROM abc; | 187 SELECT * FROM abc; |
| 169 } | 188 } |
| 170 execsql { | 189 execsql { |
| 171 SELECT * FROM sqlite_master; | 190 SELECT * FROM sqlite_master; |
| 172 BEGIN; | 191 BEGIN; |
| 173 SELECT * FROM def; | 192 SELECT * FROM def; |
| 174 } db2 | 193 } db2 |
| 175 sqlite3_release_memory | 194 value_in_range [expr $::pgalloc*2] 0.99 [sqlite3_release_memory] |
| 176 } [expr $::pgalloc * 2] | 195 } [value_in_range [expr $::pgalloc * 2] 0.99] |
| 177 do_test malloc5-3.2 { | 196 do_test malloc5-3.2 { |
| 178 concat \ | 197 concat \ |
| 179 [execsql {SELECT * FROM abc; COMMIT}] \ | 198 [execsql {SELECT * FROM abc; COMMIT}] \ |
| 180 [execsql {SELECT * FROM def; COMMIT} db2] | 199 [execsql {SELECT * FROM def; COMMIT} db2] |
| 181 } {1 2 3 4 5 6 7 8 9 10 11 12} | 200 } {1 2 3 4 5 6 7 8 9 10 11 12} |
| 182 | 201 |
| 183 db2 close | 202 db2 close |
| 184 puts "Highwater mark: [sqlite3_memory_highwater]" | 203 puts "Highwater mark: [sqlite3_memory_highwater]" |
| 185 | 204 |
| 186 # The following two test cases each execute a transaction in which | 205 # The following two test cases each execute a transaction in which |
| (...skipping 20 matching lines...) Expand all Loading... |
| 207 execsql {COMMIT;} | 226 execsql {COMMIT;} |
| 208 db cache flush | 227 db cache flush |
| 209 sqlite3_release_memory | 228 sqlite3_release_memory |
| 210 sqlite3_memory_highwater 1 | 229 sqlite3_memory_highwater 1 |
| 211 execsql {SELECT * FROM abc} | 230 execsql {SELECT * FROM abc} |
| 212 set nMaxBytes [sqlite3_memory_highwater 1] | 231 set nMaxBytes [sqlite3_memory_highwater 1] |
| 213 puts -nonewline " (Highwater mark: $nMaxBytes) " | 232 puts -nonewline " (Highwater mark: $nMaxBytes) " |
| 214 expr $nMaxBytes > 1000000 | 233 expr $nMaxBytes > 1000000 |
| 215 } {1} | 234 } {1} |
| 216 do_test malloc5-4.2 { | 235 do_test malloc5-4.2 { |
| 236 db eval {PRAGMA cache_size=1} |
| 217 db cache flush | 237 db cache flush |
| 218 sqlite3_release_memory | 238 sqlite3_release_memory |
| 219 sqlite3_soft_heap_limit 100000 | 239 sqlite3_soft_heap_limit 100000 |
| 220 sqlite3_memory_highwater 1 | 240 sqlite3_memory_highwater 1 |
| 221 execsql {SELECT * FROM abc} | 241 execsql {SELECT * FROM abc} |
| 222 set nMaxBytes [sqlite3_memory_highwater 1] | 242 set nMaxBytes [sqlite3_memory_highwater 1] |
| 223 puts -nonewline " (Highwater mark: $nMaxBytes) " | 243 puts -nonewline " (Highwater mark: $nMaxBytes) " |
| 224 expr $nMaxBytes <= 110000 | 244 expr $nMaxBytes <= 110000 |
| 225 } {1} | 245 } {1} |
| 226 do_test malloc5-4.3 { | 246 do_test malloc5-4.3 { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 } | 298 } |
| 279 db close | 299 db close |
| 280 forcedelete test.db test.db-journal test2.db test2.db-journal | 300 forcedelete test.db test.db-journal test2.db test2.db-journal |
| 281 | 301 |
| 282 # This block of test-cases (malloc5-6.1.*) prepares two database files | 302 # This block of test-cases (malloc5-6.1.*) prepares two database files |
| 283 # for the subsequent tests. | 303 # for the subsequent tests. |
| 284 do_test malloc5-6.1.1 { | 304 do_test malloc5-6.1.1 { |
| 285 sqlite3 db test.db | 305 sqlite3 db test.db |
| 286 execsql { | 306 execsql { |
| 287 PRAGMA page_size=1024; | 307 PRAGMA page_size=1024; |
| 288 PRAGMA default_cache_size=10; | 308 PRAGMA default_cache_size=2; |
| 289 } | 309 } |
| 290 execsql { | 310 execsql { |
| 291 PRAGMA temp_store = memory; | 311 PRAGMA temp_store = memory; |
| 292 BEGIN; | 312 BEGIN; |
| 293 CREATE TABLE abc(a PRIMARY KEY, b, c); | 313 CREATE TABLE abc(a PRIMARY KEY, b, c); |
| 294 INSERT INTO abc VALUES(randstr(50,50), randstr(75,75), randstr(100,100)); | 314 INSERT INTO abc VALUES(randstr(50,50), randstr(75,75), randstr(100,100)); |
| 295 INSERT INTO abc | 315 INSERT INTO abc |
| 296 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; | 316 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; |
| 297 INSERT INTO abc | 317 INSERT INTO abc |
| 298 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; | 318 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; |
| 299 INSERT INTO abc | 319 INSERT INTO abc |
| 300 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; | 320 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; |
| 301 INSERT INTO abc | 321 INSERT INTO abc |
| 302 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; | 322 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; |
| 303 INSERT INTO abc | 323 INSERT INTO abc |
| 304 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; | 324 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; |
| 305 INSERT INTO abc | 325 INSERT INTO abc |
| 306 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; | 326 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; |
| 307 COMMIT; | 327 COMMIT; |
| 308 } | 328 } |
| 309 forcecopy test.db test2.db | 329 forcecopy test.db test2.db |
| 310 sqlite3 db2 test2.db | 330 sqlite3 db2 test2.db |
| 331 db2 eval {PRAGMA cache_size=2} |
| 311 list \ | 332 list \ |
| 312 [expr ([file size test.db]/1024)>20] [expr ([file size test2.db]/1024)>20] | 333 [expr ([file size test.db]/1024)>20] [expr ([file size test2.db]/1024)>20] |
| 313 } {1 1} | 334 } {1 1} |
| 314 do_test malloc5-6.1.2 { | 335 do_test malloc5-6.1.2 { |
| 315 list [execsql {PRAGMA cache_size}] [execsql {PRAGMA cache_size} db2] | 336 list [execsql {PRAGMA cache_size}] [execsql {PRAGMA cache_size} db2] |
| 316 } {10 10} | 337 } {2 2} |
| 317 | 338 |
| 318 do_test malloc5-6.2.1 { | 339 do_test malloc5-6.2.1 { |
| 319 execsql {SELECT * FROM abc} db2 | 340 execsql {SELECT * FROM abc} db2 |
| 320 execsql {SELECT * FROM abc} db | 341 execsql {SELECT * FROM abc} db |
| 321 expr [nPage db] + [nPage db2] | 342 expr [nPage db] + [nPage db2] |
| 322 } {20} | 343 } {4} |
| 323 | 344 |
| 324 do_test malloc5-6.2.2 { | 345 do_test malloc5-6.2.2 { |
| 325 # If we now try to reclaim some memory, it should come from the db2 cache. | 346 # If we now try to reclaim some memory, it should come from the db2 cache. |
| 326 sqlite3_release_memory 3000 | 347 sqlite3_release_memory 3000 |
| 327 expr [nPage db] + [nPage db2] | 348 expr [nPage db] + [nPage db2] |
| 328 } {17} | 349 } {4} |
| 329 do_test malloc5-6.2.3 { | 350 do_test malloc5-6.2.3 { |
| 330 # Access the db2 cache again, so that all the db2 pages have been used | 351 # Access the db2 cache again, so that all the db2 pages have been used |
| 331 # more recently than all the db pages. Then try to reclaim 3000 bytes. | 352 # more recently than all the db pages. Then try to reclaim 3000 bytes. |
| 332 # This time, 3 pages should be pulled from the db cache. | 353 # This time, 3 pages should be pulled from the db cache. |
| 333 execsql { SELECT * FROM abc } db2 | 354 execsql { SELECT * FROM abc } db2 |
| 334 sqlite3_release_memory 3000 | 355 sqlite3_release_memory 3000 |
| 335 expr [nPage db] + [nPage db2] | 356 expr [nPage db] + [nPage db2] |
| 336 } {17} | 357 } {4} |
| 337 | 358 |
| 338 do_test malloc5-6.3.1 { | 359 do_test malloc5-6.3.1 { |
| 339 # Now open a transaction and update 2 pages in the db2 cache. Then | 360 # Now open a transaction and update 2 pages in the db2 cache. Then |
| 340 # do a SELECT on the db cache so that all the db pages are more recently | 361 # do a SELECT on the db cache so that all the db pages are more recently |
| 341 # used than the db2 pages. When we try to free memory, SQLite should | 362 # used than the db2 pages. When we try to free memory, SQLite should |
| 342 # free the non-dirty db2 pages, then the db pages, then finally use | 363 # free the non-dirty db2 pages, then the db pages, then finally use |
| 343 # sync() to free up the dirty db2 pages. The only page that cannot be | 364 # sync() to free up the dirty db2 pages. The only page that cannot be |
| 344 # freed is page1 of db2. Because there is an open transaction, the | 365 # freed is page1 of db2. Because there is an open transaction, the |
| 345 # btree layer holds a reference to page 1 in the db2 cache. | 366 # btree layer holds a reference to page 1 in the db2 cache. |
| 346 execsql { | 367 execsql { |
| 347 BEGIN; | 368 BEGIN; |
| 348 UPDATE abc SET c = randstr(100,100) | 369 UPDATE abc SET c = randstr(100,100) |
| 349 WHERE rowid = 1 OR rowid = (SELECT max(rowid) FROM abc); | 370 WHERE rowid = 1 OR rowid = (SELECT max(rowid) FROM abc); |
| 350 } db2 | 371 } db2 |
| 351 execsql { SELECT * FROM abc } db | 372 execsql { SELECT * FROM abc } db |
| 352 expr [nPage db] + [nPage db2] | 373 expr [nPage db] + [nPage db2] |
| 353 } {20} | 374 } {4} |
| 354 do_test malloc5-6.3.2 { | 375 do_test malloc5-6.3.2 { |
| 355 # Try to release 7700 bytes. This should release all the | 376 # Try to release 7700 bytes. This should release all the |
| 356 # non-dirty pages held by db2. | 377 # non-dirty pages held by db2. |
| 357 sqlite3_release_memory [expr 7*1132] | 378 sqlite3_release_memory [expr 7*1132] |
| 358 list [nPage db] [nPage db2] | 379 list [nPage db] [nPage db2] |
| 359 } {10 3} | 380 } {1 3} |
| 360 do_test malloc5-6.3.3 { | 381 do_test malloc5-6.3.3 { |
| 361 # Try to release another 1000 bytes. This should come fromt the db | 382 # Try to release another 1000 bytes. This should come fromt the db |
| 362 # cache, since all three pages held by db2 are either in-use or diry. | 383 # cache, since all three pages held by db2 are either in-use or diry. |
| 363 sqlite3_release_memory 1000 | 384 sqlite3_release_memory 1000 |
| 364 list [nPage db] [nPage db2] | 385 list [nPage db] [nPage db2] |
| 365 } {9 3} | 386 } {1 3} |
| 366 do_test malloc5-6.3.4 { | 387 do_test malloc5-6.3.4 { |
| 367 # Now release 9900 more (about 9 pages worth). This should expunge | 388 # Now release 9900 more (about 9 pages worth). This should expunge |
| 368 # the rest of the db cache. But the db2 cache remains intact, because | 389 # the rest of the db cache. But the db2 cache remains intact, because |
| 369 # SQLite tries to avoid calling sync(). | 390 # SQLite tries to avoid calling sync(). |
| 370 if {$::tcl_platform(wordSize)==8} { | 391 if {$::tcl_platform(wordSize)==8} { |
| 371 sqlite3_release_memory 10500 | 392 sqlite3_release_memory 10500 |
| 372 } else { | 393 } else { |
| 373 sqlite3_release_memory 9900 | 394 sqlite3_release_memory 9900 |
| 374 } | 395 } |
| 375 list [nPage db] [nPage db2] | 396 list [nPage db] [nPage db2] |
| 376 } {0 3} | 397 } {1 3} |
| 377 do_test malloc5-6.3.5 { | 398 do_test malloc5-6.3.5 { |
| 378 # But if we are really insistent, SQLite will consent to call sync() | 399 # But if we are really insistent, SQLite will consent to call sync() |
| 379 # if there is no other option. UPDATE: As of 3.6.2, SQLite will not | 400 # if there is no other option. UPDATE: As of 3.6.2, SQLite will not |
| 380 # call sync() in this scenario. So no further memory can be reclaimed. | 401 # call sync() in this scenario. So no further memory can be reclaimed. |
| 381 sqlite3_release_memory 1000 | 402 sqlite3_release_memory 1000 |
| 382 list [nPage db] [nPage db2] | 403 list [nPage db] [nPage db2] |
| 383 } {0 3} | 404 } {1 3} |
| 384 do_test malloc5-6.3.6 { | 405 do_test malloc5-6.3.6 { |
| 385 # The referenced page (page 1 of the db2 cache) will not be freed no | 406 # The referenced page (page 1 of the db2 cache) will not be freed no |
| 386 # matter how much memory we ask for: | 407 # matter how much memory we ask for: |
| 387 sqlite3_release_memory 31459 | 408 sqlite3_release_memory 31459 |
| 388 list [nPage db] [nPage db2] | 409 list [nPage db] [nPage db2] |
| 389 } {0 3} | 410 } {1 3} |
| 390 | 411 |
| 391 db2 close | 412 db2 close |
| 392 | 413 |
| 393 sqlite3_soft_heap_limit $::soft_limit | 414 sqlite3_soft_heap_limit $::soft_limit |
| 415 test_restore_config_pagecache |
| 394 finish_test | 416 finish_test |
| 395 catch {db close} | 417 catch {db close} |
| OLD | NEW |