プロジェクト

全般

プロフィール

Bug(バグ) #3258

完了

2 系で退会したメンバのデータが 3 系で新規登録したメンバに紐付いてしまう場合がある

Chiharu Nakajima さんが約12年前に追加. 約9年前に更新.

ステータス:
Fixed(完了)
優先度:
Normal(通常)
対象バージョン:
開始日:
2012-11-12
期日:
進捗率:

100%

予定工数:
3.6 で発生するか:
Yes (はい)
3.8 で発生するか:
No (いいえ)

説明

概要

2 系で退会したはずのメンバのコメントが 3 系で新規登録したメンバによって書かれたかのような処理が行われる.

再現方法

日記コメントの場合.他のデータも紐付く可能性があるが未調査.

  1. 2.14 をインストール
  2. 初期メンバ A を登録(SNS メンバ数 1)
  3. メンバ B を追加(SNS メンバ数 2)
  4. メンバ C を追加(SNS メンバ数 3)
  5. メンバ A で日記 d を書く
  6. 日記 d に対して メンバ C がコメント x を書く
  7. メンバ C が退会する(SNS メンバ数 2)
  8. 3.6.3 へアップグレード
  9. 日記 d を閲覧する -> コメント x のメンバが非表示であることを確認する
  10. メンバ D を追加(SNS メンバ数 3)
  11. 日記 d を閲覧する -> コメント x が メンバ D によって書かれたことになっている

確認バージョン

バージョンアップ前: OpenPNE 2.14
バージョンアップ後: OpenPNE 3.6.3

CentOS 5.8
MySQL 5.0.95

原因

メンバのデータを表すテーブルの auto_increment の値が 2.14 のときのものと一致していないため,新規登録した場合に 2 系ですでに使われていた メンバID に数字が割り当てられてしまう.

mysql> show table status where name = "c_member";
+----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------+
| Name     | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time         | Check_time | Collation       | Checksum | Create_options | Comment |
+----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------+
| c_member | MyISAM |      10 | Dynamic    |    2 |             64 |         128 | 281474976710655 |         3072 |         0 |              4 | 2012-06-11 01:28:50 | 2012-06-11 01:28:50 | NULL       | utf8_general_ci |     NULL |                |         | 
+----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------+
1 row in set (0.00 sec)

mysql> show table status where name = "member";
+--------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+----------------------------------------------------------------------------------+
| Name   | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation       | Checksum | Create_options | Comment                                                                          |
+--------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+----------------------------------------------------------------------------------+
| member | InnoDB |      10 | Compact    |    2 |           8192 |       16384 |               0 |        32768 |         0 |              3 | 2012-06-11 01:28:50 | NULL        | NULL       | utf8_unicode_ci |     NULL |                | Saves informations of members; InnoDB free: 1845248 kB; (`invite_member_id`) REF | 
+--------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+----------------------------------------------------------------------------------+
1 row in set (0.00 sec)


関連するチケット 1 (0件未完了1件完了)

関連している OpenPNE 3 - Bug(バグ) #3074: 2 系で退会したメンバのデータが 3 系で新規登録したメンバに紐付いてしまう場合があるInvalid(無効)2012-06-11

操作

ichikawa tatsuya さんが約12年前に更新

c_memberテーブルのオートインクリメントの値をmemberテーブルへ引き継ぐよう修正。
https://github.com/ichikawatatsuya/OpenPNE3/commit/516b397435f0602879b43d49088f95580bfc296c

diff --git data/upgrade/2/sql/member_basic.sql data/upgrade/2/sql/member_basic.sql
index 4766c81..304045b 100644
--- data/upgrade/2/sql/member_basic.sql
+++ data/upgrade/2/sql/member_basic.sql
@@ -1,3 +1,8 @@
 INSERT INTO member (id, name, is_active, is_login_rejected, created_at, updated_at) (SELECT c_member_id, nickname, 1, is_login_rejected, r_date, u_datetime FROM c_member);
