Project

General

Profile

QA #297

誤削除したチケットを復活したい(バックアップからのチケット復旧用スクリプト有)

Added by 奈良 裕記 over 3 years ago. Updated 14 days ago.

Status:
回答済
Priority:
通常
Assignee:
-
Category:
-
Target version:
Start date:
02/03/2017
Due date:
% Done:

0%

Estimated time:

Description

■現象/要望

誤削除したチケットを復活したい
本件の解説動画(YouTube)

■解決策

■前提条件確認

誤削除の状況,環境は千差万別。
下記条件により、可能な対応は異なります。

1.削除したチケットの内容が不明/バックアップデータ有
2.チケット親子関係の使用有無
3.SCMとの連携要否
4.元の番号に復元する必要の有無

■保険&影響緩和策

DBダンプを定期的に自動作成しておくと、誤削除時のリカバリが容易になります。(保険)
テストサーバにリストアし、内容コピペで十分なケースが殆ど。
長期保存不要で上書き対応。

チケット削除権限は基本的にユーザに付与しない。却下などでCloseにする。
削除必要な場合はadmin作業。

■復旧手順1(RedmineのDB対応の場合)

チケットを復旧する
http://daily-postit.blogspot.jp/2012/12/blog-post.html

具体的な作業内容は↓
Redmineの誤って削除したチケットをバックアップから復活させた話
http://shrkw.hatenablog.com/entry/how_to_recover_redmine_issue

チケット誤削除時の復旧用SQL(上記のDB操作部分に相当)を作成しました。
https://redmine.tokyo/issues/297#note-13

テーブル間の関連などは、↓の「Redmineサーバ統合事例」を参照ください。(CM:-)
http://www.slideshare.net/y503unavailable/redmine-42182169

(要注意)チケットの親子関係を利用している場合は、lft,rgtの調整を行わないと、下記の様なトラブルを招く可能性があります。
http://dqn.sakusakutto.jp/2012/04/redmine.html

削除してしまったチケットを復活させる。
http://rms-099.hatenablog.jp/entry/20101231/1293736805
production.logの書込み内容を利用してチケット再作成
親子チケットの対応含む

■復旧手順2(RedmineのDBを弄りたくない&バックアップデータ有&SVN連携)

チケットを別途作成し、内容を設定します。
(バックアップ用データを見ながら or テストサーバにバックアップデータをリストアして内容確認しながらコピペ)

