ほげほげ

ようやく(仮)が取れたらしい。他愛もないことを書いてみるのです。

Redmine0.9.1(CentOS5.8上)→Bitnami Redmine Stack2.5.1(Windows)に移行+Bitnami添付のSubversionへのデータ移行まとめ

はてなブログの見たまま編集モードで記事投稿した後にはてな記法に変更しようとしたら、どうやらできないらしい!ひどい。。。
 整形がぐちゃぐちゃだったので新規エントリで投稿しておく。この前の記事と順番が前後しているけど気にしないことにしよう。備忘録的なもんだし。


サーバ退役を契機にRedmine(on CentOS)をBitnami Redmine Stack(for Windows)というAll-in-oneなパッケージに移行しました。

移行の際、文字化けやらログインできない問題やらいろいろ遭遇しましたので、メモとしてまとめておきます。

自分用メモ(と言って整形するのめんどいなあというのをさらっと言ってみるw)。

1.データベースバックアップ

CentOS上でcronバックアップを1週間ごとに実施していました。

mysqldump -u root -h localhost redmine > $backups_dir/$today_str/redmine_mysql.dump;

しかし、このバックアップダンプ、中身をテキストエディタで見ると日本語が化けている。
そのため以下のようにして「--default-character-set=binary」オプションを付加してバックアップするようにしたところ、テキストエディタで日本語がきちんと読める状態になりました。

mysqldump -u root -h localhost --default-character-set=binary redmine >$backups_dir/$today_str/redmine_mysql.dump;

2.(注)リストア時の文字化け

ただこのダンプデータを新サーバのMySQLに突っ込んだところ見事に文字化け。

C:\Bitnami\redmine\apps\redmine\htdocs>mysql bitnami_redmine --user=bitnami --password=xxxxxxxx --default-character-set=utf8 < redmine_full-backup.dump

日本語は問題なく書き込まれているのになんで?
と思ってダンプの中身を見てみると、こんな記述がありました。

CREATE TABLE `attachments` (
(中略)
) ENGINE=InnoDB AUTO_INCREMENT=1549 DEFAULT CHARSET=latin1;

テーブルのCHARSETにlatin1を指定している。。
これはいかにも文字化けしそうです。

http://www.goodpic.com/mt/archives2/2009/01/mysql_41_50mysq.html
参考にしてLinuxサーバ上で
$ perl -pi -e 's/latin1/utf8/' redmine_full-backup.dump
をかましてlatin1という文字列を無理やりutf8に変更。
この変換したダンプファイルをBitnamiのMySQL上に突っ込んでやったら文字化けが解消しました。

※詳しく調べていませんが、移行元のLinuxのサーバ上のMySQLの設定がおかしいためにそんな挙動になっているのではないかと。

移行元のMySQLの設定

mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     | 
| character_set_connection | latin1                     | 
| character_set_database   | latin1                     |←これ
| character_set_filesystem | binary                     | 
| character_set_results    | latin1                     | 
| character_set_server     | latin1                     |←これ
| character_set_system     | utf8                       | 
| character_sets_dir       | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+

このあたり?このまま運用していた私が悪かったのかもです…。

そして移行先(Bitnami Redmine)のMySQLの設定

mysql> show variables like '%char%';
+--------------------------+------------------------------------------+
| Variable_name            | Value                                    |
+--------------------------+------------------------------------------+
| character_set_client     | utf8                                     |
| character_set_connection | utf8                                     |
| character_set_database   | utf8                                     |
| character_set_filesystem | binary                                   |
| character_set_results    | utf8                                     |
| character_set_server     | utf8                                     |
| character_set_system     | utf8                                     |
| character_sets_dir       | C:\Bitnami\redmine\mysql\share\charsets\ |
+--------------------------+------------------------------------------+

移行元のDBのcharacter_setをutf8にしていればこんな問題はおきないんじゃないか?と思います。

3.マイグレーション実行
データベースを流してやったらマイグレーションの実行です。

C:\Bitnami\redmine\apps\redmine\htdocs>ruby bin\rake db:migrate RAILS_ENV=production

しかしここでもハマりポイントが。

なんか既にテーブルがある系のエラーが3種類ほど出ました。
changeset_parents
custom_fields_roles
queries_roles
あたりが既に存在するエラー。中身が空であることを確認してdrop tableし、再度マイグレーション実行でOK。

(参考)
http://d.hatena.ne.jp/rabbit2go/20140309/1394374120

その後、上記サイトの通りにセッション情報をクリアしました。

ruby bin\rake tmp:cache:clear
ruby bin\rake tmp:sessions:clear


4.移行先のRedmineにログイン出来ない…

素の状態でのBitnami Redmine Stackではadminユーザでログインできたのですが、上記マイグレーションを実行したところ、移行元のadminユーザのパスワードではログインできない状態となってしまいました。これは原因がよくわからないのですが、パスワードのHash値生成の仕組みが異なるから?

よくわかりません。

