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

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

Issue 8574045: Revert 110384 - 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 sqlite_utils::scoped_sqlite_db_ptr scoped_handle(*handle); 194 sqlite3_busy_timeout(*handle, std::numeric_limits<int>::max());
195 sqlite3_busy_timeout(scoped_handle.get(), std::numeric_limits<int>::max());
196 { 195 {
197 string integrity_error; 196 string integrity_error;
198 bool is_ok = CheckIntegrity(scoped_handle.get(), &integrity_error); 197 bool is_ok = CheckIntegrity(*handle, &integrity_error);
199 if (!is_ok) { 198 if (!is_ok) {
200 LOG(ERROR) << "Integrity check failed: " << integrity_error; 199 LOG(ERROR) << "Integrity check failed: " << integrity_error;
200 sqlite3_close(*handle);
201 *handle = NULL;
201 return false; 202 return false;
202 } 203 }
203 } 204 }
204 { 205 {
205 sqlite_utils::SQLStatement statement; 206 sqlite_utils::SQLStatement statement;
206 statement.prepare(scoped_handle.get(), "PRAGMA fullfsync = 1"); 207 statement.prepare(*handle, "PRAGMA fullfsync = 1");
207 if (SQLITE_DONE != statement.step()) { 208 if (SQLITE_DONE != statement.step()) {
208 LOG(ERROR) << sqlite3_errmsg(scoped_handle.get()); 209 LOG(ERROR) << sqlite3_errmsg(*handle);
210 sqlite3_close(*handle);
211 *handle = NULL;
209 return false; 212 return false;
210 } 213 }
211 } 214 }
212 { 215 {
213 sqlite_utils::SQLStatement statement; 216 sqlite_utils::SQLStatement statement;
214 statement.prepare(scoped_handle.get(), "PRAGMA synchronous = 2"); 217 statement.prepare(*handle, "PRAGMA synchronous = 2");
215 if (SQLITE_DONE != statement.step()) { 218 if (SQLITE_DONE != statement.step()) {
216 LOG(ERROR) << sqlite3_errmsg(scoped_handle.get()); 219 LOG(ERROR) << sqlite3_errmsg(*handle);
220 sqlite3_close(*handle);
221 *handle = NULL;
217 return false; 222 return false;
218 } 223 }
219 } 224 }
220 sqlite3_busy_timeout(scoped_handle.release(), 225 sqlite3_busy_timeout(*handle, kDirectoryBackingStoreBusyTimeoutMs);
221 kDirectoryBackingStoreBusyTimeoutMs);
222 #if defined(OS_WIN) 226 #if defined(OS_WIN)
223 // Do not index this file. Scanning can occur every time we close the file, 227 // Do not index this file. Scanning can occur every time we close the file,
224 // which causes long delays in SQLite's file locking. 228 // which causes long delays in SQLite's file locking.
225 const DWORD attrs = GetFileAttributes(backing_filepath_.value().c_str()); 229 const DWORD attrs = GetFileAttributes(backing_filepath_.value().c_str());
226 const BOOL attrs_set = 230 const BOOL attrs_set =
227 SetFileAttributes(backing_filepath_.value().c_str(), 231 SetFileAttributes(backing_filepath_.value().c_str(),
228 attrs | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); 232 attrs | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
229 #endif 233 #endif
230 234
231 return true; 235 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;
232 } 244 }
233 return false;
234 } 245 }
235 246
236 bool DirectoryBackingStore::CheckIntegrity(sqlite3* handle, string* error) 247 bool DirectoryBackingStore::CheckIntegrity(sqlite3* handle, string* error)
237 const { 248 const {
238 sqlite_utils::SQLStatement statement; 249 sqlite_utils::SQLStatement statement;
239 statement.prepare(handle, "PRAGMA integrity_check(1)"); 250 if (SQLITE_OK !=
251 statement.prepare(handle, "PRAGMA integrity_check(1)")) {
252 *error = sqlite3_errmsg(handle);
253 return false;
254 }
240 if (SQLITE_ROW != statement.step()) { 255 if (SQLITE_ROW != statement.step()) {
241 *error = sqlite3_errmsg(handle); 256 *error = sqlite3_errmsg(handle);
242 return false; 257 return false;
243 } 258 }
244 string integrity_result = statement.column_text(0); 259 string integrity_result = statement.column_text(0);
245 if (integrity_result != "ok") { 260 if (integrity_result != "ok") {
246 *error = integrity_result; 261 *error = integrity_result;
247 return false; 262 return false;
248 } 263 }
249 return true; 264 return true;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 STLDeleteElements(entry_bucket); 297 STLDeleteElements(entry_bucket);
283 298
284 // Close database handle. 299 // Close database handle.
285 EndLoad(); 300 EndLoad();
286 301
287 return result; 302 return result;
288 } 303 }
289 304
290 bool DirectoryBackingStore::BeginLoad() { 305 bool DirectoryBackingStore::BeginLoad() {
291 DCHECK(load_dbhandle_ == NULL); 306 DCHECK(load_dbhandle_ == NULL);
292 bool ret = OpenAndConfigureHandleHelper(&load_dbhandle_); 307 return 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;
323 } 308 }
324 309
325 void DirectoryBackingStore::EndLoad() { 310 void DirectoryBackingStore::EndLoad() {
326 sqlite3_close(load_dbhandle_); 311 sqlite3_close(load_dbhandle_);
327 load_dbhandle_ = NULL; // No longer used. 312 load_dbhandle_ = NULL; // No longer used.
328 } 313 }
329 314
330 void DirectoryBackingStore::EndSave() { 315 void DirectoryBackingStore::EndSave() {
331 sqlite3_close(save_dbhandle_); 316 sqlite3_close(save_dbhandle_);
332 save_dbhandle_ = NULL; 317 save_dbhandle_ = NULL;
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 "id TEXT primary key, " 1255 "id TEXT primary key, "
1271 "name TEXT, " 1256 "name TEXT, "
1272 "store_birthday TEXT, " 1257 "store_birthday TEXT, "
1273 "db_create_version TEXT, " 1258 "db_create_version TEXT, "
1274 "db_create_time INT, " 1259 "db_create_time INT, "
1275 "next_id INT default -2, " 1260 "next_id INT default -2, "
1276 "cache_guid TEXT )"); 1261 "cache_guid TEXT )");
1277 return ExecQuery(load_dbhandle_, query.c_str()); 1262 return ExecQuery(load_dbhandle_, query.c_str());
1278 } 1263 }
1279 } // namespace syncable 1264 } // 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