blob: 3d0ac611b2df949ca8db6739f14abeb81a2b5932 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.database.sqlite;
18
Fyodor Kupolovb7733122017-07-24 16:13:50 -070019import android.annotation.TestApi;
Jeff Brown89101cd92011-10-27 21:24:54 -070020import android.os.Build;
Makoto Onukia761d2b2018-08-01 15:57:45 -070021import android.os.Process;
Jeff Brown89101cd92011-10-27 21:24:54 -070022import android.os.SystemProperties;
Fred Quintanac4516a72009-09-03 12:14:06 -070023import android.util.Log;
Jeff Brown6754ba22011-12-14 20:20:01 -080024import android.util.Printer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025
Artur Satayevf0b7d0b2019-11-04 11:16:45 +000026import dalvik.annotation.compat.UnsupportedAppUsage;
27
Fyodor Kupolovb7733122017-07-24 16:13:50 -070028import java.util.ArrayList;
29
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030/**
31 * Provides debugging info about all SQLite databases running in the current process.
Vasu Nori4dd4ab42010-01-29 16:24:23 -080032 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033 * {@hide}
34 */
Fyodor Kupolov6fe565e2018-04-06 14:48:05 -070035@TestApi
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036public final class SQLiteDebug {
Jeff Brown254fba82012-01-19 17:06:44 -080037 private static native void nativeGetPagerStats(PagerStats stats);
38
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039 /**
Makoto Onukia761d2b2018-08-01 15:57:45 -070040 * Inner class to avoid getting the value frozen in zygote.
Jeff Brown638eff72012-03-01 10:21:29 -080041 *
Makoto Onukia761d2b2018-08-01 15:57:45 -070042 * {@hide}
Jeff Browne5360fb2011-10-31 17:48:13 -070043 */
Makoto Onukia9be33f2019-05-31 16:03:50 -070044 public static final class NoPreloadHolder {
Makoto Onukia761d2b2018-08-01 15:57:45 -070045 /**
46 * Controls the printing of informational SQL log messages.
47 *
48 * Enable using "adb shell setprop log.tag.SQLiteLog VERBOSE".
49 */
50 public static final boolean DEBUG_SQL_LOG =
51 Log.isLoggable("SQLiteLog", Log.VERBOSE);
Jeff Browne5360fb2011-10-31 17:48:13 -070052
Makoto Onukia761d2b2018-08-01 15:57:45 -070053 /**
54 * Controls the printing of SQL statements as they are executed.
55 *
56 * Enable using "adb shell setprop log.tag.SQLiteStatements VERBOSE".
57 */
58 public static final boolean DEBUG_SQL_STATEMENTS =
59 Log.isLoggable("SQLiteStatements", Log.VERBOSE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
Makoto Onukia761d2b2018-08-01 15:57:45 -070061 /**
62 * Controls the printing of wall-clock time taken to execute SQL statements
63 * as they are executed.
64 *
65 * Enable using "adb shell setprop log.tag.SQLiteTime VERBOSE".
66 */
67 public static final boolean DEBUG_SQL_TIME =
68 Log.isLoggable("SQLiteTime", Log.VERBOSE);
Vasu Nori3ef94e22010-02-05 14:49:04 -080069
Makoto Onukia761d2b2018-08-01 15:57:45 -070070
71 /**
72 * True to enable database performance testing instrumentation.
73 */
74 public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE;
75
76 private static final String SLOW_QUERY_THRESHOLD_PROP = "db.log.slow_query_threshold";
77
78 private static final String SLOW_QUERY_THRESHOLD_UID_PROP =
79 SLOW_QUERY_THRESHOLD_PROP + "." + Process.myUid();
80
81 /**
Makoto Onuki6cb20332018-08-07 15:57:13 -070082 * Whether to add detailed information to slow query log.
Makoto Onukia761d2b2018-08-01 15:57:45 -070083 */
Makoto Onuki6cb20332018-08-07 15:57:13 -070084 public static final boolean DEBUG_LOG_DETAILED = Build.IS_DEBUGGABLE
85 && SystemProperties.getBoolean("db.log.detailed", false);
Makoto Onukia761d2b2018-08-01 15:57:45 -070086 }
Jeff Brown89101cd92011-10-27 21:24:54 -070087
Jeff Brownbaefdfa2012-03-05 10:33:13 -080088 private SQLiteDebug() {
89 }
90
Jeff Brown89101cd92011-10-27 21:24:54 -070091 /**
92 * Determines whether a query should be logged.
93 *
94 * Reads the "db.log.slow_query_threshold" system property, which can be changed
95 * by the user at any time. If the value is zero, then all queries will
Jeff Brown638eff72012-03-01 10:21:29 -080096 * be considered slow. If the value does not exist or is negative, then no queries will
Jeff Brown89101cd92011-10-27 21:24:54 -070097 * be considered slow.
98 *
Makoto Onukia761d2b2018-08-01 15:57:45 -070099 * To enable it for a specific UID, "db.log.slow_query_threshold.UID" could also be used.
100 *
Jeff Brown89101cd92011-10-27 21:24:54 -0700101 * This value can be changed dynamically while the system is running.
Jeff Brown638eff72012-03-01 10:21:29 -0800102 * For example, "adb shell setprop db.log.slow_query_threshold 200" will
103 * log all queries that take 200ms or longer to run.
Jeff Brown89101cd92011-10-27 21:24:54 -0700104 * @hide
105 */
Makoto Onukia761d2b2018-08-01 15:57:45 -0700106 public static boolean shouldLogSlowQuery(long elapsedTimeMillis) {
107 final int slowQueryMillis = Math.min(
Makoto Onukia9be33f2019-05-31 16:03:50 -0700108 SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_PROP,
109 Integer.MAX_VALUE),
110 SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_UID_PROP,
Makoto Onukia761d2b2018-08-01 15:57:45 -0700111 Integer.MAX_VALUE));
112 return elapsedTimeMillis >= slowQueryMillis;
Jeff Brown89101cd92011-10-27 21:24:54 -0700113 }
114
115 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 * Contains statistics about the active pagers in the current process.
Vasu Nori4dd4ab42010-01-29 16:24:23 -0800117 *
Jeff Brown254fba82012-01-19 17:06:44 -0800118 * @see #nativeGetPagerStats(PagerStats)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 */
120 public static class PagerStats {
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000121
122 @UnsupportedAppUsage
123 public PagerStats() {
124 }
125
Vasu Noric3849202010-03-09 10:47:25 -0800126 /** the current amount of memory checked out by sqlite using sqlite3_malloc().
127 * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
128 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000129 @UnsupportedAppUsage
Vasu Noric3849202010-03-09 10:47:25 -0800130 public int memoryUsed;
131
132 /** the number of bytes of page cache allocation which could not be sattisfied by the
133 * SQLITE_CONFIG_PAGECACHE buffer and where forced to overflow to sqlite3_malloc().
134 * The returned value includes allocations that overflowed because they where too large
135 * (they were larger than the "sz" parameter to SQLITE_CONFIG_PAGECACHE) and allocations
136 * that overflowed because no space was left in the page cache.
137 * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
138 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000139 @UnsupportedAppUsage
Jeff Brown2a293b62012-01-19 14:02:22 -0800140 public int pageCacheOverflow;
Vasu Noric3849202010-03-09 10:47:25 -0800141
142 /** records the largest memory allocation request handed to sqlite3.
143 * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
144 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000145 @UnsupportedAppUsage
Vasu Noric3849202010-03-09 10:47:25 -0800146 public int largestMemAlloc;
147
148 /** a list of {@link DbStats} - one for each main database opened by the applications
149 * running on the android device
150 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000151 @UnsupportedAppUsage
Vasu Noric3849202010-03-09 10:47:25 -0800152 public ArrayList<DbStats> dbStats;
153 }
154
155 /**
156 * contains statistics about a database
Vasu Noric3849202010-03-09 10:47:25 -0800157 */
158 public static class DbStats {
159 /** name of the database */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000160 @UnsupportedAppUsage
Vasu Nori00e40172010-11-29 11:03:23 -0800161 public String dbName;
Vasu Noric3849202010-03-09 10:47:25 -0800162
163 /** the page size for the database */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000164 @UnsupportedAppUsage
Vasu Nori00e40172010-11-29 11:03:23 -0800165 public long pageSize;
Vasu Noric3849202010-03-09 10:47:25 -0800166
167 /** the database size */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000168 @UnsupportedAppUsage
Vasu Nori00e40172010-11-29 11:03:23 -0800169 public long dbSize;
Vasu Noric3849202010-03-09 10:47:25 -0800170
Fyodor Kupolovb7733122017-07-24 16:13:50 -0700171 /**
172 * Number of lookaside slots: http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000173 @UnsupportedAppUsage
Vasu Nori00e40172010-11-29 11:03:23 -0800174 public int lookaside;
Vasu Noric3849202010-03-09 10:47:25 -0800175
Vasu Nori90a367262010-04-12 12:49:09 -0700176 /** statement cache stats: hits/misses/cachesize */
Vasu Nori00e40172010-11-29 11:03:23 -0800177 public String cache;
Vasu Nori90a367262010-04-12 12:49:09 -0700178
179 public DbStats(String dbName, long pageCount, long pageSize, int lookaside,
Vasu Nori00e40172010-11-29 11:03:23 -0800180 int hits, int misses, int cachesize) {
Vasu Noric3849202010-03-09 10:47:25 -0800181 this.dbName = dbName;
Vasu Nori90a367262010-04-12 12:49:09 -0700182 this.pageSize = pageSize / 1024;
Vasu Noric3849202010-03-09 10:47:25 -0800183 dbSize = (pageCount * pageSize) / 1024;
184 this.lookaside = lookaside;
Vasu Nori90a367262010-04-12 12:49:09 -0700185 this.cache = hits + "/" + misses + "/" + cachesize;
Vasu Noric3849202010-03-09 10:47:25 -0800186 }
187 }
188
189 /**
190 * return all pager and database stats for the current process.
191 * @return {@link PagerStats}
192 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000193 @UnsupportedAppUsage
Vasu Noric3849202010-03-09 10:47:25 -0800194 public static PagerStats getDatabaseInfo() {
195 PagerStats stats = new PagerStats();
Jeff Brown254fba82012-01-19 17:06:44 -0800196 nativeGetPagerStats(stats);
Vasu Noric3849202010-03-09 10:47:25 -0800197 stats.dbStats = SQLiteDatabase.getDbStats();
198 return stats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 }
200
201 /**
Jeff Brown6754ba22011-12-14 20:20:01 -0800202 * Dumps detailed information about all databases used by the process.
203 * @param printer The printer for dumping database state.
Jeff Browna9be4152012-01-18 15:29:57 -0800204 * @param args Command-line arguments supplied to dumpsys dbinfo
Jeff Brown6754ba22011-12-14 20:20:01 -0800205 */
206 public static void dump(Printer printer, String[] args) {
Makoto Onukiee93ad22018-10-18 16:24:13 -0700207 dump(printer, args, false);
208 }
209
210 /** @hide */
211 public static void dump(Printer printer, String[] args, boolean isSystem) {
Jeff Browna9be4152012-01-18 15:29:57 -0800212 boolean verbose = false;
213 for (String arg : args) {
214 if (arg.equals("-v")) {
215 verbose = true;
216 }
217 }
218
Makoto Onukiee93ad22018-10-18 16:24:13 -0700219 SQLiteDatabase.dumpAll(printer, verbose, isSystem);
Jeff Brown6754ba22011-12-14 20:20:01 -0800220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221}