バックアップデータ構造の改善

  • ページ: BugTrack2
  • 投稿者: Cue
  • 優先順位: 低
  • 状態: 保留
  • カテゴリー: 本体新機能
  • 投稿日: 2005-08-31 (水) 03:50:07
  • バージョン:

メッセージ

従来の仕様と特徴 (- PukiWiki 1.4.6)

バックアップファイル構造

  1. バックアップファイル1ファイルの中にそのページの全ての世代が保存されている
    1. ディスクスペースは少なくて良い(特に小さいページが沢山ある場合)
  2. Boundaryは、PKWK_SPLITTER\sUTIME\n
  3. データ中にBoundaryが現れた場合、行末に半角スペースを加える
    1. 保存データに手を加えるので処理としては良くない
    2. PKWK_SPLITTERは過去にはglobal $splitter
    3. \sに半角スペース以外が使われた事はない
  4. zlib extensionの有無でファイル形式が変わる*1
    1. 設置サーバーの状況が変わると手作業しか移行手段がない(zlib無で.gz対応は不可能)
    2. Boundaryも含めて圧縮されるので、一部の損傷が全滅につながる

lib/backup.php内で外部からコールされる関数

  • make_backup 特定のページのバックアップ追加処理
  • get_backup 特定のページのバックアップ全データの取得、世代を指定した場合はその世代の全データのみ取得
    • 過去には一覧の取得と各データ取得で分けられていたようだが、今は全取得しか使われていない
  • _backup_file_exists 特定のページのバックアップの有無確認
  • _backup_delete 特定のページのバックアップの全削除
  • 直接データ構造にアクセスする個所
    • plugin/dump.inc.php
    • plugin/backup.inc.php(バックアップの存在する全ページ名の一覧取得・表示、特定のページの世代一覧の表示など)
    • plugin/deleted.inc.php
    • plugin/rename.inc.php

backup.inc.phpとの連携部など

  1. 常に解凍された全データを要求する
    1. 複数回のファイル読み込みと解凍を要さない
    2. バックアップファイルが大きくなると処理の負荷が大きい(BugTrack/732,BugTrack2/159)
  2. 各バックアップは世代番号で管理される。世代番号はバックアップファイル内に存在する順で割り当てられる
    1. 一覧表示から各データの取得までにバックアップ処理が起こると世代番号がずれる
  3. バックアップ日時は、そのページの前回の最終更新日時(そのデータが作られた日時)が割り当てられる
    1. タイムスタンプを変更しない編集を繰り返すと同じタイムスタンプのバックアップが複数作られる(BugTrack/685)
  4. $cycle=0 でも同一タイムスタンプでバックアップは働かない
    1. 重いバックアップ処理を連打されずにすむ
    2. UTIMEでtouchはしていないので処理が重い場合など若干のずれが生じる

問題点

backupに対する既存の機能要望

  1. 自動生成されるページを含めて基本は全ページが対象(BugTrack/708)
  2. 世代を指定してバックアップを削除できない(official:欲しいプラグイン/137)
  3. バックアッップの特定の世代からwikiソースをコピー(ロールバック)して編集したい(BugTrack/507,BugTrack2/53,official:欲しいプラグイン/188)
  4. 通常バックアップと別に版管理を行いたい(BugTrack2/86)
    • バックアップ時刻の外に一覧用の別データを埋め込める構造にする?要望した人は別の方法を見付けたみたいですが。
  5. backupじゃなくて(あるいは選択式で)データベースが使えるようになって欲しい
    • lib/backup.phpをカプセル化して標準データとの相互変換コードを用意すれば内部構造をどう変えても対応可能
  6. ページが(部分)削除された場合には、通常サイクルとは別基準できめ細かくバックアップを実行したい(PukiWiki/1.4/ちょっと便利に/バックアップを少しだけ荒らしに強く)
  • ちょっと便利に~の1件を追記 -- 2016-01-18 (月) 20:44:31

改善案

1ファイルは維持し、日付部分は圧縮しない案

  1. ファイル読み込み・一覧作成の段階で解凍は発生しないので比較的低負荷
  2. 一部が損傷しても全体に影響は及ばない
  3. ディスクスペースは若干増える
  4. 圧縮部分に偶然Boundaryが現れる可能性にどう対処するか
    1. 普通は各ブロックサイズを記録しておいてfseekしながら飛ばし読みする
    2. 飛ばし読みのみでは一部の欠落等の事故に対応できない
    3. multipart-mixedのような動的にBoundaryを生成する方法が無難

