人気記事表示用のプラグインを更新したらDBエラーが発生するようになった


いつごろから出るようになったんだろうか。。。

スマホなどからの表示確認をすると、DBエラーが出力されるようになっていました。

 

WordPress database error: [Unknown column ‘day_no_time’ in ‘field list’]
INSERT INTO <テーブルプレフィクス>_popularpostsdatacache (id, day, day_no_time) VALUES (614, '2012-09-01 07:25:40', '2012-09-01') ON DUPLICATE KEY UPDATE pageviews = pageviews + 1, day = '2012-09-01 07:25:40', day_no_time = '2012-09-01';

 

テーブル名にある "popularposts" というのは、人気記事を表示するための「WordPress Popular Posts」というプラグイン。

実は他サイトでもWordPressを使って運営しているのだけれど、そちらも同じ現象。ちなみにPCからは問題なく表示されます。

 

スマホや携帯、つまりPC以外からの表示では、トップページは表示されるものの単一記事を表示すると上記のDBエラーが表示されてしまう。

なにか変なことしたかな、と思って最近入れたプラグインをすべて停止した。けど症状は変わらず。

 

ためしにですが、単純に手動で対象テーブルにDate型のカラム “day_no_time” を追加したらエラーは表示されなくなった。まぁそりゃ当然ですが。

しかしそんなのは根本的な対策になっていない。はてさて、どうしたことやら。。。(悩)

 

原因がわかったら、追ってエントリーします。あーあ。。。orz

 

追記:

まず問題の切り分けをしてみました。

このプラグインを更新したのが 2012/09/01 だったことがわかったので、こいつ自身の更新で問題が起きたのではと考えました。

更新前のバージョン 2.2.1

更新後のバージョン 2.3.0

 

問題となっているキーワード “day_no_time” という文字列でgrep をかけようと思いましたが、そんなことよりバックアップしたファイルがあったのでメインのソース wordpress-popular-posts.php を比較することにしました。すると、いきなりサイズがずいぶん違います。まぁ更新されているわけですから、サイズが違うのも当然ではあります。

で、ここで勘が働きました。

仕様追加(もしくは変更)がされた。でもソースが更新されただけで、関係するテーブルのパッチまでは流れてこなかった。流れてきたかもしれないけど実行されなかった。きっとそうに違いない。そう思って、WordPress Popular Posts プラグインを削除してインストールしなおしてみました。

 

結果、エラーは回避されました。いちおう一安心。

いや、頼みますよホント。。。で、当然のことながら過去のデータはなくなりましたorz

 

他サイトにも同じものを入れているので、今から削除→インストールしなおします。。。パッチなんてあるのかな、無いだろうな。

それとも、当ブログで更新されたテーブル構成を見ながら、手動でカラム追加しよっかな。そしたらデータは飛ばないままだし。

うん、そうしよう。。。トホホ。

(なんでPCからだとエラーにならなかったんだろうとか思うけど、もういいや。)

 

ちなみにですが、復旧中にやったことを下記にまとめておきます。

けっこうゴチャっとした書き方ですがご勘弁を(^ω^;)

 

日本語化をしている場合

管理画面からプラグインを更新すると日本語化ファイルも消えているので、手動でアップロードしなおす必要があります。

wordpress-popular-posts-ja.mo と wordpress-popular-posts-ja.po ですね。

 

手動でDBテーブルを操作する場合

MySQLの管理ツール「phpMyAdmin」などで、以下のSQLを実行する必要があります。が、注意点があります。

  • 以下に記載したSQLを発行したことによって何らかの問題が生じた場合、当方では一切責任を持ちませんのであしからず。
  • テーブルプレフィクスを ”wp_”としている場合のSQLとしています。SQLを利用する場合は自分の環境に合わせてください。
  • テーブルプレフィクスは wp-config.php で確認できます。”$table_prefix”で検索してみてください。

1)既存テーブルにカラムを追加する

