
本番データを使わずにバグを再現する|安全な検証データの作り方
「このお客さんのデータで帳票を出すと、エラーで落ちるんです」。 問い合わせを受けて、検証環境で試してみる。でも、検証のデータでは何も起きない。いちばん早いのは、本番のデータベースを丸ごと検証にコピーすること——そう分かっていても、そこで手が止まる。そんな経験、ありませんか。
手が止まるのは、あなたが慎重だからです。本番データには、お客さんの名前もメールアドレスも住所も入っています。それを検証環境に持ち出すことに引っかかりを感じるのは、保守を預かる人としてとても健全な感覚です。
この記事では、本番データを丸ごと持ち出さずに、バグを再現できる検証データを作る方法を、一人運用でも回せる3ステップで整理します。一緒に順番に見ていきましょう。
結論:バグの再現に必要なのは「本番データそのもの」ではなく、バグを起こす「形」(文字数・空欄・特殊な文字・件数・日付・状態の組み合わせ)です。手順は3つ。①条件を言葉にする(何がそろうと落ちるのか)、②必要な分だけ取り出す(行も列も絞る)、③置き換えてから持ち出す(個人情報はダミーに差し替える)。条件が分かれば、本番から1行も持ち出さずにダミーデータだけで再現できることも多いです。
何が起きているか:本番データの丸ごとコピーがためらわれる理由
本番をそのままコピーすれば、確かに再現はしやすくなります。それでも多くの現場でためらわれるのには、ちゃんと理由があります。
- 個人情報が増える:本番と同じ個人情報が、検証環境・手元のPC・バックアップファイルと、置き場所の数だけ増えていく。
- 検証環境は守りが薄いことが多い:本番ほどアクセス制限やログが整っていない。共有の開発用アカウントで入れることもある。
- 思わぬ「本物への送信」:検証環境から、本物のお客さんのメールアドレスに通知メールが飛んでしまう事故は、現場でも起きやすいものです。
- 消し忘れる:調査が終わったあと、コピーしたデータがそのまま残り続ける。
扱いのルールは会社や契約によって違います。社内の規程や、委託元との取り決めがある場合はそちらが優先です。そのうえで、「そもそも持ち出す量を減らす」ことは、どの現場でも取り入れやすい工夫です。
安全な検証データを作る3ステップ

