扩展多维数据集的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"

完全转储的数据约为4gb,但我尝试仅转储带有-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)时,它失败了,因为该函数不在其搜索路径中或尚未还原,但是这不是表明扩展是要还原的第一件事吗?这个可以解决吗?

这是我编写的脚本的一部分,该脚本会将数据库转储到生产环境中,并每天在测试环境中还原数据库,以便它们匹配。在我开始使用此扩展程序之前,它已经工作了几个月,而我对如何纠正它一无所知。

解决方法

出于安全原因,pg_dumpsearch_path设置为空,因此,如果在没有模式限定的情况下对其进行引用,则只会在系统模式pg_catalog中找到对象。

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

您将必须更改功能以对扩展对象使用诸如public.earth之类的限定名称。另外,可能更好的方法是修复该功能的search_path

ALTER FUNCTION myfun SET search_path = public;

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...