7

数百のクライアントに導入されているPostgreSQLデータベースサーバーを使用した製品があります。それらのいくつかは、何年にもわたって数十ギガバイトのデータを収集してきました。そのため、次のバージョンでは、夜間のバッチジョブ中に古いレコードを徐々にアーカイブおよび削除する自動クリーンアップ手順を導入します。

私が正しく理解していれば、autovacuumが開始され、タプルが分析および再編成されるため、レコードが少ない場合と同じようにパフォーマンスが向上します。

実際のディスク容量は、正しく理解していれば解放されません。これは、VACUUM FULLでのみ発生し、 autovacuumによってトリガーされないためです。

だから私はこれを行う自動化されたプロセスについて考えていました。

nagioscheck_postgresで使用されている肥大化ビューをhttp://wiki.postgresql.org/wiki/Show_database_bloatで見つけました。

この見方はいいですか?tbloatが2より大きい場合、VACUUM FULLを使用できることを理解して正しいですか?また、ibloatが高すぎる場合は、REINDEXを使用できますか?

毎日のバッチジョブとして実行する次のジョブに関するコメントはありますか?

  • vacuumdb -Z mydatabase#vacuum withanalyze-only
  • select tablename from bloatview order by tbloat desc limit 1
  • vacuumdb -f -t tablename mydatabase
  • select tablename, iname from bloatview order by ibloat desc limit 1
  • reindexdb -t tablename -i iname mydatabase

もちろん、それをcrontabの素敵なperlスクリプトでラップする必要があります(ubuntu 12を使用しています)、またはpostgresqlにはこれを行うことができるある種のスケジューラがありますか?

それとも、これは完全にやり過ぎであり、はるかに簡単な手順がありますか?

4

2 に答える 2

5

あなたはおそらくそれを必要としないでしょう。これを一度行うのは良いことです—最初のアーカイブジョブの後でディスクスペースを取り戻すことができますが、その後は毎日のアーカイブジョブと自動バキュームによって死んだタプルの膨満を防ぐことができます。

また、代わりにvacuum fullを実行する方がよい場合がよくありますcluster table_name using index_name; analyze table_name。これにより、インデックスに従って行が並べ替えられます。このようにして、関連するテーブル行をディスク上で物理的に近くに保存できます。これにより、ディスクシーク(従来のディスクドライブでは重要、SSDではほとんど関係ありません)と一般的なクエリの読み取り回数を制限できます。

vacuum fullまた、両方を覚えておくとcluster、実行中はテーブルが使用できなくなります。

于 2012-12-19T18:42:10.200 に答える
3

OK、私はそれを通り抜けました。

ビューを簡略化/再加工して、次の2つに分割しました。

CREATE OR REPLACE VIEW
    bloat_datawidth AS
SELECT
    ns.nspname AS schemaname,
    tbl.oid   AS relid,
    tbl.relname,
    CASE
        WHEN every(avg_width IS NOT NULL)
        THEN SUM((1-null_frac)*avg_width) + MAX(null_frac) * 24
        ELSE NULL
    END AS datawidth
FROM
    pg_attribute att
JOIN
    pg_class tbl
ON
    att.attrelid = tbl.oid
JOIN
    pg_namespace ns
ON
    ns.oid = tbl.relnamespace
LEFT JOIN
    pg_stats s
ON
    s.schemaname=ns.nspname
AND s.tablename = tbl.relname
AND s.inherited=false
AND s.attname=att.attname
WHERE
    att.attnum > 0
AND tbl.relkind='r'
GROUP BY
    1,2,3;

CREATE OR REPLACE VIEW
    bloat_tables AS
SELECT
    bdw.schemaname,
    bdw.relname,
    bdw.datawidth,
    cc.reltuples::bigint,
    cc.relpages::bigint,
    ceil(cc.reltuples*bdw.datawidth/current_setting('block_size')::NUMERIC)::bigint AS expectedpages,
    100 - (cc.reltuples*100*bdw.datawidth)/(current_setting('block_size')::NUMERIC*cc.relpages) AS bloatpct
FROM
    bloat_datawidth bdw
JOIN
    pg_class cc
ON
    cc.oid = bdw.relid
AND cc.relpages > 1
AND bdw.datawidth IS NOT NULL;

そしてcronジョブ:

#!/bin/bash

MIN_BLOAT=65
MIN_WASTED_PAGES=100
LOG_FILE=/var/log/postgresql/bloat.log
DATABASE=unity-stationmaster
SCHEMA=public

if [[ "$(id -un)" != "postgres" ]]
then
echo "You need to be user postgres to run this script."
exit 1
fi

TABLENAME=`psql $DATABASE -t -A -c "select relname from bloat_tables where bloatpct > $MIN_BLOAT and relpages-expectedpages > $MIN_WASTED_PAGES and schemaname ='$SCHEMA' order by wastedpages desc limit 1"`

if [[ -z "$TABLENAME" ]]
then
echo "No bloated tables." >> $LOG_FILE
exit 0
fi

vacuumdb -v -f -t $TABLENAME $DATABASE >> $LOG_FILE
于 2012-12-19T14:27:33.970 に答える