6

テーブルの最新の変更時刻を取得する必要があるため、出くわしました

select relfilenode from pg_class where relname = 'test';

これにより、relfilenode id が得られます。これは、ディレクトリ名のようです

L:\Databases\PostgresSQL\data\base\inodenumber

後で最新の変更時刻を抽出します。

これはこれを行う正しい方法ですか、それとも同じことを行うためのより良い方法はありますか

4

2 に答える 2

5

テーブルの relfilenode の mtime をテストしてもうまくいきません。EelkeVACUUMが他の操作の中で指摘したように、タイムスタンプが変更されます。ヒント ビットを設定するとテーブルも変更されるため、 によって「変更」されたように見えますSELECT。さらに、テーブルにディスク上のリレーション (1GB チャンク) への複数のフォークがある場合があり、それらすべてをチェックして最新のものを見つける必要があります。

テーブルの最終変更時刻を保持する場合は、変更時刻AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ... FOR EACH STATEMENTの追跡に使用するテーブルのタイムスタンプ行を更新するトリガーを追加します。

トリガーの欠点は、テーブルの単一行ロックに競合するため、すべてのトランザクションがシリアル化されることです。また、デッドロックが発生する可能性が大幅に増加します。あなたが本当に欲しいのは、おそらく、トランザクションがロールバックする必要のない非トランザクションのものであり、複数のトランザクションがカウンターを更新すると、最も高い値が勝ちます。C 拡張機能としてはそれほど難しくないかもしれませんが、そのようなものは組み込まれていません。

もう少し洗練されたオプションは、最後に更新されたカウンターの更新を行うために使用するトリガーを作成することです。dblinkこれにより、ほとんどの競合の問題は回避されますが、実際にはデッドロックが悪化します。これは、PostgreSQL のデッドロック検出では、2 つのセッションが仲介によってデッドロックされているという事実を「確認」できないためです。SELECT ... FOR UPDATEトランザクションを頻繁に中止せずに信頼できるようにするには、タイムアウトを使用する方法が必要です。

ただし、いずれにせよ、トリガーは DDL をキャッチしません。DDL トリガー (「イベント トリガー」) は 9.3 ページで提供されます。

以下も参照してください。

于 2012-10-06T00:04:43.737 に答える
1

バキュームによってテーブルを含むファイルも変更されるため、完全に信頼できるとは思いませんが、バキューム中にテーブルの論理コンテンツは変更されません。

別のテーブルの各テーブルの最終変更タイムスタンプを保持する INSERT、UPDATE、および DELETE のトリガーを作成できます。この方法はパフォーマンスにわずかな影響を与えますが、正確な情報を提供します。

于 2012-10-05T16:25:02.963 に答える