- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2017-05-29T04:05:13+09:00;2017-05-29T03:27:22+09:00","","")
#author("2017-05-29T22:12:07+09:00","","")
* アクセスカウンタが時々リセットされる [#x7c9bdfd]
- ページ: BugTrack
- 投稿者: [[umorigu]]
- 優先順位: 低
- 状態: 着手
- カテゴリー: 本体バグ
- 投稿日: 2017-05-24 (水) 02:32:06
- バージョン: 1.5.1
** メッセージ [#se4e36a8]
アクセスカウンタがリセットされてしまう。
Database等を使ってリセットされないようなオプションを用意する。
*** 対応 [#fbc22beb]
Database等を使ってリセットされないようなオプションを用意する。SQLiteがPHP5.1で組み込まれているので利用しやすい。
plugin/counter.inc.php:
// Use Database (1) or not (0)
define('PLUGIN_COUNTER_USE_DB', 0);
PLUGIN_COUNTER_USE_DB を 1 にするとDB利用カウンタになる。(PDOオプションは設定可能、デフォルトは SQLite利用で counter/counter.db に保存される。
*** 変換ツール [#x5f6e3c0]
ファイル利用カウンタのデータをデータベース上のデータに変換するツールです。
&ref(counter_db_import_files.php);
- 1. counter_db_import_files.php をダウンロードして、pukiwikiルートディレクトリに配置する
- 2. コマンドラインから次のphpコマンドを実行する
php -r "include 'counter_db_import_files.php'; plugin_counter_tool_convert_to_db();"
- 3. counter/counter.db ファイル(SQLiteファイル)が出来ているのを確認する
- 4. plugin/counter.inc.php で PLUGIN_COUNTER_USE_DB を 1 に設定する。
- 5. PukiWiki上で動作を確認する
- 5. 正しく動作することが確認できたらページ別カウンタファイル counter/*.count をすべて削除する
*** ToDo [#w5597210]
- 済 %%counterプラグインにDB(PDO)実装を追加する%%
- 済 %%ファイル利用カウンタをDB利用カウンタに変換するツール%%
- 未 populerプラグインの対応
- 未 renameプラグインの対応
--------
- [[official:WebTrack/102]] -- &new{2017-05-24 (水) 21:31:36};
- counterプラインのオプションとして、カウンタをSQLiteのDBで保持するようにしました。 commit:1a7d267248ea -- [[umorigu]] &new{2017-05-28 (日) 07:30:03};
- このサイト(PukiWiki-dev)でDB利用カウンタを運用開始しました -- [[umorigu]] &new{2017-05-28 (日) 07:49:42};
- 現行のcounterの排他処理はちゃんと記述されているように見えましたが、Modify処理(ftruncate→fputs)がアトミックではないので何らかの理由でサーバー側のプロセスが異常終了するとカウンタが消失してしまうということでしょうか。 -- [[Yorkfield]] &new{2017-05-28 (日) 19:32:23};
-- コメントありがとうございます。正直なところ、カウンタがリセットされる原因がはっきりわかっているわけではないです。[[BugTrack/191]]も解決済みになっています。ただ、このサイトのトップページでもでもたびたびリセットが発生しています(ここのバックエンドはNFSだと思われます)し、私の運用しているサイトでも発生します。ファイルベースでは限界があるのかな、と思って確実な動作が期待できるDBにしてみました -- [[umorigu]] &new{2017-05-29 (月) 02:19:19};
- 従来のcounterは「排他ロック→Read→Modify(+1)→Write→アンロック」という排他制御がされています。しかし、SQLite版のcounterは排他制御が不十分で、「Read→Modify→Write」の間に他のアクセスが割り込むとそのアクセスではWriteする前の値をReadしてしまいます。その結果、カウント数が実アクセス数より少なくなる恐れがあります。&br;EXCLUSIVEトランザクションを使えば問題は解決できると思いますが、SQLiteは行ロックが無くデータベース全体のロックになること、Wikiページ全てで1つのデータベースを共有する構成であることからパフォーマンス面で懸念があります。 -- [[Yorkfield]] &new{2017-05-28 (日) 22:02:41};
-- 鋭いご指摘ありがとうございます。もともとそれほど厳密なカウントでなく、またご指摘のように過剰なロックでパフォーマンスが落ちてしまうことを避けるために、多少の誤差には目をつぶることにしました。(リセットされてしまうよりはマシ、ということです)。未確認ですが、SQLite依存の処理は使っていないのでMySQLなど他のDBを使っても動作すると思います -- [[umorigu]] &new{2017-05-29 (月) 02:27:39};
-- UPDATEの際は必ず+1する (SET total = total + 1) ことにすれば、既存処理と同程度の精度にはなりますね。表示する値とのズレを気にしていたのですが、表示の方がずれても問題は少ないということに気が付きました。対応しました commit:5e61ada134 -- [[umorigu]] &new{2017-05-29 (月) 03:25:57};
- PukiWiki-official もDB利用カウンタ(PLUGIN_COUNTER_USE_DB:1)での運用に切り替えました -- [[umorigu]] &new{2017-05-29 (月) 02:36:09};
- カウンタがリセットされるぐらいflockが期待通りに動かない環境ならSQLiteのトランザクションも期待できないことに気づきました。やっぱりMySQL使わないとダメか… -- [[umorigu]] &new{2017-05-29 (月) 22:12:07};
#comment