全力で怠けたい

怠けるために全力を尽くしたいブログ。

mysql コマンドのステートメント履歴の削除とか履歴を保存しない設定のメモ。

mysql コマンドは実行する SELECT とか UPDATE ステートメントを記録するので、カーソルキーの上下でステートメント履歴をたどることができる。 ステートメント履歴は便利なんだけどパスワードとかの機密情報は記録したくないとか、過去に実行した UPDATE とか DELETE の履歴は削除したいとかそもそも履歴に残したくないときがあるので、mysql コマンドのステートメント履歴の削除方法とかをメモしておく。

mysql コマンドのステートメント履歴

すべてのステートメント履歴の削除

mysql コマンドは実行したステートメントを履歴ファイルに記録する。

デフォルトでは .mysql_history というファイル名でユーザーのホームディレクトリに記録しているので、.mysql_history を消すとすべてのステートメント履歴を削除できる。

$ rm ~/.mysql_history

個別のステートメント履歴の削除

個別のステートメントの履歴だけ削除するときは .mysql_history の中身を編集する。 エディターで .mysql_history を開いて編集してから保存してもいいし、sed コマンドとかで編集してもいい。

ステートメントの履歴ファイルの指定

mysql コマンドは実行したステートメントをデフォルトでは .mysql_history というファイル名でユーザーのホームディレクトリに記録するけど、履歴ファイルの保存場所は MYSQL_HISTFILE 環境変数で指定できる。 たとえば履歴ファイルをホームディレクトリの .mymysql_history というファイルに保存するなら .bashrc とかに MYSQL_HISTFILE=~/.mymysql_history と追加しておく。

ステートメント履歴を記録しない方法: --batch オプション, --execute オプション

mysql コマンドは対話的に実行しているときだけステートメントを履歴ファイルに保存するので、ステートメントをファイルとかパイプから mysql コマンドに流し込むときはステートメントは履歴ファイルに保存しない。

たとえば以下の select * from sample_table ステートメントは履歴ファイルには保存しない。

$ echo 'select * from sample_table' | mysql -h127.0.0.1 -uroot -proot -P3306

mysql コマンドを実行するときに --batch オプション か --execute オプションを指定することでもステートメントを履歴ファイルに保存するのを抑制できる。

たとえば以下の show databases ステートメントexit ステートメントは履歴ファイルに保存しない。

$  mysql -h127.0.0.1 -uroot -proot -P3306 --batch
show databases;
Database
information_schema
mysql
performance_schema
exit

以下の show databases ステートメントは履歴ファイルに保存しない。

$ mysql -h127.0.0.1 -uroot -proot -P3306 --execute='show databases'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+

任意のステートメントを履歴ファイルに保存しない方法

ステートメントの履歴は保存したいけどパスワードとかの機密情報は保存したくないとか、 SELECT は保存したいけど INSERT, UPDATEDELETE は保存したくないときがあると思う。 任意のステートメントを履歴ファイルに保存したくないときは MYSQL_HISTIGNORE 環境変数--histignore オプションを指定すると履歴ファイルへの保存を抑制できる。

たとえば '*INSERT*'MYSQL_HISTIGNORE 環境変数を指定しておくと以下の use sample_db, select * from sample_tableexit ステートメントは履歴ファイルに保存するけど insert into sample_table values (2) ステートメントは履歴ファイルに保存しない。

$ MYSQL_HISTIGNORE='*INSERT*' mysql -h127.0.0.1 -uroot -proot -P3306

mysql> use sample_db;
mysql> select * from sample_table;
+------+
| id   |
+------+
|    1 |
+------+
1 rows in set (0.00 sec)

mysql> insert into sample_table values (2);
Query OK, 1 row affected (0.01 sec)

mysql> exit
Bye

--histignore オプションでも同じことができる。

たとえば *INSERT*--histignore= オプションに指定すると以下の use sample_db, select * from sample_tableexit ステートメントは履歴ファイルに保存するけど insert into sample_table values (3) ステートメントは履歴ファイルに保存しない。

$ mysql -h127.0.0.1 -uroot -proot -P3306 --histignore='*INSERT*'

mysql> use sample_db;
mysql> select * from sample_table;
+------+
| id   |
+------+
|    1 |
+------+
1 rows in set (0.00 sec)

mysql> insert into sample_table values (3);
Query OK, 1 row affected (0.01 sec)

mysql> exit
Bye

ちなみに mysql コマンドはデフォルトでは *IDENTIFIED*:*PASSWORD* を無視するのでパスワードとかが履歴ファイルに保存されることはない。 MYSQL_HISTIGNORE 環境変数あるいは --histignore オプションを指定すると指定したステートメントがデフォルトの無視リスト(*IDENTIFIED*:*PASSWORD*) に追加される。

すべてのステートメントを履歴ファイルに保存しない方法

すべてのステートメントを履歴ファイルに保存したくないときは履歴ファイルを /dev/null へのシンボリックリンクにしてしまえばよい。

たとえば履歴ファイルが ~/.mysql_history なら以下のコマンドを実行すれば以後すべてのステートメントは履歴ファイルに保存しなくなる。

$ ln -s /dev/null ~/.mysql_history