ALTER TABLE `wp_popularpostsdatacache`
ADD `day_no_time` DATE NULL DEFAULT '0000-00-00';

2)新しいカラムにデータをセットする

UPDATE `wp_popularpostsdatacache`
SET `day_no_time` = `day`;

3)INDEX構成と名称が変更になっているので、書き換える

 ALTER TABLE `wp_popularpostsdatacache` DROP INDEX `id`
, ADD UNIQUE `compositeID` (`id`, `day_no_time`); 

 

しかしですね、INDEX構成を書き換えると、場合によっては重複エラーが発生します。

「日時」がキーになっているのに「日付」をキーに変えたら重複する場合も当然ありえますね。

なので重複データを削除してからもう一度INDEX変更をする必要があります。うーんめんどくさい。

重複データの中からページビューが最大であるデータを見つけるには、以下を発行して確認します。条件は

  • idが重複している
  • day_no_timeが2つ以上重複している
  • その中でpageviewsが最大である
SELECT `id`, `day`, MAX(`pageviews`) AS pageviews, `day_no_time`
FROM `wp_popularpostsdatacache`
GROUP BY `id`, `day_no_time`
HAVING COUNT(`day_no_time`)>1;

そもそも day_no_time というのは何のためのカラムなのか現時点では不明ですが、

復旧を急ぐためにもこのSQLで抽出されたデータ以外を削除します。

削除対象のデータ抽出SQLは次のようになるでしょう。

SELECT * FROM `wp_popularpostsdatacache`
WHERE (`id`, `day`) IN (
SELECT X.`id`, X.`day`
FROM `wp_popularpostsdatacache` X
INNER JOIN (
SELECT `id`, `day`, MAX(`pageviews`), `day_no_time`
FROM `wp_popularpostsdatacache`
GROUP BY `id`, `day_no_time`
HAVING COUNT(`day_no_time`)>1
) A
WHERE X.`id` = A.`id`
AND X.`day` <> A.`day`
AND X.`day_no_time` = A.`day_no_time`
);

ついでにDELETE文を発行してもよいのでしょうが、念のためphpMyAdmin上から手動で消すことにします。

データを消したら 3)INDEX構成と名称の書き換え をやり直します。

きっとこれで、新規インストールした場合と同じ状態となるはずです。 人気のあるブログではアクセスが多いでしょう。

重複データ削除からINDEX書き換えは、すぐにやらないとそのアクセスによってデータが更新されてしまう場合があるので、

わりとサッサとやる必要があると思います。

 

もっといい方法を知っていたら、教えてください。

SQL文法に問題もあったら教えてください(久しぶりに書いたので自信なしw)

3 comments

  1. いまさらな自分ツッコミ→必死になってエントリーしたけど、よくよく考えたら「キャッシュ」なんだし、対象テーブル(popularpostsdatacache)のデータは消えてもいいかも。その間は”メンテナンスモード”にしてアクセスさせないようにしてればいいんだし。あーあ、なんだかなぁ。まぁ覚書ってことで。

  2. 自分も今日このプラグインを管理画面上で更新してみたら、いきなりサムネイル画像が表示されなくなりました。 phpのエラーログを見てみたところ、touch(): Utime failed: とでててパーミッションに問題がありそうなことがわかりました。 なのでchmodで当該のフォルダのパーミッション変更したんですけど、エラーはそのまま吐き続け、もうお手上げ状態、めでたくバックアップしてあった過去verに戻しました。

    何か今回の更新は色々問題が多そうです(;´Д`)

  3. サムネイル側にも問題が出ていたんですね。幸いにもコチラでは不都合はありませんでした。touch()しているならパーミッション関係だろうとなんとなく予測つきますが…おかしいですね。今回の更新は改悪と言わざるを得ないかもしれませんね…また【プラグインを無効→有効化】で直るという記事を見かけましたが、こちらではすでにその対策はしたものの、なぜか直りませんでしたorz

Leave a Reply

メールアドレスが公開されることはありません。