Ошибка pg_dump/pg_restore с кубом расширения

Я столкнулся с проблемой сброса и восстановления одной из моих баз данных, я думаю, из-за некоторых расширений в общедоступной схеме. Расширение, которое вызывает ошибку, похоже, является расширением Cube или расширением EarthDistance. Это ошибка, которую я получаю:

pg_restore: [archiver (db)] Error from TOC entry 2983;
pg_restore: [archiver (db)] could not execute query: ERROR: type "earth" does not exist
LINE 1: ...ians($1))*sin(radians($2))),earth()*sin(radians($1)))::earth

QUERY: SELECT cube(cube(cube(earth()*cos(radians($1))*cos(radians($2))),earth()*cos(radians($1))*sin(radians($2))),earth()*sin(radians($1)))::earth
CONTEXT: SQL function "ll_to_earth" during inlining
   Command was: REFRESH MATERIALIZED VIEW public.locationsearch

У меня была похожая проблема с некоторыми функциями, которые я написал сам, и проблема оказалась в пути поиска, поэтому явное указание пути поиска для этих функций для общественности решило мою проблему. Я пробовал то же самое с ll_to_earth, но, похоже, проблема во всем расширении. Я действительно не хочу пытаться установить расширение для pg_catalog, потому что это кажется плохой практикой.

Это моя типичная команда дампа:

pg_dump -U postgres -h ipAddress -p 5432 -w -F t database > database.tar

С последующим:

pg_restore -U postgres -h localhost -p 5432 -w -d postgres -C "database.tar"

Полный дамп с данными весит около 4гб, но я пробовал дампить только схему с -s и -F p и что интересно это начало:

--
-- PostgreSQL database dump
--

-- Dumped from database version 12.2
-- Dumped by pg_dump version 12.2

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

--
-- Name: cube; Type: EXTENSION; Schema: -; Owner: -
--

CREATE EXTENSION IF NOT EXISTS cube WITH SCHEMA public;


--
-- Name: EXTENSION cube; Type: COMMENT; Schema: -; Owner: 
--

COMMENT ON EXTENSION cube IS 'data type for multidimensional cubes';


--
-- Name: earthdistance; Type: EXTENSION; Schema: -; Owner: -
--

CREATE EXTENSION IF NOT EXISTS earthdistance WITH SCHEMA public;


--
-- Name: EXTENSION earthdistance; Type: COMMENT; Schema: -; Owner: 
--

COMMENT ON EXTENSION earthdistance IS 'calculate great-circle distances on the surface of the Earth';

Думаю, меня смущает... логически, разве это не то же самое, что было бы, если бы я использовал формат tar? Я знаю, что проблема в том, что когда pg_restore попадает в это материализованное представление и пытается использовать функцию ll_to_earth(float8, float8), она терпит неудачу, потому что этой функции либо нет в пути поиска, либо она еще не восстановлена, но разве это не указывает на то, что расширения восстанавливать в первую очередь? Можно ли это исправить?

Это часть сценария, который я написал, который будет выгружать базы данных в моей производственной среде и ежедневно восстанавливать базы данных в моей тестовой среде, чтобы они совпадали. Это работало в течение нескольких месяцев, пока я не начал использовать это расширение, и я не знаю, как это исправить.


person HelpMeExitVim    schedule 25.08.2020    source источник


Ответы (1)


Из соображений безопасности pg_dump устанавливает search_path пустым, поэтому будут найдены только объекты в системной схеме pg_catalog, если на них ссылаются без уточнения схемы.

Теперь ваши функции SQL используют тип данных earth без схемы (вероятно, public), поэтому вы получаете сообщение об ошибке.

Вам придется изменить функцию, чтобы использовать полные имена, такие как public.earth, для объектов расширения. В качестве альтернативы и, вероятно, лучше исправить search_path для функции:

ALTER FUNCTION myfun SET search_path = public;

В любом случае это хорошая идея, потому что иначе ваша функция перестанет работать, если пользователь изменит search_path. В зависимости от того, как ваша функция определена или используется, это может даже представлять собой проблему безопасности (именно поэтому pg_dump делает это именно так).

person Laurenz Albe    schedule 26.08.2020
comment
Большое спасибо, Лоренц! Это отлично решило мою проблему. - person HelpMeExitVim; 27.08.2020