Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 May 2015 17:55:26 +1000
From:      andrew clarke <mail@ozzmosis.com>
To:        Scott Bennett <bennett@sdf.org>
Cc:        freebsd-ports@freebsd.org
Subject:   Re: damage to pkg's sqlite data base
Message-ID:  <20150513075526.GA18834@ozzmosis.com>
In-Reply-To: <201505120617.t4C6HkA3019096@sdf.org>
References:  <201505120617.t4C6HkA3019096@sdf.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue 2015-05-12 01:17:46 UTC-0500, Scott Bennett (bennett@sdf.org) wrote:

>      For nearly two weeks I've been stymied by an apparently damaged record
> in the sqlite data base used by pkg(8) and pkg-static(8).  Unfortunately,
> it is a record for a port that is depended upon rather heavily, lang/gcc.
> lang/gcc compiled and linked just fine, but any attempt to install the result
> ends up like this.
> 
> ===>  Checking if gcc already installed
> ===>   Registering installation for gcc-4.8.4_3
> Installing gcc-4.8.4_3...
> pkg-static: sqlite error while executing iterator in file pkgdb_iterator.c:931: database disk image is malformed
> pkg-static: sqlite error while executing INSERT OR REPLACE INTO files (path, sha256, package_id) VALUES (?1, ?2, ?3) in file pkgdb.c:1722: database disk image is malformed
> *** Error code 70
> 
> Stop.
> make: stopped in /usr/ports/lang/gcc

"database disk image is malformed" is an error from SQLite, the
underlying database library that pkg uses, not pkg itself.

If you can confidently rule-out hardware or filesystem error then
presumably there is a glitch in SQLite that causes it to corrupt the
database it's writing to. It shouldn't happen, and is evidently very
rare judging from the lack of FreeBSD PRs about it.

SQLite is quite popular and is used by Mozilla Firefox & Google Chrome
internally.

It's possible pkg did something to trigger a bug in SQLite, so it may
be worthwhile uploading your local.sqlite to a web site somewhere for
one of the pkg developers to investigate, and file a PR with a link to
the file.

A bit of Googling indicates a fix may be possible, along the lines of:

$ sqlite3 /var/db/pkg/local.sqlite
SQLite version 3.8.10.1 2015-05-09 12:14:55
Enter ".help" for usage hints.
sqlite> pragma integrity_check;
ok

[sqlite may give an error here, but you can hopefully keep going...]

sqlite> .mode insert
sqlite> .output local.sqlite.dump
sqlite> .dump
sqlite> .quit

$ ls -l local.sqlite.dump 
-rw-r--r--  1 ozzmosis  ozzmosis  10113463 2015-05-13 17:24:46 local.sqlite.dump

Note that the database dump is simply a text file:

$ file local.sqlite.dump
local.sqlite.dump: ASCII text

We can then recreate the database from the dump we just made:

$ sqlite3 local.sqlite.new
SQLite version 3.8.10.1 2015-05-09 12:14:55
Enter ".help" for usage hints.
sqlite> .read local.sqlite.dump 
sqlite> .quit

Now we can use our newly created database, which should be error-free:

$ sudo cp /var/db/pkg/local.sqlite /var/db/pkg/local.sqlite.backup
$ sudo mv local.sqlite.new /var/db/pkg/local.sqlite

I don't guarantee any of the above will work. It will depend on how
much the database is corrupted etc.

You will also need databases/sqlite3 installed, which unfortunately
isn't provided in the FreeBSD base system. This could be a problem if
pkg refuses to install anything. In that case I would either run the
above sqlite3 commands on another machine (or a jail?) and sort it out
there, or run the sqlite3 binary from the
/usr/ports/databasess/sqlite3 directory without installing it, or if
that's not possible, make a backup of local.sqlite, delete
local.sqlite, install sqlite3 from ports (or pkg install), then work
on fixing the corrupt database.

Obviously another option is to simply declare pkg bankruptcy. Get a
list of all your installed packages (with "pkg info -ao > pkglist.txt"),
delete the corrupt local.sqlite then reinstall your packages.

Regards
Andrew



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150513075526.GA18834>