ownCloudのDBマイグレーション失敗とリカバー

Pocket

ふとしたことから、手元のsid環境を更新したのですが、その時にownCloudが5.0.25から7.0.2へと大きく変わってしまいました。ownCloudはアップブレード機能を持っている(web, occコマンド)のですが、それが途中でこけてしまったので、対処方法をblogに残しておきます。

5.0.25から7.0.2へ移行

自分はsid環境を、lxcコンテナの一つに持っています。その中でownCloudも運用しています。最初に導入したときのバージョンは5.0.25だったのですが、この記事を書いている辞典では7.0.2が最新です。5->6のメジャーアップグレードをはさめばうまくいったのかもしれませんが、自分のケースではデータベースの移行がうまくゆきませんでした。バックエンドにはSQLite3を使っています。

oc_lucene_statusでのエラー

アップグレード時に発生したエラーログの一部を以下に示します。

{"app":"core","message":"Simulated database structure update failed (exception OC\\DB\\MigrationException' with message 'An exception occurred while executing
'INSERT INTO oc_lucene_status (fileid, status) SELECT fileid, status FROM __temp;
__oc_lucene_status':\n\nSQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: oc_lucene_status.fileid'

oc_lucene_statusというテーブルの移行に失敗しています。このテーブルはLuceneによる全文検索用のものと思われますが、自分自身が全文検索を使ったことがこれまでなかったので、単純にテーブルの削除と再作成をすればよいだろうと推測し、まずはバックアップを取ったうえでdropしてみました。

単純にdropをしただけでは、当然テーブルがなくなるだけなので、やはりアップグレードに失敗します。その時のエラーは以下の通りです。

$ sudo occ upgrade
Turned on maintenance mode
Checked database schema update
Updated database
An exception occurred while executing 'DELETE FROM "oc_lucene_status" WHERE "fileid" IN (
                                        SELECT "fileid"
                                        FROM "oc_lucene_status"
                                        GROUP BY "fileid"
                                        HAVING count("status")  1
                                )
                      ':
SQLSTATE[HY000]: General error: 1 no such table: oc_lucene_status
Turned off maintenance mode
Update successful

データベースのテーブルの定義はXMLで書かれています。ソースコードのapps/search_lucene/appinfo/database.xmlが該当するファイルです。これを見て適当に見よう見まねでテーブルを作ってみたところ、うまくゆきませんでした。

$ sudo occ upgrade
Turned on maintenance mode
Unknown database type integerv requested, Doctrine\DBAL\Platforms\SqlitePlatform may not support it.
Turned off maintenance mode
Update successful

これはまずいと思い、バックアップしておいた方のデータベース上でのテーブル構造を参照してみました。

sqlite> .schema oc_lucene_status
CREATE TABLE "oc_lucene_status" ("fileid" INTEGER DEFAULT 0 NOT NULL, "status" VARCHAR(1))
CREATE INDEX status_index ON "oc_lucene_status" (status ASC)

この結果を参考に、新しい方のデータベースで同じテーブルを作成し(表示されているSQLをそのまま実行する)、再度アップグレードを試みたところ成功しました。

$ sudo occ upgrade
Turned on maintenance mode
Checked database schema update
Updated database
Turned off maintenance mode
Update successful

無事アップグレードに成功し、今では普通に利用できています。

By knok

I am a Debian Developer and a board member of Free Software Initiative (FSIJ).