【2026年10月24日時点の情報です】
第6回では、書き換えを取り消せるトランザクションを試しました。ただし、トランザクションで戻せるのは、確定する前の書き換えだけです。確定したあとで間違いに気づいたときに備えて、書き換える前のデータをファイルに控えておきます。
第7回は、mysqldump で一部の行だけを控え、その行を消してから、控えで戻しました。途中で、パスワードの入力で何度もつまずきました。
場面0:この回の前に知っておくこと
mysqldump の控えは、SQL の命令の並び
mysqldump は、データベースの中身を、SQL の命令の形で書き出すコマンドです。bash で使います(MariaDB の中では使いません)。何も付けずに表を控えると、中身は次の3つの命令になります。
控えを戻すと、この3つが上から順に実行されます。つまり、表を一度消してから作り直す形です。組み込みでいえば、書き込み用のスクリプトで、領域を消去してからイメージを書き戻すのと同じです。
一部だけ控えるときの2つの指定
- –where=”条件”:
条件に合う行だけを控える。ただし、これだけだと DROP TABLE と CREATE TABLE も入る - –no-create-info:
DROP TABLE と CREATE TABLE を書き出さない。INSERT の行だけになる

一部の行だけを –where で控えて、そのまま戻すと、表を消して作り直してから控えた行だけを入れるので、ほかの行がすべて消えます。一部だけを控えるときは、–no-create-info を付けます。
> と <
- > ファイル:
コマンドの結果を、画面に出す代わりにファイルに書き出す(控えるとき) - < ファイル:
ファイルの中身を、コマンドへの入力として流し込む(戻すとき)
パスワードを聞かれるコマンドは、1行ずつ実行する
mysql や mysqldump に -p を付けると、「Enter password:」と入力を待ちます。そこに、一緒に貼り付けた次の行が流れ込むと、その文字列がパスワードとして使われてしまいます。今回は、これで何度もつまずきました。
場面1:血糖の行だけを控える
血糖の2行だけを、–no-create-info を付けて控えました。練習用のデータは、第6回で id 4 を 105 に書き換えたままの状態です(値はすべて練習用の架空のもの)。
mysqldump -u practice -p --no-create-info sql_practice measurements --where="item_name='血糖'" > ~/work/blood_sugar_rows.sql- –no-create-info:
DROP TABLE と CREATE TABLE を入れない - sql_practice measurements:
データベース sql_practice の、表 measurements だけを控える - –where=”item_name=’血糖'”:
項目名が血糖の行だけ。外側を ” “、内側の文字列を ‘ ‘ で囲む - > ~/work/blood_sugar_rows.sql:
控えをファイルに書き出す
最初は、この行と、中身を確かめる grep の行を、まとめて貼り付けて実行しました。すると、何も表示されませんでした。パスワードを聞かれているところに、grep の行が流れ込んだのだと思います。
そこで、mysqldump の行だけを実行し直すと、今度は次のエラーになりました。
結果の例:
mysqldump: Got error: 1045: "Access denied for user 'practice'@'localhost' (using password: YES)" when trying to connect- Access denied … (using password: YES):
パスワードは送られたが、合っていなかったという意味
パスワードを入力し直して通ったあと、控えに入っている命令を grep で確かめました。
grep -E "^(DROP|CREATE|INSERT)" ~/work/blood_sugar_rows.sql結果の例:
INSERT INTO `measurements` VALUESDROP TABLE と CREATE TABLE の行はなく、INSERT の行だけでした。ただ、値の部分が出てこないので、後ろの行も一緒に表示しました。
grep -A 3 "^INSERT" ~/work/blood_sugar_rows.sql結果の例:
INSERT INTO `measurements` VALUES
(1,'2026-09-01','血糖','98',98.000,'mg/dL'),
(4,'2026-10-01','血糖','105',105.000,'mg/dL');
/*!40000 ALTER TABLE `measurements` ENABLE KEYS */;- -A 3:
見つかった行の後ろ(After)を3行、あわせて表示する。この mysqldump は、入れる行を次の行から1行ずつ書き出していた - (1,…)、(4,…):
血糖の2行(id 1 と 4)だけが入っている。id 4 は第6回で書き換えた 105 - /*!40000 … */:
バージョン付きのコメント。MariaDB や MySQL は、中身を命令として実行する。行を入れ終わったあとに、索引をまとめて作り直すための命令で、mysqldump が自動で付ける
場面2:消すつもりが、消えていなかった
次は、血糖の2行を消してから、控えで戻す練習です。消すコマンドと、確かめるコマンドを、また2行まとめて貼り付けてしまいました。
mysql -u practice -p sql_practice -e "DELETE FROM measurements WHERE item_name='血糖';"
mysql -u practice -p sql_practice -e "SELECT * FROM measurements;"結果の例:
Enter password:
ERROR 1045 (28000): Access denied for user 'practice'@'localhost' (using password: YES)
Enter password:
+----+-------------+-----------+------------+-----------+-------+
| id | measured_on | item_name | value_text | value_num | unit |
+----+-------------+-----------+------------+-----------+-------+
| 1 | 2026-09-01 | 血糖 | 98 | 98.000 | mg/dL |
| 2 | 2026-09-01 | CRP | 0.05 | 0.050 | mg/dL |
| 3 | 2026-09-01 | 尿蛋白 | (-) | NULL | NULL |
| 4 | 2026-10-01 | 血糖 | 105 | 105.000 | mg/dL |
| 5 | 2026-10-01 | CRP | 0.03未満 | 0.030 | mg/dL |
| 6 | 2026-10-01 | 尿蛋白 | (+-) | NULL | NULL |
+----+-------------+-----------+------------+-----------+-------+血糖の行が残っています。起きたことを順に並べると、次のとおりです。
| No. | 起きたこと |
|---|---|
| 1 | 1行目の DELETE のコマンドが、パスワードを聞いてきた |
| 2 | 一緒に貼った2行目の文字列が流れ込み、パスワードとして使われた |
| 3 | パスワードが違うので Access denied。DELETE は実行されていない |
| 4 | 2つ目のコマンドが動き、本当のパスワードを入れたので SELECT は成功した |
エラーのあとに表が表示されたので、一瞬、消せたように見えます。結果の表を見て、消えているべき行が残っていないかを確かめることが大事でした。
場面3:残っている行に戻すと、重複エラーで止まる
血糖の行が残ったまま、控えを流し込んでしまいました。
mysql -u practice -p sql_practice < ~/work/blood_sugar_rows.sql結果の例:
--------------
INSERT INTO `measurements` VALUES
(1,'2026-09-01','血糖','98',98.000,'mg/dL'),
(4,'2026-10-01','血糖','105',105.000,'mg/dL')
--------------
ERROR 1062 (23000) at line 25: Duplicate entry '1' for key 'PRIMARY'- Duplicate entry ‘1’ for key ‘PRIMARY’:
id 1 の行がすでにあるので、同じ番号の行は入れられない。第2回で付けた PRIMARY KEY(重複を許さない)が効いている - at line 25:
控えのファイルの25行目の命令で止まった
このとき、id 4 の行も入っていません。INSERT の命令は1つのまとまりとして扱われるので、途中でエラーになると、その命令全体が実行されません。組み込みでいえば、書き込みのパケットを、ベリファイのエラーで丸ごと破棄するのと同じです。
失敗ではありますが、守りが働いた結果でもあります。同じ控えをうっかり2回流しても、同じ行が2つに増えることはありません。
場面4:1行ずつ実行して、消してから戻す
今度は、コマンドを1つ貼り付けて実行し、行頭に戻ったのを確かめてから次を貼る、を守って進めました。
mysql -u practice -p sql_practice -e "DELETE FROM measurements WHERE item_name='血糖';"パスワードを入れると、何も表示されずに行頭に戻りました。-e で実行した DELETE は、消した件数を表示しません。確かめます。
mysql -u practice -p sql_practice -e "SELECT * FROM measurements;"結果の例:
+----+-------------+-----------+------------+-----------+-------+
| id | measured_on | item_name | value_text | value_num | unit |
+----+-------------+-----------+------------+-----------+-------+
| 2 | 2026-09-01 | CRP | 0.05 | 0.050 | mg/dL |
| 3 | 2026-09-01 | 尿蛋白 | (-) | NULL | NULL |
| 5 | 2026-10-01 | CRP | 0.03未満 | 0.030 | mg/dL |
| 6 | 2026-10-01 | 尿蛋白 | (+-) | NULL | NULL |
+----+-------------+-----------+------------+-----------+-------+血糖の2行が消えて、4行になりました。id が 2、3、5、6 と飛び飛びになっているのは、消した行の番号が詰められずに空くためです。控えを流し込みます。
mysql -u practice -p sql_practice < ~/work/blood_sugar_rows.sql今度はエラーが出ずに、行頭に戻りました。もう一度確かめます。
mysql -u practice -p sql_practice -e "SELECT * FROM measurements;"結果の例:
+----+-------------+-----------+------------+-----------+-------+
| id | measured_on | item_name | value_text | value_num | unit |
+----+-------------+-----------+------------+-----------+-------+
| 1 | 2026-09-01 | 血糖 | 98 | 98.000 | mg/dL |
| 2 | 2026-09-01 | CRP | 0.05 | 0.050 | mg/dL |
| 3 | 2026-09-01 | 尿蛋白 | (-) | NULL | NULL |
| 4 | 2026-10-01 | 血糖 | 105 | 105.000 | mg/dL |
| 5 | 2026-10-01 | CRP | 0.03未満 | 0.030 | mg/dL |
| 6 | 2026-10-01 | 尿蛋白 | (+-) | NULL | NULL |
+----+-------------+-----------+------------+-----------+-------+血糖の2行が、同じ id(1 と 4)のまま戻り、6行になりました。CRP と尿蛋白の4行には、何も起きていません。–no-create-info で控えたので、表を消して作り直すことなく、血糖の行だけが入り直しました。
場面5:タイトルを変える前に取った控えを読む
ブログの連載のタイトルをまとめて変える前(第6回の場面5)には、次のコマンドで、対象の記事を控えていました。
mysqldump -u wordpress -p wordpress wp_posts --where="post_type='post' AND post_name LIKE 'embedded-to-web-0%'" > ~/work/backup_titles_20261012.sql- wordpress wp_posts:
データベース wordpress の、記事の表 wp_posts - –where=”…”:
連載の入門編の記事だけを控える
この控えには、–no-create-info が付いていません。場面0 のとおり、中には DROP TABLE と CREATE TABLE が入ります。このまま流し込んでいたら、wp_posts の表がまるごと消えて、連載の8本以外のブログの記事がすべて消えるところでした。
タイトルの変更はうまくいったので、この控えを戻すことはありませんでした。ただ、「控えを取ったから安心」ではなく、戻したらどうなるかまで確かめておく必要があると分かりました。この控えは、戻すのに使えない形なので、消しておくのが安全です。
まとめ
第7回では、一部の行だけを控え、消してから戻しました。覚えたことは、次のとおりです。
| No. | 覚えたこと | つまずいたところ |
|---|---|---|
| 1 | mysqldump の控えは、DROP TABLE → CREATE TABLE → INSERT の並び | ― |
| 2 | 一部だけを控えるときは、–where に –no-create-info を付ける | タイトルを変える前の控えは、戻すと表が消える形だった |
| 3 | パスワードを聞かれるコマンドは、1行ずつ実行する | 2行まとめて貼り、2行目がパスワードとして読まれた |
| 4 | エラーのあとに表が出ても、中身を見て確かめる | DELETE が実行されていないのに、消えたつもりで戻そうとした |
| 5 | 同じ行を二重に入れようとすると、PRIMARY KEY の重複エラーで止まる | 血糖の行が残ったまま戻した |
| 6 | 控えは、戻したらどうなるかまで確かめておく | ― |
今回いちばん多かったのは、パスワードを聞かれるコマンドをまとめて貼るまちがいでした。まとめて貼れるのは、パスワードを聞かれないコマンドだけです。
次回は、「測定データ」と「項目の対応表」のように、2つの表をつないで取り出す JOIN を試します。
この記事は、シリーズ「組み込みエンジニアの Web 開発入門」の1本です。ほかの回は、シリーズの目次からどうぞ。



コメント