41から始めました

文字通り41歳から始めたブログです。DB(MySQL)を使ってお仕事してるので、DB周りの話を中心に最近始めたこととかをTwitterのノリで書いています。なお、本サイトにおいて示されている見解は私個人の見解であり、所属団体や組織を代表するものではありません。

MHSレプリカでトランザクションをスキップする方法

はじめに

MySQL HeatWave Service いわゆるMHS(MDS またはHeatWave)のレプリカでトランザクションをスキップする場合、MySQLのドキュメントにある方法だと全てが使えるわけじゃないので書いておきます。

特にソースがGTID無効(非GTID)にしたレプリケーションの場合が分かりづらかったので参考にしてください。

MHSで非GTIDレプリにてトランザクションをスキップするには

MHSがレプリカかつソースがGTIDが無効な場合、ここにあるいくつかの方法が使えません。

使えるのは

mysql>CHANGE MASTER TO MASTER_LOG_FILE='source_log_name', MASTER_LOG_POS=source_log_pos;

またはMySQL 8.0.24以降なら

mysql>CHANGE REPLICATION SOURCE TO SOURCE_LOG_FILE='source_log_name', SOURCE_LOG_POS=source_log_pos;

のいずれかです。

スキップ作業の流れ

作業の流れとしては

1.mysqlbinlogコマンドでソースのバイナリログを確認

2.スキップしていいクエリ・ポジションを確認

3.STOP REPLICA;

4.CHANGE MASTER またはCHANGE REPLICATION SOURCEでスキップ

5.START REPLICA;

となります。

MHSで使えない方法

その1 SET GLOBALが使えない

MHSでは残念ながらSET GLOBALが使えない。つまり

mysql>SET GLOBAL sql_slave_skip_counter = N;

mysql>SET GLOBAL sql_replica_skip_counter = N;

トランザクションをスキップすることができない。(実行すると以下のエラーが出る)

ERROR: 1227 (42000): Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation

では、Configuration(MySQLで言うmy.cnf|my.iniのようなもの)で設定すればいいじゃないかと思うだろうが、sql_slave_skip_counter やsql_replica_skip_counter は変更できる変数ではない。

ここにあるものだけが変更できる。

その2 CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION=1;も使えない

CHANGE MASTER TO MASTER_AUTO_POSITION=1; やCHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION=1;を使った場合もエラーが出る

ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or REPLICATION_SLAVE_ADMIN privilege(s) for this operation

そのため、トランザクションをスキップしたい場合、最初に書いた方法となる。

MHSでGTIDレプリにてトランザクションをスキップするには

ここに書かれている以下の方法でスキップする。

SET GTID_NEXT='aaa-bbb-ccc-ddd:N';
BEGIN;
COMMIT;
SET GTID_NEXT='AUTOMATIC';

ただし

GTID版もドキュメントにある方法全部が使えるわけではなく、以下のコマンドは実行できないので注意が必要。

FLUSH LOGS;
PURGE BINARY LOGS TO 'binlog.000xxx';

原因としてはこちらも実行するための権限が無いためです。

おまけ

OCI MHS APIを使うと同じようなことができるっぽいが、それは試してない。

AssignTargetUuidHandling — oci 2.119.1 documentation

バイナリログファイル名をlast_configured_log_filenameに、ポジションをlast_configured_log_offsetに設定するようだ。

OCI MHS API、今度試してみるか。

さいごに

こういうこと書くとMHS不便やなー、使いづらそうだなーとか思うかもしれませんが、ゴリッゴリにいじらなくて済むようになってると考えたら逆にスッキリしてますよね。

DBAが余計なことを考えなくて済むようにしてるので、実際には移行してしまえば何かしらやりようはあるので慣れます。

問題はドキュメントが分かりづらかったり、記載が足りなかったりすることなので、それは内部でプッシュし続けていきます。

文字コードとデフォルトの照合順序とPAD、それとutf8mb4のそれ

自分用のメモです

最近、照合順序の話を良くしている気がするので、これが見たくなる時があるので自分向けに。

文字コードとデフォルトの照合順序とPAD

