JdbcRunner 1.3.1リリース(データベース負荷テストツール)
JdbcRunner 1.3.1をリリースしました。JdbcRunnerは各種RDBMSを対象としたオープンソースの負荷テストツールです。スクリプトでトランザクションを定義して多重実行し、スループットとレスポンスタイムを測定できます。またJdbcRunnerにはOracle Database、MySQL、PostgreSQLを対象としたテストキットが付属しており、ユーザーが独自にスクリプトを作成する以外にこれらを用いたベンチマークを行うことも可能です。
JdbcRunner 1.3.1では最新環境への追従と細かい不具合修正を行いました。機能追加はありません。
- 動作要件をJava 8 → Java 17へ変更
- PostgreSQL JDBC Driverを42.6.0へ更新
- MySQL Connector/Jを8.0.32へ更新
- MySQL Connector/J 8.0.27以降でANALYZE文をexecute()で実行できない件に対応
以下のRDBMSで動作を確認しています。
- Oracle Database 21c
- Oracle Database 23c Free–Developer Release
- MySQL 8.0
- PostgreSQL 15
それぞれのRDBMSにおける注意点
久しぶりにツールを動かしてみて、つまづいたところを共有します。
Oracle Databaseのコンテナーイメージを使う場合は-Doracle.net.disableOob=trueを指定する
Oracle Database 19c以降では、クエリーのキャンセルにTCPのURGフラグを使用しています。
参考:第15回 信頼性のある通信を実現するTCPプロトコル(2):基礎から学ぶWindowsネットワーク(2/3 ページ) - @IT
ここで、ルーターやプロキシーによってはURGフラグを正常に処理できずに通信エラーを引き起こすものがあります。残念ながらDocker、Podmanは条件に該当してしまうので、コンテナーイメージを使う場合はツールの起動オプションに-Doracle.net.disableOob=trueを指定してください。
参考:docker-images/FAQ.md at main · oracle/docker-images · GitHub
shell> java -Doracle.net.disableOob=true JR tpcc.js ...
MySQL Connector/J 8.0.27以降ではANALYZE文をquery()で実行する
MySQL Connector/J 8.0.27における不具合修正で、結果セットを返すSQLはexecuteQuery()、結果セットを返さないSQLはexecuteUpdate()で実行するように明確化されました。JdbcRunnerのスクリプトではそれぞれquery()とexecute()に対応しています。
MySQLのANALYZE文は結果セットを返すので、MySQL Connector/J 8.0.27以降ではANALYZE文をexecute()で実行できなくなりました。JdbcRunnerのスクリプトでexecute("ANALYZE TABLE sbtest");という箇所がある場合はquery("ANALYZE TABLE sbtest");への書き換えをお願いいたします。OPTIMIZE文も同様です。ツール付属のテストキットは修正済みです。
PostgreSQLでは極力publicスキーマを使わない
PostgreSQL 15以降ではpublicスキーマに対するCREATE権限がデータベース所有者以外には付与されなくなりました。これはCVE-2018-1058に対処したものです。今後は極力publicスキーマを使わずにデータベースユーザーごとにスキーマを作成することが推奨されます。
参考:A Guide to CVE-2018-1058: Protect Your Search Path - PostgreSQL wiki
shell> psql -U postgres sql> CREATE DATABASE sbtest TEMPLATE template0 ENCODING 'UTF-8' LC_COLLATE 'C' LC_CTYPE 'C'; sql> CREATE USER sbtest PASSWORD ...; shell> psql -U postgres sbtest sql> CREATE SCHEMA AUTHORIZATION sbtest;
今後の予定
JdbcRunnerに機能追加の予定は特にありませんが、今後はJavaのLTSバージョンに追従する形でメンテナンスを続けていければと考えています。
RequestDisplayOn - スクリーンセーバーを抑止する
RequestDisplayOnという小さなアプリケーションをリリースしました。コンピューターを長時間操作していないときに、スクリーンセーバーが起動したりディスプレイがオフになったりすることを抑止するコンソールアプリケーションです。Windows 10 Version 1809以降に対応しています。
- バイナリ
- ソースコード(MITライセンス)
WindowsのノートPCでLinuxサーバにSSH接続して作業をしているとき、少し席を外しただけで接続が切れてしまって何度も困ったので作成しました。ノートPCの電源オプションを都度調節すればよいのですが私は変更したことを忘れてしまうので…。
もし似たような状況で困っている方がいらっしゃいましたら試してみていただければと思います。このアプリケーションはインストーラーなし、ランタイムライブラリなし、管理者権限なしで動くように作ってあります。
SnapパッケージをNFS上で起動する場合はAppArmorに注意
UbuntuなどのLinuxディストリビューションで、比較的新しいソフトウェアをインストールするためにSnapパッケージを利用することがあるかと思います。このSnapパッケージについてNFSマウントしたディレクトリ上では起動しないという不具合に遭遇したので、原因と暫定対処策をメモしておきます。Ubuntu 22.04 LTSで確認しています。
例としてKotlinのSnapパッケージをインストールしてみます。
~$ sudo snap install kotlin … ~$ kotlin -version Kotlin version 1.7.21-release-272 (JRE 17.0.5+8-Ubuntu-2ubuntu122.04) ~$ cd /nfs /nfs$ kotlin -version cannot open path of the current working directory: Permission denied
このようにNFS上ではKotlinが起動しません。原因はAppArmorがプロセスをブロックしてしまっているためで、syslogでその様子を確認できます。
Jan 24 22:08:09 ubuntu2204-01 systemd[1099]: Started snap.kotlin.kotlin.2c2e7cf1-5e19-43f0-853f-0f1eee666559.scope. Jan 24 22:08:09 ubuntu2204-01 kernel: [ 76.634145] nfs: RPC call returned error 13 Jan 24 22:08:09 ubuntu2204-01 kernel: [ 76.634166] kauditd_printk_skb: 31 callbacks suppressed Jan 24 22:08:09 ubuntu2204-01 kernel: [ 76.634168] audit: type=1400 audit(1674565689.275:43): apparmor="DENIED" operation="sendmsg" profile="/snap/snapd/17950/usr/lib/snapd/snap-confine" pid=1336 comm="snap-confine" laddr=192.168.1.148 lport=800 faddr=192.168.1.2 fport=2049 family="inet" sock_type="stream" protocol=6 requested_mask="send" denied_mask="send"
以下のような仕組みになっているようです。
- Snapパッケージはsnap-confineというコマンド経由で起動される
- snap-confineはAppArmorによってネットワーク処理が禁止されている
- NFS上ではファイルアクセスがネットワーク処理だと解釈されてブロックされてしまう
関連リンクです。
- AppArmorがNFSアクセスをネットワーク処理として取り扱うことが間違いではないか?という報告。2023年1月時点であまり進展はありません。
暫定対処策です。AppArmorを丸ごと無効化してしまいたくなるところですがそれでは影響が大きすぎるので、さしあたりsnap-confineにネットワーク処理を許可することにします。
syslogを見るとAppArmorに /snap/snapd/17950/usr/lib/snapd/snap-confine というプロファイルが登録されていることが分かります。このプロファイルの設定は /var/lib/snapd/apparmor/profiles に格納されています。ちなみに17950というのはsnapdの内部的なリビジョン番号を表しています。
設定ファイルの末尾にnetwork,を追加します。カンマを付け忘れると動きませんので注意してください。
~$ sudo vim /var/lib/snapd/apparmor/profiles/snap-confine.snapd.17950 … deny /etc/nsswitch.conf r, deny /etc/passwd r, network, }
snapd.apparmorサービスを再起動します。
~$ sudo systemctl restart snapd.apparmor
これでNFS上でもSnapパッケージが起動するようになりました。
~$ cd /nfs /nfs$ kotlin -version Kotlin version 1.7.21-release-272 (JRE 17.0.5+8-Ubuntu-2ubuntu122.04)
注意点として、Snapパッケージを追加、削除するとプロファイルが上書きされて元に戻ってしまうため、プロファイルを再度編集することになる点があります。暫定対処策なので、これくらいは仕方ないかなと考えています。
JdbcRunner 1.3リリース(データベース負荷テストツール)
かなり昔に紹介したJdbcRunnerを、7年ぶりに更新しました。JdbcRunnerは各種データベースを対象とした負荷テストツールで、スクリプトでトランザクションを定義して多重実行し、スループットとレスポンスタイムを測定することができます。レスポンスタイムはきれいにグラフ化もできます。
- JdbcRunner - 汎用データベース負荷テストツール - dbstudy.info
- sh2/jdbcrunner - GitHub
Oracle Database 18c、MySQL 8.0、PostgreSQL 10といった現行バージョンへの追従がメインです。Oracle Database 18cとPostgreSQL 10は昔のままでも動いたのですが、MySQL 8.0に接続するためにConnector/J 8.0が推奨されていて、Connector/J 8.0を動かすためにはJava SE 8が必須で…、という状況でしたので諸々更新しておきました。また、いくつか細かな不具合も修正しています。
大きく手を入れる機会があればJavaScriptエンジンをMozilla Rhinoからより高速なNashornに入れ替えたかったのですが、意外と非互換があるのと、残念ながらNashornがDuplicatedになってしまうとのことで、見送ることにしました。
このツールを最初に作っていたときはWindows XPとEclipse 3.4を使って、ソースコードは自宅サーバのSubversionで管理していました。それからWindowsは4バージョン、Eclipseは9バージョン上がり、ソースコードはGitHubに移行し、動作確認用のRDBMSはDockerで動かすようになり、あと最近4Kのモニタを導入しまして(^^;、だいぶ快適になりました。私は普段あまりプログラミングをしていないので何かしようとするたびに開発環境から作り直しているような状態ですが、今後もバージョンアップ追従は続けていこうと思います。
dstat2graphs(dstatグラフ化ツール)の更新
5年前に作ったdstat2graphsを更新しました。
- sh2/dstat2graphs: Draw graphs from a dstat CSV file. - GitHubリポジトリ
- dstat2graphs - dbstudy.info - デモサイト
- k01sl6.local 2017/01/29 17:54:14 - dstat2graphs - サンプルレポート
- RHEL 7系に対応し、RHEL 5系の対応を終了しました。
- dstatのオプション -r(Disk IOPS) と -l(Load Average) に対応しました。
- 任意の取得間隔秒数に対応しました。
- X軸に経過時間を表示するか実際の時刻を表示するかを選べるようにしました。
OSのリソース情報を収集する際、本番環境であればZabbix、Elastic Stackなどの監視ツールを使うところですが、試験環境でしたら手軽にdstatで済ませるのも一つの案かと思います。dstatはディストリビューションに付属しているので、導入の壁が低いのもうれしいですね。
dstat2graphsもなかなか自由にソフトウェアの導入ができない開発現場を想定して、ディストリビューション付属のパッケージのみで構築できるようにしています。ぜひ、試してみてください。
(おまけ)iostat2graphsとrstat
dstatはとても便利なのですが、DBエンジニアとしてはディスクI/Oをもう少し詳しく調査したいところです。そこでiostatを使うわけですが、せっかくなのでiostatもグラフ化できるようにしておきました。
- sh2/iostat2graphs: Draw graphs from an iostat CSV file. - GitHubリポジトリ
- iostat2graphs - dbstudy.info - デモサイト
- k01sl6.local 2017/01/29 17:54:14 - iostat2graphs - サンプルレポート
iostatはdstatほどmachine-readableなログを出力してくれないので、あらかじめフィルタを挟む設計にしました。リソース情報を収集する際はiostatを直接実行するのではなく、以下のrstatというツールを使用してください。
- sh2/rstat: Run dstat, iostat and pidstat on multiple remote hosts and outputs the log files in CSV format. - GitHubリポジトリ
rstatはdstat、iostatとついでにpidstatを複数のリモートホストで実行し、ログをCSV形式で出力するツールです。出力されたdstatのログはdstat2graphs、iostatのログはiostat2graphsでグラフ化することができます。pidstatに対しては特にツールは用意しておらず、Excelでオートフィルタをかけて見ることを想定しています。
MySQLのロックについて
JPOUG> SET EVENTS 20140907 | Japan Oracle User Group (JPOUG)に参加して発表をしてきました。IIJさまのセミナルームは窓からの眺めがすばらしいですね。JPOUGの運営メンバのみなさま、会場を提供してくださったIIJのみなさま、当日お越しいただいたみなさま、どうもありがとうございました。
私のセッションでは「MySQLのロックについて」と題してネクストキーロックなどの説明をしました。プレゼンテーション資料と、調査のために作成したツールを公開します。
プレゼンテーション資料からリンクしているウェブサイトの一覧です。
過去記事の訂正
@kamipoさんから言及がありましたが、私は2009年の記事でネクストキーロックという用語を誤って使用していました。
ところで、ネクストキーロックというとsh2さんのMySQL InnoDBのネクストキーロック おさらい - SH2の日記の記事が有名ですよね。この、ひとつ先のインデックスレコードまでロックするのもネクストキーロックと呼ぶし、レコードロックとその直前のギャップロックの組み合わせもネクストキーロックと書いてるし、議論するときにはどちらの意味で使ってるのか文脈読み取れる社会性が必要そうです(今回はレコードロックとその直前のギャップロックの組み合わせの意味で使います)。
- 誤:一つ先のレコードまでロックを取得すること。
- 正:レコードとその手前のギャップに対するロックのこと。
ご指摘ありがとうございました。
訂正前
1つめのセッションではc1 < 30の行だけロックをすればいいのですが、実際にはc1 = 30の行もロックされてしまっています。これはInnoDBのアーキテクチャからもたらされている制限事項で、このロックのことをネクストキーロックといいます。ある範囲をロックする際に、一つ先の行までロックをかけることで「範囲」というものを表現する仕組みです。
訂正後
1つめのセッションではc1 < 30の行だけロックをすればいいのですが、実際にはc1 = 30の行もロックされてしまっています。これはInnoDBのアーキテクチャからもたらされている制限事項です。InnoDBはインデックス上で走査した行に対してロックをかけるアーキテクチャとなっており、このケースではc1 = 30の行まで走査しています。また、走査したそれぞれの行に対してネクストキーロックと呼ばれる特殊なロックをかけています。ネクストキーロックとは行とその手前のギャップに対するロックのことで、現時点で存在しない行に対してロックをかける現実的な仕組みです。InnoDBはこのような仕組みで「範囲」というものを表現し、ファントムリードを防いでいるのです。
MySQL Casual Talks vol.6の復習
今回の資料は、MySQL Casual Talks vol.6での@karupaneruraさんの発表にインスパイアされて作成しました。
じっくり復習すると、P20はセカンダリインデックスでcol1 = 8の手前に対するギャップロックが取得されていること、P21以降で(gap)は最初と最後だけではなく途中にも存在していること、などが分かるかと思います。
Lock Inspector
今回の資料を作るにあたって、簡単なツールを作成しました。以下のようなスクリプトを準備すると、
1:RC 2:RC 1:Q:SELECT * FROM emp WHERE empno = 7788 FOR UPDATE 2:Q:SELECT * FROM emp WHERE empno = 7788 FOR UPDATE S:10 1:C 2:C
複数のワーカがコマンドを逐次発行してくれます。
Lock Inspector 1:READ_COMMITTED 2:READ_COMMITTED 1:QUERY:SELECT * FROM emp WHERE empno = 7788 FOR UPDATE (empno ename job mgr hiredate sal comm deptno ) (7788 scott analyst 7566 1987-04-19 3000.00 null 20 ) (1:QUERY) 2:QUERY:SELECT * FROM emp WHERE empno = 7788 FOR UPDATE SLEEP:10 (2:QUERY) (2:com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request) 2:ABORT (SLEEP) 1:COMMIT 1:EXIT
トランザクション処理 概念と技法
参考書籍です。洋書は購入可能です。
- 作者: Jim Gray,Andreas Reuter
- 出版社/メーカー: Morgan Kaufmann
- 発売日: 1993
- メディア: ハードカバー
- クリック: 8回
- この商品を含むブログ (1件) を見る
- 作者: ジムグレイ,アンドレアスロイター,Jim Gray,Andreas Reuter,喜連川優
- 出版社/メーカー: 日経BP社
- 発売日: 2001/10/20
- メディア: 単行本
- 購入: 7人 クリック: 145回
- この商品を含むブログ (21件) を見る
- 作者: ジムグレイ,アンドレアスロイター,Jim Gray,Andreas Reuter,喜連川優
- 出版社/メーカー: 日経BP社
- 発売日: 2001/10/20
- メディア: 単行本
- 購入: 7人 クリック: 47回
- この商品を含むブログ (13件) を見る
MySQL 5.1のプロダクトライフサイクルが終了
2013年12月31日をもってMySQL 5.1のプロダクトライフサイクルが終了しました。今後MySQL 5.1に対して新たな不具合や脆弱性が見つかっても、開発元による修正は行われません。現在もMySQL 5.1を使用している場合は、MySQL 5.5/5.6へ計画的にバージョンアップをされることをおすすめいたします。
リリース | GA日 | Premier Support終了 | Extended Support終了 | Sustaining Support終了 |
---|---|---|---|---|
MySQL 5.0 | 2005年10月 | 2011年12月 | Not Available | Indefinite |
MySQL 5.1 | 2008年12月 | 2013年12月 | Not Available | Indefinite |
MySQL 5.5 | 2010年12月 | 2015年12月 | 2018年12月 | Indefinite |
MySQL 5.6 | 2013年2月 | 2018年2月 | 2021年2月 | Indefinite |
(Lifetime Support Policy, Coverage for Oracle Technology Products - November, 2013より引用)