あるいは /dev/nullMYSQL_HISTFILE 環境変数指定しておくことでもすべてのステートメントを履歴ファイルに保存しないようにできる。 たとえば .bashrc とかに MYSQL_HISTFILE=/dev/null と書いておくとよい。

参考ページ

curl コマンドでメッセージを Slack に post するメモ。

Slack はデスクトップアプリとかブラウザーで使っているけど CLI からメッセージを post したりファイルをアップロードしたりがちょいちょいあるので、curl コマンドでメッセージを Slack に post したりするのをメモしておく。

curl コマンドでメッセージを Slack に post

シンプルなメッセージ

curl コマンドでシンプルなメッセージを Slack に post するには chat.postMessage メソッドを使う。

$ curl --request POST \
        --form channel=${SLACK_CHANNEL} \
        --form token=${SLACK_TOKEN} \
        --form 'text=Hello World!' \
        https://slack.com/api/chat.postMessage

SLACK_CHANNEL はメッセージを post する Slack のチャンネルとかグループの ID を指定する。 ブラウザーで Slack を表示するとアドレスバーが https://app.slack.com/client/xxxxxxxxx/yyyyyyyyy みたいになっていると思うので yyyyyyyyy の部分を指定すればよい。 SLACK_TOKEN は Slack OAuth トークンを指定しておく。

ファイルのアップロード

curl コマンドでファイルを Slack に upload するには files.upload メソッドを使う。

 curl --request POST \
     --form channels=${SLACK_CHANNEL} \
     --form token=${SLACK_TOKEN} \
     --form file=@${FILEPATH} \
     --form title=タイトル \
     --form initial_comment=コメント \
     https://slack.com/api/files.upload

FILEPATH はアップロードするファイルのパスを指定する。

参考ページ

sar コマンドでよく使うオプションのメモ (CPU とメモリ)

sar コマンドでわりとよく使うオプションのうち CPU とメモリに関するメモ。

普段は AWS の EC2 インスタンスに入って使うことが多いのでこのエントリーを書くときも EC2 インスタンスに入って sar コマンドを実行した結果とかをメモっている。

sar コマンドのバージョン。

$ sar -V
sysstat version 10.1.5

sar コマンドのオプション

sar コマンドはプロセスのメモリ、プロセス、スワップ、ディスク IO、ネットワーク、ロードアベレージ、CPU ……等の統計情報を表示するコマンド。

システムの一通りの情報が揃っているので「なにか変だな」みたいなときはまず使ってみる、みたいな使い方をすることが多いように思う。

sar コマンドはリアルタイムの統計情報を取得して表示することのほかに過去の統計情報を表示することもできるが、このページではリアルタイムの統計情報の表示についてメモしておく。

自分はなんとなく使うことが多い気がするのでよく使うオプションをメモしておく => オプションがかなり多いので CPU とメモリに関してメモしておく

-h オプション: ヘルプ

-h オプションを指定すると sar コマンドの使い方を表示する……んだけど man sar が使えないときにしか使わない。

$ sar -h
Usage: sar [ options ] [ <interval> [ <count> ] ]
Main options and reports:
    -b  I/O and transfer rate statistics
    -B  Paging statistics
    -d  Block device statistics
    -F [ MOUNT ]
        Filesystems statistics
    -H  Hugepages utilization statistics
    -I { <int> | SUM | ALL | XALL }
        Interrupts statistics
    -m { <keyword> [,...] | ALL }
# 省略

interval, count

オプションじゃないんだけど sar コマンドでリアルタイムの統計情報を取得するときは必ずといっていいほど指定するやつ。

sar みたいに interval なしで実行するとこんな感じで起動 (再起動) してからシステムが一定間隔で記録してくれている統計情報を表示するんだけど、

$ sar

12:25:16 PM       LINUX RESTART

12:30:01 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
12:40:01 PM     all      0.01      0.00      0.02      0.00      0.00     99.96
12:50:01 PM     all      0.01      0.00      0.02      0.00      0.00     99.97
01:00:01 PM     all      0.02      0.00      0.01      0.00      0.00     99.97
01:10:01 PM     all      0.01      0.00      0.02      0.00      0.01     99.96
Average:        all      0.01      0.00      0.02      0.00      0.00     99.97

sar 5 みたいに interval を指定すると指定した interval 秒ごとに表示を更新する。

$ sar 5

01:21:41 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:21:46 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:21:51 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:21:56 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:22:01 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:22:06 PM     all      0.00      0.00      0.00      0.00      0.00    100.00

sar 5 3 みたいに interval と count を指定すると指定した interval 秒ごとに count 回分だけ表示を更新する。

$ sar 5 3

01:22:46 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:22:51 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:22:56 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:23:01 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
Average:        all      0.00      0.00      0.00      0.00      0.00    100.00

-u: CPU 使用率の表示

-u オプションを指定すると CPU 使用率を表示する。

sar コマンドは表示するリソースをオプションで指定しないときは -u オプションを指定するときと同じように動くので sarsar -u は実質同じ。

表示項目の単位はパーセンテージ。

$ sar -u 5 2

02:04:21 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
02:04:26 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
02:04:31 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
Average:        all      0.00      0.00      0.00      0.00      0.00    100.00

ALL を指定するとすべての表示項目を出力する。

$ sar -u ALL 5 2

