mysqldump を pv で制限

mysqldump 動いてる時間に同サーバで GNU social とか Nextcloud とかの mysql を利用しているアプリケーションが重くて使い物にならないです.nice + ionice は指定していますが効いてない感じ.
dump した sql を圧縮している xz コマンドが cpu を1 core 使い潰しているようです.このマシンは2 core あるのですが,もう1つの core もその他の処理でほぼ使い切って待ちが出ているような感じ.

$ vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0 328212 264788 212260 5628192    1    2    35   160    2   15 35  9 44 12  0
 1  1 328212 259136 212264 5628192    0    0     0   191 1497 3132 63  6 19 12  0
 1  1 328212 252492 212264 5628192    0    0     0    88  959 1716 81  6  7  6  0
 2  1 328212 248264 212264 5628196    0    0     0   114  973 1887 85  3  7  5  0
 2  0 328212 242572 212264 5628196    0    0     0    85  972 1967 74  5 15  5  0
 4  0 328212 241664 212100 5624380    0    0     0    97 1106 4226 91  7  2  2  0
 2  1 328212 234268 212100 5624384    0    0     0   140 1013 1815 70  5 19  7  0
 3  0 328212 235760 211944 5620076    0    0     0  2461 1289 4063 94  4  1  0  0
 1  0 328212 229656 211944 5620080    0    0     0   110  953 1685 61  6 18 15  0
 1  0 328212 224616 211952 5620072    0    0     0   151  983 1683 84  2  8  6  0

pv -L で帯域絞ってみました.
cpu の様子を見ながらだんだん絞っていって 128k 迄絞ってやっと xz の cpu 25〜40% 位になりました.この状態だと普通に使える感じです.
しばらくこれで試してみます.

pv で帯域制限
$ time sh -c "nice -n 19 ionice -c 3 mysqldump --defaults-file=/backup/micro/.my-backup.cnf --single-transaction --quick
--all-databases --events | pv -L 128k 2>/dev/null | nice -n 19 ionice -c 3 xz -9 > /dev/null"

real 127m16.113s
user 34m30.508s
sys 0m23.428s
cronでの実行
$ sudo -u backup crontab -l | grep mysqldump
14 3 * * *     umask 0266 && nice -n 19 ionice -c 3 /usr/bin/mysqldump --defaults-file=/mnt/backup/micro/.my-backup.cnf --single-transaction --quick --all-databases --events | pv -L 128k 2>/dev/null | nice -n 19 ionice -c 3 /usr/bin/xz -9 > /mnt/backup/micro/`date +\%F_\%T_$$`.sql.xz
環境
$ dpkg-query -W mysql-client-5.7 pv xz-utils
mysql-client-5.7        5.7.23-0ubuntu0.16.04.1
pv      1.6.0-1
xz-utils        5.1.1alpha+20120614-2ubuntu2
$ lsb_release -d
Description:    Ubuntu 16.04.5 LTS
$ uname -m
x86_64
$ grep -m1 model\ name /proc/cpuinfo
model name      : AMD Athlon(tm) II Neo N36L Dual-Core Processor

GNU coreutils の dd に プログレスオプションがあった

dd の進捗は SIGUSR1 を投げると覚えていたのですが,man を眺めていると status=progress というオプションがあるのに気づきました.

manより
status=LEVEL
       The LEVEL of information to print to stderr; 'none' suppresses
       everything but error messages, 'noxfer' suppresses  the  final
       transfer  statistics,  'progress' shows periodic transfer sta‐
       tistics

2015-07-03 の GNU coreutils 8.24 で入ったようです.

dd accepts a new status=progress level to print data transfer statistics
on stderr approximately every second.

これまでも独自パッチでddにプログレスを出すようにするものなどはありましたがGNU ddに導入されていたんですね.気づきませんでした.

てことで試してみます.まずは従来の方法から.

dd開始
$ dd if=/dev/urandom of=/dev/null count=99999 &
[1] 19386
killコマンドで USER1 シグナルを投げる
$ kill -USR1 19522
2294+0 レコード入力
2293+0 レコード出力
2404384768 bytes (2.4 GB, 2.2 GiB) copied, 11.0258 s, 218 MB/s
killallコマンドでpidではなくプロセス名を指定
$ killall -USR1 dd
15648+1 レコード入力
15647+1 レコード出力
16407664896 bytes (16 GB, 15 GiB) copied, 76.1063 s, 216 MB/s

※pkillを使うと部分一致になるので意図しないプロセスにシグナルを送ってしまうことがあるので注意

$ pgrep dd
2
70
3937
$ ps 2 70 3937
  PID TTY      STAT   TIME COMMAND
    2 ?        S      0:00 [kthreadd]
   70 ?        I<     0:00 [ipv6_addrconf]
 3937 pts/9    R      0:13 dd if=/dev/urandom of=/dev/null bs=1M count=99999
watchコマンドで定期的に実行
$ watch killall -USR1 dd
98448+3 レコード入力
98447+3 レコード出力
103231407040 bytes (103 GB, 96 GiB) copied, 487.072 s, 212 MB/s
 :
ddコマンド実行時にpvコマンドを挟む
$ cat /dev/urandom | pv | dd of=/dev/null bs=1M count=99999
1.06GiB 0:00:06 [ 182MiB/s] [     <=>                                        ]
pvコマンドでファイル出力
$ pv /dev/urandom | dd of=/dev/null bs=1M count=99999
 502MiB 0:00:03 [ 170MiB/s] [  <=>                                           ]
ddの status=progress オプションを利用
$ dd if=/dev/urandom of=/dev/null bs=1M count=99999 status=progress
1910505472 bytes (1.9 GB, 1.8 GiB) copied, 9 s, 212 MB/s

流石に純正だけあっていい感じですね.問題はいざ使うときに思い出せるかという…….pvが覚えやすくて便利なんですよね.

そもそもdd使わずGNU ddrescue を使う?まあ大抵の用途ではそっちのほうが良いかもです.

試した環境
$ dd --version
dd (coreutils) 8.28
Copyright (C) 2017 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

作者 Paul Rubin、 David MacKenzie、および Stuart Kemp。
$ dpkg-query -W coreutils
coreutils       8.28-1
pv      1.6.6-1
$ lsb_release -d
Description:    Debian GNU/Linux unstable (sid)
$ uname -m
x86_64