web-dev-qa-db-ja.com

PostgreSQL 9.3.13、異なるユーザーでマテリアライズドビューを更新するにはどうすればよいですか?

[この問題の根本的な原因は、権限と特権を理解していないことにあると思います...]

だから、ステージを設定するには、私が持っている設定はDBで、それをMyDbと呼びます。

spu11の2人のユーザーがいますspu1はスーパーユーザーで、1は「通常の」ユーザーです。 MyDbの所有者はspu1です。 1には、データベースの作成とグループの役割から継承された作成の役割の特権があることも言っておかなければなりません。

スキーマsch1があります。これはユーザー定義のスキーマです。

このスキーマ内にテーブルがありますtbl1と呼び、マテリアライズドビューをmvw1と呼びます。

tbl1の所有者はspu1mvw1の所有者は1です。


問題:

上記のように、現在の設定ではmvw11またはspu1として更新できません。私は単に以下の楽しいエラーを受け取りました(私は広範囲にグーグルで検索しましたが、私のセットアップで解決するものは何も見つかりませんでした。)。

ERROR:  permission denied for relation tbl1
********** Error **********

ERROR: permission denied for relation tbl1
SQL state: 42501

私はそれを見つけました

  1. mvw1の所有者をspu1に変更すると、spu1として更新できます。
  2. 以下を実行すると、mvw11として更新できます。

不足しているアクセス許可(理想的には最低限必要なもの)を見つけようとしています。通常のユーザー1を許可する必要があるため、ログインしてこのビューを更新できます。

最初のオプションは、知っておくと便利ですが、私の問題は解決しません。 2番目のオプションは、実際にはスーパーユーザー以外のユーザーにスーパーユーザーのアクセス許可を付与するか、必要以上の特権を付与するようです。

誰かがここで何が起こっているのかを正確に説明できたら(またはそれを解決するために必要な私の問題の説明で私が見逃した情報を指摘して)、私の2番目のオプションが実際に進む方法であるかどうかを知らせてくださいまたはより良い代替品の?

どうもありがとう!

3
Alex

これは、その所有者のセキュリティコンテキストで実行される関数で実行できます。

ビューを更新する関数(MV /テーブルを所有するユーザーで作成):

CREATE OR REPLACE FUNCTION refresh_mvw1()
RETURNS void
SECURITY DEFINER
AS $$
BEGIN
REFRESH MATERIALIZED VIEW mvw1 with data;
RETURN;
END;
$$ LANGUAGE plpgsql;

ビューを更新できるようにするすべてのユーザーに、関数の実行を許可します。

-- Users have 'execute' permissions by default on functions!
revoke all on function refresh_mvw1() from public;
grant execute on function refresh_mvw1() to u1;

更新するには:

select refresh_mvw1();

Postgres docs から:

SECURITY DEFINERは、関数を作成したユーザーの特権で実行することを指定します。

パラメータをサポートするバージョン:

CREATE OR REPLACE FUNCTION refresh_mv_xxx(table_name text)
RETURNS void
SECURITY DEFINER
AS $$
DECLARE sql text; 
BEGIN
sql := 'REFRESH MATERIALIZED VIEW ' || table_name || ' with data';
EXECUTE sql;
RETURN;
END;
$$ LANGUAGE plpgsql;

...しかし、動的SQLがまだ定義者として実行されるかどうかはわかりません。

12
Philᵀᴹ

もう1つのオプションは、spu1とu1の両方が所属する(スーパーユーザーではない)グループロールを作成し(「refreshers」など)、そのグループロールをマテリアライズドビューの所有者として割り当てることです。

1
Dologan