mysql> SELECT CHARACTER_SET_NAME, COLLATION_NAME, IS_COMPILED, SORTLEN, PAD_ATTRIBUTE FROM information_schema.COLLATIONS WHERE IS_DEFAULT = 'Yes';
+--------------------+---------------------+-------------+---------+---------------+
| CHARACTER_SET_NAME | COLLATION_NAME      | IS_COMPILED | SORTLEN | PAD_ATTRIBUTE |
+--------------------+---------------------+-------------+---------+---------------+
| armscii8           | armscii8_general_ci | Yes         |       1 | PAD SPACE     |
| ascii              | ascii_general_ci    | Yes         |       1 | PAD SPACE     |
| big5               | big5_chinese_ci     | Yes         |       1 | PAD SPACE     |
| binary             | binary              | Yes         |       1 | NO PAD        |
| cp1250             | cp1250_general_ci   | Yes         |       1 | PAD SPACE     |
| cp1251             | cp1251_general_ci   | Yes         |       1 | PAD SPACE     |
| cp1256             | cp1256_general_ci   | Yes         |       1 | PAD SPACE     |
| cp1257             | cp1257_general_ci   | Yes         |       1 | PAD SPACE     |
| cp850              | cp850_general_ci    | Yes         |       1 | PAD SPACE     |
| cp852              | cp852_general_ci    | Yes         |       1 | PAD SPACE     |
| cp866              | cp866_general_ci    | Yes         |       1 | PAD SPACE     |
| cp932              | cp932_japanese_ci   | Yes         |       1 | PAD SPACE     |
| dec8               | dec8_swedish_ci     | Yes         |       1 | PAD SPACE     |
| eucjpms            | eucjpms_japanese_ci | Yes         |       1 | PAD SPACE     |
| euckr              | euckr_korean_ci     | Yes         |       1 | PAD SPACE     |
| gb18030            | gb18030_chinese_ci  | Yes         |       2 | PAD SPACE     |
| gb2312             | gb2312_chinese_ci   | Yes         |       1 | PAD SPACE     |
| gbk                | gbk_chinese_ci      | Yes         |       1 | PAD SPACE     |
| geostd8            | geostd8_general_ci  | Yes         |       1 | PAD SPACE     |
| greek              | greek_general_ci    | Yes         |       1 | PAD SPACE     |
| hebrew             | hebrew_general_ci   | Yes         |       1 | PAD SPACE     |
| hp8                | hp8_english_ci      | Yes         |       1 | PAD SPACE     |
| keybcs2            | keybcs2_general_ci  | Yes         |       1 | PAD SPACE     |
| koi8r              | koi8r_general_ci    | Yes         |       1 | PAD SPACE     |
| koi8u              | koi8u_general_ci    | Yes         |       1 | PAD SPACE     |
| latin1             | latin1_swedish_ci   | Yes         |       1 | PAD SPACE     |
| latin2             | latin2_general_ci   | Yes         |       1 | PAD SPACE     |
| latin5             | latin5_turkish_ci   | Yes         |       1 | PAD SPACE     |
| latin7             | latin7_general_ci   | Yes         |       1 | PAD SPACE     |
| macce              | macce_general_ci    | Yes         |       1 | PAD SPACE     |
| macroman           | macroman_general_ci | Yes         |       1 | PAD SPACE     |
| sjis               | sjis_japanese_ci    | Yes         |       1 | PAD SPACE     |
| swe7               | swe7_swedish_ci     | Yes         |       1 | PAD SPACE     |
| tis620             | tis620_thai_ci      | Yes         |       4 | PAD SPACE     |
| ucs2               | ucs2_general_ci     | Yes         |       1 | PAD SPACE     |
| ujis               | ujis_japanese_ci    | Yes         |       1 | PAD SPACE     |
| utf16              | utf16_general_ci    | Yes         |       1 | PAD SPACE     |
| utf16le            | utf16le_general_ci  | Yes         |       1 | PAD SPACE     |
| utf32              | utf32_general_ci    | Yes         |       1 | PAD SPACE     |
| utf8mb3            | utf8mb3_general_ci  | Yes         |       1 | PAD SPACE     |
| utf8mb4            | utf8mb4_0900_ai_ci  | Yes         |       0 | NO PAD        |
+--------------------+---------------------+-------------+---------+---------------+
41 rows in set (0.00 sec)

utf8mb4の照合順序とPADの一覧

