はじめに
まずは、DBmarlinのドキュメントをご確認ください。
https://docs.dbmarlin.com/docs/DBmarlin/introduction
ドキュメントの「ライセンス」に、以下の記載があります。
DBmarlin is licensed using a Freemium model where the first database you monitor is free forever.
DBmarlinはフリーミアムモデルで提供されており、最初に監視するデータベースは永久に無料でご利用いただけます。
そのため、ライセンス購入前に導入、および無償で1DBインスタンスを対象に検証を行うことが可能なようです。
今回はこのライセンスを利用して導入からDBのチューニングまでを検証します。
前提条件
Instana SaaS はすでに構築済みであるものとします。
準備
環境
DBmarlinを導入するためのサポートOSとシステム要件はそれぞれ以下です。
サポートOS:
https://docs.dbmarlin.com/docs/Getting-Started/supported-platforms
システム要件:
https://docs.dbmarlin.com/docs/Getting-Started/server-installation/hardware-requirements
DBmarlinサーバ構築
DBmarlinパッケージのダウンロード
DBmarlinを以下のサイトからダウンロードします。ダウンロードにはユーザー名とメールアドレスの入力が毎回必要です。
https://www.dbmarlin.com/download
一度登録すると、時々DBmarlinから「状況はどうだい?」的なメールが飛んでくるようになります。ご承知おきください。
「DOWNLOAD NOW」をクリックするとプラットフォーム別のパッケージがリスト表示されますので、そこからダウンロードします。
今回はLinuxにインストールしますので、ここでダウンロードするのではなく、ダウンロードリンクをコピーしてLinuxサーバ側でダウンロードを行いました。
$ curl -O https://download.dbmarlin.com/dbmarlin-Linux-****.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 166M 100 166M 0 0 15.2M 0 0:00:10 0:00:10 --:--:-- 19.3M
URLさえ知っていれば直接ダウンロードできそうです。
が、DBmarlin的にはダウンロード時にユーザー情報を登録して欲しいだろうなと思いますので、tar.gzの名前は伏せておきます。
インストール
DBmarlinのインストール手順公式ドキュメント
https://docs.dbmarlin.com/docs/Getting-Started/server-installation/installation-on-linux
基本は上記ドキュメントに沿って実施します。
まずはnetstatで、DBmarlinが使いたいポートが使われていないこと(=netstatのレスポンスがないこと)を確認します。
$ sudo dnf install net-tools -y
$ netstat -na | grep LISTEN | grep 9080
$ netstat -na | grep LISTEN | grep 9090
$ netstat -na | grep LISTEN | grep 9070
次に、dbmarlin用ユーザを作成します。
$ sudo useradd dbmarlin
DBmarlinのtar.gzを /optに展開します。 (tar名は伏せておきます)
$ sudo tar xzvf dbmarlin-Linux-********.tar.gz -C /opt/
dbmarlinというディレクトリが展開されるので、Permissionをdbmarlinユーザに変更します。
$ sudo chown -R dbmarlin:dbmarlin /opt/dbmarlin/
インストールスクリプトを実行します。
$ sudo su - dbmarlin
# cd /opt/dbmarlin
$ ./configure.sh
処理が開始されます。DBmarlinのTermを読みagreementをacceptしたら、続けてprofileの選択などを実施したらインストールが開始されます。
Local postgresql install
Starting DBmarlin configuration...
Press Enter then space bar to scroll
**DBmarlin Terms of Service for On-Premises Deployments**
This on-premises Terms of Service licence agreement (this “Agreement”)
(..省略..)
Do you accept the agreement Y/N ? Y
Continuing....
Set port for Nginx (current 9090):
Set port for Tomcat (current 9080):
Set port for PostgreSQL (current 9070):
See https://docs.dbmarlin.com/docs/Getting-Started/server-installation/hardware-requirements for Profile sizes
1) XSmall
2) Small
3) Medium
4) Large
5) XLarge
Choose the profile [1-5]: 2
Small profile selected
Recommended RAM is 4GB. You have 8.1GB
Continue Y/N ? Y
(..省略..)
Next run ./start.sh to startup the DBmarlin services
Then connect to http://<hostname>:9090/ in your browser
以上で DBmarlinのインストールは完了です。シンプルですね。
DBmarlinのWebアプリケーションはnginxを通じて公開されており、デフォルトポートは9090です。
起動はコマンド一発です。dbmarlinユーザーが /opt/dbmarlin にて
$ ./start.sh
を実行すれば、http://<hostname>:9090 でDBmarlinにアクセスできるようになります。
ここで dbmarlinユーザーからは抜けておきます。
$ exit
ブラウザで http://<hostname>:9090 にアクセスすると、 http://<hostname>:9090/dashboard に遷移した上で以下の画面が出れば導入は成功です。