02:05:00 PM     CPU      %usr     %nice      %sys   %iowait    %steal      %irq     %soft    %guest    %gnice     %idle
02:05:05 PM     all      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00    100.00
02:05:10 PM     all      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00    100.00
Average:        all      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00    100.00

-u オプションを指定して CPU 使用率を表示するときの表示項目について軽くメモしておく。

表示項目の単位はパーセンテージ。

項目 意味
%user カーネル以外が CPU を使用した時間。仮想マシンの実行に使用した時間も含まれる
%usr カーネル以外が CPU を使用した時間。仮想マシンの実行に使用した時間は含まれない
%nice nice 値を変更しているプロセスが CPU を使用した時間
%system カーネルが CPU を使用した時間。ハードウェア割り込みとソフトウェア割り込みの処理に使用した時間も含まれる
%sys カーネルが CPU を使用した時間。ハードウェア割り込みとソフトウェア割り込みの処理に使用した時間も含まれる
%iowait IO 待ちで CPU がアイドルだった時間
%steal 仮想マシンから盗まれた時間 ※
%irq ハードウェア割り込みの処理に CPU を使用した時間
%soft ソフトウェア割り込みの処理に CPU を使用した時間
%guest 仮想マシンの実行に CPU を使用した時間
%gnice nice 値を変更している仮想マシンの実行に CPU を使用した時間
%idle CPU がアイドルだった時間

%steal: 仮想マシンから盗まれた時間

仮想マシンから盗まれた時間」とはなにを意味するのか。

sar の man page は以下が書いてある。

Percentage of time spent in involuntary wait by the virtual CPU or CPUs while the hypervisor was servicing another virtual processor.

Google 翻訳にかけると ハイパーバイザーが別の仮想プロセッサーにサービスを提供している間に、1つまたは複数の仮想CPUが不本意に待機した時間の割合 って感じで、OS が仮想マシン (仮想サーバー) 上で動いているときに意味を持ってくる値で、仮想マシンが CPU を要求するけど CPU の使用率の上限が決められていて仮想マシンが CPU を利用できないときとか、仮想マシンが CPU を要求するけど 他の仮想マシンが CPU を使いまくってて CPU を利用できないときに %steal が上昇する。

自分は普段あまり %steal の上昇は見ないような気がするけど AWS の EC2 の t2 とかのバーストパフォーマンスインスタンスを使ってるときに見たりする。 たとえば、t2 インスタンスとかで CPU をぶん回して CPU バーストして CPU 使用率が 100% に張り付くような状態を続けていくといずれ CPU クレジットを使い切って CPU 使用率が落ちていく。 このへんを sar で見てると %steal の値が上昇していくのが分かる。

プログラムが仮想マシン上で動いていて CPU 使用率はそんなに高くないんだけど CPU バウンドっぽい……みたいなときは %steal の値が上昇しているかチェックしてみるのがよさそう。

-P: コアごとの CPU 使用率の表示

-P オプションを指定するとコアごとの CPU 使用率を表示する。

表示項目の単位はパーセンテージ。

-P オプションはどのコアの CPU 使用率を表示するかも指定することができる。

-P オプションに続けて ALL を指定するとすべてのコアそれぞれの CPU 使用率とすべてのコアの合計の CPU 使用率を表示する。 CPU のところにどのコアかが表示する。コアは 0 始まり。

t2.micro インスタンスで sar コマンドを実行しているのでコアが1つしかないが、複数コアがあるときはコアごとの情報を出力する。

$ sar -P ALL 5 2

01:41:58 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:42:03 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:42:03 PM       0      0.00      0.00      0.00      0.00      0.00    100.00

01:42:03 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:42:08 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:42:08 PM       0      0.00      0.00      0.00      0.00      0.00    100.00

Average:        CPU     %user     %nice   %system   %iowait    %steal     %idle
Average:        all      0.00      0.00      0.00      0.00      0.00    100.00
Average:          0      0.00      0.00      0.00      0.00      0.00    100.00

-P オプションに続けて表示するコアを指定すると指定したコアそれぞれの CPU 使用率を表示する。 CPU のところにどのコアかが表示する。コアは 0 始まり。

$ sar -P 0 5 2

01:47:33 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:47:38 PM       0      0.00      0.00      0.00      0.00      0.00    100.00
01:47:43 PM       0      0.00      0.00      0.00      0.00      0.00    100.00
Average:          0      0.00      0.00      0.00      0.00      0.00    100.00

-r: メモリ使用率の表示

-r オプションを指定するとメモリ使用率を表示する。

表示項目の単位はキロバイト

$ sar -r 5 2

01:50:11 PM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
01:50:16 PM    536276    470688     46.74      2088    347508    191396     19.01    160256    220424       296
01:50:21 PM    536276    470688     46.74      2088    347508    191396     19.01    160256    220424       296
Average:       536276    470688     46.74      2088    347508    191396     19.01    160256    220424       296

-r オプションを指定してメモリ使用率を表示するときの表示項目について軽くメモしておく。

表示項目の単位はキロバイト