mysql> SELECT CHARACTER_SET_NAME, COLLATION_NAME, IS_COMPILED, SORTLEN, PAD_ATTRIBUTE FROM information_schema.COLLATIONS WHERE CHARACTER_SET_NAME = 'utf8mb4';
+--------------------+----------------------------+-------------+---------+---------------+
| CHARACTER_SET_NAME | COLLATION_NAME             | IS_COMPILED | SORTLEN | PAD_ATTRIBUTE |
+--------------------+----------------------------+-------------+---------+---------------+
| utf8mb4            | utf8mb4_general_ci         | Yes         |       1 | PAD SPACE     |
| utf8mb4            | utf8mb4_bin                | Yes         |       1 | PAD SPACE     |
| utf8mb4            | utf8mb4_unicode_ci         | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_icelandic_ci       | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_latvian_ci         | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_romanian_ci        | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_slovenian_ci       | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_polish_ci          | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_estonian_ci        | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_spanish_ci         | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_swedish_ci         | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_turkish_ci         | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_czech_ci           | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_danish_ci          | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_lithuanian_ci      | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_slovak_ci          | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_spanish2_ci        | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_roman_ci           | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_persian_ci         | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_esperanto_ci       | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_hungarian_ci       | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_sinhala_ci         | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_german2_ci         | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_croatian_ci        | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_unicode_520_ci     | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_vietnamese_ci      | Yes         |       8 | PAD SPACE     |
| utf8mb4            | utf8mb4_0900_ai_ci         | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_de_pb_0900_ai_ci   | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_is_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_lv_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_ro_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_sl_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_pl_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_et_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_es_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_sv_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_tr_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_cs_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_da_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_lt_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_sk_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_es_trad_0900_ai_ci | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_la_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_eo_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_hu_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_hr_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_vi_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_0900_as_cs         | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_de_pb_0900_as_cs   | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_is_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_lv_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_ro_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_sl_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_pl_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_et_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_es_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_sv_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_tr_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_cs_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_da_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_lt_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_sk_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_es_trad_0900_as_cs | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_la_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_eo_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_hu_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_hr_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_vi_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_ja_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_ja_0900_as_cs_ks   | Yes         |      24 | NO PAD        |
| utf8mb4            | utf8mb4_0900_as_ci         | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_ru_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_ru_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_zh_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_0900_bin           | Yes         |       1 | NO PAD        |
| utf8mb4            | utf8mb4_nb_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_nb_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_nn_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_nn_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_sr_latn_0900_ai_ci | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_sr_latn_0900_as_cs | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_bs_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_bs_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_bg_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_bg_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_gl_0900_ai_ci      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_gl_0900_as_cs      | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_mn_cyrl_0900_ai_ci | Yes         |       0 | NO PAD        |
| utf8mb4            | utf8mb4_mn_cyrl_0900_as_cs | Yes         |       0 | NO PAD        |
+--------------------+----------------------------+-------------+---------+---------------+
89 rows in set (0.00 sec)

ドキュメント

dev.mysql.com

アップグレードしたいとき見るべきドキュメントは?

この記事はMySQL Advent Calendar 2023 25日目の記事です。

はじめに

アップグレードってどうすればいいの?と言う人にドキュメントベースでアップグレードの流れを書いてみます。

本当はここから全てのリンク先を読むのが一番良いのですが、

これが多くのユーザーにはおそらくツライ(汗)

「ドキュメントのどこ読めばいいんですか?」という問い合わせが非常に多いのです。(わかる気はする)

というわけで、少しチョイスしてみました。(たまに寄り道します)

この記事で上げていったリンクのうち、必要なページを熟読していってみてください。

できれば英語版で最新を読むのが良いんですが、つらい方は和訳版を先に読むのもアリです。

(但し、和訳版は少し古いので、最新のバージョンにする人は最終的には英語版を読みましょう)

そしてその後に手順書を書いて、気になるところを都度調べていくと良いです。

1.どのバージョンにアップグレードするのか決める

まずはどのバージョンにアップグレードするのか決めましょう。(決めないことには始まりません)

「僕は優柔不断なので決められない。誰か決めて!」

と言う人には基本的には最新をお勧めします。理由はバグが可能な限り修正されているから。

しかし、人によっては最新が常に良いとは限らないのが難しいところ。

機能が削除されていたり、リグレッションがあったり、機能追加で新たなバグが生まれたり…

ここを絶対に間違えたくない!と言う人はyoku0825さんの話(これとかこれとかこれ)なんかを参考にしてみるのが良いかもしれません。

アップグレードパス

もしあなたが5.6を使っていて8.0や8.xへのアップグレードを考えている場合、二回以上のアップグレードが必要になります。

と言うのも、MySQL Serverではバージョンまたぎのアップグレードをサポートしていないからです。

(ここでは闇の下法をお勧めしないので標準的なやり方を記載してます)

例えば、

  • 5.7から8.0、8.0.34以降から8.xなどは一回です。
  • 5.7以前から8.x、8.0.33以前から8.xは二回以上アップグレードが必要です。

そのため、アップグレードパスを確認して、アップグレードが一回で済むのか二回以上かかるのかを確認します。

のアップグレードパスドキュメントを読みます。

以降のクリック先のURLは8.0ベースにしていますが、画面の右上にあるバージョンのリストから自分のアップグレード先を選択してください。

2回以上アップグレードが必要な場合は2ページずつ読む必要があります。