DBmarlinの導入、簡単ですね!
PostgreSQL と テストアプリの作成・デプロイ
次に監視対象のデータベースとそのデータベースを使ったテストアプリを作成、デプロイしていきます。
監視データベースの導入
DBmarlinとは別のサーバにログインし、PostgreSQLをサクッと導入します。
$ sudo dnf install postgresql postgresql-server libpq-devel -y
$ sudo su - postgres
$ /usr/bin/initdb
$ exit
$ sudo systemctl start postgresql
テストデータインポート
こちらの記事を参考に、テストデータを投入します。
https://bsofsys.com/2023/01/12/postgresql-performance/
$ sudo su - postgres
$ psql
postgres=# CREATE TABLE tr_test
(
test_code character varying(12),
test_date date,
test_contents character varying(50),
test_kinds character varying(1),
test_price numeric(10,0),
CONSTRAINT tr_test_pkey PRIMARY KEY (test_code)
);
CREATE TABLE
postgres=# insert into tr_test
select lpad(i::character varying, 12, '0') as test_code
,'2010-01-01'::date + (random() * 5000)::integer as test_date
,format('内容%s', i) as test_contents
,(random() * 9)::integer as test_kinds
,(random() * 1000)::integer * 100 as test_price
from generate_series(1, 100000000) as i;
INSERT 0 100000000
敢えてIndexは未生成でいきます。DBmarlinはIndexの生成をアドバイスしてくれるでしょうか?
テストアプリの構築
Copilotにpython flaskアプリを作ってもらいます。
プロンプトはこんな感じ。
python flask でデータベースの情報を表示するWebアプリケーションを作成してください。
データベースはPostgresqlで、hostはlocalhost、portは5432、databaseはpostgres、ユーザーはtest1、パスワードはtestpw1です。
テーブル tr_test からデータを取得し、UI上で表として表示します。10件づつ取得し、ページングできるようにしてください。
test_dateカラムは日付型データですので、特定日付を指定して絞り込みができるようにしてください。
作成したflaskアプリケーションを80ポートで公開したいです。
生成されたflaskアプリはこんな感じ。
app.py
from flask import Flask, render_template, request
import psycopg2
import math
import instana
app = Flask(__name__)
# DB接続情報
DB_CONFIG = {
"host": "localhost",
"port": 5432,
"database": "postgres",
"user": "test1",
"password": "testpw1"
}
def get_connection():
return psycopg2.connect(**DB_CONFIG)
@app.route('/')
def index():
# ページ番号(デフォルト1)
page = int(request.args.get('page', 1))
per_page = 10
# 日付フィルタ
filter_date = request.args.get('filter_date')
# SQL組み立て
base_query = "SELECT * FROM tr_test"
params = []
if filter_date:
base_query += " WHERE test_date = %s"
params.append(filter_date)
# 件数取得
count_query = f"SELECT COUNT(*) FROM ({base_query}) AS sub"
conn = get_connection()
cur = conn.cursor()
cur.execute(count_query, params)
total_count = cur.fetchone()[0]
# ページング計算
total_pages = math.ceil(total_count / per_page)
offset = (page - 1) * per_page
# データ取得
data_query = base_query + " ORDER BY test_date DESC LIMIT %s OFFSET %s"
params.extend([per_page, offset])
cur.execute(data_query, params)
rows = cur.fetchall()
cur.close()
conn.close()
return render_template('index.html',
rows=rows,
page=page,
total_pages=total_pages,
filter_date=filter_date)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=80)
templates/index.html
<!DOCTYPE html>
<html>
<head>
<title>tr_test データ表示</title>
</head>
<body>
<h1>tr_test データ一覧</h1>
<form>
<label>日付で絞り込み (YYYY-MM-DD):</label>
<input type="text" name="filter_date" value="{{ filter_date or '' }}">
<button type="submit">検索</button>
</form>
<table border="1">
<tr>
<th>ID</th>
<th>test_date</th>
<th>その他カラム</th>
</tr>
{% for row in rows %}
<tr>
<td>{{ row[0] }}</td>
<td>{{ row[1] }}</td>
<td>{{ row[2] }}</td>
</tr>
{% endfor %}
</table>
<div>
{% if page > 1 %}
<a href="?page={{ page - 1 }}{% if filter_date %}&filter_date={{ filter_date }}{% endif %}">前へ</a>
{% endif %}
ページ {{ page }} / {{ total_pages }}
{% if page < total_pages %}
<a href="?page={{ page + 1 }}{% if filter_date %}&filter_date={{ filter_date }}{% endif %}">次へ</a>
{% endif %}
</div>
</body>
</html>
Copilotで出力したhtmlやapp.pyは、そのままでは使えません。上記は何ヶ所か手動修正したあとのコードです。
pythonライブラリ導入します。 (本当はpipはsudo しない方がよいけど)
$ sudo dnf install python3-pip -y
$ sudo pip install flask psycopg2-binary instana
アプリ用DBユーザーを作成し、権限を付与します。
$ sudo su - postgres
$ psql
postgres=# CREATE USER test1 WITH PASSWORD 'testpw1';
CREATE ROLE
postgres=# GRANT CONNECT ON DATABASE postgres TO test1;
GRANT
postgres=# GRANT USAGE ON SCHEMA public TO test1;
GRANT
postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO test1;
GRANT
postgres=# exit
$ exit
アプリケーションを起動します。
sudo nohup python app.py &
Instana Agentの導入
Instana AgentはInstana SaaSのUIからダウンロード可能です。
https://******.instana.io/#/instanaagent/installation/linux_auto
今回は「Linux ワンライナーインストーラ」を使います。
curlコマンドがクリップボードコピーできるので、コピーしてLinuxサーバ上で実行しましょう。
$ curl -o setup_agent.sh https://setup.instana.io/agent && chmod 700 ./setup_agent.sh && sudo ./setup_agent.sh -a <**key**> -d <**key**> -t dynamic -e ingress-****-saas.instana.io:443 -j -s
PostgreSQL監視設定
今回は、アプリ用に作ったユーザを流用して Instana AgentからPostgreSQLに接続します。
まずは、PostgreSQLを監視するために、統計情報の取得を有効にします。
https://www.ibm.com/docs/ja/instana-observability/current?topic=technologies-monitoring-postgresql#enable-statistics-collection-persistently__title__1
$ sudo su - postgres
$ psql
postgres=# ALTER SYSTEM SET track_activities = 'on';
ALTER SYSTEM
postgres=# ALTER SYSTEM SET track_counts = 'on';
ALTER SYSTEM
postgres=# ALTER SYSTEM SET track_io_timing = 'on';
ALTER SYSTEM
postgres=# exit
$ exit
次に、Instana Agentの設定ファイルを更新します。
$ sudo vi /opt/instana/agent/etc/instana/configuration.yaml
postgresql で文字列検索して、以下をコメントアウト & 接続情報を記載します。
# PostgreSQL
com.instana.plugin.postgresql:
user: 'test1'
password: 'testpw1'
database: 'postgres' # by default PostgreSQL will use 'user' as database to connect to.
可視化状況確認
pythonアプリ、PostgreSQL、インフラが可視化できていることを確認できました。


