モヒカンメモ

髪色が定期的に変わることに定評のある(比較的)若者Webエンジニアの備忘録

PHPUnit 7系が2020年2月でサポート終了するぞ!バージョンアップを急げ!

PHPでデファクトスタンダードなテスティングツール PHPUnit の7系バージョンが2020年2月7日でサポートが終了します。

ざっくりまとめ

  • PHPUnit 7系(あるいはそれ以下)を使っているひとは、PHPUnit 8系へ乗り換えましょう
  • PHPUnit 8系はPHP7.2以上が必須。7.1以下の人は先にPHPのバージョンアップを計画しましょう

f:id:pinkumohikan:20191207174810p:plain
2020年2月でサポート終了

phpunit.de

github.com

PR

この記事は若手ものづくりコミュニティ Oysters のAdvent Calendar 2019にかこつけて書きました。

adventar.org

サポート終了するとどうなる?

PHPUnitはメジャーバージョンのリリースから2年がサポート期限で、既に4, 5, 6はサポート終了済み。現行は7系と8系で、7系はもうじきサポート終了です。

一般的にはサポートが切れるとそれ以降、改善がされなかったり、バグが修正されなかったり、ドキュメントが公式サイトから消去されて行ったり、脆弱性が見つかっても放置されたりします。

なので、サポート期限が来る前に新しいバージョンへ追従していくのが基本です。

え?そんな工数割けない?じゃあ最初からOSSなんて使わなければ良かったのに(真顔で火の玉ストレート攻撃ズドーン)

PHPUnit 7系から8系って何が変わる?

phpunit.de

大きなところでいうと

  • PHP 7.2が最低サポートバージョンになる
    • PHP 7.1以下の環境ではそもそもinstallできなくなる
  • ライフサイクル系メソッド (setUpとかtearDownとか) のreturn typeとして void が明示される
    • テストクラスでそれらを使っている場合、同じように void を明示しないとmethod signatureが合わないぞって怒られる
  • いくつかのアサーションメソッド、アノテーションがdeprecatedに
    • assertArraySubsetは個人的には好きだったのでちょっとショック

どんな流れでバージョンアップすれば良い?

だいたいいつもこんな感じで上げています。

  1. 手元でcomposer updateコマンドでPHPUnitをバージョンアップ
  2. 脳死でテストを走らせる
  3. 出てくるwarningやerrorをissueにまとめ、怒られのパターンを見る
  4. えいやで行けそうな数ならえいやで直す、そうでなければ怒られパターンごとに分割して直す
    • このとき現行バージョンでも動く変更を心がけ、バージョンアップのPRとは切り離して先行リリースしていくと変更の影響範囲を狭められてオススメです
  5. PHPUnitのバージョンアップをリリース (master等へmerge)

最後に

PHPUnitに限らず、OSSを使うならバージョンアップは割けて通れないと考えています。目先の工数削減のために脳死で使うんじゃなくて、OSS採用の際にはバージョンアップへの追従コストも考えましょう。また、バタバタしながらのビッグバン変更にならないよう、こまめに計画的にアップデートしていきましょう。

自分の前職では毎週、OSSのバージョンアップをやっていました。とても良い文化だなと思って自分の周りや今の職場でも普及活動中をしているところです。

techlog.voyagegroup.com

awscliで 'AWSHTTPSConnection' object has no attribute 'server_hostname' って怒られたときにやったこと

ざっくりまとめ

  • awscliをインストールして使おうとしたら何か怒られた
  • よく分からんけど、aptでインストールするのやめてpipで入れ直したら直った

起きたこと

とあるUbuntuサーバへawscliをインストールして、aws configureして、awsコマンドを叩いたところ下記のようなエラーが置きた

$ sudo apt install awscli
...

$ aws s3 ls
fatal error: 'AWSHTTPSConnection' object has no attribute 'server_hostname'

アイヤー、謎のエラー

エラーメッセージ的にはこっちの設定が悪いとかでは無さそうな雰囲気を感じる、良く分からんけど

やったこと

Try 1: 再インストール

エラーメッセージでぐぐったら、再インストールしたら直ったよ記事がいくつかヒットしたので試してみた

$ sudo apt remove awscli
...


$ sudo apt install awscli
...

$ aws s3 ls
fatal error: 'AWSHTTPSConnection' object has no attribute 'server_hostname'

ハイダメー!!!

Try 2: pipで入れ直す