(例:5.6 -> 5.7 -> 8.0 なら5.7と8.0の分をそれぞれ読む)

※アップグレード先のバージョンとOSのコンパチを確認する

アップグレードしたらOSがサポート外なんてことがないように対応プラットフォームのページを必ず見ておきましょう。

※5.7が既にEOLになってて見れません…。そんな時どうすれば良いかについては後述の「余談その3.魚拓を見る」を参考にしてください。

2.新機能・追加・非推奨・削除された機能を確認する。

特に、削除された機能とかオプションとかはアップグレード時(新バージョンのmysqldで起動時)に失敗する元になりやすいので必ず一読しておいてください。

マイナーバージョンアップグレードの場合はリリースノート で差分を読むのもおすすめです

こちらは必須ではありませんが、特定の問題を回避したい場合などに特定の単語やバグIDで検索したりしてどのバージョンが目的を達成するための最低条件なのかが分かります。

ドキュメントには無いけど…

バージョン間の差分を確認するのに便利なのが日本MySQLユーザー会(MyNA)代表のとみたさんが公開しているMySQL Parametersです

使い方等はとみたさんのブログを参照していただくのが良いですが、パラメータに限らず文字コードやシステムテーブル等まで差分比較ができるので非常に便利です。

便利すぎて、海外の中の人やお客さんまでもが使っていたりしますw

3.レプリケーションを使用している場合

細かいことはドキュメントを読んでもらえばいいんですが、大事なのは

「Read Onlyノードからアップグレードし、Read Writeノードは最後!」

ってことです。(=プライマリとかソース(マスター)を最後にアップグレードする)

4.OSごとにアップグレード手順を確認→手順書作成

各OSごとにアップグレードの手順が微妙に異なります。

とは言っても、Windows以外はコマンドの違いとかだったりで、作業パターンとしては共通だったりします。

なので、他のOSのアップグレード手順に、自分のOSのアップグレード作業時にも役立つ話があったりするので、一通り目を通しておくとよりアップグレード手順というものを理解することができるでしょう。

(時間が惜しい人は関連OSの情報のみ読む感じでOKです)

論理アップグレードとインプレースアップグレード

方法としては大きく分けて2つです。

論理アップグレードインプレースアップグレードです。

論理アップグレードはバックアップを取って、新バージョンのMySQL Serverがインストールされたところにリストアする方法で、

インプレースアップグレードは直接今使っているMySQL Serverをアップグレードする方法です。

論理アップグレードのメリットはアップグレード時やアップグレード後に

「問題が発生したー!Σ(゚д゚lll)ガーン」

ってなった時に切り戻し作業が楽なこと、

インプレースアップグレードのメリットは別インスタンスを作る必要が無い事です。

インプレースアップグレードでやる人は論理アップグレードの方法については読み飛ばせます。

(逆もしかりです)

4-1.論理アップグレードの方法

簡単に言うとインストールして、バックアップ取って、リストアです。

なので、見るべきドキュメントはインストールとバックアップとリストアのものになります。

インストール

Linuxの場合、インストールに関するドキュメントが非常に多く混乱するのはここでしょう。

汎用バイナリを使用したUnix/LinuxへのMySQLのインストール か、

LinuxへのMySQLのインストールに分かれますが、これは最初のほうにあった

対応プラットフォームのページに載っているOSかそうじゃないかで分かれます。

(注:対応プラットフォームのページに載っていないOSにインストールした場合、それは対応プラットフォームでも再現するのであればバグになりますが、そうでない場合そのOS特有の現象とされ、修正されない可能性があります)

対応プラットフォームのページに載っている各LinuxOSごとに用意されているバイナリやインストール方法は以下のように細分化されています。

複数使えたとしても最終的に選ぶのはどれか一つです。関係しそうなものだけ読めばいいでしょう。

Windows(インストール)もいくつかのインストール方法があります。

WindowsについてはインストーラとZIPアーカイブ両方見ておくといいでしょう。なぜなら今後のアップグレードにも役に立つからです。

その他のOSについては以下の通りです。

バックアップとリストア

バックアップのパターンは物理と論理がありますが、それぞれでまた使うツールが変わります。

ここにどのようなバックアップやリストア手法があるかが書かれていますが、論理アップグレードでよく使うのは以下の3つのどれかでしょう。

  • mysqldump
  • MySQL Shellのダンプロードユーティリティ
  • mysqlpump

mysqldump

昔ながらおなじみの論理バックアップの定番、mysqldumpです。

論理アップグレードの手順にもありますが、以下のようなコマンドを実行します。