DBmarlin データベース接続設定
DBmarlinのPostgreSQL接続設定ドキュメントはこちら。
https://docs.dbmarlin.com/docs/Monitored-Technologies/Databases/postgresql
接続ユーザーの作成
まずは DBmarlin接続用のユーザdbmarlinを作ります。統計情報などを取得することもあり、SUPERUSER権限を付与する必要があります。
$ sudo su - postgres
$ psql
postgres=# CREATE USER dbmarlin WITH PASSWORD 'securepassword';
GRANT pg_monitor to dbmarlin;
ALTER USER dbmarlin WITH SUPERUSER;
CREATE ROLE
GRANT ROLE
ALTER ROLE
postgres=# exit
PostgreSQL 設定ファイルの更新
続けて、postgresqlの設定ファイルを更新します。
postgresql.conf
外部から接続するので、listen_addressesを変更します。
今回は深く考えずどこからでも接続OKにしてしまいました。
# - Connection Settings -
listen_addresses = '*'
#listen_addresses = 'localhost' # what IP address(es) to listen on;
pg_hba.conf
今回は、DBmarlinから dbmarlinというユーザーで、postgresデータベースにアクセスするので、一番下の行を追加しました。
# IPv4 local connections:
host all all 127.0.0.1/32 trust
host postgres dbmarlin <DBmarlinサーバのIPアドレス>/32 md5
DBmarlinのDB接続設定
DBmarlinがPostgreSQLに接続するための下準備が整いました。
それではDBmarlinのDB接続設定を行います。
左メニューで SETTINGS > Database Instances をクリックし、画面上側の Create をクリックします。

