OLD | NEW |
| (Empty) |
1 # Run this TCL script using "testfixture" in order get a report that shows | |
2 # how much disk space is used by a particular data to actually store data | |
3 # versus how much space is unused. | |
4 # | |
5 | |
6 # Get the name of the database to analyze | |
7 # | |
8 if {[llength $argv]!=1} { | |
9 puts stderr "Usage: $argv0 database-name" | |
10 exit 1 | |
11 } | |
12 set file_to_analyze [lindex $argv 0] | |
13 | |
14 # Open the database | |
15 # | |
16 sqlite db [lindex $argv 0] | |
17 set DB [btree_open [lindex $argv 0]] | |
18 | |
19 # Output the schema for the generated report | |
20 # | |
21 puts \ | |
22 {BEGIN; | |
23 CREATE TABLE space_used( | |
24 name clob, -- Name of a table or index in the database file | |
25 is_index boolean, -- TRUE if it is an index, false for a table | |
26 payload int, -- Total amount of data stored in this table or index | |
27 pri_pages int, -- Number of primary pages used | |
28 ovfl_pages int, -- Number of overflow pages used | |
29 pri_unused int, -- Number of unused bytes on primary pages | |
30 ovfl_unused int -- Number of unused bytes on overflow pages | |
31 );} | |
32 | |
33 # This query will be used to find the root page number for every index and | |
34 # table in the database. | |
35 # | |
36 set sql { | |
37 SELECT name, type, rootpage FROM sqlite_master | |
38 UNION ALL | |
39 SELECT 'sqlite_master', 'table', 2 | |
40 ORDER BY 1 | |
41 } | |
42 | |
43 # Initialize variables used for summary statistics. | |
44 # | |
45 set total_size 0 | |
46 set total_primary 0 | |
47 set total_overflow 0 | |
48 set total_unused_primary 0 | |
49 set total_unused_ovfl 0 | |
50 | |
51 # Analyze every table in the database, one at a time. | |
52 # | |
53 foreach {name type rootpage} [db eval $sql] { | |
54 set cursor [btree_cursor $DB $rootpage 0] | |
55 set go [btree_first $cursor] | |
56 set size 0 | |
57 catch {unset pg_used} | |
58 set unused_ovfl 0 | |
59 set n_overflow 0 | |
60 while {$go==0} { | |
61 set payload [btree_payload_size $cursor] | |
62 incr size $payload | |
63 set stat [btree_cursor_dump $cursor] | |
64 set pgno [lindex $stat 0] | |
65 set freebytes [lindex $stat 4] | |
66 set pg_used($pgno) $freebytes | |
67 if {$payload>238} { | |
68 set n [expr {($payload-238+1019)/1020}] | |
69 incr n_overflow $n | |
70 incr unused_ovfl [expr {$n*1020+238-$payload}] | |
71 } | |
72 set go [btree_next $cursor] | |
73 } | |
74 btree_close_cursor $cursor | |
75 set n_primary [llength [array names pg_used]] | |
76 set unused_primary 0 | |
77 foreach x [array names pg_used] {incr unused_primary $pg_used($x)} | |
78 regsub -all ' $name '' name | |
79 puts -nonewline "INSERT INTO space_used VALUES('$name'" | |
80 puts -nonewline ",[expr {$type=="index"}]" | |
81 puts ",$size,$n_primary,$n_overflow,$unused_primary,$unused_ovfl);" | |
82 incr total_size $size | |
83 incr total_primary $n_primary | |
84 incr total_overflow $n_overflow | |
85 incr total_unused_primary $unused_primary | |
86 incr total_unused_ovfl $unused_ovfl | |
87 } | |
88 | |
89 # Output summary statistics: | |
90 # | |
91 puts "-- Total payload size: $total_size" | |
92 puts "-- Total pages used: $total_primary primary and $total_overflow overflow" | |
93 set file_pgcnt [expr {[file size [lindex $argv 0]]/1024}] | |
94 puts -nonewline "-- Total unused bytes on primary pages: $total_unused_primary" | |
95 if {$total_primary>0} { | |
96 set upp [expr {$total_unused_primary/$total_primary}] | |
97 puts " (avg $upp bytes/page)" | |
98 } else { | |
99 puts "" | |
100 } | |
101 puts -nonewline "-- Total unused bytes on overflow pages: $total_unused_ovfl" | |
102 if {$total_overflow>0} { | |
103 set upp [expr {$total_unused_ovfl/$total_overflow}] | |
104 puts " (avg $upp bytes/page)" | |
105 } else { | |
106 puts "" | |
107 } | |
108 set n_free [expr {$file_pgcnt-$total_primary-$total_overflow}] | |
109 if {$n_free>0} {incr n_free -1} | |
110 puts "-- Total pages on freelist: $n_free" | |
111 puts "COMMIT;" | |
OLD | NEW |