何も考えずにaptでインストールしたけど、そう言えばいつもawscliはpipでインストールしていたのを思い出した

pipで入れ直してみる

$ sudo apt remove awscli
...

$ sudo pip3 install awscli
Traceback (most recent call last):
  File "/usr/bin/pip3", line 9, in <module>
    from pip import main
ImportError: cannot import name 'main'

あらやだ(たまに起こるけど、rootとしてログインしてからなら通るのでそれ以上調べる気にならずなんでこうなるのかちゃんと理解していない人の顔)

$ sudo --login pip3 install awscli
...
Successfully installed awscli-1.16.283

$ aws s3 ls
-bash: /usr/bin/aws: No such file or directory

チッ (aptで入れていたs3コマンドへのpathが通ったままなのでloginしなおす)

$ aws s3 ls
2019-11-16 18:23:14 very-nice-na-bucket

勝った

Laravelのレートリミットミドルウェアについて調べた

ざっくりまとめ

  • Laravelには任意のエンドポイントに対してレートリミットを行うためのミドルウェアが用意されている
  • 1分当たり10リクエストまで、という感じで制限可能
  • ログイン中ならユーザ、そうでなければIPアドレス単位でカウントされる

レートリミットとは

1分間に10回まで実行してよい、みたいな感じで制限を課すこと。Web APIや高負荷な集計/エクスポート機能といった、必要だがむやみに連打されたくない機能で利用することが多い

Laravelには、レートリミット機能を提供するミドルウェアが標準で用意されている

laravel.com

あんまりドキュメントには情報がないのでコードを追った

参考にしたコードは、Laravel 6.5リリース時点のもの

実装的にはこの辺から: https://github.com/laravel/framework/blob/v6.5.0/src/Illuminate/Routing/Middleware/ThrottleRequests.php

制限の単位

何分当たり何リクエストまで、という感じで指定可能

誰がどのぐらいリクエストしてきたかは内部的にはcacheで管理される

制限を超えると、ステータスコード429を返す

ユーザにこの画面を見せるわけにはいかないので、ちゃんと適切なエラーページを用意してあげよう

使い方

throttle:$何回まで,$何分間のうちに みたいな感じでミドルウェアを指定すれば使える

公式ドキュメントに乗っている下記の例だと、1分間に60回までリクエストを許すという設定になる