とにかくログインできないと先に進めませんので、adminパスワードを初期化する方法を検索。
http://redmine.jp/faq/administration/reset-admin-password/
上記にありました。

Bitnamiの場合は以下のようにしてコンソールを起動。

C:\Bitnami\redmine\apps\redmine\htdocs>ruby bin\rails console production
irb(main):001:0>admin_user = User.find_by_login('admin')
irb(main):002:0>admin_user.password = 'xxxxxxxx'
irb(main):003:0>admin_user.save!

しかしさらにここでもエラー。。

ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Email notifications is not included in the list

正直このエラーもまったくわかっていないのですが、Railsのバリデーションという値チェックで引っかかっているようです。

C:\Bitnami\redmine\apps\redmine\htdocs\app\models\user.rb
の中にある

MAIL_NOTIFICATION_OPTIONS = [
['all', :label_user_mail_option_all],
['selected', :label_user_mail_option_selected],
['only_my_events', :label_user_mail_option_only_my_events],
['only_assigned', :label_user_mail_option_only_assigned],
['only_owner', :label_user_mail_option_only_owner],
['none', :label_user_mail_option_none]
]

のリストに含まれていないということらしいです。
(Redmineのメール通知設定のあれでしょう)
そして

validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true

このmail_notificationはblankを許容する、ということで

irb(main):004:0>admin_user.mail_notification = ''
irb(main):005:0>admin_user.save!

とすることで無事にadminのパスワード初期化が出来ました。。
(Rubyに詳しいお方にだいぶ助けていただきました。。)

これでようやくadminでRedmineを利用することができるようになりました。
admin以外のユーザも何故かログインできない状態になっていました(上記のメール通知の仕組みが引っかかっているのか、パスワードのHash値が合わないのかはわかりません…)ので、各ユーザのパスワード設定をRedmineの管理画面から初期化し、無事に移行完了。。


半日くらいハマってしまいましたが、MySQL文字コードには気をつけなければ、など良い経験になりました。

(おまけ)
Subversionのデータ移行(Subversion 1.6.5 LinuxSubversion 1.8.5 Windows Bitnami添付版)


Bitnami Redmine Stack上のSubversionデータ移行も合わせておこないました。
こちらはそれほどハマることもなく行きました。

1.データバックアップ
データバックアップ、Subversionはデータがデカいので
・週次:フルバックアップ
・日時:差分バックアップ
としていました。
svnadmin dumpコマンドを利用します。
Subversion実践入門の書籍に書いてあったそのままなので割愛します。

Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)

Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)


2.間引き
長年Subversionを利用していたのでかなりデータが肥大化していました(tar.gzで6GB…)Subversionは履歴も全て保存されますので、データは増えることはあっても減ることはない。これではバックアップも大変だ、ということで大きなデータを探って間引くことにしました。

-bash-3.2# du -m /home/svn/repos/db/revs/* |sort -nr | head -n 20
473 /home/svn/repos/db/revs/1234
...
...

これでデータのデカいコミットベスト20が出てきます。
そのコミットのリビジョン番号(上記だと1234)に相当するコミットおをsvn logコマンドなどで確認し、どこが大きいのか突き止めます。
大抵どこかのプロジェクトが大半をしめているのですよ。
(バイナリを登録していたりね…あほかw)

今回の場合、1プロジェクトがリポジトリの半分を食っていることがわかりました。

間引きはこのあたりを参考に。
http://dqn.sakusakutto.jp/2012/06/subversion_svndumpfilter.html

>svndumpfilter exclude /trunk/images/dekaiyatu < old.dump > new.dump

これでdekaiyatu配下のコミットはごっそり消えてなくなります。
(消した部分のリビジョンは空コミットとなりますのでリビジョン番号が若返ったりはしませんでした)

3.データリストア

> svnadmin load E:\SVN_Repo < svnYYYYMMDD.dmp

でリストアの途中、エラーでコケました。

svnadmin: E125005: Invalid property value found in dumpstream; consider repairing the source or using --bypass-prop-validation while loading.
svnadmin: E125005: Cannot accept non-LF line endings in 'svn:ignore' property

ググってみると同じ現象の人発見。
http://shinsuke789.hatenablog.jp/entry/20120713/1342162178
改行コードで引っかかっている模様。たしかにリストアでコケたリビジョンのコミットを元サーバで検索してみるとコミットのコメントに改行コードが使われていた。

このエラーに出ているまんま「--bypass-prop-validation」設定して

> svnadmin load --bypass-prop-validation E:\SVN_Repo < svnYYYYMMDD.dmp

としたら無事貫通。


ユーザ認証などはいろいろなスタイルがあるので割愛しますが、私の場合httpasswdによる認証をとっていたのですが、Linux:crypt Windows:MD5となっており、htpasswdファイルを流用できなかったようです。


結局パスワードは全て設定しなおしました。

htaccess認証などはほぼそのま流用できました。

やるとわからないことが結構あるのと、グーグル先生に聞けば結構ヒントが得られるなあ、と改めて感じました。