お金をかけずにサーバーの勉強をしよう

MySQLバックアップ (MySQL Shellによる論理バックアップ編)

2024年5月8日

メニューへ戻る

MySQLインストール」で DBを使うことができるようになりましたので、いざの時のためにバックアップを取るようにしましょう。

ここでは論理バックアップというものと取得することにします。

論理バックアップというのは物理バックアップに対する観念ですが、概ね以下の捉え方をしておけば良いかと思います。

物理バックアップ
データベースを構成するファイルのコピーを取る。
取るのも速くて戻すのも速いが、取得できる単位はデータベース全体。

論理バックアップ
データベースのデータを吸い出す。
取るのが遅くて戻すのも遅いが、取得出来る単位はテーブルなど細かく指定できる。
データベースを他の環境にコピーする時によく使われる。

それぞれのバックアップにはどちらが良いというものではなく、どういったバックアップ運用をするか、どういうリカバリプランを作るかでどちらを使うか決めることになります。

ここではあくまでテクニックとして論理バックアップをする方法を記しているのであって、MySQLのバックアップはこうすべきというものではないということは知っておいて下さい。


MySQLでの論理バックアップと言えば従来は mysqldumpコマンドを使うのがセオリーでしたが、MySQL 5.7から MySQL Shell という新しいツールが作られ、それを使って論理バックアップをする手法が確立しているようです。

Oracle公式のドキュメントを読むに、今後はこれを使わせたい意図があるように見えますので、これを使ってみることにします。


1.環境

MySQLインストール」で作った環境を前提とします。

具体的には以下のバージョンとなっています。

なお Ubuntu Server 24.04のインストールについては「Ubuntu 24.04 Server インストール」に書いています。

MySQL 8ではストレージエンジンとして InnoDBがデフォルトになりましたし、もう特に理由がなければ MyISAMを使わないと思いますので、InnoDB前提で書いています。

Oracleのオフィシャルドキュメントのバックアップの手順についてはこちらです。
英語ですけど頑張って読みます。
11.5 Instance Dump Utility, Schema Dump Utility, and Table Dump Utility


2.そもそも MySQL Shell とは何者なのか

Bashとかと並ぶコマンドシェルであることは間違いありません。

なんとも定義し難いですが、従来の mysqlコマンドが Windowsの cmd.exeで、MySQL Shellが Powershellという(個人的な)感じ…です。

Powershellは独自の文法を持っていますが、MySQL Shellでは JavaScriptと Pythonがそれに相当します。

MySQL Shellには 3つのモードがあります。

同時に 1つのモードしか使えず、これらを切り替えながら使います。

「#!/snap/bin/mysqlsh」なんて書いたMySQLシェルスクリプトも作れますし、ログインシェルにしたこともあります。

この辺り Bashなど Linuxではお馴染みのシェルと似ているのですが、やっぱりとっつき難いというか「教育コストを払ってまでこれをシェルとして使う人いるかな?」というのが正直な感想です。

内部で SQLを実行できるのは mysqlコマンドと同じですが、Pythonや JavaScriptの関数を直に呼び出せるのが特徴で、MySQLが新しく投入してくる諸々のユーティリティはこれらの関数で提供されてくるようです。

Oracle社か MySQL開発陣の意向か、この力の入れ様は、今後はこれを使わせて行きたいのだろうと思わせる所があり、MySQLの運用管理者は覚えざるを得ないと思います。


3.MySQL Shellで論理バックアップ

過去には mysqldumpコマンドでやっていた定番のバックアップを MySQL Shellから呼び出せる新しい機能でやってみます。

こちらマルチスレッドで動くようになっており、Oracle DBの expコマンド/expdpコマンドの関係とよく似ていますね。

Mysql Shellでできる論理バックアップには以下3種類あります。

ここではデータベース全部を取りたいので、インスタンスバックアップをやってみますが、他の 2つも基本的にやり方は変わりません。

それでは私の好みで Pythonモードにて実際に動かしていってみます。

上記公式ドキュメントの「Running the Utilities」段落では、インスタンスバックアップの例が JavaScriptモードで書いてあるので「Pythonモードではどうやるんだろう?」と探してみましたら、Pythonモードでのファンクションのマニュアルは以下にありました。
dump_instance()

なお、以下が MySQLのドキュメントの一覧です。
MySQL Documentation

このドキュメントの「X DevAPI」に 「MySQL Shell JavaScript API Reference」と「MySQL Shell Python API Reference」があり、それぞれの下に 8.0と 8.4へのリンクがあります。

前置きが長くなりましたが、実際にやってみます。

subro@UbuntuServer2404-2:~$ mysqlsh -h localhost -u root -p
Please provide the password for 'root@localhost':MySQLの[root]ユーザーのパスワードを入れる
ave password for 'root@localhost'? [Y]es/[N]o/Ne[v]er (default No): N  ← パスワードは覚えさせませんでした。

MySQL Shell 8.4.0

Copyright (c) 2016, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'root@localhost'
Fetching global names for auto-completion... Press ^C to stop.
Your MySQL connection id is 9 (X protocol)
Server version: 8.4.0 MySQL Community Server - GPL
No default schema selected; type \use  to set one.

 MySQL  localhost:33060+ ssl  SQL > \py  ← Pythonモードに変更
Switching to Python mode...

 MySQL  localhost:33060+ ssl  Py > util.dump_instance("./mysqlbackup")  ← バックアップの関数を実行
