OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "sql/connection.h" | 5 #include "sql/connection.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <string.h> | 10 #include <string.h> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/debug/dump_without_crashing.h" | 14 #include "base/debug/dump_without_crashing.h" |
15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
16 #include "base/files/file_util.h" | 16 #include "base/files/file_util.h" |
17 #include "base/format_macros.h" | 17 #include "base/format_macros.h" |
18 #include "base/json/json_file_value_serializer.h" | 18 #include "base/json/json_file_value_serializer.h" |
19 #include "base/lazy_instance.h" | 19 #include "base/lazy_instance.h" |
20 #include "base/logging.h" | 20 #include "base/logging.h" |
21 #include "base/message_loop/message_loop.h" | 21 #include "base/message_loop/message_loop.h" |
22 #include "base/metrics/histogram.h" | 22 #include "base/metrics/histogram.h" |
23 #include "base/metrics/sparse_histogram.h" | 23 #include "base/metrics/sparse_histogram.h" |
24 #include "base/strings/string_split.h" | 24 #include "base/strings/string_split.h" |
25 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
26 #include "base/strings/stringprintf.h" | 26 #include "base/strings/stringprintf.h" |
27 #include "base/strings/utf_string_conversions.h" | 27 #include "base/strings/utf_string_conversions.h" |
28 #include "base/synchronization/lock.h" | 28 #include "base/synchronization/lock.h" |
29 #include "base/trace_event/memory_dump_manager.h" | 29 #include "base/trace_event/memory_dump_manager.h" |
30 #include "base/trace_event/process_memory_dump.h" | 30 #include "sql/connection_memory_dump_provider.h" |
31 #include "sql/meta_table.h" | 31 #include "sql/meta_table.h" |
32 #include "sql/statement.h" | 32 #include "sql/statement.h" |
33 #include "third_party/sqlite/sqlite3.h" | 33 #include "third_party/sqlite/sqlite3.h" |
34 | 34 |
35 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) | 35 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) |
36 #include "third_party/sqlite/src/ext/icu/sqliteicu.h" | 36 #include "third_party/sqlite/src/ext/icu/sqliteicu.h" |
37 #endif | 37 #endif |
38 | 38 |
39 namespace { | 39 namespace { |
40 | 40 |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 int basic_error = error & 0xff; | 247 int basic_error = error & 0xff; |
248 | 248 |
249 // These errors relate more to the runtime context of the system than to | 249 // These errors relate more to the runtime context of the system than to |
250 // errors with a SQL statement or with the schema, so they aren't generally | 250 // errors with a SQL statement or with the schema, so they aren't generally |
251 // interesting to flag. This list is not comprehensive. | 251 // interesting to flag. This list is not comprehensive. |
252 return basic_error == SQLITE_BUSY || | 252 return basic_error == SQLITE_BUSY || |
253 basic_error == SQLITE_NOTADB || | 253 basic_error == SQLITE_NOTADB || |
254 basic_error == SQLITE_CORRUPT; | 254 basic_error == SQLITE_CORRUPT; |
255 } | 255 } |
256 | 256 |
257 bool Connection::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, | |
258 base::trace_event::ProcessMemoryDump* pmd) { | |
259 if (args.level_of_detail == | |
260 base::trace_event::MemoryDumpLevelOfDetail::LIGHT || | |
261 !db_) { | |
262 return true; | |
263 } | |
264 | |
265 // The high water mark is not tracked for the following usages. | |
266 int cache_size, dummy_int; | |
267 sqlite3_db_status(db_, SQLITE_DBSTATUS_CACHE_USED, &cache_size, &dummy_int, | |
268 0 /* resetFlag */); | |
269 int schema_size; | |
270 sqlite3_db_status(db_, SQLITE_DBSTATUS_SCHEMA_USED, &schema_size, &dummy_int, | |
271 0 /* resetFlag */); | |
272 int statement_size; | |
273 sqlite3_db_status(db_, SQLITE_DBSTATUS_STMT_USED, &statement_size, &dummy_int, | |
274 0 /* resetFlag */); | |
275 | |
276 std::string name = base::StringPrintf( | |
277 "sqlite/%s_connection/%p", | |
278 histogram_tag_.empty() ? "Unknown" : histogram_tag_.c_str(), this); | |
279 base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(name); | |
280 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, | |
281 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | |
282 cache_size + schema_size + statement_size); | |
283 dump->AddScalar("cache_size", | |
284 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | |
285 cache_size); | |
286 dump->AddScalar("schema_size", | |
287 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | |
288 schema_size); | |
289 dump->AddScalar("statement_size", | |
290 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | |
291 statement_size); | |
292 return true; | |
293 } | |
294 | |
295 void Connection::ReportDiagnosticInfo(int extended_error, Statement* stmt) { | 257 void Connection::ReportDiagnosticInfo(int extended_error, Statement* stmt) { |
296 AssertIOAllowed(); | 258 AssertIOAllowed(); |
297 | 259 |
298 std::string debug_info; | 260 std::string debug_info; |
299 const int error = (extended_error & 0xFF); | 261 const int error = (extended_error & 0xFF); |
300 if (error == SQLITE_CORRUPT) { | 262 if (error == SQLITE_CORRUPT) { |
301 debug_info = CollectCorruptionInfo(); | 263 debug_info = CollectCorruptionInfo(); |
302 } else { | 264 } else { |
303 debug_info = CollectErrorInfo(extended_error, stmt); | 265 debug_info = CollectErrorInfo(extended_error, stmt); |
304 } | 266 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 poisoned_(false), | 341 poisoned_(false), |
380 mmap_disabled_(false), | 342 mmap_disabled_(false), |
381 mmap_enabled_(false), | 343 mmap_enabled_(false), |
382 total_changes_at_last_release_(0), | 344 total_changes_at_last_release_(0), |
383 stats_histogram_(NULL), | 345 stats_histogram_(NULL), |
384 commit_time_histogram_(NULL), | 346 commit_time_histogram_(NULL), |
385 autocommit_time_histogram_(NULL), | 347 autocommit_time_histogram_(NULL), |
386 update_time_histogram_(NULL), | 348 update_time_histogram_(NULL), |
387 query_time_histogram_(NULL), | 349 query_time_histogram_(NULL), |
388 clock_(new TimeSource()) { | 350 clock_(new TimeSource()) { |
389 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | |
390 this, "sql::Connection", nullptr); | |
391 } | 351 } |
392 | 352 |
393 Connection::~Connection() { | 353 Connection::~Connection() { |
394 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( | |
395 this); | |
396 Close(); | 354 Close(); |
397 } | 355 } |
398 | 356 |
399 void Connection::RecordEvent(Events event, size_t count) { | 357 void Connection::RecordEvent(Events event, size_t count) { |
400 for (size_t i = 0; i < count; ++i) { | 358 for (size_t i = 0; i < count; ++i) { |
401 UMA_HISTOGRAM_ENUMERATION("Sqlite.Stats", event, EVENT_MAX_VALUE); | 359 UMA_HISTOGRAM_ENUMERATION("Sqlite.Stats", event, EVENT_MAX_VALUE); |
402 } | 360 } |
403 | 361 |
404 if (stats_histogram_) { | 362 if (stats_histogram_) { |
405 for (size_t i = 0; i < count; ++i) { | 363 for (size_t i = 0; i < count; ++i) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
504 | 462 |
505 if (db_) { | 463 if (db_) { |
506 // Call to AssertIOAllowed() cannot go at the beginning of the function | 464 // Call to AssertIOAllowed() cannot go at the beginning of the function |
507 // because Close() must be called from destructor to clean | 465 // because Close() must be called from destructor to clean |
508 // statement_cache_, it won't cause any disk access and it most probably | 466 // statement_cache_, it won't cause any disk access and it most probably |
509 // will happen on thread not allowing disk access. | 467 // will happen on thread not allowing disk access. |
510 // TODO(paivanof@gmail.com): This should move to the beginning | 468 // TODO(paivanof@gmail.com): This should move to the beginning |
511 // of the function. http://crbug.com/136655. | 469 // of the function. http://crbug.com/136655. |
512 AssertIOAllowed(); | 470 AssertIOAllowed(); |
513 | 471 |
472 // Reseting acquires a lock to ensure no dump is happening on the database | |
473 // at the same time. Unregister takes ownership of provider and it is safe | |
474 // since the db is reset. memory_dump_provider_ could be null if db_ was | |
475 // poisoned. | |
476 if (memory_dump_provider_) { | |
477 memory_dump_provider_->reset_database(); | |
478 base::trace_event::MemoryDumpManager::GetInstance() | |
479 ->UnregisterAndDeleteDumpProviderSoon( | |
480 std::move(memory_dump_provider_)); | |
481 } | |
482 | |
514 int rc = sqlite3_close(db_); | 483 int rc = sqlite3_close(db_); |
515 if (rc != SQLITE_OK) { | 484 if (rc != SQLITE_OK) { |
516 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.CloseFailure", rc); | 485 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.CloseFailure", rc); |
517 DLOG(FATAL) << "sqlite3_close failed: " << GetErrorMessage(); | 486 DLOG(FATAL) << "sqlite3_close failed: " << GetErrorMessage(); |
518 } | 487 } |
519 } | 488 } |
520 db_ = NULL; | 489 db_ = NULL; |
521 } | 490 } |
522 | 491 |
523 void Connection::Close() { | 492 void Connection::Close() { |
(...skipping 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1841 | 1810 |
1842 // Determine if memory-mapping has actually been enabled. The Execute() above | 1811 // Determine if memory-mapping has actually been enabled. The Execute() above |
1843 // can succeed without changing the amount mapped. | 1812 // can succeed without changing the amount mapped. |
1844 mmap_enabled_ = false; | 1813 mmap_enabled_ = false; |
1845 { | 1814 { |
1846 Statement s(GetUniqueStatement("PRAGMA mmap_size")); | 1815 Statement s(GetUniqueStatement("PRAGMA mmap_size")); |
1847 if (s.Step() && s.ColumnInt64(0) > 0) | 1816 if (s.Step() && s.ColumnInt64(0) > 0) |
1848 mmap_enabled_ = true; | 1817 mmap_enabled_ = true; |
1849 } | 1818 } |
1850 | 1819 |
1820 memory_dump_provider_.reset( | |
Primiano Tucci (use gerrit)
2016/01/11 19:27:42
Add a DCHECK(!memory_dump_provider_)
The mdp_ must
ssid
2016/01/12 12:23:07
Done.
| |
1821 new ConnectionMemoryDumpProvider(db_, histogram_tag_)); | |
1822 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | |
1823 memory_dump_provider_.get(), "sql::Connection", nullptr); | |
1824 | |
1851 return true; | 1825 return true; |
1852 } | 1826 } |
1853 | 1827 |
1854 void Connection::DoRollback() { | 1828 void Connection::DoRollback() { |
1855 Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK")); | 1829 Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK")); |
1856 | 1830 |
1857 // Collect the rollback time manually, sql::Statement would register it as | 1831 // Collect the rollback time manually, sql::Statement would register it as |
1858 // query time only. | 1832 // query time only. |
1859 const base::TimeTicks before = Now(); | 1833 const base::TimeTicks before = Now(); |
1860 rollback.RunWithoutTimers(); | 1834 rollback.RunWithoutTimers(); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1984 ignore_result(Execute(kNoWritableSchema)); | 1958 ignore_result(Execute(kNoWritableSchema)); |
1985 | 1959 |
1986 return ret; | 1960 return ret; |
1987 } | 1961 } |
1988 | 1962 |
1989 base::TimeTicks TimeSource::Now() { | 1963 base::TimeTicks TimeSource::Now() { |
1990 return base::TimeTicks::Now(); | 1964 return base::TimeTicks::Now(); |
1991 } | 1965 } |
1992 | 1966 |
1993 } // namespace sql | 1967 } // namespace sql |
OLD | NEW |