プロジェクト

全般

プロフィール

Bug(バグ) #3986

v0.9.0からv1.0.2へのマイグレーション後とv1.0.2のクリーンインストール後でDBスキーマに差異がある

Youichi Kimura7年以上前に追加.

ステータス:
Accepted(着手)
優先度:
High(高め)
担当者:
対象バージョン:
-
開始日:
2016-07-27
期日:
進捗率:

0%

3.6 で発生するか:
Unknown (未調査)
[QA]バグ通知済:
いいえ
3.8 で発生するか:
Unknown (未調査)

説明

Overview (現象)

マイグレーションスクリプトの不備により v1.0.2 へのマイグレーションと v1.0.2 のクリーンインストール後で blog_rss_cache テーブルのスキーマに差異が生じている。

$ cd plugins/opBlogPlugin

$ git checkout v0.9.0
$ ../../symfony doctrine:build --env=test --all --and-load
$ git checkout v1.0.2
$ ../../symfony openpne:migrate --env=test --no-update-plugin --target=opBlogPlugin
$ echo 'SHOW CREATE TABLE blog_rss_cache\G' | mysql -u root openpne_test > schema-migrate.txt

$ ../../symfony doctrine:build --env=test --all --and-load
$ echo 'SHOW CREATE TABLE blog_rss_cache\G' | mysql -u root openpne_test > schema-rebuild.txt

$ diff -u schema-migrate.txt schema-rebuild.txt
--- schema-migrate.txt 2016-07-27 17:45:29.927593471 +0900
+++ schema-rebuild.txt 2016-07-27 17:46:18.371593471 +0900
@@ -11,5 +11,7 @@
   `updated_at` datetime NOT NULL,
   PRIMARY KEY (`id`),
   KEY `date_INDEX_idx` (`date`),
-  KEY `member_id_date_idx` (`member_id`,`date`)
+  KEY `member_id_date_idx` (`member_id`,`date`),
+  KEY `member_id_idx` (`member_id`),
+  CONSTRAINT `blog_rss_cache_member_id_member_id` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8

不足している箇所:

  • インデックス member_id_idx (Doctrine によって自動で追加されたもの) が追加されていない
  • 外部キー制約 blog_rss_cache_member_id_member_id が追加されていない

特に blog_rss_cache_member_id_member_id が存在しない不一致については、v1.0.3 で修正された #3473 に関するマイグレーション時に問題となる。
具体的には v0.9.0 をクリーンインストールした状態から v1.0.3 にマイグレーションすると下記のエラーが発生して異常終了する。

  migrating of opBlogPlugin encountered the following errors:

   Error #1 - SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'blog_rss_cache_member_id_member_id'; check that column/key exists. Failing Query: "ALTER TABLE `blog_rss_cache` DROP FOREIGN KEY blog_rss_cache_member_id_member_id" 

このエラーが発生した場合、マイグレーションが途中まで完了した状態かつ opBlogPlugin_revision が更新されないままロールバックされずに中断されるため、復旧が困難な 非常に面倒な状態になる。(チケットの優先度を高めにしたのはこのため)

Causes (原因)

data/migrations/1.0.0/001_add_blog_rss_cache_table.php に必要な定義が不足していたことが原因。

Way to fix (修正内容)

修正にあたって下記のパターンを考慮する必要がある。

  • v0.9.0 をクリーンインストールした状態から最新版にマイグレーション
    • opBlogPlugin_revision が存在しない状態からリビジョン 1, 2, 3, 4 の差分が一度に適用される
    • この場合、リビジョン 1 を直接修正することで blog_rss_cache_member_id_member_id を追加できる
    • 一方で、リビジョン 1 を修正したとしても、追加された blog_rss_cache_member_id_member_id の存在をリビジョン 4 の up メソッド内でチェックすることはできない
    • 各リビジョンの up メソッド内で呼ばれる addForeignKey などのメソッドは即時に SQL として実行されるものではない(全てのリビジョンの up メソッドが呼ばれた後に一度に実行される)
  • v0.9.0 をクリーンインストールした状態から一度 v1.0.2 にマイグレーションしてから最新版にマイグレーション
    • opBlogPlugin_revision が存在しない状態からリビジョン 1, 2, 3 の差分が適用され、その後リビジョン 4 が適用される
    • 修正前のリビジョン 1 がすでに適用された状態からのマイグレーション
    • リビジョン 4 が実行される時点では blog_rss_cache_member_id_member_id が存在しない状態
  • v1.0.2 をクリーンインストールした状態から最新版にマイグレーション
    • opBlogPlugin_revision が 3 の状態からリビジョン 4 が適用される
    • リビジョン 4 が実行される時点では blog_rss_cache_member_id_member_id が存在する状態
  • 最新版をクリーンインストール

上記の全てのパターンでインストールまたはマイグレーションが正常に完了し、かつ最終的な blog_rss_cache テーブルのスキーマが同一でなければならない。

他の形式にエクスポート: Atom PDF