表示項目 意味
kbmemfree 使用可能な空きメモリの量
kbmemused 使用中のメモリの量。カーネルが使用中のメモリの量は含まない
%memused メモリ使用率
kbbuffers カーネルがバッファとして使用中のメモリの量
kbcached カーネルがキャッシュとして使用中のメモリの量
kbcommit システムの動作に必要な事前に確保されているメモリの量 (RAM + swap)
%commit システムの動作に必要な事前に確保されているメモリの総メモリ量に対する割合 (RAM + swap) ※
kbactive アクティブなメモリの量 (最近使用されたメモリ。絶対に必要がない限り通常は再利用されないメモリ)
kbinact アクティブではないメモリの量 (最近使用されたメモリ。他に用途があれば再利用されるメモリ)
kbdirty ディスクに書き戻すのを待機しているメモリの量

カーネルはオーバーコミット (実メモリ以上にメモリをプロセスに割り当てる) することがあるので %commit は 100% 以上になることがある。

参考ページ

vmstat コマンドでよく使うオプションのメモ。

vmstat コマンドでわりとよく使うオプションのメモ。

普段は AWS の EC2 インスタンスに入って使うことが多いのでこのエントリーを書くときも EC2 インスタンスに入って vmstat コマンドを実行した結果とかをメモっている。

vmstat コマンドのバージョン。

$ vmstat --version
vmstat from procps-ng 3.3.10

vmstat コマンドのオプション

vmstat コマンドはプロセスのメモリ、プロセス、スワップ、IO、割り込みと CPU の情報を表示するコマンド。

vmstat コマンドの名前の由来は virtual memory statistics だと思うんだけど、メモリだけじゃなくてシステムの一通りの情報が揃っているので「なにか変だな」みたいなときはまず使ってみる、みたいな使い方をすることが多いように思う。

自分はなんとなく使うことが多い気がするのでよく使うオプションをメモしておく。

--help オプション: ヘルプ

--help オプションを指定すると vmstat コマンドの使い方を表示する……んだけど man vmstat が使えないときにしか使わない。

$ vmstat --help

Usage:
 vmstat [options] [delay [count]]

Options:
 -a, --active           active/inactive memory
 -f, --forks            number of forks since boot
 -m, --slabs            slabinfo
 -n, --one-header       do not redisplay header
 -s, --stats            event counter statistics
 -d, --disk             disk statistics
 -D, --disk-sum         summarize disk statistics
 -p, --partition <dev>  partition specific statistics
 -S, --unit <char>      define display unit
 -w, --wide             wide output
 -t, --timestamp        show timestamp

 -h, --help     display this help and exit
 -V, --version  output version information and exit

delay, count

オプションじゃないんだけど vmstat コマンドを使うときは必ずといっていいほど指定するやつ。

vmstat みたいに delay なしで実行するとこんな感じで起動 (再起動) してからの平均値を表示するんだけど、

$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 579228   2088 348192    0    0    84   123   90 2074 10 17 72  0  0

vmstat 5 みたいに delay を指定すると指定した delay 秒ごとに表示を更新する。

$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 579360   2088 348192    0    0    80   117   87 1977 10 16 73  0  0
 0  0      0 579352   2088 348192    0    0     0     0   27   50  0  0 100  0  0
 0  0      0 579352   2088 348192    0    0     0     8   22   40  0  0 100  0  0
 0  0      0 579352   2088 348192    0    0     0     0    4    7  0  0 100  0  0
 0  0      0 579352   2088 348192    0    0     0     0    5   10  0  0 100  0  0
 0  0      0 579352   2088 348192    0    0     0     0    7    9  0  0 100  0  0

vmstat 5 3 みたいに delay と count を指定すると指定した delay 秒ごとに count 回分だけ表示を更新する。

$ vmstat 5 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 579360   2088 348192    0    0    80   117   87 1977 10 16 73  0  0
 0  0      0 579352   2088 348192    0    0     0     0   27   50  0  0 100  0  0
 0  0      0 579352   2088 348192    0    0     0     8   22   40  0  0 100  0  0

-t, --timestamp オプション: 日時を表示する

vmstat --timestamp 5 みたいに -t オプションか --timestamp オプションを指定すると日時も表示する。

$ vmstat --timestamp 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st                 UTC
 0  0      0 579388   2088 348196    0    0    72   105   79 1777  9 15 76  0  0 2020-02-20 12:10:25
 0  0      0 579380   2088 348196    0    0     0     0   24   46  0  0 100  0  0 2020-02-20 12:10:30
 0  0      0 579380   2088 348196    0    0     0     3   23   44  0  0 100  0  0 2020-02-20 12:10:35
 0  0      0 579256   2088 348196    0    0     0     4   35   56  0  0 100  0  0 2020-02-20 12:10:40
 0  0      0 579256   2088 348196    0    0     0     0   23   45  0  0 100  0  0 2020-02-20 12:10:45

-n, --one-header オプション: ヘッダーは最初の1回だけ表示

vmstat 5 とか実行すると定期的 (ウィンドウのサイズによる) にヘッダー行を表示するけど -n オプションか --one-header オプションを指定するとヘッダーは最初の1回だけ表示する。

-S, --unit オプション: メモリの単位を指定する

memory の表示単位はキロバイトがデフォルトだけど -S オプションか --unit オプションを指定すると memory の表示単位を変更できる。

-S オプションと --unit オプションに指定できる値と表示単位は以下のとおり。

