扩展多维数据集出现 pg_dump / pg_restore 错误

Hel*_*Vim 3 postgresql pg-dump pg-restore pg

我在转储和恢复我的一个数据库时遇到了问题,我认为是由于公共模式中的一些扩展所致。引发错误的扩展似乎是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
Run Code Online (Sandbox Code Playgroud)

我自己编写的一些函数也遇到了类似的不同问题,问题最终是搜索路径,因此明确地将这些函数的搜索路径设置为公开解决了我的问题。我尝试了同样的方法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"

-s包含数据的完整转储大约为 4GB,但我尝试仅使用和转储模式-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';
Run Code Online (Sandbox Code Playgroud)

我想我很困惑......从逻辑上讲,这不是和我使用 tar 格式一样吗?我知道问题是,当pg_restore到达该物化视图并尝试使用该函数时,ll_to_earth(float8, float8)它会失败,因为该函数不在其搜索路径中或尚未恢复,但这是否表明扩展是首先要恢复的是?这可以解决吗?

这是我编写的脚本的一部分,该脚本将转储生产环境中的数据库,并每天在测试环境中恢复数据库,以便它们匹配。它工作了几个月,直到我开始使用这个扩展,但我不知道如何纠正它。

Lau*_*lbe 5

出于安全原因,pg_dump设置为空,因此如果在没有架构限定的情况下引用它们,则只会找到search_path系统架构中的对象。pg_catalog

earth现在,您的 SQL 函数使用没有架构的数据类型(可能public),因此您会收到错误消息。

您必须更改函数以使用限定名称,例如public.earth扩展对象。或者,可能更好的是修复该search_path函数:

ALTER FUNCTION myfun SET search_path = public;
Run Code Online (Sandbox Code Playgroud)

无论如何,这是一个好主意,因为否则如果用户更改,您的功能将停止工作search_path。根据定义或使用函数的方式,这甚至可能构成安全问题(这就是为什么pg_dump这样做)。

  • 非常感谢你,劳伦兹!这完美解决了我的问题。 (2认同)