Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Блокировка при вставке записи в таблицу / 7 сообщений из 7, страница 1 из 1
08.02.2019, 10:49
    #39770993
fortress
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка при вставке записи в таблицу
Добрый день.
Есть PostgresSQL 9.6, в нем создана база данных, в базе данных есть пара таблиц (названия полей придумал не я):
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
CREATE TABLE public.streettbl
(
  id integer NOT NULL DEFAULT nextval('streettbl_id_seq'::regclass),
  citykey integer,
  name text,
  CONSTRAINT streettbl_pkey PRIMARY KEY (id),
  CONSTRAINT "PKCity_key" FOREIGN KEY (citykey)
      REFERENCES public."Citytbl" (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);

CREATE TABLE public.housetbl
(
  id integer NOT NULL DEFAULT nextval('housetbl_id_seq'::regclass),
  "housePK" integer,
  "number" text,
  CONSTRAINT housetbl_pkey PRIMARY KEY (id),
  CONSTRAINT "housetbl_housePK_fkey" FOREIGN KEY ("housePK")
      REFERENCES public.streettbl (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);



При попытке вставить строку в таблицу housetbl таким запросом (улица с кодом 15 существует):
Код: plsql
1.
2.
INSERT INTO public.housetbl("housePK", "number")
VALUES (15, '4');


получаю сообщение об ошибке:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
ОШИБКА:  нет доступа к отношению streettbl
CONTEXT:  SQL-оператор: "SELECT 1 FROM ONLY "public"."streettbl" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
********** Ошибка **********

ОШИБКА: нет доступа к отношению streettbl
SQL-состояние: 42501
Контекст: SQL-оператор: "SELECT 1 FROM ONLY "public"."streettbl" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"


Все запросы выполняются в PgAdmin3.
Как я понял, возможно, возникает блокировка при вставке ( похожая тема ).
Если убрать ограничение внешнего ключа в таблице housetbl, то вставка проходит нормально.
С базой работает несколько программ. Раньше такого не наблюдалось, можно было свободно вставлять таким образом записи в таблицу.
Пробовали перезапускать службу сервера, результат тот же.
Что вообще означает это сообщение об ошибке?
Можно ли как-то отследить, что может вызывать подобную блокировку?
Или причина в чем-то ещё?
...
Рейтинг: 0 / 0
08.02.2019, 10:55
    #39770997
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка при вставке записи в таблицу
fortress,

Это не блокировка.
У вас проблема с правами доступа к таблице для проверки foreign key. Смотрите в \dp, используемых юзеров и выдайте недостающие grant'ы.
...
Рейтинг: 0 / 0
08.02.2019, 11:20
    #39771014
fortress
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка при вставке записи в таблицу
Melkij,

Спасибо за ответ. Права могли измениться администраторами БД.

Проверяю с учетной записью пользователя postgres, права стояли такие:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
DB1=# \dp street*
                                       Access privileges
 Schema |       Name       |   Type   |      Access privileges      | Column access privileges
--------+------------------+----------+-----------------------------+--------------------------
 public | streettbl        | table    | operatorsn=arDxt/operatorsn+|
        |                  |          | svm4096=arwdDxt/operatorsn +|
        |                  |          | clients=r/operatorsn       +|
        |                  |          | sp50=r/operatorsn          +|
        |                  |          | postgres=arwdDxt/operatorsn |
 public | streettbl_id_seq | sequence | operatorsn=rwU/operatorsn  +|
        |                  |          | svm4096=rwU/operatorsn      |
(2 rows)

DB1=# \dp house*
                                       Access privileges
 Schema |      Name       |   Type   |       Access privileges       | Column access privileges
--------+-----------------+----------+-------------------------------+--------------------------
 public | housetbl        | table    | operatorsn=arwdDxt/operatorsn+|
        |                 |          | svm4096=arDxt/operatorsn     +|
        |                 |          | clients=r/operatorsn         +|
        |                 |          | sp50=r/operatorsn             |
 public | housetbl_id_seq | sequence | operatorsn=rwU/operatorsn    +|
        |                 |          | svm4096=rwU/operatorsn        |
(2 rows)


Дал все права (grant all ...) пользователю postgres для таблиц streetbl и housetbl (и их индексов):
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
DB1=# \dp street*
                                       Access privileges
 Schema |       Name       |   Type   |      Access privileges      | Column access privileges
--------+------------------+----------+-----------------------------+--------------------------
 public | streettbl        | table    | operatorsn=arDxt/operatorsn+|
        |                  |          | svm4096=arwdDxt/operatorsn +|
        |                  |          | clients=r/operatorsn       +|
        |                  |          | sp50=r/operatorsn          +|
        |                  |          | postgres=arwdDxt/operatorsn |
 public | streettbl_id_seq | sequence | operatorsn=rwU/operatorsn  +|
        |                  |          | svm4096=rwU/operatorsn     +|
        |                  |          | postgres=rwU/operatorsn     |
(2 rows)

DB1=# \dp house*
                                       Access privileges
 Schema |      Name       |   Type   |       Access privileges       | Column access privileges
--------+-----------------+----------+-------------------------------+--------------------------
 public | housetbl        | table    | operatorsn=arwdDxt/operatorsn+|
        |                 |          | svm4096=arDxt/operatorsn     +|
        |                 |          | clients=r/operatorsn         +|
        |                 |          | sp50=r/operatorsn            +|
        |                 |          | postgres=arwdDxt/operatorsn   |
 public | housetbl_id_seq | sequence | operatorsn=rwU/operatorsn    +|
        |                 |          | svm4096=rwU/operatorsn       +|
        |                 |          | postgres=rwU/operatorsn       |
(2 rows)


Пока по-прежнему не получается добавить запись:
Код: plsql
1.
2.
3.
DB1=# insert into housetbl ("housePK","number") values(15,'4');
ОШИБКА:  нет доступа к отношению streettbl
CONTEXT:  SQL-оператор: "SELECT 1 FROM ONLY "public"."streettbl" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
...
Рейтинг: 0 / 0
08.02.2019, 12:35
    #39771054
Павел Лузанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка при вставке записи в таблицу
fortress,

Владелец таблицы housetbl должен иметь привилегии для таблицы streettbl.
Судя по всему владелец - operatorsn и у него не хватает UPDATE и DELETE.
Должно помочь:
Код: sql
1.
GRANT ALL ON streettbl TO operatorsn;
...
Рейтинг: 0 / 0
08.02.2019, 13:19
    #39771076
fortress
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка при вставке записи в таблицу
Павел ЛузановДолжно помочь:
Код: sql
1.
GRANT ALL ON streettbl TO operatorsn;

Действительно помогло. Теперь работает, спасибо!
Павел ЛузановВладелец таблицы housetbl должен иметь привилегии для таблицы streettbl.
Судя по всему владелец - operatorsn и у него не хватает UPDATE и DELETE.
Про такое поведение не подозревал, полагая что все запросы выполняются с правами текущего пользователя. Видимо это связано с работой внутренних механизмов PostgreSQL по обеспечению целостности? По каким ключевым словам можно найти описание этого механизма?
...
Рейтинг: 0 / 0
08.02.2019, 14:27
    #39771127
Павел Лузанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка при вставке записи в таблицу
fortress,

Сказать по-честному, не могу найти в документации где про это написано.
Можно поискать в исходном коде, но верю тому, что пишет Том Лэйн в похожем случае:
Том...query will be run with the permissions of the owner of the table, so it's that user (not necessarily the one doing the INSERT) who lacks permissions.
Проверка внешнего ключа выполняется запросом:
Код: sql
1.
SELECT 1 FROM ONLY "public"."streettbl" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x


Выполнять её с правами пользователя, вызвавшего оригинальный запрос(insert) неправильно. Ведь для работы с определенной таблицей (housetbl) пользователь необязан иметь права на работу с таблицами, на которые она ссылается (streettbl).
Значит нужно выполнять проверку с правами другого пользователя. Выбор пал на владельца таблицы, что вполне логично.

Кстати, не проверял, но подозреваю, что для выполнения проверочного запроса достаточно привилегий SELECT и UPDATE (для установки разделяемой блокировки FOR KEY SHARE). У вас не хватало UPDATE.
...
Рейтинг: 0 / 0
08.02.2019, 15:26
    #39771165
fortress
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка при вставке записи в таблицу
Павел Лузанов,

Спасибо за разьяснения.
Павел ЛузановКстати, не проверял, но подозреваю, что для выполнения проверочного запроса достаточно привилегий SELECT и UPDATE (для установки разделяемой блокировки FOR KEY SHARE). У вас не хватало UPDATE.Проверил - всё так. При наличии только SELECT ошибка ещё остается, если добавить ещё привелегию UPDATE то всё работает.

Резюмируя выше описанное, могу заключить что для вставки в таблицу записей у её владельца должны быть привелегии SELECT и UPDATE на таблицу, с которой у неё связь через внешний ключ.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Блокировка при вставке записи в таблицу / 7 сообщений из 7, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]