指定できる値 表示単位
k キロバイト (KB)
K キビバイト (KiB)
m ガバイト (MB)
M メビバイト (MiB)

vmstat コマンドの表示項目

vmstat コマンドの表示項目について軽くメモしておく。

procs

プロセスの情報。 r + b = ロードアベレージ

項目 意味
r 実行中もしくは実行待ちのプロセス数
b ディスク I/O やロック待ちのプロセス数

memory

メモリの情報。

項目 意味
swpd 使用中の仮想メモリの量
free 空きメモリの量
buff バッファとして使用中のメモリの量
cache キャッシュとして使用中のメモリの量
inact アクティブになっていないメモリの量
active アクティブになっているメモリの量

swap

スワップの情報。

項目 意味
si ディスクからスワップインしているメモリの量。KB / 秒
so ディスクにスワップアウトしているメモリの量。 KB / 秒

io

IO の情報。

項目 意味
bi HDD のようなブロックデバイスから1秒あたりに受け取ったブロック数
bo HDD のようなブロックデバイスに1秒あたりに送ったブロック数

system

項目 意味
in 1秒あたりの割り込み回数。タイマー割り込みを含む
cs 1秒あたりのコンテキストスイッチ回数

cpu

CPU の情報。 単位はトータル CPU 時間におけるパーセンテージ。

項目 意味
us ユーザー CPU 時間。カーネル以外が CPU を使用した時間
sy システム CPU 時間。カーネルが CPU を使用した時間
id CPU がアイドル状態だった時間
wa プロセスが IO 待ちだった時間
st 仮想マシンから盗まれた時間 ※

st: 仮想マシンから盗まれた時間とは

仮想マシンから盗まれた時間」とはなにを意味するのか。

vmstat の man page は Time stolen from a virtual machine とだけ書いてあってなんのことかよく分からないんだけど vmstat と同じくシステムの負荷監視系コマンドの sar の man page が分かりやすい。

Percentage of time spent in involuntary wait by the virtual CPU or CPUs while the hypervisor was servicing another virtual processor.

Google 翻訳にかけると ハイパーバイザーが別の仮想プロセッサーにサービスを提供している間に、1つまたは複数の仮想CPUが不本意に待機した時間の割合 って感じで、OS が仮想マシン (仮想サーバー) 上で動いているときに意味を持ってくる値で、仮想マシンが CPU を要求するけど CPU の使用率の上限が決められていて仮想マシンが CPU を利用できないときとか、仮想マシンが CPU を要求するけど 他の仮想マシンが CPU を使いまくってて CPU を利用できないときに st が上昇する。

自分は普段あまり st の上昇は見ないような気がするけど AWS の EC2 の t2 とかのバーストパフォーマンスインスタンスを使ってるときに見たりする。 たとえば、t2 インスタンスとかで CPU をぶん回して CPU バーストして CPU 使用率が 100% に張り付くような状態を続けていくといずれ CPU クレジットを使い切って CPU 使用率が落ちていく。 このへんを vmstat で見てると st の値が上昇していくのが分かる。

プログラムが仮想マシン上で動いていて CPU 使用率はそんなに高くないんだけど CPU バウンドっぽい……みたいなときは st の値が上昇しているかチェックしてみるのがよさそう。

参考ページ

ps コマンドでよく使うオプションのメモ。

ps コマンドでわりとよく使うオプションのメモ。

普段は AWS の EC2 インスタンスに入って使うことが多いのでこのエントリーを書くときも EC2 インスタンスに入って ps コマンドを実行した結果とかをメモっている。

ps コマンドのバージョン。

$ ps --version
procps-ng version 3.3.10

ps コマンドのオプション

ps コマンドはプロセスの情報を表示するコマンド。

自分はなんとなく使うことが多い気がするのでよく使うオプションをメモしておく。

--help オプション: ヘルプ

--help オプションを指定すると ps コマンドの使い方を表示する……んだけど man ps が使えないときにしか使わない。

$ ps --help all

Usage:
 ps [options]

Basic options:
 -A, -e               all processes
 -a                   all with tty, except session leaders
  a                   all with tty, including other users
 -d                   all except session leaders
 -N, --deselect       negate selection
  r                   only running processes
  T                   all processes on this terminal
  x                   processes without controlling ttys

# 省略

--no-header オプション: ヘッダーを表示しない

--no-header オプションを指定するとヘッダーを表示しない。

オプションなしの psPID とか TTY とかヘッダーを表示するけど、

$ ps
  PID TTY          TIME CMD
 3288 pts/0    00:00:00 bash
22180 pts/0    00:00:00 ps

--no-header オプションを指定すると PID とか TTY とかのヘッダーを表示しない。

$ ps --no-header
 3288 pts/0    00:00:00 bash
22180 pts/0    00:00:00 ps

u オプション: プロセスの詳細情報を表示

u オプションを指定するとプロセスの詳細情報を表示する。

$ ps u
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
ec2-user  3288  0.0  0.3 125068  4004 pts/0    Ss   14:01   0:00 -bash
ec2-user 22117  0.0  0.4 124992  4140 pts/1    Ss   14:02   0:00 -bash
ec2-user 22199  0.0  0.3 126116  3524 pts/1    S+   14:15   0:00 man ps
ec2-user 22210  0.0  0.2 117300  2624 pts/1    S+   14:15   0:00 less -s
ec2-user 25636  0.0  0.4 164368  4060 pts/0    R+   14:37   0:00 ps u