SVNのコミットメッセージを変更します。(refs #チケット番号を変更)

RedmineのDB修正も必要です。refs #番号の変更
changesets , changesets_issues , journals

■復旧手順3(RedmineのDBを弄りたくない&バックアップデータ有&SVN連携&admin操作削減)

・チケット再作成
・SVNの該当変更部分を一旦戻す。
・SVNに再度コミットする時に再作成したチケット番号と紐付ける。

■対応状況

作業事例はありますが、心して対応ください。
作業前のDBとレポジトリのフルバックアップは当然です。

SCMとの連携必要&元の番号に復元する必要が無ければ、
チケット新規作成&SVNコミットメッセージ変更を選択した方が安全かもしれません。

■補足

Redmine本家でも、誤削除の対応提案チケットが出ており、数十件の要望が出ています。希望者は+1しに行きましょう。。

Deleting an issue only marks it as being deleted
http://www.redmine.org/issues/1380
Soft delete of issues
http://www.redmine.org/issues/6666

現状ではシャドウコピー機能の無いWindowsファイルサーバですね。
(シャドウコピーがあれば、ユーザのリストア依頼は桁違いに減る)


Files

redmine_dump_issueno.sh (3.45 KB) redmine_dump_issueno.sh 奈良 裕記, 05/17/2020 02:47 AM
#1

Updated by 奈良 裕記 over 3 years ago

  • Description updated (diff)
#2

Updated by 奈良 裕記 over 3 years ago

  • Description updated (diff)
#3

Updated by 奈良 裕記 over 3 years ago

■Redmineのチケット削除処理内容

ソースファイル/関連メソッド
destroyとdeleteで検索

app/helpers/issue_helper.rb
削除前の確認ダイアログ表示
def issues_destroy_confirmation_message

app/views/issues/_action_menu.html.erb
<%= link_to l(:button_delete), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if @issue.deletable? %>

app/views/context_menus/issues.html.erb
<li><%= context_menu_link l(:button_delete), issues_path(:ids => @issue_ids, :back_url => @back),
:method => :delete, :data => {:confirm => issues_destroy_confirmation_message(@issues)}, :class => 'icon-del', :disabled => @can[:delete] %></li>


app/controllers/issues_controller.rb

親子関係、作業時間の処理
def destroy
@issues.each do |issue|
begin
issue.reload.destroy
rescue ::ActiveRecord::RecordNotFound # raised by #reload if issue no longer exists # nothing to do, issue was already deleted (eg. by a parent)
end
end

/app/models/issue.rb

alias :base_reload :reload
def reload(*args)
@workflow_rule_by_attribute = nil
@assignable_versions = nil
@relations = nil
@spent_hours = nil
@total_spent_hours = nil
@total_estimated_hours = nil
base_reload(*args)
end
after_destroy :update_parent_attributes
親チケットがある場合は進捗率を再計算
#4

Updated by 奈良 裕記 over 3 years ago

  • Description updated (diff)
#5

Updated by 奈良 裕記 over 3 years ago

  • Description updated (diff)
  • Status changed from 新規 to 問合せ中
#6

Updated by 奈良 裕記 over 3 years ago

  • Description updated (diff)
  • Status changed from 問合せ中 to 回答済
  • Target version set to 設定変更対応
#7

Updated by 奈良 裕記 over 3 years ago

  • Description updated (diff)

作業手順3が一番安全だな。。

#8

Updated by 奈良 裕記 about 2 years ago

  • Description updated (diff)
#9

Updated by 奈良 裕記 about 2 years ago

  • Description updated (diff)
#10

Updated by 奈良 裕記 about 2 years ago

  • Description updated (diff)
#11

Updated by 奈良 裕記 9 months ago

  • Description updated (diff)
#12

Updated by 奈良 裕記 9 months ago

  • Description updated (diff)
#13

Updated by 奈良 裕記 about 2 months ago

■Redmineチケット誤削除時の復旧用SQL作成(Mysql/MariaDB対応)

■機能

Redmineでチケットを誤削除した時に、誤削除前の環境から削除したチケットのSQL情報を出力するシェルスクリプトです。
(誤削除前のDBバックアップが無いと役に立ちません)

■前提条件

下記を全て満たした場合に、自己責任で利用してください。
適用後に正常に動作しなくなっても対応できません。

・Linux環境にて、mysql/mariadbでRedmineを運用していること。
 動作環境にroot権限でアクセスできること。DBに直接アクセスできること。

・チケット誤削除前のデータで正常に動作するバックアップ環境があり、mysqldumpで直接アクセスできること。
(dailyでsqlのdumpを出力しておく事を推奨)

・本スクリプトの出力をリストア先の環境に適用する前に、リストア先環境でDBのフルバックアップを取得すること。(特に本番稼働環境の場合、利用者へのアクセス/更新停止連絡は必須)

・SQLの基本的な処理内容が理解できていること。

・誤削除したチケットのIDが判っていること。

■作業手順

・誤削除環境と同等のバックアップ環境を立ち上げ、誤削除前のDB内容を反映する。

 (稼働環境と同等のRedmineの環境に、誤削除前のRedmineのDBダンプ内容を取り込んで起動させる)

 実際には起動しなくとも良いが、内容確認のために、Redmine上で誤削除前のデータを参照出来る事を推奨

スクリプトのコピーと実行権限設定

バックアップ環境のワーク用フォルダに、本スクリプトをコピーする。

redmine_dump_issueno.sh

chmod +x で、実行権限を付ける。

作業用アカウントが、本フォルダ上に書き込める事が必要。

スクリプトファイルのDBアクセス権限設定

コピーしてきたスクリプトファイルを編集し、先頭の下記3つの行を実際の動作環境に合わせる。

database=redmine
username=redmine
password=pass-word1

実際の動作環境の設定値は、下記ファイルに記載されている。この内容を転記する。
但し、転記先のpasswordには、ダブルクオーテーションを含まないこと。

Redmineインストールパスの下、config/database.yml
(例: /var/lib/redmine/config/database.yml )

productionセクションの
database=redmine
username=redmine
password=pass-word1

スクリプト実行し、リストア用SQLファイルを作成する

誤削除したチケット番号を引数にしてスクリプトを実行する。
(以下は 1004 番のチケットを誤削除した場合)

./redmine_dump_issueno.sh  1004

当該チケットに関連するSQLのINSERT文のファイルが生成される。(INSERT_チケット番号.sql)

念のため、このSQLファイルの内容を確認する。
SQLのINSERT文が並んでいる筈。

指定した番号のチケット情報が存在した場合は、
そのINSERT_チケット番号.sqlのファイルとして生成し、ファイル名を表示する。
また、チケットに紐付けられた添付ファイル情報も表示される。

指定した番号のチケット情報が存在しなかった場合には、
その旨表示する。

チケット復活対象RedmineのDBフルバックアップを作成する。

誤動作時に復旧可能とするため、

mysqldump -u username -p%password% database > backup_redmine_日付日時.sql
sqlファイルが正常に生成されていることを確認する。
(バックアップが正常に生成できていない場合は、絶対に以下の作業を実施してはならない)

本番環境のRedmine上に、作成したSQLファイルを転送する。

作成したSQLファイルを、SCPなどで復活対象のRedmineに転送する。

本番環境のRedmine上で、転送したSQLファイルを実行する。DBのバックアップを必ず作成する。

mysql -u username -p%password% %database < 誤削除したチケット番号.sql

チケット親子関係の修復

チケットの親子関係を利用している場合は、階層構造を再構築する必要がある。
Redmineのインストールフォルダに移動し下記実行する。

RAILS_ENV=production rails runner 'Issue.rebuild_tree!'

systemctl restart httpd

添付ファイルを戻す。

チケットに紐付けられた添付ファイルが無かった場合は作業無し
添付ファイルが存在する場合は、バックアップサーバからコピーする。

Redmine3.4以降の場合、削除したチケットの添付ファイルが残っている場合がある。(正常動作)
この場合は、残っていた添付ファイルをそのまま利用して構わない。

/* Redmine3.4で追加された、ファイル単位の重複排除機能が原因と思われる。
https://www.redmine.org/issues/25215
*/

attachmentsテーブル

2020/05/16なら、
2005/16時分..ファイル名となる。

MariaDB [redmine]> select disk_filename from attachments where container_id=61295;
+-----------------------------------------------+
| disk_filename                                 |
+-----------------------------------------------+
| 200127231549_clipboard-202001272315-xfzke.png |
+-----------------------------------------------+
1 row in set (0.000 sec)

# ls -al /var/lib/redmine/files/2020/01

-rw-r--r-- 1 apache apache 70663 Jan 27 23:15 200127231549_clipboard-202001272315-xfzke.png

#14

Updated by 奈良 裕記 15 days ago

  • Description updated (diff)
#15

Updated by 奈良 裕記 15 days ago

  • Subject changed from 誤削除したチケットを復活したい to 誤削除したチケットを復活したい(バックアップからのチケット復旧用スクリプト有)
#16

Updated by 奈良 裕記 14 days ago

  • Description updated (diff)

Also available in: Atom PDF