各バックアップ世代をページ名のディレクトリ下に独立ファイル化する案

  1. 一覧作成はディレクトリ検索速度に依存する(必要メモリは少ないが、システムコールは多いはず)
  2. 一部が損傷しても全体に影響は及ばない
  3. ディスクスペースは増える(特にFATファイルシステムで)
  4. Boundaryとバックアップ読み込み時のflock処理が不要
  5. 特定の世代だけ削除するのが容易(ftpでも可能)
  6. dump.inc.phpが1ファイル状態を前提にファイルにアクセスしている
    1. データ構造に直接アクセスすべきではない。必要ならAPIを作る。

CVS likeに差分のみで全体を構成する案

  1. 無圧縮でも非常に小さいサイズになる
    1. 昨今の状況ではディスクスペースをそれほど重視しなくて良いのでは?

世代管理にバックアップ時刻を使う案

  1. ページのタイムスタンプを変更しなくても編集した時刻が分かってしまう
    1. Recentには影響しないので構わないのでは?
  2. ページの最終更新日時はlast-modified headerにも使われるので、タイムスタンプを更新しない場合でも変更した方が良いはず。Recentに入れない等の処理は別の方法で実現した方が良いのでは?
  3. 暫定的に差分の最終更新日時から得る方法もあり

lib/backup.phpに必要とされるAPI

  1. バックアップの追加 (現在のmake_backup関数)
  2. バックアップの有無 (現在の_backup_file_exists関数)
  3. バックアップデータ一覧の取得
    • 現在のget_backup関数で世代指定を省略した時は、全世代のwikiソースと他データ(タイムスタンプ)を同時に取得する
  4. ある世代のバックアップデータの取得
    • 現在のget_backup関数で世代を指定した時は、その世代のwikiソースと他データ(タイムスタンプ)を同時に取得する(内部的には、いったんすべてを読み込んでから抽出)
  5. バックアップの全削除 (現在の_backup_delete関数)
  6. バックアップの部分削除
  7. バックアップの存在する全ページ名の一覧取得
    • 現状の1.4.xでは、呼び出し側に内包されて存在
  8. バックアップデータを標準データと相互変換する機能
  9. renameに対応する機能
  • get_backupでの全取得はやめる
  • どの形式を標準データにするか?
    • 互換性で問題がないのは現在の構造で無圧縮
  • dump.inc.phpは標準データを扱うようにする
  • バックアップデータの変換はタイムアウト対策が必須
  • バックアップデータを一行ずつの配列(file()で読み込んだソース相当)で渡す必要はないのでは?
    • (array)$multi_line_strの形で返しても問題無いみたいです

  • 過去(現状の調査と把握)を踏まえて進めようとされていて、ここにわかり易く解説していらっしゃる、それだけでも素晴らしい仕事だと思います ;) -- henoheno 2005-09-01 (木) 23:10:03
  • 他に気付いた点や案があれば追加お願いします。 -- Cue 2005-09-03 (土) 00:39:25
  • 過去ログの世代管理についてですが、logrotateのようにファイル名に.1/.2とつけていく。というだけでも良い気がします。 -- romap? 2005-09-15 (木) 14:18:45
  • ディレクトリを読むだけで一覧に必要な情報を取得できるようにしたかったので差分の最終更新日時(=バックアップするデータの更新日時)をファイル名にしてみました。同一日時がある場合に一秒加算でなく.1,.2を付けていく手は有りだと思います。 -- Cue 2005-09-15 (木) 19:14:08
    • 気付いたのですが、ページ毎にディレクトリ分けせず「ページ名.No.gz」といった形で保存する方法はbackup/下のファイル総数がページ数×保存世代数になるので速度的にきつそうなことと、ファイル名の長さ制限の問題が起こりそうなので見送りました。 -- Cue 2005-09-21 (水) 00:13:37
  • 古いネタに反応してすいません。「zlib extensionの有無でファイル形式が変わる」でハマったので、改善の検討をお願いしたいです。
    - zlibありなんだけどバックアップファイルが*.txtで存在する場合は*.txtでバックアップを保存
    - zlibなしなんだけどバックアップファイルが*.gzで存在する場合は「バックアップが保存されないけどいい?」と確認を促す
    といった感じで。あ、zlibで圧縮する場合の拡張子は*.gzではなくて*.txt.gzがいいようなきがします。 -- よっちい? 2008-04-14 (月) 23:12:46

実装案

See also

  • BugTrack2/374 どのユーザーがページを変更したかの記録を残したい

*1 PHP 4.3.0 以降、zlib モジュールは php バイナリにビルトインされたため、PHP4.2.x以前+zlibなし→PHP4.3.0以降でのみ発生する

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-01-18 (月) 20:44:31
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u7. HTML convert time: 0.547 sec.

OSDN