最近、自動バキューム機能を利用して他の30個のPGSQLサーバーと連携するために、PostgreSQL 8.2.11サーバーを8.4にアップグレードしました。これは、ハードウェアを管理する別のITグループによって行われたため、他のアップグレードを選択する余地はほとんどありません(しばらくの間、9以上は表示されません)。サーバーは非常に閉じた環境(孤立したネットワーク、限られたroot権限)に存在し、RHEL5.5(i686)で実行されます。アップグレード後、データベースは常に1日あたり5〜6 GBに成長しています。通常、データベース全体では、約20GBです。現在、それは〜89GBです。同等のデータベースを実行し、実際にサードパーティのアプリケーションを介してレコードを相互に同期するサーバーがいくつかあります(1つは内部の仕組みにアクセスできません)。他のデータベースは、本来あるべきように〜20GBです。
次のSQLを実行すると、特定のテーブル、具体的にはそのTOASTテーブルに問題があることはかなり明白です。
SELECT nspname || '.' || relname AS "relation",
pg_size_pretty(pg_relation_size(C.oid)) AS "size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_relation_size(C.oid) DESC
LIMIT 20;
生成されるもの:
関係| サイズ ------------------------------------ + --------- pg_toast.pg_toast_16874 | 89 GB 数00.warmstates | 1095 MB ... (20行)
このTOASTテーブルは、ブロブされたデータの大きなレコードを保存する「timeseries」と呼ばれるテーブル用です。SUM(LENGTH(blob)/1024./1024.)
timeseriesのすべてのレコードのA は、その列に最大16GBをもたらします。あってはならない理由は、そのままこのテーブルのTOASTテーブルが大きいようにする必要があります。
私はを実行しましたがVACUUM FULL VERBOSE ANALYZE timeseries
、バキュームはエラーなしで完了まで実行されます。
情報: "pg_toast.pg_toast_16874"をバキュームします
情報: "pg_toast_16874":10448587ページで22483取り外し可能、10475318取り外し不可行バージョンが見つかりました
詳細:0デッド行バージョンはまだ削除できません。
削除できない行バージョンの範囲は、37〜2036バイトです。
20121422の未使用のアイテムポインターがありました。
合計空き容量(取り外し可能な行バージョンを含む)は0バイトです。4944885ページは空であるか、空になります。表の最後の0も含まれます。空きバイトが0の4944885ページは、移動先になる可能性があります。
CPU 75.31s / 29.59u秒経過877.79秒。
情報:インデックス "pg_toast_16874_index"に179931ページの10475318行バージョンが含まれるようになりました
詳細:23884インデックス行バージョンが削除されました。
101623インデックスページが削除されました。101623は現在再利用可能です。
CPU 1.35s / 2.46u秒経過21.07秒。
一部のスペース(約1GB)を解放したテーブルをREINDEXしました。プロセスにディスク上に十分なスペースがないため、テーブルをCLUSTERできません。同等のデータベースよりもはるかに大きい理由を知りたいので、テーブルを完全に再構築するのを待っています。
ここで PostgreSQL wikiからクエリを実行しました-"Show Database Bloat"、これは私が得るものです:
current_database | スキーマ名| テーブル名| tbloat | wastedbytes | いなめ| ibloat | 無駄なバイト ----------------- + ------------ + ------------------- ------------- + -------- + ------------- + ------------- -------------------- + -------- + -------------- ptrdb04 | 数00 | timeseries | 1.0 | 0 | idx_timeseries_synchlevel | 0.0 | 0 ptrdb04 | 数00 | timeseries | 1.0 | 0 | idx_timeseries_localavail | 0.0 | 0 ptrdb04 | 数00 | timeseries | 1.0 | 0 | idx_timeseries_expirytime | 0.0 | 0 ptrdb04 | 数00 | timeseries | 1.0 | 0 | idx_timeseries_expiry_null | 0.0 | 0 ptrdb04 | 数00 | timeseries | 1.0 | 0 | uniq_localintid | 0.0 | 0 ptrdb04 | 数00 | timeseries | 1.0 | 0 | pk_timeseries | 0.1 | 0 ptrdb04 | 数00 | idx_timeseries_expiry_null | 0.6 | 0 | ?| 0.0 | 0
データベースはこの領域を「空」とはまったく見なしていないようですが、すべてのディスク領域がどこから来ているのかわかりません!
このデータベースサーバーは、他のデータサーバーから取得した同じレコードを保存するために、4〜5倍のディスク容量を使用することを決定していると思います。私の質問はこれです:行の物理ディスクサイズを確認する方法はありますか?このデータベースの1つの行のサイズを別の「正常な」データベースと比較したいと思います。
あなたが提供できる助けをありがとう!
アップデート1
サイズが原因で、ダンプされたスキーマからテーブルを再構築することになりました(別の日だけ放置することはできませんでした)。ソフトウェア同期プロセスを介してデータを同期した後、TOASTテーブルは約35GBでした。ただし、値の点で最も長いはずのblob列からの9GBまでしか説明できませんでした。他の26GBがどこから来ているのかわからない。CLUSTERed、VACUUM FULLed、およびREINDEXEDが使用できません。ローカルとリモートのデータサーバー間のpostgresql.confファイルはまったく同じです。このデータベースが各レコードをディスク上のより大きなスペースで保存しようとする理由はありますか?
更新2-修正済み
システムにPostgreSQL84パッケージを再インストールするまでも、データベースを最初から完全に再構築することにしました。データベースパスが再初期化され、テーブルスペースが完全に消去されました。サードパーティのソフトウェア同期プロセスによりテーブルが再作成され、最終的なサイズは最大12GBになりました。残念ながら、これは、問題の正確な原因が何であるかを解決するのに役立ちません。1〜2日見て、活性化されたデータベースがTOASTテーブルを処理する方法に大きな違いがあるかどうかを確認し、それらの結果をここに投稿します。
関係のサイズ
ptrdb04=> SELECT nspname || '.' || relname AS "relation",
ptrdb04-> pg_size_pretty(pg_relation_size(C.oid)) AS "size"
ptrdb04-> FROM pg_class C
ptrdb04-> LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
ptrdb04-> WHERE nspname NOT IN ('pg_catalog', 'information_schema')
ptrdb04-> ORDER BY pg_relation_size(C.oid) DESC
ptrdb04-> LIMIT 2;
関係 | サイズ
------------------------- + ---------
pg_toast 。pg_toast_17269 | 18 GB
fews00 。ウォームステート | 1224 MB
(2 行)
VACUUM VERBOSE ANALYZE timeseries;
情報:「timeseries」:68382ページのうち58130ページで、取り外し可能な12699、取り外し不可能な681961行のバージョンが見つかりました 詳細:0デッド行バージョンはまだ削除できません。 未使用のアイテムポインターが105847個ありました。 0ページは完全に空です。 CPU 0.83s / 2.08u秒経過33.36秒 情報:「pg_toast.pg_toast_17269」をバキュームしています 情報:2055849行バージョンを削除するためにインデックス "pg_toast_17269_index"をスキャンしました 詳細:CPU 0.37s / 2.92u秒経過13.29秒 情報:「pg_toast_17269」:518543ページの2055849行バージョンを削除 詳細:CPU 8.60s / 3.21u秒経過358.42秒 情報:インデックス「pg_toast_17269_index」の36786ページに7346902行のバージョンが含まれるようになりました 詳細:2055849インデックス行バージョンが削除されました。 10410のインデックスページが削除され、5124は現在再利用可能です。 CPU 0.00s / 0.00u秒経過0.01秒。 情報:「pg_toast_17269」:2328079ページのうち1257871に、取り外し可能な1286128、取り外し不可能な行バージョン2993389が見つかりました 詳細:0デッド行バージョンはまだ削除できません。 未使用のアイテムポインタは18847個ありました。 0ページは完全に空です。 CPU 26.56s / 13.04u秒経過714.97秒 情報:「fews00.timeseries」を分析しています 情報: "timeseries":360192のライブ行と0のデッド行を含む68382ページのうち30000をスキャンしました。サンプルは30000行、推定合計行は1021022
(ディスク使用量を除いて)再構築後の唯一の顕著な違いは
情報:「pg_toast_17269」:取り外し可能な1286128、取り外し不可能な2993389行バージョンが見つかりました@CraigRingerがコメントで述べたように。削除できない行数は、以前よりもはるかに少なくなっています。
新しい質問: 他のテーブルが別のテーブルのサイズに影響を与えることはありますか?(外部キーなどを介して)テーブルを再構築しても何も起こりませんでしたが、データベース全体を再構築すると問題が解決することが判明しました。