20

バッチで更新されるpostgreSQLデータベースを使用しています。データベース(またはデータベース内のテーブル)が最後に更新または変更されたのはいつかを知る必要があります。

postgeSQLフォーラムの誰かが、ログを使用してログをクエリすることを提案しているのを見ました。クライアントのコードベースを制御できないため、これは機能しません。

4

5 に答える 5

29

特定のテーブルで挿入/更新が行われるたびに実行するトリガーを作成できます。一般的な使用法は、行の「created」または「last_updated」列を現在の時刻に設定することですが、既存のテーブルを変更したくない場合は、中央の場所で時刻を更新することもできます。

したがって、たとえば、一般的な方法は次のとおりです。

CREATE FUNCTION stamp_updated() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$
BEGIN
  NEW.last_updated := now();
  RETURN NEW;
END
$$;
-- repeat for each table you need to track:
ALTER TABLE sometable ADD COLUMN last_updated TIMESTAMP;
CREATE TRIGGER sometable_stamp_updated
  BEFORE INSERT OR UPDATE ON sometable
  FOR EACH ROW EXECUTE PROCEDURE stamp_updated();

次に、最終更新時刻を見つけるには、追跡している各テーブルから「MAX(last_updated)」を選択し、それらの中で最大のものを取得する必要があります。例:

SELECT MAX(max_last_updated) FROM (
  SELECT MAX(last_updated) AS max_last_updated FROM sometable
  UNION ALL
  SELECT MAX(last_updated) FROM someothertable
) updates

シリアル(または同様に生成された)主キーを持つテーブルの場合、主キーインデックスを使用して最新の更新時刻を見つけるための順次スキャンを回避するか、last_updatedにインデックスを作成してみてください。

-- get timestamp of row with highest id
SELECT last_updated FROM sometable ORDER BY sometable_id DESC LIMIT 1

IDが完全に連続していない場合、これによりわずかに間違った結果が生じる可能性があることに注意してください。ただし、どの程度の精度が必要ですか。(トランザクションとは、作成中の行とは異なる順序で行が表示される可能性があることを意味します。)

各テーブルに「更新された」列が追加されないようにする別の方法は、更新タイムスタンプを格納するための中央テーブルを用意することです。次に例を示します。

CREATE TABLE update_log(table_name text PRIMARY KEY, updated timestamp NOT NULL DEFAULT now());
CREATE FUNCTION stamp_update_log() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$
BEGIN
  INSERT INTO update_log(table_name) VALUES(TG_TABLE_NAME);
  RETURN NEW;
END
$$;
-- Repeat for each table you need to track:
CREATE TRIGGER sometable_stamp_update_log
 AFTER INSERT OR UPDATE ON sometable
 FOR EACH STATEMENT EXECUTE stamp_update_log();

これにより、テーブルの更新ごとに1行のテーブルが表示されます。次の操作を実行できます。

SELECT MAX(updated) FROM update_log

最終更新時刻を取得します。(必要に応じて、これをテーブルごとに分割できます)。もちろん、このテーブルは成長し続けます。「updated」でインデックスを作成するか(最新のインデックスを非常に高速に取得できるようにする必要があります)、ユースケースに適合する場合は定期的に切り捨てます(たとえば、テーブルの排他ロックを取得します。最新の更新時刻を取得し、変更が加えられているかどうかを定期的に確認する必要がある場合は、それを切り捨てます)。

別のアプローチ(フォーラムの人々が意味するかもしれない)は、データベース構成(クラスターに対してグローバルに、または追跡する必要のあるデータベースまたはユーザーに対して)で「log_statement = mod」を設定し、次にすべてのステートメントを設定することです。データベースを変更すると、サーバーログに書き込まれます。次に、サーバーログをスキャンしたり、関心のないテーブルを除外したりするために、データベースの外部に何かを書き込む必要があります。

于 2009-05-22T19:02:13.153 に答える
6

pg_stat_databaseトランザクション数を取得し、これがバックアップの実行ごとに変わるかどうかを確認するために使用できるようです。詳細については、このdba.seの回答とコメントを参照してください。

于 2011-08-27T21:24:13.857 に答える
2

次の記事を参照してください。

MySQLとPostgreSQL:「最終変更時刻」列をテーブルに追加する http://www.pointbeing.net/weblog/2008/03/mysql-versus-postgresql-adding-a-last-modified-column-to-a -table.html

于 2009-05-22T18:19:54.443 に答える
2

ジャックのアプローチが好きです。テーブルの統計を照会して、挿入、更新、削除などの数を知ることができます。

select n_tup_upd from pg_stat_user_tables  where relname = 'YOUR_TABLE';

更新するたびに、カウントが1ずつ増えます。

この方法は、DBが1つしかない場合に実行可能であることを念頭に置いてください。複数のインスタンスでは、おそらく異なるアプローチが必要になります。

于 2015-04-30T12:17:52.107 に答える
0

ストアドプロシージャは「信頼できない言語」(plpythonuなど)で記述できます。これにより、postgresの「base」ディレクトリにあるファイルにアクセスできます。ストアドプロシージャでこれらのファイルのラージmtimeを返します。

しかし、バキュームはこれらのファイルとmtimeを変更するため、これはあいまいなだけです。

于 2013-01-09T15:05:52.263 に答える