+INSERT INTO c_member value("","","","","","","","","","","","","","","","","","","","","","","","","","");
+SET @lastId = (SELECT last_insert_id());
+SET @auto_inc_query = CONCAT('ALTER TABLE member AUTO_INCREMENT = ', @lastId);
+PREPARE query_prepare FROM @auto_inc_query;
+EXECUTE query_prepare;
 UPDATE member, c_member SET invite_member_id = c_member_id_invite WHERE id = c_member_id AND c_member_id_invite <> 0;

ichikawa tatsuya さんが約12年前に更新

  • ステータスNew(新規) から Accepted(着手) に変更
  • 担当者ichikawa tatsuya にセット

ichikawa tatsuya さんが約12年前に更新

  • ステータスAccepted(着手) から Pending Review(レビュー待ち) に変更
  • 進捗率0 から 50 に変更

Yuya Watanabe さんが約12年前に更新

  • トラッカーBackport(バックポート) から Bug(バグ) に変更
  • 3.6 で発生するかYes (はい) にセット
  • 3.8 で発生するかNo (いいえ) にセット

Yuya Watanabe さんが約12年前に更新

メモを書き写してきた.

https://redmine.openpne.jp/issues/3074#note-4

他にも auto_increment の値が更新されないことによって発生しうる問題を調査する必要がある.

メンバについては 下記データが影響を受けるものとおもわれる.他にもあるかどうかは調査が必要.
  • 日記コメント
  • あしあと
  • コミュニティトピックコメント
  • コミュニティイベントコメント

Kousuke Ebihara さんが約12年前に更新

  • ステータスPending Review(レビュー待ち) から Rejected(差し戻し) に変更

差し戻します。以下の説明を読んで、修正方法について再度検討しなおしてください。

AUTO_INCREMENT の取得方法について

c_member テーブルのレコードは、 OpenPNE 3 のデータベースには (まだ) 入れることのできない情報を持っているために、アップグレードが終わっても c_member テーブルの削除処理をおこなっていません。

c_member テーブルは今後も使用する可能性があるため、ダミーのデータを挿入したのち、そのデータを削除していないことは問題です。

また、できるだけ無用なデータ操作処理を伴わない形で実現できないかについても再考してください。

アップグレードに関しては MySQL に依存していても問題ありません。ということで、以下の手段によって AUTO_INCREMENT を取得することができます。

  • SHOW TABLE STATUS LIKE "c_member" によって得られたレコードの、 Auto_increment カラムを取得する
  • SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_NAME='c_member' AND TABLE_SCHEMA = DATABASE(); によって取得する

ただし後者は information_schema を利用する関係で、 MySQL 5.1 以降でしか使えない手ということになり、採用することができません。前者は OpenPNE がサポートするバージョンよりも古い MySQL でも利用可能だと思いますが、もし採用する場合は念のため確認をお願いします。

AUTO_INCREMENT の設定方法について

PREPARE 文や EXECUTE 文は MySQL 5.1 の新機能であり、 5.1 未満のバージョンでは利用できません。

http://bugs.mysql.com/bug.php?id=20665#c92132

[10 Nov 2006 18:05] Paul DuBois

Clarification: The additional statements are supported both
for SQL syntax for prepared statements (PREPARE/EXECUTE)
and by the binary protocol. The additional supported statements
are noted in both these places:

http://dev.mysql.com/doc/refman/5.1/en/sqlps.html
http://dev.mysql.com/doc/refman/5.1/en/c-api-prepared-statements.html

http://dev.mysql.com/doc/refman/5.1/en/news-5-1-12.html

The following statements now can be executed as prepared statements (using PREPARE plus EXECUTE):

OpenPNE 3 がサポートする MySQL は 4.1 以降であると doc/ja/OpenPNE3_Setup_Guide.txt 等に明示されていますから、少なくとも安定版においては MySQL 4.1 でも動作する形での対応をおこなわなければなりません。

おそらく PREPARE 文と EXECUTE 文を使わないことには MySQL のみで対応をおこなうことは難しいと思います。今回の場合は無理して SQL のみで完結させる必要はないと思うので、 PHP 等のレベルでクエリを構築して実行するわけにはいかないでしょうか。

ichikawa tatsuya さんが約12年前に更新

  • ステータスRejected(差し戻し) から Accepted(着手) に変更
  • 進捗率50 から 0 に変更