mysqldump -u root -p
  --add-drop-table --routines --events
  --all-databases --force > data-for-upgrade.sql

インポートは以下のような感じです。(必ずインポート先で!

mysql -u root -p < data-for-upgrade.sql

MySQL Shellのダンプロードユーティリティ

mysqldumpだと処理がシーケンシャルなのでCPUをガッツリ使って並列処理化して高速にバックアップ・リストアしたいと言う方にはMySQL Shellのダンプロードユーティリティがおすすめです。

ダンプはここ、ロードはここのドキュメントをじっくり読んで試してみましょう。

多分最初は慣れが必要ですが、使い方に慣れたころにdumpInstanceやdumpSchemasで必要なものを全て取得するようにします。

例えば以下を実行すると、16スレッドでカレントディレクトリ直下にdb-migrateフォルダを作って、ビューやルーチンやイベントおよびトリガからはDEFINER節を削除した定義を作ります。

util.dumpInstance("db-migrate",{threads: 16 , compatibility: ["strip_definers"]})

ロードはフォルダごと取得元から移動して、以下を実行です。

util.loadDump("db-migrate",{threads: 16})

オプションは色々あって、試してもらえばいいですがそんな複雑なことは無いはずです。テスト環境で色々試して雰囲気を一度つかんでみればそんなに難しくないことが分かると思います。

mysqlpump

残念ながらmysqlpumpMySQL 8.0.34で非推奨(一応使える)となりました。

理由はMySQL Shellのダンプロードユーティリティができたから。

データインポート時は結局シーケンシャルだし、ちょっと致命的なバグもちらほらあったのも原因かもしれません。

それでもmysqldumpっぽく、スキーマ単位ですが、パラレルにダンプを取得できるので、使いたいという人はいるかもしれません。

和訳版を添付しておきますので、使いたい方はご参照ください。

MySQL :: MySQL 8.0 Reference Manual :: 4.5.6 mysqlpump — A Database Backup Program

4-2.OSごとのアップグレード方法(論理以外)

論理アップグレードは既に記載したので、残りはインプレース形式やその他についてです。

Unix/Linux

Windows

インストーラを使ったアップグレードはバージョン間をまたぐアップグレードに使えません。

どうしてもインストーラを使いたい場合は、

  1. 論理アップグレード
  2. 旧Verのアンインストール+新Verのインストール+データディレクトリの付替
  3. マイナーバージョンアップグレードだけ行う となります。

インストーラを使うと良いのはレジストリの情報が更新されるので、一度でもインストーラでインストールした場合には、その後インストーラを使ってアップグレードをする場合に便利な点です。

逆に言うと、メジャーアップグレードでは2のような方法でしかできないので、この後のWindows ZIP ディストリビューションを使用した MySQL のアップグレードと何が違うんだという話にもなりますが、インストーラーから見えるバージョンが更新したい人にはおすすめです。

通常はWindows ZIP ディストリビューションを使用した MySQL のアップグレードがメジャーアップグレードの基本的な方法です。

その他のアップグレード

ソースからビルドですが、最近はツヨツヨなお兄さんたちがビルドで記事書いてくれてたりするんでそっちを見たほうが良いかもしれませんね。(本番環境でそういうのを使う人は稀でしょうが)

4-3.MySQL Serverが8.0.15以前はmysql_upgrade必須

ここはMySQL Serverが8.0.16にアップグレードする人はスキップしても大丈夫です。

但し、5.6から5.7にアップグレードする人は必ず以下のドキュメントを読んでmysql_upgradeを新バージョン起動直後に行ってください。

mysql_upgradeのドキュメント

5.アップグレードチェッカーで事前チェック

ここで作った手順に過不足ないか、事前作業に漏れが無いかがチェックできます。

開発環境に本番環境のバックアップをリストアし、アップグレードチェッカー(MySQL Shellのutil.checkForServerUpgrade()ユーティリティ)でテーブル等に問題が無いかチェックしましょう。

完璧ではありませんが、新機能・追加・非推奨・削除された機能などのチェック漏れができますので、使って損はありません。

6.アップグレードするためのブツを手に入れましょう

コミュニティエディションはここからダウンロードできます。

ここからダウンロードできるのはコミュニティエディションですが、サポート契約をしている人は別の場所から商用版をダウンロードできます。

また、サポート契約をしている人はドキュメント以外の詳細な作業手順や注意点が書かれたナレッジドキュメントを参照することもでき、かつサポートからも対象のバージョンで注意しておく点などを聞くことができます。(宣伝)

7.作業手順書に基づいてLet's Try!!

  • 作業直前にデータベースのバックアップは必ず取りましょう。いざとなったら戻せるように。
  • システム止めていられる時間にはバッファをもっておきましょう。
  • 切り戻しの手順も固めておきましょう。
  • 開発環境で何度もアップグレードと切り戻しのテストをしておきましょう。(作業時間の短縮は作業の慣れに比例する)
  • パフォーマンスの問題が無いかについても開発でしっかり検証しておくのをお勧めします。

8.問題が起きたら?

まずはエラーログを見てみましょう。アップグレード作業中のどこかで [ERROR] となっている箇所があればそれについてググってみましょう。

そして、前述の新機能・追加・非推奨・削除された機能にあった各ページを見て、それらが関係していないか確認してみましょう。

次に以下のドキュメントを読んでみましょう。

どうしてもわからない場合、世の中には多くのMySQLに詳しい人がいます。その人たちにSNS上で聞いてみるのも良いでしょう。

でも彼らもいつでも対応できるわけじゃありません。いざという時にすぐ聞ける人が欲しい!と言う人はサポートに聞けばいいのです。

興味のある方はここから問い合わせができます。

もしくは、明らかにバグだと思われる事象にぶつかったのであれば、バグ登録するのもありです。

調査が進めば開発者達から回避方法や今後の修正方針などのコメントをもらえることがあります。

余談

その1.その他のMySQL製品とか

サーバーをアップグレードするなら、クライアントツール、コネクタ、監視ツール、バックアップツールなどのバージョンが対応しているかも確認が必要です。

アップグレード先のバージョンに対応しているか、あらかじめチェックしておきましょう。

その2.必須ではないけど…

アップグレード前にテーブルたちが健康かどうかをチェックしておくのも大事です。

mysqlcheckCHECK TABLE コマンドでテーブルたちが壊れてないか見ておくことで、普段使ってなかったけどアップグレード時に参照されて「あーーーー」なんてことが無くなります。

その3.魚拓を見る

MySQLのドキュメント、たまにあるんですが

  • 更新されててOSとかのサポートがされてるかわからん
  • URLクリックしたら記事が無い

とかいうことがあります。

そういう時、魚拓を見に行くことを自分もしばしばやります。

自分が使っているのはこれですが、色々あると思うのでそれは各自探してみてください。

更新されてしまっているページのURLの過去の記事を探し、そのスナップショットを見ることで当時はそうだったんだ…と確認できます。

その4.その他の参考資料

日本MySQLのSEチームは定期的にセミナーを開いてくれていますが、そこにもたくさんのアップグレード関連の資料があります。

MySQL :: 資料ダウンロード

どれもその時々のドキュメントを要約し、わかりやすく書かれているものばかりです。

情報が少し古くなっていたとしても、ドキュメントと比べて圧倒的に読みやすく、一度は目を通しておくことをお勧めします。

(僕も読むことで認識の漏れに気付くことが過去に何度もありました。感謝!)

最後に

書いてみて思ったけど、結局書き出してみるとそれなりの量があってやっぱり見るのはツライままかもしれませんw

それに作ってみたけど、これがみんなの役に立つかどうかはわからない。

でも自分で見直す時に良いかもと思って備忘録的に作ってみたということで自己満足にはなりました。

おそらく、新しいバージョンが出れば、気が向いたときに更新すると思います。

サポートしてない方法も含めれば実はアップグレード方法はこの限りではありません。

それでも、ドキュメントにある話を知った上で使うのとそうでないのとではリスクが全然違います。

どうしてもドキュメントにある方法じゃないやり方をするにしてもまずは基本を知っておくべきです。

こんな駄文でも、誰かのお役にも立てれば幸いです。

MySQL Advent Calendar 2023参加者の皆さん、お疲れさまでした。

MySQLにとっても自分たちにとっても来年もいい年になると良いなあ、と思ってます。

では、良いお年を~~~!!

cluster.status()で特定の情報だけ抜き出したい人へ

この記事はMySQL Advent Calendar 2023 8日目の記事です。

今回もMySQL Shellの小ネタです。

cluster.status()でレプリカの遅延情報だけ取得して検知させたい

MySQL Shellのcluster.status()、JSON形式だから特定の情報「だけ」を抜き出せないかなー?という人向け

例)

 MySQL  127.0.0.1:27536 ssl  JS > cluster.status()
{
    "clusterName": "testCluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "127.0.0.1:27536",
        "ssl": "REQUIRED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "127.0.0.1:27536": {
                "address": "127.0.0.1:27536",
                "memberRole": "PRIMARY",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": "applier_queue_applied",
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.35"
            },
            "127.0.0.1:27537": {
                "address": "127.0.0.1:27537",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": "applier_queue_applied",
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.35"
            },
            "127.0.0.1:27538": {
                "address": "127.0.0.1:27538",
                "memberRole": "SECONDARY",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": "applier_queue_applied",
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.35"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "127.0.0.1:27536"
}

