「東京メトロ my!アプリ」をバージョンアップします!...「東京メトロmy!アプリ」バージョンアップ 詳細 1 アプリ名称 東京メトロmy!アプリ
MySQL 4.0で9年動き続けたサーバを リプレイスしてバージョンアップした話
-
Upload
takahiro-okumura -
Category
Internet
-
view
42.558 -
download
1
Transcript of MySQL 4.0で9年動き続けたサーバを リプレイスしてバージョンアップした話
MySQL 4.0で9年動き続けたサーバを!リプレイスしてバージョンアップした話
OKUMURA Takahiro MySQL Casual Talks vol.7
OKUMURA Takahiro!
@hfm @tacahilo!
2013年ペパボ新卒入社の2年目インフラエンジニア
今日の話MySQL 4.0.25で9年動き続けたサーバを,新しいサーバへリプレイスし,MySQL 5.0.96にバージョンアップした話!
ホントはもっとバージョンを上げたかったけど,他の仕事の兼ね合いで間に合いませんでした😞
SELECT ????????? FROM ????????
しかし課題は山積み…
当初はSELECT文すらろくに書けなかった(↓を埋められない)
知識不足経験不足,勉強も並行するとして,まずは現状の把握から…
passport0# uname -a Linux passport0.heteml.jp 2.6.17-1.2142_FC4 #1 Tue Jul 11 22:41:06 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux !
# cat /etc/redhat-release Fedora Core release 4 (Stentz) !
# mysql --version mysql Ver 12.22 Distrib 4.0.25, for unknown-linux-gnu (x86_64)
passport系DBの構成MySQL !4.0.25!
!MASTER
MySQL!5.1.49!
!SLAVE
MySQL !4.0.25!
!SLAVE
masterに(無い|有る)DBやユーザがいたりしてデータが不安
masterに(無い|有る)DBやユーザがいるし,独自パッチが当たっているし,あと一部DBの中身がぶっ壊れたままレプリケーションしてた
masterしか信用出来ない…
MySQL 4.0からレプリケーション可能なバージョンは?
各バージョンのMySQLをビルドして,4.0.25からレプリケーション出来るか各バージョン毎に調べたりhttps://github.com/kamipo/mysql-build (神)
途中,道を外してただひたすらチェインレプリケーションを行ったりも
MySQL 4.0!!
port 3306
MySQL 4.1!!
3307
MySQL 5.0!!
3308
MySQL 5.1!!
3309
MySQL 5.5!!
3310
VagrantのVM (1個)
MySQL 4.0!!
port 3306
MySQL 4.1!!
3307
MySQL 5.0!!
3308
MySQL 5.1!!
3309
MySQL 5.5!!
3310
MySQL 5.6!!
3311
VagrantのVM (1個)
途中成果物
https://speakerdeck.com/hfm/27https://github.com/tacahilo/mysql-allstar
MySQL 5.0化へ
社内でMySQL 4.0 -> 5.0へのアップグレード経験があった(ので不安も少なめ)
CentOS 6用のMySQL 5.0.86 rpmが社内yumリポジトリにあった(昔ビルドしたらしい)
passport系DBの構成MySQL !4.0.25!
!MASTER
MySQL!5.1.49!
!SLAVE
MySQL !4.0.25!
!SLAVE
masterに無いDBやユーザがいたりしてデータが不安
masterに無いDBやユーザがいるし,独自パッチが当たっているし,あと一部DBの中身がぶっ壊れたままレプリケーションしてた
masterしか信用出来ない…
(再掲)
!! INSERT breaks bin-log !!ERROR: Error in Log_event::read_log_event(): 'read error', data_len: 66899, event_type: 41 Could not read entry at offset 881:Error in log format or read error # at 575 #140620 3:59:32 server id 1 end_log_pos 642 Query thread_id=575 exec_time=0 error_code=0 !
BEGIN /*!*/; -- use SYSTEMtestdb/*!*/; etstdbINSERT INTO a_data (id, create_date) VALUES ('1', /*!*/;
!! INSERT breaks bin-log !!ERROR: Error in Log_event::read_log_event(): 'read error', data_len: 66899, event_type: 41 Could not read entry at offset 881:Error in log format or read error # at 575 #140620 3:59:32 server id 1 end_log_pos 642 Query thread_id=575 exec_time=0 error_code=0 !
BEGIN /*!*/; -- use SYSTEMtestdb/*!*/; etstdbINSERT INTO a_data (id, create_date) VALUES ('1', /*!*/;
1. 途中挟まっている「SYSTEM」という文字列はタイムゾーン
2. 「use <database>」の間にタイムゾーンの文字が割り込む
3. INSERT文行頭に「1文字削れたDB名」がくっつき,VALUES以降が消失してしまう
4. flushすれば再開するが,結局INSERT毎にbin-logが破損してしまう
MySQL 5.0系のsourceとGCCバージョンの相性に問題?
• http://bugs.mysql.com/bug.php?id=48357
• https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38562
MySQL 5.0系のsourceとGCCバージョンの相性に問題?
log_event.cc:
!write_str_with_code_and_len((char **)(&start), catalog, catalog_len, Q_CATALOG_NZ_CODE); !!(*dst)+= len;
MySQL 5.0系のsourceとGCCバージョンの相性に問題?該当箇所では char * を Log_event::Byte* ( = unsigned char) として扱っている
これは strict aliasing に違反するコードになる(難しくてよく分かってない)http://d.hatena.ne.jp/yohhoy/20120220/p1
strict aliasing に違反(あるいは有効にしている場合?)は,異なる型でポインタを操作すると動作が未定義になるらしい
=> 未定義の結果として、ポインタのサイズが期待通りに計算されなくて binlog のポジションがズレて物故割れた
MySQL 5.0系のsourceとGCCバージョンの相性に問題?MySQL 5.0にバグがあった? => NO
GCCにバグがあった? => NO
GCCの特定バージョン (4.3.3~4.4.0あたり) でMySQL 5.0をビルドしようとするとバグってしまうという,組み合わせの問題っぽい
• -O1でビルドするとmysqlのテストスイートがコケる • -O2でビルドするとbinlog周りのテストがコケる • -O2 -fno-strict-aliasingならテスト通る
MySQL 5.0系のsourceとGCCバージョンの相性に問題?
@hiboma先生の調査メモに再現方法つきで更に詳細が載っております(僕自身がちゃんと問題を把握しきれてなくてすみません…)
https://github.com/hiboma/hiboma/blob/master/mysql/bug-48357-binlog-corruputed.md
MySQLをrpmbuildする過程specファイルを見ると,2回ビルドしていることが分かる
1. DEBUG=1をつけてビルドする
• mysql-debugバイナリを生成する
• 1回目のテストを走らせる
2. DEBUG=0をつけてビルドする
• 2回目のテストを走らせる
• mysqldバイナリを生成する
MySQLをrpmbuildする過程specファイルを見ると,2回ビルドしていることが分かる
1. DEBUG=1をつけてビルドする
• mysql-debugバイナリを生成する
• 1回目のテストを走らせる
2. DEBUG=0をつけてビルドする
• 2回目のテストを走らせる
• mysqldバイナリを生成する
この時点でmysqld-debug.sym というファイルが生成される
何故か途中でmysqld-debug.symが消えてビルドがコケる
そのとき出ていたエラー
RPM build errors: File not found: /home/vagrant/rpmbuild/BUILDROOT/MySQL-community-5.0.96-1.rhel5.x86_64/usr/sbin/mysqld-debug File not found: /home/vagrant/rpmbuild/BUILDROOT/MySQL-community-5.0.96-1.rhel5.x86_64/usr/lib64/mysql/mysqld-debug.sym
redhat-rpm-configの罠
Development Toolsに同梱されているrpmパッケージ
/usr/lib/rpm/redhatにマクロやヘルパスクリプトを用意してる!
本当ならきっとイイヤツ
/usr/lib/rpm/redhat/macros#=================================================================== # ---- Build policy macros. # # #------------------------------------------------------------------- # Expanded at beginning of %install scriptlet. # !%__spec_install_pre %{___build_pre}\ [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "${RPM_BUILD_ROOT}"\ mkdir -p `dirname "$RPM_BUILD_ROOT"`\ mkdir "$RPM_BUILD_ROOT"\ %{nil}
/usr/lib/rpm/redhat/macros#=================================================================== # ---- Build policy macros. # # #------------------------------------------------------------------- # Expanded at beginning of %install scriptlet. # !%__spec_install_pre %{___build_pre}\ [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "${RPM_BUILD_ROOT}"\ mkdir -p `dirname "$RPM_BUILD_ROOT"`\ mkdir "$RPM_BUILD_ROOT"\ %{nil}
%install前にディレクトリ消してる…
CentOS6 (Vagrantがオススメ) で走らせるとMySQL 5.0.96 rpmが出来上がるshellscript
https://gist.github.com/tacahilo/321657c75722a24204fa
8/22 リベンジメンテ
バッチ処理や利用時間帯を考えて,2回目は早朝メンテになった.
1回目のメンテで取ったdumpのおかげで,具体的な作業はマスタ昇格のみ.すぐ終わった.
メンテ終わりに,朝日に照らされながら飲んだ珈琲が美味しかった☕
before afterMySQL !5.0.96!
!MASTER
MySQL!5.5.40!
!SLAVE
MySQL !5.0.96!
!SLAVE
MySQL !4.0.25!
!MASTER
MySQL!5.1.49!
!SLAVE
MySQL !4.0.25!
!SLAVE
実は100%成功ではなかったり…
MySQL 4.0にMovable Typeのデータ (UTF-8) が入っていた.
手を変え品を変えてデータリカバリに取り組んだが,どうしてもMTのDBだけが壊れてしまう…
一応現在はmiddlemanをベースにリプレイス作業が進行中.