Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
DB移行、油断した瞬間に 肝が冷えた話
Search
Shuma
July 30, 2026
Programming
66
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
DB移行、油断した瞬間に 肝が冷えた話
JAWS-UG 神戸 #13 / 2026-07-30
Shuma
July 30, 2026
More Decks by Shuma
See All by Shuma
信頼性の目標を誰も求めてない
shubox
0
490
AIの権限設定に悩んでいる話
shubox
0
66
インフラ深掘りLT
shubox
0
66
飲食店長から_SREになった話
shubox
0
62
Ansible で Vector を導入し Slack 通知とログレベル色分けまでした話
shubox
0
67
阿部寛のホームページをSRE観点で改善出来るか考えてみた。
shubox
0
160
一日の終わりに、晩酌しながら眺めたいシステムログの世界
shubox
0
140
プロダクトがクローズした話
shubox
0
220
今も熱いもの!魂を揺さぶる戦士の儀式:マオリ族のハカ
shubox
0
340
Other Decks in Programming
See All in Programming
Building an Out-of-Order CPU
latte72
0
670
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
100
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
810
リアルな遅延を測る仕様
kota_yata
1
140
Gmail/Google DriveをトリガーにAIエージェントを動かそう! / Run AI agents with Gmail/Google Drive as triggers!
har1101
3
460
新卒PdEのリアル
ryu1013
1
390
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
0
350
FastAPI の並行処理モデルを完全に理解する
hoto17296
9
3.7k
DynamoDBの基礎を振り返りながらベクトル検索機能を理解する
musan
3
260
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
110
AI時代に学ぶ 好きなルール 嫌いなルール Linter編
shorty5121
0
830
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
110
Featured
See All Featured
Joys of Absence: A Defence of Solitary Play
codingconduct
1
470
Raft: Consensus for Rubyists
vanstee
141
7.7k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
410
The Invisible Side of Design
smashingmag
301
52k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.8k
The Cult of Friendly URLs
andyhume
79
7k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
490
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Optimising Largest Contentful Paint
csswizardry
37
3.9k
Transcript
DB移行、油断した瞬間に 肝が冷えた 〜 5.6 から 8.4 への肝試し 〜 JAWS-UG 神戸
#13 / 2026-07-30 / Shuma
SELF INTRODUCTION 自己紹介 (Shuma) @ShuShuShuBOOOx システム開発企業の一人目SRE/クラウドインフラエンジニア ファンクラブプラットフォームをAWSで運用 EC2 / RDS
/ ElastiCache / WAF など
OVERVIEW 今日の話 = この移行 5.6 → 8.4 約230GB 74分 /
3時間 MySQL 3メジャーバージョン飛ばし 本番データ量(EC2 c5.12xlarge → RDS) dump(21GB) / インポート実測 方式: mysql.rds_set_external_source によるbinlogレプリケーション 開発 手順の初回実施 → 同じ手順を3回まわして、本番はぶっつけにしない ステージング 本番リハーサル → 本番 2026-07-09 切替
ARCHITECTURE (BEFORE) 移行前の構成 — DBまでぜんぶEC2 binlog レプリ 参照/更新 Internet ALB
+ WAF アプリEC2群 DBマスター DBスレーブ ドメイン別に複数系統 Web / 管理 / 決済 / バッチ EC2 / MySQL 5.6.50 EC2 / 別AZ SSL終端 nginx + PHP (Symfony) 48vCPU (AZ-a) 日次dump・調査 周辺コンポーネント(今回のスコープ外) ElastiCache (Valkey) DynamoDB S3 + Athena 監視EC2 キャッシュ セッション管理 ログ保管・分析 Prometheus / Grafana DBは監視・パッチ・フェイルオーバーまで全部自前。 ※ 実構成から固有情報を省略した概略図 今回このマスター/スレーブをRDS (Multi-AZ) に置き換える
BACKGROUND そもそも、なぜEC2で自前運用だったのか マスター/スレーブ + binlog の自前構成 完全な自由度。スレーブで無負荷バックアップ・調査SQLの逃がし先も確保できていた 自由の代償は「全部自分たち」 コスト的な制約、保守等のメンテナンスが特定の人間の担当になっていた 「バージョンアップ作業に時間を費やすことが難しかった。
バージョンアップを先送り → 5.6. のまま塩漬けに RDS に 5.6 の受け皿はもう無い 移行するなら3世代アップグレードとセット —— これが今回の肝試しの正体
PREPARATION 1 / 3 スペックは実測で決めた EC2の自前DBはメトリクスが勝手に集まらない マスター/スレーブにSSHで入り、コマンドで実測 CPU 2〜3% 平均使用率(ピークでも
4.7%) 設定の実態も棚卸し buffer pool は RAM 96GB 中 40GB の割当てなど 見積もりではなく実測で判断 ほぼ遊んでいる48vCPUを維持する理由がなかった 48 → 16 vCPU c5.12xlarge → db.m8g.4xlarge へ適正化
PREPARATION 2 / 3 5秒の確認が半日を救った インポート直前、念のため確認 SHOW BINARY LOGS で控えていたレプリ開始位置を再確認
5秒 かかった確認の時間 binlogはパージ済みで存在しなかった vs そのまま流せば数時間のインポート後にエラー1236で全やり直し dumpを即取り直して回避 重い処理の前の軽い確認、が身に染みた 半日 救われた手戻りの時間
PREPARATION 3 / 3 事故は人の注意ではなく構造で防ぐ ステージングで意図しない二重書き込み 開発環境の .env が新RDSを向いたまま →
PK重複(エラー1062)でレプリケーション停止 反省を本番に反映: 同期期間中は read_only=1 書き込みを物理的に遮断。「気をつける」ではなく「書けない」状態を作る ここまでやった。油断はしていなかった —— はずだった。
移行方式: binlogレプリケーションの流れ 1 スレーブからdump取得(74分 / 21GB) --dump-slave でレプリ開始位置を記録。本番マスターは無負荷のまま 2 中継EC2経由でRDSへインポート(約3時間)
sedで照合順序を焼き込みつつ投入 3 mysql.rds_set_external_source でレプリケーション開始 RDSを旧マスターのレプリカにする(binlog位置指定) 4 同期を待つ(数時間で遅延0に収束) この間もサービスは旧環境で通常稼働。read_only=1で保護 5 アプリ切替 → レプリ解除・書込可能化(昇格) rds_reset_external_source → read_only=0。切替当日の作業はこれだけ
THE MOMENT 切替翌日、15時24分。 クライアントからの一報 —— 「 絵文字が ? になっています 」
本当に肝が冷えたのは、この瞬間です
ROOT CAUSE 原因は mysqldump の1オプション mysqldumpの既定文字コードは utf8mb3 エラー 0件 --default-character-set=utf8mb4
の指定が漏れていた 警告もなし。インポートは正常終了 4バイト文字が「?」に置換されてダンプ 絵文字・一部の異体字など。3バイト以内の文字は無傷 5.6のデータ 「 🍺」 4バイト文字 → dump(utf8mb3) ここで欠落 → RDSには 「?」 サイレント破損
IRONY 皮肉なことに 照合順序(collation) 文字コード(charset) • sedでダンプに明示COLLATEを焼き込み • その一段「隣」のレイヤーに穴 • 220テーブルを完全統一
• 3バイト以内の文字は無傷 • 手を尽くして守り切った • → 抽出検証も切替後の目視もすり抜け サイレント破損は、検証設計の外側に落ちる
RECOVERY 復旧 — 旧5.6を「正」として書き戻す 1 切替時点のデータを保持していた旧5.6を「正」に 止めてあった旧サーバーがそのまま正解データだった 37 / 219
被害を受けたテーブル数 2 バイト一致する行だけ、カラム単位で書き戻し 切替後にユーザーが編集した行は上書きしない 約20時間 3 書き戻し残 0件まで照合して完了 発覚から全復旧まで 全テーブルを突き合わせて完了判定
LESSONS LEARNED 教訓 charsetとcollationは別レイヤー エラーの出ない失敗が一番怖い 片方に手を尽くしても、もう片方は守れない そしてそれを最初に見つけるのは、顧客 検証データに4バイト絵文字を混ぜる 対策は人の注意ではなく設定に固定 「すり抜けない検証」はデータ側で作る
[mysqldumpの取得スクリプトに utf8mb4 を固定
AND YET それでも、RDSに移行してよかった レプリケーション・フェイルオーバー・パッチをAWSに任せられる SSHで入って実測する日々から卒業 バージョンアップが日常になる 次の「3世代飛ばしの肝試し」自体が不要になる 移行は一度冷や汗をかく。でも—— 移行しない方が、将来もっと冷える
TAKEAWAY 実測で決める・軽い確認を先に・構造で防ぐ。 それでも、穴は空く。 空くなら —— エラーが出ない場所に空く。 皆さんの検証データに、今日から絵文字を1つ ご清聴ありがとうございました 🍧