Acquiring global read lock
Global read lock acquired
Initializing - done
1 out of 5 schemas will be dumped and within them 1 table, 0 views.
2 out of 5 users will be dumped.
Gathering information - done
All transactions have been started
Locking instance for backup
Global read lock has been released
Writing global DDL files
Writing users DDL
Running data dump using 4 threads.
NOTE: Progress information uses estimated values and may not be accurate.
NOTE: Table statistics not available for `subrotest`.`subrotesttable`, chunking operation may be not optimal. Please consider running 'ANALYZE TABLE `subrotest`.`subrotesttable`;' first.
Writing schema metadata - done
Writing DDL - done
Writing table metadata - done
Starting data dump
?% (1 rows / ?), 0.00 rows/s, 0.00 B/s uncompressed, 0.00 B/s compressed
Dump duration: 00:00:00s
Total duration: 00:00:00s
Schemas dumped: 1
Tables dumped: 1
Uncompressed data size: 7 bytes
Compressed data size: 25 bytes
Compression ratio: 0.3
Rows written: 1
Bytes written: 25 bytes
Average uncompressed throughput: 7.00 B/s
Average compressed throughput: 25.00 B/s

 MySQL  localhost:33060+ ssl  Py > \quit  ← 終わるときはこう
 Bye!

上手く行きました。

コマンドプロンプトを見ると、MySQLサーバーの [33060/tcp] にアクセスしていることが伺えます。
mysqlコマンドは [3306/tcp] でしたけどそれと違うんですね。

実はプロトコルも違っていて、「X Protocol」という新しいプロトコルを使っています。

util.dump_instance()は、ディレクトリが無ければ作ってくれますので
[/home/subro/mysqlbackup]ディレクトリの中身を確認してみます。

subro@UbuntuServer2404-2:~$ ls -l mysqlbackup
合計 52
-rw-r----- 1 subro subro  372  5月  7 19:20 @.done.json
-rw-r----- 1 subro subro  877  5月  7 19:20 @.json
-rw-r----- 1 subro subro  237  5月  7 19:20 @.post.sql
-rw-r----- 1 subro subro  237  5月  7 19:20 @.sql
-rw-r----- 1 subro subro 2599  5月  7 19:20 @.users.sql
-rw-r----- 1 subro subro  315  5月  7 19:20 subrotest.json
-rw-r----- 1 subro subro  578  5月  7 19:20 subrotest.sql
-rw-r----- 1 subro subro  578  5月  7 19:20 subrotest@subrotesttable.json
-rw-r----- 1 subro subro  652  5月  7 19:20 subrotest@subrotesttable.sql
-rw-r----- 1 subro subro   16  5月  7 19:20 subrotest@subrotesttable@0.tsv.zst
-rw-r----- 1 subro subro    8  5月  7 19:20 subrotest@subrotesttable@0.tsv.zst.idx
-rw-r----- 1 subro subro    9  5月  7 19:20 subrotest@subrotesttable@@1.tsv.zst
-rw-r----- 1 subro subro    8  5月  7 19:20 subrotest@subrotesttable@@1.tsv.zst.idx

この MySQLのインスタンスには、[subrotest]データベースがあって、その中に [subrotesttable]テーブルがあります。

1つのファイルに纏められるのかと思いましたが、従来の mysqldump と似た感じで、要素ごとに別ファイルが作られている形式です。
このディレクトリを一纏まりとして考れば良いのでしょう。

バックアップはこれで取れているはずです。


MySQL障害復旧 (MySQL Shellによる論理リストア編)]で、バックアップからデータベースを復旧してみます。


==========
当ページですが、以前 MySQL 8.0で書いていたときは、MySQL Shellは snapパッケージで入れたのでした。

その際は色々と問題が出てしまって、かなり難儀でしたね。

今回は MySQLの aptリポジトリから deb形式のパッケージを導入したので、随分と簡単になって記載内容が減りました。

せっかくなのでその時の後書きを一応載せて遺しておきますね。

====
しかし…疲れました…。
MySQL Shellだけでも複雑になっているのに、snapパッケージになっているお陰で増々複雑になってしまっています。

今回はここまでとして、障害からの復旧はまた別に書こうと思います。
Ubuntuは本当に今後 snapを採用していくのでしょうか。

バックアップファイルの作り先のディレクトリを [$HOME」以下や [/tmp] 以下(こちらもサンドボックス風のディレクトリになります)に制限されてしまうのは、運用では致命的な感じもいたしますが…。

その後の実験で何となく分かってきたのですが、snap版パッケージだからかプラガブルパスワードストアの機能が発動しません。

本来は mysqlshコマンドで MySQLデーターベースに接続しに行った時にパスワードを入れますけど、その後にプラガブルパスワードストアに保存するかどうかを聞いてくるはずです。
それが全く聞かれない。

Linux版の MySQL Shellでは、プラガブルパスワードストアが実行ユーザーのホームディレクトリにファイルを書くのを snapの設計思想が嫌がったからかも知れません。

この点裏が取れていないので誤っているかも知れませんが、JavaScriptモードがカットされている事情を鑑みるに、何かと機能のカットをしている可能性は高いと思います。

本当はバックアップの作業をスクリプト化して動かしてみたかったのですが、プラガブルパスワードストアが使えればシンプルになるはずのところ、あえて別な仕組みでログインパスワードを取得する気になれず、これは諦めてしまいました。

ここまで問題があるとなると、これでは使えないなぁ…というのが正直な感想ですね。

snapの導入を進めている Canonicalの出方と他がどう追随していくかが鍵だと思いますが、下手をすると Ubuntuの人気に陰りが出るかも知れません。

●snapでハマった際に技術評論社のホーム-ページを参考にさせていただきました。
第714回 Firefoxを含むsnapパッケージとの付き合い方
====

snapパッケージを扱った当時に苦しみが滲み出ていますわ。

8.4用の snapパッケージはまだ出てませんが、改善するんでしょうかねぇ…。


流石にニッチ過ぎるのか、Amazonの Kindle版で 1つあるだけです。