この記事は MySQLのカレンダー | Advent Calendar 2023 の7日目の記事です。
6日目は けんつ さんの MySQL いい感じにコントリビュートする方法(非公式) - それが僕には楽しかったんです。 でした。
TL;DR
- なんの変哲もないよく使うワンライナーです。SQLだけでできたり使ったりするものは入っていない気がする
バージョンxxx移行yyy未満、みたいなのをやりたい
- MySQLは内部的にも
メジャーバージョン番号 * 10000 + マイナーバージョン番号 * 100 + リリース番号
みたいな計算式をよく使っているのでそれに倣う
$ mysql -sse "SELECT @@version" | awk -F"[.-]" '{printf("%d%02d%02d\n", $1, $2, $3)}'
- MySQL 5.7とそれ以降に限定するなら
sys
スキーマの関数を使っても引ける
$ mysql -sse "SELECT sys.version_major() * 10000 + sys.version_minor() * 100 + sys.version_patch()"
バイナリログだけのサイズを合計したい
$ mysql -sse "SHOW BYNARY LOGS" | awk '{i += $2}END{print i}' | numfmt --to=iec
(番外)リレーログだけのサイズを合計したい
SHOW BINARY LOGS
みたいなのが無いので、厳密にやろうとすると大変 (relay_log_basename
をたどったりとか)。おとなしく*relay*
で引いちゃうのが良いんではないか。
$ ls -l /path/to/datadir/*relay* | awk '{i += $5}END{print i}' | numfmt --to=iec
master_info_repositoryからCHANGE REPLICATION SOURCE TOステートメントを作る
- 急に
perl
が出てくるのはawk
だとシングルクォートが面倒だったから
$ mysql -sse "SELECT host, port, user_name, user_password, enabled_auto_position FROM mysql.slave_master_info WHERE channel_name = ''" | perl -nlaE 'printf(qq{CHANGE REPLICATION SOURCE TO source_host = "%s", source_port = %d, source_user = "%s", source_password = "%s", source_auto_position = %d;\n}, @F)'
(番外) master.infoファイルからCHANGE REPLICATION SOURCE TOステートメントを作る
cat
で取った内容を一度変数に詰めるとspace seperatedな1行に出来ることを利用している- ワンライナーじゃない(∩゚д゚)アーアーきこえなーい
master.info
の並び順は一応ドキュメントに解説されているけれど、将来変わるかも知れないしそもそもmaster_info_repository=FILE
自体が非推奨になったので微妙。
$ line=$(cat master.info)
$ echo $line | while read dummy dummy dummy master_host master_user master_password master_port dummy ; do
printf "CHANGE MASTER TO master_host = '%s', master_port = %d, master_user = '%s', master_password= '%s';\n" $master_host $master_port $master_user $master_password
done
ダメなクエリが延々流れてきてCPUが詰まっているのでとにかく来た順番にKILLしたい
- grep次第で特定のクエリに絞ったり絞らなかったりができるあたりがよく使う所以か
$ mysql -sse "SHOW PROCESSLIST" | grep -v 'system user' | grep -v 'Binlog Dump' | awk -F"\t" -v timelimit=10 '$6 > timelimit && $5 != "Sleep"{print $1}' | while read id ; do
mysql -e "KILL $id"
done
MySQL 8.0とそれ以降でも mysql_native_passwordのハッシュを知りたい
$ mysql -sse "SELECT CONCAT('*', UPPER(SHA1(UNHEX(SHA1('$raw_password')))));"
read用のVIPでちゃんと分散してるかどうか確かめる
- forの外側で sort | uniq -cでちゃんと分散してるか数える
$ for n in {1..100}; do
mysql -h $read_vip -sse "SELECT @@hostname"
done | sort | uniq -c
auto_incrementなカラムで梳きながらDELETEなりUPDATEなりする
- 日々の覚書: MySQLから大量のレコードをちまちま削除するメモ の 「idが数値型」の時のやり方
$ for ((i=$min; i<=$max; i+=$limit)); do
mysql -ve "DELETE FROM t1 WHERE id BETWEEN $i AND $i+$limit AND $original_where_clause"
sleep $sleep
done
圧縮しながらxtrabackupを取る
- ファイルリダイレクトでなく
ssh "cat - > .."
とかにパイプすればリモートにも転送できる
$ xtrabackup -uroot --stream=xbstream --backup | pzstd -c > xtrabackup.xb.zst
圧縮済のxbstreamを展開する
- ↑の逆パターン
- カレントディレクトリに色々ぶちまけるのでワーキングディレクトリを作った方が良いと思う
$ pzstd -dc xtrabackup.xb.zst | xbstream -xv
トランザクションがなかなか途切れないテーブルにどうしてもALTER TABLEしたくて1秒までなら何とか我慢しながら成功するまでひたすらリトライする
- 1秒までの他のクエリのブロッキングは許す(でないといつまでも終わらない)
- オンラインALTER TABLEは「2回」メタデータロックを取るので、開始前と終了直前どちらでタイムアウトする可能性もある
- 30分かかるALTER TABLEが終了処理のメタデータロックでタイムアウトしても泣かない
$ while true ; do
mysql -sse "SET SESSION lock_wait_timeout= 1; ALTER TABLE t1 ADD KEY idx_something(some_column)" || break
sleep 1
done
バックアップしたりリストアしたりKILLしたりALTER TABLE無限リトライなんてことをしょっちゅうやってるんですねわかります!()
明日は taka_yuki_04 さんです!
0 件のコメント :
コメントを投稿