ステップ1:条件を言葉にする(何がそろうと落ちるのか)
最初にやるのは、データを触ることではなく、「どんなデータだと落ちるのか」を言葉にすることです。
エラーが出たデータと、出ないデータを比べながら、次のような観点で違いを探します。
- 長さ:名前や住所がとても長い、逆に1文字しかない。
- 空欄:本来入っているはずの項目が空(NULL や空文字)。
- 文字の種類:機種依存文字、絵文字、全角と半角の混在、改行が入っている。
- 件数:明細が100件を超えている、0件である。
- 日付・数値の境界:月末、うるう日、年をまたぐ、金額が0円やマイナス。
- 状態の組み合わせ:「キャンセル済みなのに出荷済み」のような、ふだんは起きない組み合わせ。
このとき、値そのものではなく「性質」を見るのがコツです。たとえば住所なら、中身を読むのではなく「何文字あるか」「空欄か」だけを調べます。
-- MySQL:エラーになる顧客の住所の「長さ」だけを見る(中身は表示しない)
SELECT id, CHAR_LENGTH(address) AS addr_len, address IS NULL AS addr_null
FROM customers
WHERE id = 12345;
-- 比較用:住所の長さが全体でどのくらいの範囲にあるか
SELECT MIN(CHAR_LENGTH(address)), MAX(CHAR_LENGTH(address))
FROM customers;
MySQL では LENGTH() がバイト数、CHAR_LENGTH() が文字数を返します。日本語を含む項目は、バイト数と文字数で結果が変わるので、どちらで見ているかを意識しておくと安心です(PostgreSQL では length() が文字数、octet_length() がバイト数です)。 本番への接続は、参照(SELECT)だけにとどめてください。読み取り専用のユーザーがあれば、そちらを使うとより安心です。
ステップ2:「作る」か「取り出す」かを決める
条件が言葉になったら、検証データの用意の仕方を選びます。
- 条件がはっきり分かった → ダミーデータを作る:「住所が80文字を超えると落ちる」と分かったなら、検証環境に「80文字を超えるダミー住所」の顧客を1件 INSERT するだけで再現できます。本番からは1行も持ち出しません。いちばん安全で、いちばんおすすめの形です。
- 条件がまだ絞れない → 必要な分だけ取り出す:どの項目が効いているか分からないときは、問題の1件と、その周りの関連データだけを取り出します。テーブル丸ごとではなく、行も列も絞るのが基本です。
取り出すときは、「問題の顧客1件と、その注文と明細だけ」のように、再現に関係するテーブルと行に限定します。列も、バグに関係なさそうな個人情報の列は最初から取り出さないか、次のステップで置き換えます。
ステップ3:置き換えてから持ち出す(マスキング)
取り出すデータに個人情報が含まれるときは、本番から出す時点で置き換えておくのがおすすめです。検証環境にコピーしてから置き換えると、そのあいだだけでも本物の個人情報が検証側に存在することになるからです。
置き換え(マスキング)のポイントは、バグに効く「性質」は残し、中身だけを差し替えることです。
| 項目 | 置き換え方の例 | 残しておきたい性質 |
|---|---|---|
| 氏名 | 「テスト 太郎123」のように id を付けたダミー | 文字数、全角/半角、空欄かどうか |
| メールアドレス | user123@example.com(予約ドメイン) | 形式(@の有無、長さ) |
| 電話番号 | 000-0000-0000 などの明らかなダミー | 桁数、ハイフンの有無 |
| 住所 | 同じ文字数の「テスト住所あああ…」 | 文字数、改行や特殊文字の有無 |
メールアドレスには、example.com のような例示用に予約されたドメインを使うと、万一送信されても実在の誰かに届くことはありません(RFC 2606 で例示用として予約されています)。
-- MySQL:取り出すときに置き換える例(本番では SELECT のみ。UPDATE はしない)
SELECT
id,
CONCAT('テスト太郎', id) AS name,
CONCAT('user', id, '@example.com') AS email,
'000-0000-0000' AS tel,
RPAD('テスト住所', CHAR_LENGTH(address), 'あ') AS address -- 文字数だけ本物に合わせる
FROM customers
WHERE id = 12345;
RPAD で文字数をそろえる例のように、「長さが原因かもしれない」項目は長さを保ったまま置き換えるのがコツです。逆に、絵文字や特殊な文字が原因だと分かっているなら、その文字だけをダミーの文字列に混ぜて作ります。 関数名や挙動は、データベースの種類やバージョンで違うことがあります。初めて使う書き方は、まず検証環境で結果を確かめてから本番の SELECT に使ってください。
検証環境に置いたあとの「安全装置」
検証データを用意できたら、検証環境側にも小さな安全装置を付けておくと安心です。
- メール・外部APIの送信を止める:検証環境の設定で、メール送信を無効にするか、送信先を自分だけに固定しておく(詳しくはメール誤送信を防ぐリリース手順)。
- 置き場所を決める:取り出したファイルは、決めたフォルダ1か所にだけ置く。デスクトップやダウンロードフォルダに散らさない。
- 使い終わったら消す:調査が終わったら、検証データと取り出したファイルを削除する。調査メモに「いつ・何を取り出し・いつ消したか」を1行残しておく。
具体例:「住所が長いお客さんだけ帳票が落ちる」を再現する
ある日の問い合わせです。「特定のお客さんの請求書PDFを出そうとすると、エラーになる」。検証環境ではどの顧客でも正常に出ます。
- 条件を言葉にする:エラーログを見ると、帳票の住所欄の描画で落ちていた。そこで本番で、その顧客の住所の文字数だけを SELECT すると 92文字。全体の最大値も同じ顧客だった。「住所が長いと落ちるのでは」という仮説が立った。
- 作る:検証環境に、住所が92文字のダミー顧客を1件 INSERT。請求書を出すと、同じエラーで落ちた。本番からは1行も持ち出さずに再現できた。
- 境界を探す:ダミー住所の長さを少しずつ変えて試すと、80文字を超えたところから落ちることが分かった。帳票の住所欄の折り返し処理に、長さの上限があったのが原因だった。
修正後は、80文字前後と92文字のダミー顧客で帳票を出し、問題なく表示されることを確かめてリリースしました。このダミー顧客は、次の改修の回帰確認にもそのまま使えます。
影響:「形」で再現できると、何が変わるか
本番データを丸ごと使わない再現は、遠回りに見えて、実はいいことがたくさんあります。
- 個人情報を増やさずに済む:持ち出す量が減るので、置き場所や消し忘れを気にする時間も減る。
- 原因に早く近づける:「何がそろうと落ちるのか」を言葉にする過程で、原因の見当がつきやすくなる。
- 再利用できる:作ったダミーデータは、修正の確認や、次の改修の回帰確認に何度でも使える。
- 説明しやすい:「住所が80文字を超えると落ちていました」と、依頼者にも上司にも一言で伝えられる。
明日やること:次のバグ報告で「性質を見る SELECT」を1本書く
全部を一度に整える必要はありません。明日できる、いちばん小さな一歩はこれです。
- 次にバグ報告を受けたら、本番をコピーする前に、エラーになるデータの「性質」をメモに書き出す(長さ・空欄・文字の種類・件数・日付・状態)。
- 本番では、値そのものではなく文字数や件数だけを見る SELECT を1本書いてみる。
- 条件が見えたら、検証環境にダミーデータを1件だけ作って再現を試す。
- どうしても取り出すときは、置き換えた形で、必要な行と列だけを取り出す。
- 調査が終わったら、取り出したデータを消して、調査メモに1行残す。
「安全な検証データ」チェックリスト
バグ再現のために検証データを用意するときに、確かめたい項目です。調査メモの横に置いて使ってみてください。
- エラーになるデータの「性質」(長さ・空欄・文字の種類・件数・日付・状態)を書き出した
- 本番への接続は参照(SELECT)だけにとどめた
- 条件が分かったものは、ダミーデータを作って再現を試した
- 取り出すときは、テーブル丸ごとではなく必要な行と列だけにした
- 個人情報の列は、取り出す時点で置き換えた
- 置き換えるときに、バグに効く性質(文字数・形式など)は残した
- メールアドレスは
example.comなどの予約ドメインに差し替えた - 検証環境のメール送信・外部連携を止めてある(または送信先を自分に固定した)
- 取り出したデータの置き場所を1か所に決め、調査後に削除した
- 社内規程や委託元との取り決めがある場合は、それに沿っているか確認した
全部に印がつかなくても大丈夫です。最初の「性質を書き出した」だけでも、本番データに手を伸ばす回数はぐっと減ります。
よければ、こちらも
バグの再現は、調査の手順・環境の違い・リリース前の確認とつながっている仕事です。あわせて読むと、次の調査が少し楽になります。
- バグ報告から再現・原因特定までの最短ルート:再現できたあとの、原因の絞り込み方を整理しています。
- 「再現しない」バグの調べ方|環境とタイミングを疑う順番:データ以外が原因のときの疑い方です。
- 本番でしか起きない不具合を追う|ログとデータ差分の調べ方:本番と検証の違いを、順番に洗い出す方法です。
- 環境差で事故らない設定管理|開発・検証・本番を一人運用で:検証環境の設定を整えておくと、安全装置も付けやすくなります。
- 本番データをSQLで直すときの安全手順|バックアップと件数確認:再現して原因が分かったあと、本番データを直すときの手順です。
- 改修後のデグレを防ぐ|回帰確認する範囲の決め方:作ったダミーデータは、回帰確認にもそのまま使えます。

本番データに手を伸ばす前に立ち止まれるのは、あなたがお客さんの情報を大切にしている証拠です。その慎重さは、遠回りではなく、原因にまっすぐ近づくための近道にもなります。 次のバグ報告では、まず「どんな形のデータで落ちるのか」をメモに書き出すところから始めてみましょう。形が分かれば、本物を借りなくても、バグはちゃんと姿を見せてくれます。
ほかの実務ヒントは記事一覧からどうぞ。保守運用の小さな備えを、メールでも少しずつお届けしています。