レプリカのreplicationLagを抜きたい場合こうする

 MySQL  127.0.0.1:27536 ssl  JS > cluster.status()["defaultReplicaSet"]["topology"]["127.0.0.1:27537"]["replicationLag"]
applier_queue_applied
 MySQL  127.0.0.1:27536 ssl  JS > cluster.status()["defaultReplicaSet"]["topology"]["127.0.0.1:27538"]["replicationLag"]
applier_queue_applied

はい、とれました。

とはいえ…

バッチでゴリゴリぶん回したいとかになってくるとjqとか使うのが良いでしょうね。

今回のはちょっと見てみたいけど、不要な情報見たくない時どーぞ、って感じの話でした。

明日のイルカのお友達は

いつも僕が色々とお世話になってる@meijik さんの「最新のSQL標準(SQL:2023)とFirebird/MySQL/PostgreSQL」です。お楽しみに!

MySQL Shell 8.0.29からはBACKUP_ADMINが不要になりました

この記事はMySQL Advent Calendar 2023 1日目の記事です。

初日なので軽めのネタです。

MySQL Shell8.0.29以降

MySQL Shell でMySQL Server インスタンス(consistentオプション付き)の一貫性ダンプを実行するのにBACKUP_ADMIN権限が必要なくなりました。

対象は

  • インスタンス ダンプ ユーティリティ(util.dumpInstance())、
  • スキーマ ダンプ ユーティリティ(util.dumpSchemas())、
  • テーブル ダンプ ユーティリティ(util.dumpTables())