Route::middleware('auth:api', 'throttle:60,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});

61回目のリクエストからは 429 Too Many Requests というエラーが表示される

f:id:pinkumohikan:20191113140120p:plain
429 Too Many Requests

CircleCIのDocker Layer Cachingが有料 & だいぶ高価になっていた

ざっくりまとめ

  • CircleCIのDocker Layer Caching (DLC) がパフォーマンスプラン (従量課金) の有料機能になっていた
  • DLCが有効だと、ジョブが1回走る度にVMを20分間動かしたのと同じぶんのクレジットを消費する
  • クレジットは減ったら自動チャージで課金されるので、ガンガン課金されてCI破産しないようにご注意を

Docker Layer Caching (DLC) とはなにか

docker build時の中間キャッシュ (Layer cache) を再利用する仕組み。前回のビルドから変更がなかった分の中間キャッシュを再利用できれば、その続きからのビルドのみで済むのでCI時間を短縮できる

過去の使ってみた記事 (2018年): blog.pinkumohikan.com

いつの間にか有料になっていた

自分が先の記事を書いた2018年5月時点では無料プランでも使えたが、2019年頭ぐらいから有料オプションになっていたらしい (詳細な時期は不明)

2019年11月現在では、DLCを使うにはパフォーマンスプラン (従量課金) を契約する必要がある

Docker レイヤー キャッシュを自分の環境で有効化するには?

Docker レイヤー キャッシュを利用するには、Performance プランのアカウントが必要です。

circleci.com

そして利用料はそれなりに高い

パフォーマンスプランは毎月クレジットが割り当てられ、(基本的には) CI実行時のリソース使用量に応じてクレジットが減っていく。クレジット残量は少なくなると自動でチャージされる ( = 課金される)。

DLCの利用料は、1ジョブ実行で200クレジット消費とのこと

f:id:pinkumohikan:20191108134610p:plain

MediumサイズのLinux環境 (2コア 4Gメモリ) を1分間動かすと10クレジット消費らしいので、 1ジョブ実行でVMを20分間動かしたのと同じ分のクレジットが消費されることになる

f:id:pinkumohikan:20191108134633p:plain

金額になおすと25,000クレジット = $15とすると1ジョブ実行 200クレジット = $0.12

CI高速化のためにビルドマトリックスで何ジョブも並列で走る設計にしていたり、開発者数が多かったりしたらチリツモでそれなりの額になるやも

アイヤー

徳丸基礎試験の試験結果が届いた

8月頭にウェブセキュリティ基礎試験(徳丸基礎試験)のベータ試験を受けて、ついに今日、試験結果が届いた。

f:id:pinkumohikan:20191016213017j:plain:w300
職場の先輩にもらったモンスターエナジー。もちろん、本記事には全く関係がない

試験結果

受験直後の記事で私はこう言いました:

blog.pinkumohikan.com

ちなみに今回の試験としては手応え十分なのでまあ受かっているんじゃないかな。もしこれで落ちていたら木の下に埋めてもらっても構わないよ!

そして結果:

f:id:pinkumohikan:20191016210423p:plain
合格だよ

ぱんぱかぱーん、 無事徳丸試験 第一号合格者になりました🎉

早速Wantedlyの資格欄にも反映w

f:id:pinkumohikan:20191023204606p:plain

でも目標としていた正答率には届かず

正直、言うても基礎レベルだし9割は取れるでしょって思ってました。

f:id:pinkumohikan:20191016212116p:plain
9割取る自信発言

が、実際には87.5%。惜しいですが未達は未達ーーーー。悔しい。

カテゴリごとの正答率レポートがついていたので、それを見てだめだったところを復習します。

反省します

P.S.

自転車の前輪と後輪は基本同じなので入れ替えても意味がないらしいです。なんやねん。

徳丸試験(ウェブセキュリティ試験)を受けてきた

セキュリティ界隈で有名な徳丸さん監修のウェブセキュリティ試験(通称: 徳丸試験)を受けてきた。

peatix.com

動機

今回、徳丸試験を受けようと思った動機は下記の通り。

  1. 事業開発会社でWebアプリケーションを設計、実装する仕事をしており、Webアプリケーションの安全性についても責任がある
  2. Webエンジニアとしての強みを増やすため
  3. "徳丸試験 第1号合格者" という響きがかっこいい

試験対策

下記2冊の本を参考書として利用した。

f:id:pinkumohikan:20190804204950j:plain
初代徳丸本、二代目徳丸本、徳丸本コンプリートセット

受験申し込みから試験当日まで1ヶ月も無かったので徳丸本を通読するのは厳しいと思って赤本を先に読んだが、振り返ってみると試験対策としてはそのまま徳丸本を読んだほうが時間効率が良いように感じた。赤本は軽くWebセキュリティを抑えたい人や、PMやお客さんからセキュリティ予算 (工数) をもぎ取るために知識武装したい人にオススメ。

学習法は、軽く参考書を通読して、新たに学びになったところや良く分からなかったところに付箋を貼り、数日後に付箋を貼ったところを重点的に読み返す、というもの。過去問があればまず過去問を解いて苦手なところを見つたりするが、今回はなにせ第一回なので過去問など存在しないw

f:id:pinkumohikan:20190804205609j:plain
付箋貼って数日後に振り返る勉強法

感想

徳丸本は新卒内定者時代に一度読んで、当時はチンプンカンプンでとても苦労した覚えがある。職業エンジニアになって5年ぐらい経った今、改めて読むと概ね「分かる〜」って感じだったので基礎体力はしっかり出来ているようだ、良かった。

巷では不正アクセスや情報漏えいの話を良く聞くので、この業界でご飯食べて生きていくにはセキュリティ知識は欠かせないものになってきたと感じる。でも、一口にセキュリティと言っても幅も深さもあって「どこまで勉強すればええねん」ってなりがち。そういった意味で、試験という形なハッキリと合否がでるので「一旦の目標として、徳丸試験基礎レベルに合格出来るぐらいまで頑張ってみよっか!」って言えるのはとても良さそう。

ちなみに今回の試験としては手応え十分なのでまあ受かっているんじゃないかな。もしこれで落ちていたら木の下に埋めてもらっても構わないよ!結果が分かるのは3ヶ月後。楽しみにしてよう。

今回の学習の成果をいい感じに仕事で発揮して、給料アップにつなげるぞ 💰💰💰💰💰💰

P.S.

予言通り合格して、第一号合格者になりました 🎉

blog.pinkumohikan.com

mysqldumpしたら "unknown option '--show-warnings'" と怒られる問題

概要

f:id:pinkumohikan:20190721203820p:plain

背景

mysqlやmysqldumpなどのコマンドを実行するとき、 .my.cnf という名前の設定ファイルを用意しておくと文字コードやホスト名、パスワードなどのオプションを省略することができる。

dev.mysql.com

自分は下記のように show-warnings というオプションを設定していた。mysqlコマンドでは通常、warningの出るDB操作を行ってもwarningは表示されないが、このオプションを設定しておくとコンソールに警告メッセージを表示してくれるようになる。警告を握りつぶして良いことなど何一つとしてないので、必ず指定しておきたいオプションだ。

.my.cnf

[client]
show-warnings

警告の例

mysql> drop table if exists db.not_found_table;
Query OK, 0 rows affected, 1 warning (0.01 sec)

Note (Code 1051): Unknown table 'db.not_found_table'

だが、この設定をしたままmysqldumpを実行すると下記のように怒られてしまう。

$ mysqldump dump_target_table
mysqldump: [ERROR] unknown option '--show-warnings'.

原因と対策

原因は show-warnings オプションはmysqlコマンドにはあるがmysqldumpにはないため、存在しないオプション指定してんじゃねえぞと怒られているわけである。

解決策としては、 show-warnings オプションを [client] というgroupではなく [mysql] というgroupに記載すれば、mysqlコマンドのときだけオプションを適用することができた。

before

[client]
show-warnings

after

[mysql]
show-warnings

ドキュメントとしてはこの辺り:

dev.mysql.com

If an option group name is the same as a program name, options in the group apply specifically to that program. For example, the [mysqld] and [mysql] groups apply to the mysqld server and the mysql client program, respectively.

The [client] option group is read by all client programs provided in MySQL distributions (but not by mysqld). To understand how third-party client programs that use the C API can use option files, see the C API documentation at Section 28.7.7.50, “mysql_options()”.

これでmysqldumpを実行するときだけ show-warnings をコメントアウトするというつらい運用から開放される!

Ubuntu 18.04.2 LTSへtracerouteコマンドをインストールする

Ubuntu 18環境でネットワーク経路を確認しようとtracerouteコマンドを使おうとしたら入ってなかったのでシュパッとインストールする

f:id:pinkumohikan:20190715172330p:plain
traceroute --version

tracerouteコマンドとは

特定のIPやホストへのネットワーク経路や疎通を確認するためのコマンド

詳しくは:

tech.nikkeibp.co.jp

Ubuntu 18.04.2 LTSにはデフォルトではインストールされていない

インフラ屋か、構築直後しか使わないし、しょうがないね

$ traceroute

Command 'traceroute' not found, but can be installed with:

sudo apt install inetutils-traceroute
sudo apt install traceroute

おや、二個勧められたぞ?

www.gnu.org

inetutils-tracerouteは、GNUのやつなので安心感がありそう

sourceforge.net

tracerouteは、少ない権限で動いたり何かモダンらしい (SOURCEFORGEのdescription読んだだけw)

inetutils-tracerouteとtraceroute、どちらを使うべきか?

ぱっと調べた感じではtracerouteがおすすめっぽい

理由は、それぞれで blog.pinkumohikan.com への経路を調べたところ、 inetutils-traceroute ではオプションいじいじしても目的ホストまでたどり着けなかったが traceroute を使えばすんなりたどり着けたため

この記事も参考にした:

j3iiifn.hatenablog.com

ということでtracerouteのパッケージをインストール

$ sudo apt install traceroute
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  traceroute
0 upgraded, 1 newly installed, 0 to remove and 9 not upgraded.
Need to get 45.4 kB of archives.
After this operation, 152 kB of additional disk space will be used.
Get:1 http://nova.clouds.archive.ubuntu.com/ubuntu bionic/universe amd64 traceroute amd64 1:2.1.0-2 [45.4 kB]
Fetched 45.4 kB in 1s (35.1 kB/s)
Selecting previously unselected package traceroute.
(Reading database ... 175935 files and directories currently installed.)
Preparing to unpack .../traceroute_1%3a2.1.0-2_amd64.deb ...
Unpacking traceroute (1:2.1.0-2) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Setting up traceroute (1:2.1.0-2) ...
update-alternatives: using /usr/bin/traceroute.db to provide /usr/bin/traceroute (traceroute) in auto mode
update-alternatives: using /usr/bin/lft.db to provide /usr/bin/lft (lft) in auto mode
update-alternatives: using /usr/bin/traceproto.db to provide /usr/bin/traceproto (traceproto) in auto mode
update-alternatives: using /usr/sbin/tcptraceroute.db to provide /usr/sbin/tcptraceroute (tcptraceroute) in auto mode

すんなり入った

$ traceroute --version
Modern traceroute for Linux, version 2.1.0
Copyright (c) 2016  Dmitry Butskoy,   License: GPL v2 or any later

お試しで調査してみる

$ traceroute --icmp blog.pinkumohikan.com
You do not have enough privileges to use this traceroute method.
socket: Operation not permitted

おおん!? 少ない権限で動くとは何だったのか

$ sudo traceroute --icmp blog.pinkumohikan.com
traceroute to blog.pinkumohikan.com (13.115.18.61), 30 hops max, 60 byte packets
 1  xxx.g.tyo1.static.cnode.io (xxx.xxx.xxx.xxx)  0.918 ms  0.988 ms  1.096 ms
 2  g-o-4eb-a13-4-v-712.interq.or.jp (157.7.41.129)  6.723 ms  6.833 ms  6.961 ms
 3  unused-133-130-013-013.interq.or.jp (133.130.13.13)  0.754 ms  0.855 ms  0.965 ms
 4  unused-133-130-012-034.interq.or.jp (133.130.12.34)  0.856 ms  0.965 ms  1.029 ms
 5  16509.tyo.equinix.com (203.190.230.53)  0.600 ms  0.604 ms  0.604 ms
 6  * * *
 7  * * *
 8  54.239.52.93 (54.239.52.93)  2.063 ms  1.693 ms  1.560 ms
 9  52.95.30.38 (52.95.30.38)  0.560 ms  0.566 ms  0.651 ms
10  * * *
11  * * *
12  * * *
13  52.95.31.55 (52.95.31.55)  2.160 ms  2.135 ms  2.151 ms
14  52.95.31.173 (52.95.31.173)  1.720 ms  1.692 ms  1.691 ms
15  52.95.31.158 (52.95.31.158)  3.173 ms  3.199 ms  3.215 ms
16  52.95.31.72 (52.95.31.72)  2.948 ms  3.509 ms  3.500 ms
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

失敗しとるやんけw

ICMPだと無理っぽいけど、TCP SYNを使うモードを見つけたので試してみる

$ sudo traceroute --tcp blog.pinkumohikan.com
traceroute to blog.pinkumohikan.com (13.115.18.61), 30 hops max, 60 byte packets
 1  xxx.g.tyo1.static.cnode.io (xxx.xxx.xxx.xxx)  0.910 ms  1.024 ms  1.045 ms
 2  g-o-4eb-a13-4-v-712.interq.or.jp (157.7.41.129)  1.107 ms  1.326 ms  1.527 ms
 3  unused-133-130-013-013.interq.or.jp (133.130.13.13)  0.614 ms  0.630 ms  0.619 ms
 4  unused-133-130-012-034.interq.or.jp (133.130.12.34)  0.774 ms  0.717 ms  0.844 ms
 5  16509.tyo.equinix.com (203.190.230.53)  1.041 ms  1.033 ms  1.030 ms
 6  * * *
 7  * * *
 8  54.239.52.89 (54.239.52.89)  1.954 ms 54.239.52.103 (54.239.52.103)  9.649 ms 54.239.52.107 (54.239.52.107)  1.492 ms
 9  52.95.30.44 (52.95.30.44)  0.988 ms 52.95.30.48 (52.95.30.48)  0.996 ms 52.95.30.60 (52.95.30.60)  0.870 ms
10  * * *
11  * * *
12  * * *
13  52.95.31.19 (52.95.31.19)  2.169 ms 52.95.31.43 (52.95.31.43)  2.507 ms 52.95.31.47 (52.95.31.47)  2.097 ms
14  52.95.31.221 (52.95.31.221)  2.020 ms 52.95.31.183 (52.95.31.183)  2.802 ms 52.95.31.215 (52.95.31.215)  2.092 ms
15  52.95.31.168 (52.95.31.168)  2.189 ms 52.95.31.188 (52.95.31.188)  4.170 ms 52.95.31.172 (52.95.31.172)  3.172 ms
16  52.95.31.86 (52.95.31.86)  2.249 ms 52.95.31.72 (52.95.31.72)  3.035 ms  2.943 ms
17  27.0.0.158 (27.0.0.158)  2.431 ms * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  ec2-13-115-18-61.ap-northeast-1.compute.amazonaws.com (13.115.18.61)  1.688 ms  2.683 ms  2.617 ms
24  ec2-13-115-18-61.ap-northeast-1.compute.amazonaws.com (13.115.18.61)  1.945 ms  2.926 ms  2.171 ms

いけた 🎉

docker alpineイメージでtimezoneをAsia/Tokyoに設定する

なぜやるか

dockerで良く使われる軽量イメージalpineは、デフォルトtimezoneがUTCになっており、Asia/Tokyo (JST) に設定しないと日本時間から9時間ずれてしまう。

どうやるか

Dockerfileに下記のように記せばOK

FROM alpine:latest

RUN apk --no-cache add tzdata && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    apk del tzdata

するとほら、この通り

$ docker build . -t alpine-jst
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM alpine:latest
...
Successfully tagged alpine-jst:latest

$ docker run --rm alpine-jst date
Fri Jul 12 07:52:07 JST 2019

補足: なぜ && でつなげたり、tzdataを削除するのか

Dockerfileのベストプラクティスに従うと必然的にこうなる。

docs.docker.jp

  • cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime のあたり必要なものは既にコピー済みなのでもうパッケージとしてtzdataをインストールしておく理由がない
  • alpine使うくらいなので少しでもイメージサイズ小さくするために余計なものは積極的に削除する

開発用だとかお試し目的ぐらいならそこまでやらなくても良いと思う。

mysqldumpコマンドで "Unknown table 'COLUMN_STATISTICS' in information_schema (1109)" と怒られる原因と対策

エラーメッセージ

mysqldump コマンドでMySQL上のデータのバックアップを取ろうとしたとき、下記のようなエラーが出た。

mysqldump: Couldn't execute 'SELECT COLUMN_NAME, JSON_EXTRACT(HISTOGRAM, '$."number-of-buckets-specified"') FROM information_schema.COLUMN_STATISTICS WHERE SCHEMA_NAME = '$db_name' AND TABLE_NAME = '$table_name';': Unknown table 'COLUMN_STATISTICS' in information_schema (1109)

原因

MySQL 8以降に付属するmysqldumpでそれ以前のMySQL 5.7とかのサーバに対してダンプを実行したらこの問題が起こるらしい。

serverfault.com

MySQL 8以降ではオプティマイザがヒストグラム統計というものを考慮するようになったため、mysqldumpもdumpをloadする際にヒストグラム統計をリセットさせる目的でANALYZE TABLE文を自動生成しようとする。そのときinformation_schema.COLUMN_STATISTICSを参照するが、そのテーブルがあるのはMySQL 8.0以降なのでそれ以前のバージョンのMySQLだと怒られが発生する、という具合のようだ。

対策

この問題はmysqldumpコマンドに --skip-column-statistics というオプションを設定して、ANALYZE TABLE文の自動生成をやめさせることで回避できる。

$ mysqldump --version
mysqldump  Ver 8.0.16 for osx10.14 on x86_64 (Homebrew)

$ mysqldump --help
...
  --column-statistics Add an ANALYZE TABLE statement to regenerate any existing
                      column statistics.
                      (Defaults to on; use --skip-column-statistics to disable.)
...

このように、先のオプションをつけたら確かにエラーが出なくなった 。

$ mysqldump --skip-column-statistics --host ...

先の対策の副作用

dumpのloadした際にヒストグラム統計を更新しない副作用としては、dumpをloadした先がMySQL 5.7以下なら特に無く、MySQL 8.0以降なら分析系のクエリでオプティマイザの判断が少し狂うかもしれない、ということらしい (日本男児さんブログからの受け売り)。

nippondanji.blogspot.com

テーブル統計情報のヒストグラム MySQL 8.0では、オプティマイザがテーブル統計情報のヒストグラムを活用できるようになった。WHERE句の条件にマッチする行が、テーブルスキャンによってどの程度に絞り込まれるかということを見積もることによって、敢えてスキャンを選ぶべきかどうかが分かる。リアルタイム性が高い処理ではインデックスをバッチリ使用するように最適化することが多いのでヒストグラムの出番は無いだろうが、分析系の処理では重宝することもあるだろう。

参考にした資料

serverfault.com

dev.mysql.com

nippondanji.blogspot.com

yoku0825.blogspot.com

dev.mysql.com