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

Issue 18180013: Scoped recovery module for sql/ (Closed)

Created:
7 years, 5 months ago by Scott Hess - ex-Googler
Modified:
7 years, 5 months ago
CC:
chromium-reviews
Visibility:
Public.

Description

[Closed because landed in: https://chromiumcodereview.appspot.com/19281002 ] Scoped recovery module for sql/ BUG=

Patch Set 1 #

Patch Set 2 : bit more cleanup #

Patch Set 3 : Oops, add recover_unittest.cc #

Total comments: 4
Unified diffs Side-by-side diffs Delta from patch set Stats (+515 lines, -3 lines) Patch
M sql/connection.h View 5 chunks +17 lines, -0 lines 0 comments Download
M sql/connection.cc View 4 chunks +27 lines, -3 lines 2 comments Download
A sql/recover_unittest.cc View 1 2 1 chunk +159 lines, -0 lines 0 comments Download
A sql/recovery.h View 1 1 chunk +80 lines, -0 lines 2 comments Download
A sql/recovery.cc View 1 chunk +121 lines, -0 lines 0 comments Download
A sql/scoped_attach.h View 1 chunk +45 lines, -0 lines 0 comments Download
A sql/scoped_attach.cc View 1 chunk +61 lines, -0 lines 0 comments Download
M sql/sql.gyp View 1 2 chunks +5 lines, -0 lines 0 comments Download

Messages

Total messages: 3 (0 generated)
Scott Hess - ex-Googler
Erik, This is something I've been working up, but I'm going on vacation starting tomorrow, ...
7 years, 5 months ago (2013-06-29 00:53:08 UTC) #1
erikwright (departed)
The main question I have is about how reliable and useful this recovery mechanism is. ...
7 years, 5 months ago (2013-07-05 19:02:30 UTC) #2
Scott Hess - ex-Googler
7 years, 5 months ago (2013-07-08 21:41:51 UTC) #3
On 2013/07/05 19:02:30, erikwright wrote:
> The main question I have is about how reliable and useful this recovery
> mechanism is. Is it universally applicable or is it possibly bad depending on
> the schema in question?

Anecdotally, most database corruption seems to be in the relationships between
pages rather than the data within a page.  Most of our databases have pretty
simple schema.  So, in most cases creating the new schema and pulling out the
readable data from the table itself is sufficient to "recover" the database. 
Here "recover" means something like "The database previously threw
SQLITE_CORRUPT errors, now it doesn't, and hopefully some of the previous data
is still present."

WRT reliability, my goal is "Does this reliably result in a not-corrupt
database?", and I think it should be able to do that, either by successfully
recovering data or by razing the database.

Really, the goal is to be a best-effort improvement over deleting all of the
data.  I assume that there will be some databases which cannot productively be
recovered in an automated fashion, but something like this provides a knob for
tuning where that cut-off point is.  For instance, the recovery module has some
support for handling even sqlite_master corruption, but I suspect that doing so
will not be worthwhile in practice.  Likewise, handling corruption across
multiple versions of a database may not be worthwhile.

https://codereview.chromium.org/18180013/diff/6001/sql/connection.cc
File sql/connection.cc (right):

https://codereview.chromium.org/18180013/diff/6001/sql/connection.cc#newcode384
sql/connection.cc:384: DLOG_IF(FATAL, !poisoned_) << "Cannot poison null db";
On 2013/07/05 19:02:30, erikwright wrote:
> is this different from DCHECK(poisoned) << "..";?

Once Upon A Time, in a refactor we had a big knock-down drag-out argument about
this.  I do not remember why things ended up with DLOG(FATAL) in this code, but
we did.  I don't think there was a functional difference involved, I think it
hinged on some abstract sense of rightness.

[I also don't think I agreed with using DLOG(FATAL), at some point I just
stopped caring.]

https://codereview.chromium.org/18180013/diff/6001/sql/recovery.h
File sql/recovery.h (right):

https://codereview.chromium.org/18180013/diff/6001/sql/recovery.h#newcode41
sql/recovery.h:41: class SQL_EXPORT Recovery {
On 2013/07/05 19:02:30, erikwright wrote:
> An idiom I've been using from time to time is like this:
> 
> class Recovery {
>  public:
>   static scoped_ptr<Recovery> Begin(db, path);
>   sql::Connection* db() { return db_; }
>   static bool Recovered(scoped_ptr<Recovery>);
>   static void Unrecoverable(scoped_ptr<Recovery>);
>  private:
>   Recovery(...);
> };
> 
> In plain English, you can only construct one on the heap, and the
> Recoverable/Unrecoverable transitions explicitly require you to give up your
> instance (which makes sense, since the instance methods are no longer valid at
> that point).

I'll prototype that and see how it looks.  My main goal is to make it easier to
get right than wrong, but realistically code like this can't really enforce
strong assertions - you can call the API in the right order but still do
everything completely wrong in between and end up with garbage results.

Powered by Google App Engine
This is Rietveld 408576698