です

は?だからなに?

クラウド管理のDBって管理者権限ユーザーでも実際はフル権限じゃないし、そいつ自身に権限付与とかできないですよね。

そのユーザーにACKUP_ADMIN権限がついていない場合、この一貫性ダンプ取得しようとするときにエラーになります。

一貫性なんて無視だぜ!(consistent=false)はシステム止められるごくごく一部の人しかできないでしょう。

なので、普通はちゃんとしたバックアップ取得したいけどシステム止められないからconsistent=trueにしたいはずです。

どうすればいいの?

MySQL Shellを8.0.29以上に上げるだけです。

そうすればダンプ取得時にBACKUP_ADMIN権限を求められません。

参照情報

dev.mysql.com

dev.mysql.com

明日のイルカのお友達は

みんな大好き、DBREでおなじみの@_awache さんです。お楽しみに!

MySQL Server8.0.29では何が起きたのか?(リリースノートを眺める)

これは MySQL Advent Calendar 2022 8 日目の記事です。

はじめに

MySQL Server 8.0.29はGAであるにもかかわらず、今はダウンロードすることができません。

(なんかそれ自体闇歴史の最後を飾っても良い話な気がしてきた。きっと誰かが書くだろうw)

それは8.0.29でALGORITHM=INSTANTを使用して追加(削除も含む)されたカラムを持つInnoDBテーブルのデータが正しく解釈されないという重大な問題があるためです。

具体的にはどのような話なのでしょう?

バグの詳細については多くがセキュリティの点から非公開となっているので、公開されているリリースノート等で見ていきましょう。

(リリースノートの和訳についてはDeepLを使ってそのままのものを記載してます。

 わかりにくいからと言ってどういうことかを説明すると書いてはいけないことを

 書いてしまうかもしれませんので、申し訳ないですが英語か翻訳から感じ取ってください)

リリースノートを眺める

現在、リリースノートは8.0.29以降では8.0.308.0.31のものが出ています。

8.0.30のリリースノートより