-f オプション: プロセスの情報を完全なフォーマットで表示

-f オプションを指定するとプロセスの情報を完全なフォーマットで表示する。 親子関係のプロセスをツリー表示してくれる。

$ ps -fu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
ec2-user 22117  0.0  0.4 124992  4140 pts/1    Ss   14:02   0:00 -bash
ec2-user 22199  0.0  0.3 126116  3524 pts/1    S+   14:15   0:00  \_ man ps
ec2-user 22210  0.0  0.2 117300  2624 pts/1    S+   14:15   0:00      \_ less -s
ec2-user  3288  0.0  0.3 125068  4004 pts/0    Ss   14:01   0:00 -bash
ec2-user 25649  0.0  0.4 164368  4084 pts/0    R+   14:40   0:00  \_ ps -fu

e オプション: 環境変数を表示

e オプションを指定すると COMMAND カラムのコマンドの表示のあとにプロセスの環境変数を表示する。

$ ps e
  PID TTY      STAT   TIME COMMAND
 3288 pts/0    Ss     0:00 -bash LC_ALL=ja_JP.UTF-8
22117 pts/1    Ss     0:00 -bash LC_ALL=ja_JP.UTF-8

-L オプション: プロセスとスレッドを表示

-L オプションを指定するとプロセスとスレッドを表示する。

ps -C dockerd すると dockerd のプロセスは1つだけ表示するけど、

$ ps -C dockerd
  PID TTY          TIME CMD
  885 ?        00:00:04 dockerd

-L オプションを追加するとたくさん表示する。 増えた表示の分がスレッド。

スレッドはたくさん表示するけど PID は全部同じなので表示しているスレッドが同じプロセスのスレッドであることが分かる。 スレッド ID はLWP のところに表示する。

$ ps -L -C dockerd
  PID   LWP TTY          TIME CMD
  885   885 ?        00:00:00 dockerd
  885   981 ?        00:00:00 dockerd
  885   982 ?        00:00:00 dockerd
  885   983 ?        00:00:00 dockerd
  885   984 ?        00:00:00 dockerd

# 省略

-A, -e オプション: すべてのプロセスを表示

-A オプションか -e オプションを指定するとすべてのプロセスを表示する。

man ページの -A オプションの説明のところは select all processes. Identical to -e と書いてあって -A オプションと -e オプションはまったく同じ。

オプションなしの ps はちょっとしかプロセスを表示しないけど、

$ ps
  PID TTY          TIME CMD
 3288 pts/0    00:00:00 bash
22180 pts/0    00:00:00 ps

ps -e するとプロセスがたくさん表示される。

$ ps -e
  PID TTY          TIME CMD
    1 ?        00:00:01 systemd
    2 ?        00:00:00 kthreadd
    4 ?        00:00:00 kworker/0:0H
    5 ?        00:00:00 kworker/u30:0
    6 ?        00:00:00 mm_percpu_wq
    7 ?        00:00:00 ksoftirqd/0
    8 ?        00:00:00 rcu_sched

a オプション: 端末を持つプロセスを表示

a オプションを指定すると端末を持つすべてのプロセスを表示する。

端末を持つプロセスであれば他のユーザーのプロセスも表示する。 a オプションを指定すると表示されるプロセスは当然のことながら端末を持っているので TTY のところが tty とか pts みたいになる。

x オプションと組み合わせて使うことが多い => x オプション参照

$ ps a
  PID TTY      STAT   TIME COMMAND
 3202 tty1     Ss+    0:00 /sbin/agetty --noclear tty1 linux
 3203 ttyS0    Ss+    0:00 /sbin/agetty --keep-baud 115200,38400,9600 ttyS0 vt220
 3288 pts/0    Ss     0:00 -bash
22117 pts/1    Ss     0:00 -bash
22160 pts/1    S+     0:00 man ps
22171 pts/1    S+     0:00 less -s
22196 pts/0    R+     0:00 ps a

x オプション: 端末を持たないプロセスを表示

x オプションを指定すると端末を持たないすべてのプロセスを表示する。

$ ps x
  PID TTY      STAT   TIME COMMAND
 3287 ?        S      0:00 sshd: ec2-user@pts/0
 3288 pts/0    Ss     0:00 -bash
22116 ?        S      0:00 sshd: ec2-user@pts/1
22117 pts/1    Ss     0:00 -bash
22199 pts/1    S+     0:00 man ps
22210 pts/1    S+     0:00 less -s
25561 pts/0    R+     0:00 ps x

x オプションと a オプションを組み合わせると端末を持たないプロセスと端末を持つプロセスを表示するので表示するプロセスの数は -e オプションを指定するときと同じになる。 => 表示するときのカラムが違うとかの相違がある

$ ps -e | wc -l
90

$ ps ax | wc -l
90

r オプション: 実行中のプロセスだけ表示

r オプションを指定すると実行中もしくは実行可能状態のプロセスだけ表示する。

ps u すると何個かのプロセスが表示するけど、

