Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: chrome/browser/sync/syncable/directory_backing_store.cc

Issue 8586004: Revert 110356 - Sync: Improve handling of database load failures (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/sync/syncable/directory_backing_store.h" 5 #include "chrome/browser/sync/syncable/directory_backing_store.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #include <limits> 9 #include <limits>
10 10
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 } 184 }
185 if (NULL != save_dbhandle_) { 185 if (NULL != save_dbhandle_) {
186 sqlite3_close(save_dbhandle_); 186 sqlite3_close(save_dbhandle_);
187 save_dbhandle_ = NULL; 187 save_dbhandle_ = NULL;
188 } 188 }
189 } 189 }
190 190
191 bool DirectoryBackingStore::OpenAndConfigureHandleHelper( 191 bool DirectoryBackingStore::OpenAndConfigureHandleHelper(
192 sqlite3** handle) const { 192 sqlite3** handle) const {
193 if (SQLITE_OK == sqlite_utils::OpenSqliteDb(backing_filepath_, handle)) { 193 if (SQLITE_OK == sqlite_utils::OpenSqliteDb(backing_filepath_, handle)) {
194 sqlite3_busy_timeout(*handle, std::numeric_limits<int>::max()); 194 sqlite_utils::scoped_sqlite_db_ptr scoped_handle(*handle);
195 sqlite3_busy_timeout(scoped_handle.get(), std::numeric_limits<int>::max());
195 { 196 {
196 string integrity_error; 197 string integrity_error;
197 bool is_ok = CheckIntegrity(*handle, &integrity_error); 198 bool is_ok = CheckIntegrity(scoped_handle.get(), &integrity_error);
198 if (!is_ok) { 199 if (!is_ok) {
199 LOG(ERROR) << "Integrity check failed: " << integrity_error; 200 LOG(ERROR) << "Integrity check failed: " << integrity_error;
200 sqlite3_close(*handle);
201 *handle = NULL;
202 return false; 201 return false;
203 } 202 }
204 } 203 }
205 { 204 {
206 sqlite_utils::SQLStatement statement; 205 sqlite_utils::SQLStatement statement;
207 statement.prepare(*handle, "PRAGMA fullfsync = 1"); 206 statement.prepare(scoped_handle.get(), "PRAGMA fullfsync = 1");
208 if (SQLITE_DONE != statement.step()) { 207 if (SQLITE_DONE != statement.step()) {
209 LOG(ERROR) << sqlite3_errmsg(*handle); 208 LOG(ERROR) << sqlite3_errmsg(scoped_handle.get());
210 sqlite3_close(*handle);
211 *handle = NULL;
212 return false; 209 return false;
213 } 210 }
214 } 211 }
215 { 212 {
216 sqlite_utils::SQLStatement statement; 213 sqlite_utils::SQLStatement statement;
217 statement.prepare(*handle, "PRAGMA synchronous = 2"); 214 statement.prepare(scoped_handle.get(), "PRAGMA synchronous = 2");
218 if (SQLITE_DONE != statement.step()) { 215 if (SQLITE_DONE != statement.step()) {
219 LOG(ERROR) << sqlite3_errmsg(*handle); 216 LOG(ERROR) << sqlite3_errmsg(scoped_handle.get());
220 sqlite3_close(*handle);
221 *handle = NULL;
222 return false; 217 return false;
223 } 218 }
224 } 219 }
225 sqlite3_busy_timeout(*handle, kDirectoryBackingStoreBusyTimeoutMs); 220 sqlite3_busy_timeout(scoped_handle.release(),
221 kDirectoryBackingStoreBusyTimeoutMs);
226 #if defined(OS_WIN) 222 #if defined(OS_WIN)
227 // Do not index this file. Scanning can occur every time we close the file, 223 // Do not index this file. Scanning can occur every time we close the file,
228 // which causes long delays in SQLite's file locking. 224 // which causes long delays in SQLite's file locking.
229 const DWORD attrs = GetFileAttributes(backing_filepath_.value().c_str()); 225 const DWORD attrs = GetFileAttributes(backing_filepath_.value().c_str());
230 const BOOL attrs_set = 226 const BOOL attrs_set =
231 SetFileAttributes(backing_filepath_.value().c_str(), 227 SetFileAttributes(backing_filepath_.value().c_str(),
232 attrs | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); 228 attrs | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
233 #endif 229 #endif
234 230
235 return true; 231 return true;
236 } else {
237 // The sqlite3 API docs indicate a handle is usually returned even
238 // in the case of error. We clean it up here.
239 if (*handle != NULL) {
240 sqlite3_close(*handle);
241 *handle = NULL;
242 }
243 return false;
244 } 232 }
233 return false;
245 } 234 }
246 235
247 bool DirectoryBackingStore::CheckIntegrity(sqlite3* handle, string* error) 236 bool DirectoryBackingStore::CheckIntegrity(sqlite3* handle, string* error)
248 const { 237 const {
249 sqlite_utils::SQLStatement statement; 238 sqlite_utils::SQLStatement statement;
250 if (SQLITE_OK != 239 statement.prepare(handle, "PRAGMA integrity_check(1)");
251 statement.prepare(handle, "PRAGMA integrity_check(1)")) {
252 *error = sqlite3_errmsg(handle);
253 return false;
254 }
255 if (SQLITE_ROW != statement.step()) { 240 if (SQLITE_ROW != statement.step()) {
256 *error = sqlite3_errmsg(handle); 241 *error = sqlite3_errmsg(handle);
257 return false; 242 return false;
258 } 243 }
259 string integrity_result = statement.column_text(0); 244 string integrity_result = statement.column_text(0);
260 if (integrity_result != "ok") { 245 if (integrity_result != "ok") {
261 *error = integrity_result; 246 *error = integrity_result;
262 return false; 247 return false;
263 } 248 }
264 return true; 249 return true;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 STLDeleteElements(entry_bucket); 282 STLDeleteElements(entry_bucket);
298 283
299 // Close database handle. 284 // Close database handle.
300 EndLoad(); 285 EndLoad();
301 286
302 return result; 287 return result;
303 } 288 }
304 289
305 bool DirectoryBackingStore::BeginLoad() { 290 bool DirectoryBackingStore::BeginLoad() {
306 DCHECK(load_dbhandle_ == NULL); 291 DCHECK(load_dbhandle_ == NULL);
307 return OpenAndConfigureHandleHelper(&load_dbhandle_); 292 bool ret = OpenAndConfigureHandleHelper(&load_dbhandle_);
293 if (ret)
294 return true;
295 // Something's gone wrong. Nuke the database and try again.
296 using ::operator<<; // For string16.
297 LOG(ERROR) << "Sync database " << backing_filepath_.value()
298 << " corrupt. Deleting and recreating.";
299 file_util::Delete(backing_filepath_, false);
300 bool failed_again = !OpenAndConfigureHandleHelper(&load_dbhandle_);
301
302 // Using failed_again here lets us distinguish from cases where corruption
303 // occurred even when re-opening a fresh directory (they'll go in a separate
304 // double weight histogram bucket). Failing twice in a row means we disable
305 // sync, so it's useful to see this number separately.
306 int bucket = failed_again ? 2 : 1;
307 #if defined(OS_WIN)
308 UMA_HISTOGRAM_COUNTS_100("Sync.DirectoryOpenFailedWin", bucket);
309 #elif defined(OS_MACOSX)
310 UMA_HISTOGRAM_COUNTS_100("Sync.DirectoryOpenFailedMac", bucket);
311 #else
312 UMA_HISTOGRAM_COUNTS_100("Sync.DirectoryOpenFailedNotWinMac", bucket);
313
314 #if defined(OS_CHROMEOS)
315 UMA_HISTOGRAM_COUNTS_100("Sync.DirectoryOpenFailedCros", bucket);
316 #elif defined(OS_LINUX)
317 UMA_HISTOGRAM_COUNTS_100("Sync.DirectoryOpenFailedLinux", bucket);
318 #else
319 UMA_HISTOGRAM_COUNTS_100("Sync.DirectoryOpenFailedOther", bucket);
320 #endif // OS_LINUX && !OS_CHROMEOS
321 #endif // OS_WIN
322 return !failed_again;
308 } 323 }
309 324
310 void DirectoryBackingStore::EndLoad() { 325 void DirectoryBackingStore::EndLoad() {
311 sqlite3_close(load_dbhandle_); 326 sqlite3_close(load_dbhandle_);
312 load_dbhandle_ = NULL; // No longer used. 327 load_dbhandle_ = NULL; // No longer used.
313 } 328 }
314 329
315 void DirectoryBackingStore::EndSave() { 330 void DirectoryBackingStore::EndSave() {
316 sqlite3_close(save_dbhandle_); 331 sqlite3_close(save_dbhandle_);
317 save_dbhandle_ = NULL; 332 save_dbhandle_ = NULL;
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 "id TEXT primary key, " 1270 "id TEXT primary key, "
1256 "name TEXT, " 1271 "name TEXT, "
1257 "store_birthday TEXT, " 1272 "store_birthday TEXT, "
1258 "db_create_version TEXT, " 1273 "db_create_version TEXT, "
1259 "db_create_time INT, " 1274 "db_create_time INT, "
1260 "next_id INT default -2, " 1275 "next_id INT default -2, "
1261 "cache_guid TEXT )"); 1276 "cache_guid TEXT )");
1262 return ExecQuery(load_dbhandle_, query.c_str()); 1277 return ExecQuery(load_dbhandle_, query.c_str());
1263 } 1278 }
1264 } // namespace syncable 1279 } // namespace syncable
OLDNEW
« no previous file with comments | « chrome/browser/sync/profile_sync_service_unittest.cc ('k') | chrome/browser/sync/syncable/directory_backing_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698