InnoDB: A TRUNCATE TABLE operation failed to remove data dictionary entries for columns that were dropped using ALGORITHM=INSTANT. Thanks to Marcelo Altmann for the contribution. (Bug #34302445)

訳:TRUNCATE TABLE操作で、ALGORITHM=INSTANTを使用して削除された列のデータ辞書エントリーを削除できない。

ちなみにMarcelo AltmannはOracle ACEでPercona社の人です。この8.0.29とPercona XtraBackupの非互換性の記事や、このバグについての話も書いてますね。

InnoDB: An incorrect nullable column calculation on tables with instantly added columns caused data to be interpreted incorrectly. (Bug #34243694)

訳:即座に追加されるカラムを持つテーブルで、不正なNullableカラムの計算が行われ、データが不正に解釈されることがありました。

InnoDB: After upgrading to MySQL 8.0.29, a failure occurred when attempting to access a table with an instantly added column. (Bug #34233264)

訳:MySQL 8.0.29 にアップグレードした後、即座に追加されたカラムを持つテーブルにアクセスしようとすると失敗することがありました。

InnoDB: Only the physical position of instantly added columns was logged, which was not sufficient for index recovery. The logical position of columns was also required. (Bug #34181432)

訳:即座に追加された列の物理的な位置のみが記録され、インデックスの復元には不十分であった。カラムの論理位置も必要であった。

8.0.31のリリースノートより

InnoDB: After upgrading to a release that supports row versions for columns added or dropped using ALGORITHM-INSTANT, a failure occurred during an instant ADD COLUMN operation on a table with a nullable column and an instantly added column. (Bug #34488482)

訳:ALGORITHM-INSTANT を使用して追加または削除された列の行バージョンをサポートするリリースにアップグレードすると、NULL 可能な列とINSTANTで追加される列を持つテーブルで(ALGORITHM)INSTANT ADD COLUMN 操作中に失敗が発生しました。

InnoDB: A column added using ALGORITHM=INSTANT was visible in read views created before the DDL operation that added the column. (Bug #33937504)

訳:ALGORITHM=INSTANT を使用して追加された列が、列を追加した DDL 操作の前に作成された読み取りビューに表示されていました。

今回の騒動を受けて僕個人が思う事

これはあくまで個人的に思ってることで、会社は一切関係無いんでそこのところだけはご理解ください。

機能追加はマイナーバージョンでするもんじゃない(少なくともGAになってからは)

今回のことがあるまではMySQL何でこんなアップグレード時に機能ぶっこんでくるんだよ!バグが生まれ続けるじゃねーか…、

などと思いつつも、便利になるんなら仕方ないのかなとも思ってたんです。

でも、リリースしたものをダウンロードできなくしたって言うのはあまりにもカッコ悪い。

やはり「機能追加はマイナーバージョンでするもんじゃない」です。(他のRDBMSではあまり見ないですしね)

最新=Bestじゃなくなった

そのせいで気軽にアップグレードしてくださいを言いにくくなりましたよ。

もちろん、今は8.0.31まであるんで特定のバグを解消する方法がアップグレードするしかないんならそれをお勧めしますよ。

しかし新機能が追加されてたら、そいつのせいでまた何か起きるんじゃないかとユーザーは疑心暗鬼になるし、僕としても絶対に無いとは言えないのでそれについてはどうしようもない。

信用をこれ以上失わないためにも今後は新機能追加とか勘弁願いたいし、やるなら8.1だとか9.0だとか別バージョン切ってやって欲しいですわ。

次の8.0.32は1月頃でしょうかね。そこでも何らかの情報は上がってくるかもしれませんが、改良はしても新機能追加だけは勘弁。

yoku0825さん、あなたはホンマに凄い!

この先見の明と野生の勘に中の飼育員もアッパレでした。

ぼくらが選んだ次のMySQL 8.0 / MySQL80 Which We Choose - Speaker Deck

INSTANT DROP COLUMN(と、その影響で任意の個所にINSTANT ADD COLUMNできるようになった)はヤバい

最後に

意外と8.0.29を使っている人を問合せで見かけます。

それは氷山の一角で、サポート外の人たちを含めたら相当数なんじゃないかと思ってます。

早急にアップグレードを検討することをお勧めします。

すぐにはアップグレードが難しければALGORITHM=INSTANT を使用してカラム追加は避けてください。

明日は そんな先見の明と野生の勘を持つ、【現役Oracle ACE】の yoku0825 さんです!

Workbench 8.0.23でPerformance ReportsとPerformance Schema Setupが見えなくなった

いきなり結論

MySQL Workbench 8.0.23以降では以下の画面が表示できません。

  • Performance Reports
  • Performance Schema Setup

まだ直ってなくて、使いたい場合は8.0.22以下にする必要があります。

そもそもPerformance Reportsって?

以下のドキュメントに詳しく書いてあります。

dev.mysql.com

sysスキーマから情報引っ張ってパフォーマンス情報を引っ張ってこれるっていう代物です。

実際に見てみる

8.0.22だと

8.0.22のPR

表示されます

8.0.23以降だと

8.0.23のPR

見えません(なんでやねん!)

解決方法

今のところ8.0.31でも見えないですね…。

バグ登録は既に行ってますが、いつ直るかは不明です。

(ってか、気づかれてなかったってことは誰もこの機能使ってなかったんだな…)

最初に書きましたが、今のところは8.0.22に戻すしか無いです。

まあ、ツヨツヨな人には不要な機能なんでしょうね。

明日は @bluerabbit さんです。