1

私は pmacct を実行して、1 時間ごとにネットワーク トラフィックを postgres データベースに要約しています。そのデータを別の形式で mysql データベースに移動するには、スクリプト/クエリを作成する必要があります。このデータセットは急速に拡大するため、SQL を使用してできるだけ多くのデータ処理を行いたいと考えています。

データが存在するゾーン (local/national/international) を追跡するための追加フィールド (agent_id) を追加する perl スクリプトを実行しています。これは 0、1、または 2 として表示されます。

このデータを引き出しているテーブルのスキーマの関連フィールドは次のとおりです。

ip_src, ip_dst, agent_id, bytes, stamp_updated, processed

データを挿入したいスキーマは次のとおりです。

ip, local_down_mb, nat_down_mb, int_down_mb, local_up_mb, nat_up_mb, int_up_mb, timestamp

送信元または送信先が範囲の 1 つであるトラフィックのみを探しているので、現在、必要な方法で postgres データベースからアップロード データを取得するクエリがあります。

SELECT DISTINCT ip_src, agent_id, SUM(bytes), stamp_updated FROM acct
WHERE ip_src <<= '192.168.0.0/22'
   OR ip_src <<= '10.1.2.0/24'
   OR ip_src <<= '1.2.3.4/32'
GROUP BY ip_src, agent_id, stamp_updated
ORDER BY ip_src, agent_id, stamp_updated

そのクエリの出力例は次のとおりです。

   ip_src     | agent_id |    sum    |    stamp_updated    
--------------+----------+-----------+---------------------
10.1.2.134    |        2 |      3192 | 2012-09-13 21:20:01
10.1.2.134    |        2 |      3192 | 2012-09-13 22:20:01
10.1.2.134    |        2 |      3192 | 2012-09-13 23:20:01
10.2.3.252    |        2 |       448 | 2012-09-11 06:00:01
10.2.3.252    |        2 |       448 | 2012-09-11 07:20:01
10.2.3.252    |        2 |       448 | 2012-09-11 08:20:01
10.2.3.252    |        2 |      8112 | 2012-09-11 09:20:01

この段階で、ip_dst に対して同じクエリを実行できることがわかっています。その後、データを新しい形式で mysql に再挿入する際に少し手動のプロセスを実行して、IP ソースと宛先のタイムスタンプが一致していることを確認します。 agent_id の組み合わせと、挿入していたのが送信元 IP か送信先 IP かの組み合わせを使用して、それがインバウンドかアウトバウンドか、およびトラフィックがローカル、国内、または国際のいずれであったかを確認します。

しかし、私が望むのは、そのすべてを実行してくれるクエリです。私の SQL 知識の限界は、数か月前に W3C Web サイトのチュートリアルを読んだことです。

私が知る限り、助けが必要なのは、ip_src 用と ip_dst 用の 2 つの結果セットの間の結合を作成し、トラフィックがどちらの方向に進んでいるかの情報を使用するための魔法を行うことです。 agent_id を使用して、mysql データベースのスキーマと一致する出力を取得します。

これを達成するために役立つと思われるクエリを(非常に親切に)書くことができる人、または少なくとも関連するドキュメントを教えて、これを機能させるために使用する必要がある関数について有利なスタートを切ることができる人はいますか?

4

1 に答える 1

3
  • ip_src を ip_dst 検索にどのように接着するかという主な懸念に対処するには、指定されたタイムスタンプに対して IP が一方向にしかトラフィックを持たない場合を処理するために既に必要だった 2 つのクエリで FULL OUTER JOIN を使用する必要があります。データ ローダーがデータの一致を保証できる場合、INNER JOIN を回避できますが、なぜリスクを冒すのでしょうか?
  • ターゲット スキーマで agent_id を 3 つの個別の列にピボットする必要があるため、集約関数内の条件を使用する 1 つのアプローチを示しました。
  • 列名に基づいて、最終出力でバイト数を切り上げメガバイトに変換することについて仮定しました。

      SELECT down.ip,
             ceil(down.lb/1048576) AS local_down_mb,
             ceil(down.nb/1048576) AS nat_down_mb,
             ceil(down.ib/1048576) AS int_down_mb,
             ceil(up.lb/1048576) AS local_up_mb,
             ceil(up.nb/1048576) AS nat_up_mb,
             ceil(up.ib/1048576) AS int_up_mb,
             down.timestamp
        FROM (SELECT ip_src AS ip,
                     SUM(CASE WHEN agent_id=0 THEN bytes ELSE 0 END) AS lb,
                     SUM(CASE WHEN agent_id=1 THEN bytes ELSE 0 END) AS nb,
                     SUM(CASE WHEN agent_id=2 THEN bytes ELSE 0 END) AS ib,
                     stamp_updated AS timestamp
                FROM acct
               WHERE ip_src <<= '192.168.0.0/22'
                  OR ip_src <<= '10.1.2.0/24'
                  OR ip_src <<= '1.2.3.4/32'
            GROUP BY ip,timestamp) down
        FULL OUTER JOIN
             (SELECT ip_dst AS ip,
                     SUM(CASE WHEN agent_id=0 THEN bytes ELSE 0 END) AS lb,
                     SUM(CASE WHEN agent_id=1 THEN bytes ELSE 0 END) AS nb,
                     SUM(CASE WHEN agent_id=2 THEN bytes ELSE 0 END) AS ib,
                     stamp_updated AS timestamp
                FROM acct
               WHERE ip_dst <<= '192.168.0.0/22'
                  OR ip_dst <<= '10.1.2.0/24'
                  OR ip_dst <<= '1.2.3.4/32'
            GROUP BY ip,timestamp) up
       USING (ip,timestamp)
    ORDER BY ip,timestamp;
    
于 2012-10-14T02:52:51.667 に答える