(画面キャプチャを撮ったのが登録後なので実際とはちょっと違いますがご愛嬌で...)
接続情報の登録画面が表示されるので、下記の通り入力し画面右下の Create をクリックして作成です。

(画面キャプチャを撮ったのが登録後なので右下はUpdateになってしまってますが、読み替えてください)
- 画面右側の
□Stopが 白抜きのStartボタンになっている場合は、クリックして監視を開始します - 画面左端のアイコンは、起動直後は 灰色のアイコン表示になっています。これが画面の通り
緑のチェックアイコンになれば接続は成功です - もし赤いアイコンが表示されている場合はカーソルをその赤いアイコンにマウスオーバーしてください。解決のためのヒントが表示されます
登録が完了したら、数十分待つと情報が徐々に表示され始めます。

以上でDBmarlinの接続設定は完了です!
(Option)
PostgreSQLの統計情報を取るために、追加で以下の設定が必要です。
https://docs.dbmarlin.com/docs/monitored-technologies/databases/postgresql/#collecting-sql-statistics
必須ではないですが、統計情報はチューニングには必須と思いますので今回はこれを有効にしておきます。(ちなみに、有効にしてないと ANALYSIS > Recommendations で「有効にしてください!」的なメッセージが表示される用になります)
Postgresql.confの設定変更
$ sudo su - postgres
$ cd data
$ vi postgresql.conf
shared_preload_libraries のコメントアウトを外し、pg_stat_statements を追記します。
# - Shared Library Preloading -
shared_preload_libraries = 'pg_stat_statements' # (change requires restart)
pg_stat_statements は PostgreSQL本体とは別の、contribパッケージに含まれているのでそちらを先にインストールします。インストール後、PostgreSQLを再起動します。
$ exit
$ sudo dnf install postgresql-contrib
$ sudo systemctl restart postgresql
PostgreSQLが起動したら、データベースのExtensionを有効にします。
$ sudo su - postgres
$ psql
postgres=# create extension pg_stat_statements;
EXTENSION
postgres=# select * from public.pg_stat_statements;
(extensionが有効かどうかの確認。何か出力されればOK。 ..省略..)
postgres=# exit
$ exit
以上で導入は完了です。
ここまでの作業で、このような結果を確認することができます。

ちなみに、裏で負荷用に以下のコマンドを延々と流しています
for i in `seq -1700 1 -400`
do
s=$(date -v${i}d '+%Y-%m-%d'); curl "http://<app ip>/?filter_date=${s}"
done
Instana - DBmarlin連携設定
Instana側
設定 > グローバル設定 > 統合 > データベース を選択します。
DBmarlinカードの「統合の構成」リンクをクリックします。

DBmarlinのhttp URLを入力し、「保存して有効にする」をクリックすれば完了です。シンプルです。

DBmarlin側
SETTINGS > INTEGRATIONS > Instana を選択し、画面右上の Create をクリックします。

InstanaのURLとAPIキーを入力します。APIキーについてはDBmarling側では特に権限指定はないので、デフォルトで様子を見ます。

APIキーの生成については省略します。以下ドキュメントを参照ください。
https://www.ibm.com/docs/ja/instana-observability/current?topic=api-getting-started#generating-api-token-for-authentication__title__1
検証
Instana での可視化 と DBmarlin への連携
適当な呼び出し(Call)を見てみます。SQLが発行されている呼び出しでは、DBMARLIN で SQL を検索します リンクが表示されていることが確認できました。

ではこのDBMARLIN で SQL を検索します リンクをクリックします。
このコマンドは DBmarlin の /sql-searchをSQLをクエリストリングにしたものを付与して呼び出しています。
ただ、現状では パラメータの渡し合いでうまく連携できていないようです。
Instanaで %s となっているところを DBmarlinは認識できず、 ? に書き換えたところ検索ができるようになりました。改善を期待です。
このSQLから先はDBmarlinによる解析となるため画像での紹介に止めますが、MS Copilot Chatと連携することで、「Indexを作成」 という提案のみならず、OFFSETの使い方 や 並列処理の調整 など多くのパフォーマンスチューニング提案をしてくれました。これはDBAの力強い味方になってくれるのではと考えます。



最後に
一部要改善ポイントはあるものの、InstanaのAPMとしての強みとDBmarlinのDBチューニングアプリケーションの強みが連携することで、よりアプリケーションの運用監視をポジティブに進めることができますね。
ぜひみなさんも一度お試しください。
IBMのCSMもしくは営業担当にお声がけいただければ、詳細ご案内いたします。



