QA@IT

sqliteのDBのデータを消してしまいました

3294 PV

Railsで、sqliteのDBのdump作業中に誤って、空のファイルをloadしてしまいました。

そこであわてて、rails c等で確認したのですが、一件も結果が返ってきませんでした。

なのであきらめかけたのですが、./db/production.sqlite3ファイルの容量を確認したところ、2.4M程ありました。他の./db/development.sqlite3等は40k程です。

これはどこかにログ等がたまっているということでしょうか?
ご回答いただけると助かります。

回答

MySQLですけれど、先日、似たような事をしてしまいました。
重要なサービスだったので、かなり青ざめたのですが、
log/production.log の内容をパースしてあげると、ある程度データの復旧が出来ますね。

以下、ほぼrequest_log_analyzerのソースコードの流用ですが、参考まで。

require 'rubygems'
require 'json'
require 'request_log_analyzer'
require 'cli/command_line_arguments'
require 'cli/progressbar'
require 'cli/tools'

arguments = CommandLine::Arguments.parse do |command_line|
  # copy from https://github.com/wvanbergen/request-log-analyzer/blob/master/lib/request_log_analyzer/controller.rb
  command_line.command(:install) do |install|
    install.parameters = 1
  end

  command_line.command(:console) do |cons|
    cons.option(:database, :alias => :d, :required => true)
    cons.option(:format, :alias => :f)
    cons.option(:apache_format)
  end

  command_line.command(:strip) do |strip|
    strip.minimum_parameters = 1
    strip.option(:format, :alias => :f, :default => 'rails3')
    strip.option(:output, :alias => :o)
    strip.switch(:discard_teaser_lines, :t)
    strip.switch(:keep_junk_lines, :j)
  end

  command_line.option(:format, :alias => :f)
  command_line.option(:apache_format)
  command_line.option(:rails_format)

  command_line.option(:file, :alias => :e)
  command_line.option(:mail, :alias => :m)
  command_line.option(:mailhost, :default => 'localhost')
  command_line.option(:mailsubject)
  command_line.option(:parse_strategy, :default => 'assume-correct')
  command_line.option(:yaml)
  command_line.option(:dump) # To be deprecated

  command_line.option(:aggregator, :alias => :a, :multiple => true)

  command_line.option(:database, :alias => :d)
  command_line.switch(:reset_database)

  # filtering options
  command_line.option(:select, :multiple => true, :parameters => 2)
  command_line.option(:reject, :multiple => true, :parameters => 2)
  command_line.option(:after)
  command_line.option(:before)

  command_line.switch(:boring, :b)
  command_line.option(:output, :alias => :o, :default => 'fixedwidth')
  command_line.option(:report_width,  :default => CommandLine::Tools.terminal_width - 1)
  command_line.option(:report_amount, :default => 20)
  command_line.option(:report_sort,   :default => 'sum,mean')

  command_line.switch(:debug)
  command_line.switch(:no_progress)
  command_line.switch(:silent)

  command_line.minimum_parameters = 1
end


# Original Logics 

controller = RequestLogAnalyzer::Controller.build_from_arguments(arguments)

output = controller.output

count = 0

# paths = []
# times = {}

gr = {} # grouped request

controller.source.each_request do |r|
  lines = r.lines
  fl = lines.first
  is_routing_error = lines.count > 1 && lines[1][:line_type] == :routing_errors

  if is_routing_error
    next
  end

  unless ["PUT", "POST", "DELETE"].include? fl[:method]
    next
  end

  key = { method: fl[:method] , path: fl[:path] }

  gr[key] = [] unless gr.has_key? key

  gr[key].push r
end

gr.each do |key, requests|

  file_name = "logs/" + "#{key[:method]}#{key[:path]}.log".gsub('/','_').downcase

  open(file_name, 'w') do |file|
    file.puts "["
    requests.each do |request|
      file.puts "["
      request.lines.each do |line|
        file.puts line
        file.puts ",\n"
      end
      file.puts "]"
      file.puts ",\n\n"
    end
    file.puts "]"
  end

end
編集 履歴 (0)
  • なるほど、たしかにその手がありましたね、盲点でした。今後(無い事祈りますが)の参考にさせていただきます。
    まあ自動でバックアップを取るにこした事は無いですよね・・・。これにこりてRDSを使い始めました。
    -
  • 時期的にlain003さんのお役に立てそうにないのは推測できていたのですが、誰かが検索でヒットすることもありそうなので、一応アンサーしておくことにしました。 お返事有り難うございます。

    > 今後(無い事祈りますが)
    同感です。バックアップ大事ですね;;
    -

VACUUMを実行すると、無事40kになりました。
どうもSqlitenの使用で、データを削除しても次にデータが入ってくるまで、確保しつづけるようです。

残念ながら復旧は難しいと判断しました。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。