$ ps u
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
ec2-user  3288  0.0  0.3 125068  4004 pts/0    Ss   14:01   0:00 -bash
ec2-user 22117  0.0  0.4 124992  4140 pts/1    Ss   14:02   0:00 -bash
ec2-user 22199  0.0  0.3 126116  3524 pts/1    S+   14:15   0:00 man ps
ec2-user 22210  0.0  0.2 117300  2624 pts/1    S+   14:15   0:00 less -s
ec2-user 25631  0.0  0.3 164368  3940 pts/0    R+   14:30   0:00 ps u

r オプションを追加して ps ru すると STATR(R+) のプロセスだけ表示する。

$ ps ru
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
ec2-user 25633  0.0  0.3 164368  4008 pts/0    R+   14:30   0:00 ps ru

-C オプション: 実行ファイル名を指定して表示

-C オプションで実行ファイル名を指定すると指定した実行ファイルのプロセスだけ表示する。

ps u すると何個かのプロセスが表示するけど、

$ ps u
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
ec2-user  3288  0.0  0.4 125068  4168 pts/0    Ss   14:01   0:00 -bash
ec2-user 22117  0.0  0.4 124992  4140 pts/1    Ss   14:02   0:00 -bash
ec2-user 22199  0.0  0.3 126116  3524 pts/1    S+   14:15   0:00 man ps
ec2-user 22210  0.0  0.2 117300  2624 pts/1    S+   14:15   0:00 less -s
ec2-user 25758  0.0  0.4 164368  4064 pts/0    R+   15:07   0:00 ps u

-C オプションで -C bash みたいに指定すると bash だけ表示する。

$ ps u -C bash
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
ec2-user  3288  0.0  0.4 125068  4168 pts/0    Ss   14:01   0:00 -bash
ec2-user 22117  0.0  0.4 124992  4140 pts/1    Ss   14:02   0:00 -bash

ps コマンドのオプションでちょっと気にしておくこと

ps コマンドのバージョンによってはいくつかのオプション形式に対応している。

e オプション (環境変数を表示) と -e オプション (すべてのプロセスを表示) みたいに - があるかないかでまったく意味が違うオプションがある。

This version of ps accepts several kinds of options:

1   UNIX options, which may be grouped and must be preceded by a dash.
2   BSD options, which may be grouped and must not be used with a dash.
3   GNU long options, which are preceded by two dashes.

EBS ボリュームを EC2 インスタンスに追加と削除する方法。

EC2 を運用中にディスクが足りなくなったので EBS ボリュームを追加とアタッチをして、ついでにデタッチと削除したときのメモ。

EBS ボリュームの追加

EC2 インスタンスが追加の EBS ボリュームを使うためには EBS ボリュームの作成と EC2 インスタンスへのアタッチをしていく。

追加する EBS ボリュームの作成

今回は汎用 SSD (gp2) の EBS ボリュームを作成して EC2 インスタンスへアタッチしていく。

作業開始前の EC2 インスタンスの状態。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         475M     0  475M    0% /dev
tmpfs            492M     0  492M    0% /dev/shm
tmpfs            492M  404K  492M    1% /run
tmpfs            492M     0  492M    0% /sys/fs/cgroup
/dev/xvda1       8.0G  1.5G  6.6G   19% /
tmpfs             99M     0   99M    0% /run/user/1000

EBS ボリュームを作成する。 EBS ボリュームは追加先の EC2 インスタンスと同じアベイラビリティゾーンに作成する必要があるので追加先の EC2 インスタンスが稼働しているアベイラビリティゾーンを確認しておくこと。

$ aws ec2 create-volume \
    --availability-zone <アベイラビリティゾーン> \
    --no-encrypted --volume-type gp2 \
    --size 30

EBS ボリュームを EC2 インスタンスへアタッチ

作成した EBS ボリュームを EC2 インスタンスへアタッチする。

$ aws ec2 attach-volume --device /dev/xvdf --instance-id <EC2 インスタンス ID> --volume-id <作成した EBS ボリュームの ID>
{
    "AttachTime": "2020-02-13T13:57:31.721Z",
    "InstanceId": "<EC2 インスタンス ID>",
    "VolumeId": "<作成した EBS ボリュームの ID>",
    "State": "attaching",
    "Device": "/dev/xvdf"
}

EBS ボリュームの状態が in-use になると EC2 インスタンスから見えるようになる。

$ aws ec2 describe-volumes --volume-ids <作成した EBS ボリュームの ID> | jq -r '.Volumes[].State'
in-use

EBS ボリュームのファイルシステムの作成

作ったばかりの EBS ボリュームはファイルシステムがないのでファイルシステムを作成していく。

ファイルシステムを作成する前に今どうなってるか確認。 lsblk コマンドを実行すると EC2 インスタンス/dev/xvdf にアタッチした EBS ボリュームが見えるようになっている。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0  30G  0 disk

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         475M     0  475M    0% /dev
tmpfs            492M     0  492M    0% /dev/shm
tmpfs            492M  408K  492M    1% /run
tmpfs            492M     0  492M    0% /sys/fs/cgroup
/dev/xvda1       8.0G  1.5G  6.6G   19% /
tmpfs             99M     0   99M    0% /run/user/1000