ichikawa tatsuya さんが約12年前に更新

  • ステータスAccepted(着手) から Pending Review(レビュー待ち) に変更
  • 進捗率0 から 50 に変更

Mysql4.1以降で動作する機能のみを使用するように修正しました。
(SHOW TABLE STATUS はバージョン3.23で導入された機能なので問題ありませんでした)

また、MysqlのみではAuto_incrementの値を取得できないためPHPを使用するよう変更しました。

diff --git data/upgrade/2/definition.yml data/upgrade/2/definition.yml
index 7b5e651..25e83f7 100644
--- data/upgrade/2/definition.yml
+++ data/upgrade/2/definition.yml
@@ -8,7 +8,8 @@ create_tables:
   strategy: CreateTable

 member_basic:
-  strategy: SQLImport
+  strategy: opUpgradeFrom2MemberStrategy
+  file: %SF_DATA_DIR%/upgrade/2/opUpgradeFrom2MemberStrategy.class.php

 files:
   strategy: SQLImport
diff --git data/upgrade/2/opUpgradeFrom2MemberStrategy.class.php data/upgrade/2/opUpgradeFrom2MemberStrategy.class.php
new file mode 100644
index 0000000..721a0ec
--- /dev/null
+++ data/upgrade/2/opUpgradeFrom2MemberStrategy.class.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * This file is part of the OpenPNE package.
+ * (c) OpenPNE Project (http://www.openpne.jp/)
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file and the NOTICE file that were distributed with this source code.
+ */
+
+/**
+ * The upgrating strategy by importing member.
+ *
+ * @package    OpenPNE
+ * @subpackage task
+ * @author     tatsuya ichikawa <ichikawa@tejimaya.com>
+ */
+class opUpgradeFrom2MemberStrategy extends opUpgradeAbstractStrategy
+{
+  public function run()
+  {
+    $this->getDatabaseManager();
+    $this->conn = Doctrine_Manager::connection();
+
+    $this->conn->beginTransaction();
+    try
+    {
+      $this->doRun();
+
+      $this->conn->commit();
+    }
+    catch (Exception $e)
+    {
+      $this->conn->rollback();
+
+      throw $e;
+    }
+  }
+
+  public function doRun()
+  {
+    $this->conn->execute('INSERT INTO member (id, name, is_active, is_login_rejected, created_at, updated_at) (SELECT c_member_id, nickname, 1, is_login_rejected, r_date, u_datetime FROM c_member)');
+
+    $tableStatus = $this->conn->fetchArray('SHOW TABLE STATUS LIKE "c_member"');
+    $autoIncrement = $tableStatus[10];
+    $this->conn->execute("ALTER TABLE member AUTO_INCREMENT = $autoIncrement");
+    $this->conn->execute('UPDATE member, c_member SET invite_member_id = c_member_id_invite WHERE id = c_member_id AND c_member_id_invite <> 0;');
+  }
+}

Kousuke Ebihara さんが約12年前に更新

  • ステータスPending Review(レビュー待ち) から Rejected(差し戻し) に変更

レビュー対象となるコミットを示すか、もしくは共有リポジトリのリリースブランチにコミットを追加することによって、このチケットにコミットを紐づけてください。

ichikawa tatsuya さんが約12年前に更新

すみませんでした。
stable-3.6.xブランチで修正しました。コミットは以下です。

https://github.com/ichikawatatsuya/OpenPNE3/commit/9bb27331f8b7e98ab9b02bfb7a9626a56d953ffa

ichikawa tatsuya さんが約12年前に更新

  • ステータスRejected(差し戻し) から Accepted(着手) に変更
  • 進捗率50 から 0 に変更

ichikawa tatsuya さんが約12年前に更新

  • ステータスAccepted(着手) から Pending Review(レビュー待ち) に変更
  • 進捗率0 から 50 に変更

Kousuke Ebihara さんが約12年前に更新

  • ステータスPending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
  • 進捗率50 から 70 に変更

Mutsumi Imamura さんが約12年前に更新

  • ステータスPending Testing(テスト待ち) から Fixed(完了) に変更
  • 進捗率70 から 100 に変更

動作確認OKです。

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