file コマンドで /dev/xvdf を見るとまだファイルシステムを作成していないので data とだけ出力される。

$ sudo file -s /dev/xvdf
/dev/xvdf: data

mkfs コマンドで /dev/xvdfファイルシステムを作成していく。

$ sudo mkfs -t xfs /dev/xvdf
meta-data=/dev/xvdf               isize=512    agcount=4, agsize=1966080 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0
data     =                       bsize=4096   blocks=7864320, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=3840, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

file コマンドで /dev/xvdf を見ると XFS ファイルシステムが作成されていることが分かる。

$ sudo file -s /dev/xvdf
/dev/xvdf: SGI XFS filesystem data (blksz 4096, inosz 512, v2 dirs)

EBS ボリュームのマウント

マウントポイントのディレクトリを作成してボリュームをマウントしていく。 今回は /dev/xvdf/data にマウントしていく。

$ sudo mkdir /data
$ sudo mount /dev/xvdf /data

df コマンドを実行すると /dev/xvdf/data にマウントされているのが分かる。

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         475M     0  475M    0% /dev
tmpfs            492M     0  492M    0% /dev/shm
tmpfs            492M  464K  492M    1% /run
tmpfs            492M     0  492M    0% /sys/fs/cgroup
/dev/xvda1       8.0G  1.5G  6.6G   19% /
tmpfs             99M     0   99M    0% /run/user/1000
tmpfs             99M     0   99M    0% /run/user/0
/dev/xvdf         30G   63M   30G    1% /data

EBS ボリュームを作成して EC2 インスタンスから使えるようにする手順は以上。

EBS ボリュームの削除

EC2 インスタンスが使っている EBS ボリュームを削除するためには EBS ボリュームのアンマウントと EC2 インスタンスからのデタッチをしていく。 必要なデータが EBS ボリュームに入っているときは作業を進める前にデータを別の場所に移したりコピーなど取得しておく。

EBS ボリュームのアンマウント

$ sudo umount -d /dev/xvdf

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         475M     0  475M    0% /dev
tmpfs            492M     0  492M    0% /dev/shm
tmpfs            492M  464K  492M    1% /run
tmpfs            492M     0  492M    0% /sys/fs/cgroup
/dev/xvda1       8.0G  1.5G  6.6G   19% /
tmpfs             99M     0   99M    0% /run/user/1000
tmpfs             99M     0   99M    0% /run/user/0

EBS ボリュームのデタッチ

$ aws ec2 detach-volume --volume-id <削除する EBS ボリュームの ID>
{
    "AttachTime": "2020-02-13T13:58:31.000Z",
    "InstanceId": "<EC2 インスタンスの ID>",
    "VolumeId": "<削除する EBS ボリュームの ID>",
    "State": "detaching",
    "Device": "/dev/xvdf"
}

EBS ボリュームが EC2 インスタンスからデタッチが完了すると EBS ボリュームの状態が available になる。

$ aws ec2 describe-volumes --volume-ids <削除する EBS ボリュームの ID> | jq -r '.Volumes[].State'
available

EBS ボリュームの削除

$ aws ec2 delete-volume --volume-id <削除する EBS ボリュームの ID>

EBS ボリュームを EC2 インスタンスからデタッチして削除する手順は以上。

参考ページ

K6 を実行したら "connect: cannot assign requested address" がでたときにやったこと。

k6 で WEB サーバーに負荷をかけると "connect: cannot assign requested address" みたいなメッセージが表示されたときにやったこと。

k6 run すると "connect: cannot assign requested address" みたいなメッセージが大量に表示される

WEB サーバーに負荷をかけるために k6 run --vus <でかい数> --iterations <でかい数> --no-vu-connection-reuse script.js みたいに k6 run すると connect: cannot assign requested address というメッセージが大量に表示される。 表示されているメッセージを見た感じだと k6エフェメラルポートを使い尽くしてソケットをバインドできていないっぽいので k6 run しながら TIME_WAIT のポート数を数えてみるとたくさんあった。 やっぱり k6エフェメラルポートを使い尽くしてソケットをバインドできていないっぽい。

$ netstat -anp | grep TIME_WAIT | wc -l
28223

ちなみに k6 のバージョンは 0.26.0.

$ k6 version
k6 v0.26.0 (2019-12-16T11:07:36+0000/v0.26.0-0-gaeec9a7f, go1.13.5, linux/amd64)

やったこと

k6エフェメラルポートを使い尽くしてソケットをバインドできないのは --no-vu-connection-reuse オプションを指定しなければ k6TCP コネクションを再利用するようになるので解決できる……のだが、理由があって TCP コネクションは毎回貼り直すようにしたかったので --no-vu-connection-reuse オプションは指定しておきたい。 k6 を実行するマシンは他の用途には使わないので、お行儀がよくないけど TIME_WAIT のポートを再利用するようにした。

$ sysctl net.ipv4.tcp_tw_reuse
net.ipv4.tcp_tw_reuse = 0

$ sudo sysctl -w net.ipv4.tcp_tw_reuse=1

$ sysctl net.ipv4.tcp_tw_reuse
net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_reuse = 1 にしてから k6 run すると connect: cannot assign requested address みたいなメッセージが表示されなくなり、モリモリと WEB サーバーに負荷をかけられるようになった。