pg_dump / pg_restore 扩展立方体错误
pg_dump / pg_restore error with extension cube
我一直 运行 陷入转储和恢复我的一个数据库的问题,我认为是因为 public 模式中的一些扩展。引发错误的扩展似乎是 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())*sin(radians())),earth()*sin(radians()))::earth
QUERY: SELECT cube(cube(cube(earth()*cos(radians())*cos(radians())),earth()*cos(radians())*sin(radians())),earth()*sin(radians()))::earth
CONTEXT: SQL function "ll_to_earth" during inlining
Command was: REFRESH MATERIALIZED VIEW public.locationsearch
我自己编写的一些函数也遇到了类似的不同问题,最终问题出在搜索路径上,因此将这些函数的搜索路径明确设置为 public 解决了我的问题。我对 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)
时,它失败了,因为该函数不在其搜索路径中或尚未恢复,但是这难道不表明扩展是首先要恢复的东西吗?这可以修复吗?
这是我编写的脚本的一部分,该脚本会将数据库转储到我的生产环境中,并每天在我的测试环境中恢复数据库,以便它们匹配。它工作了几个月,直到我tar开始使用这个扩展,我不知道如何纠正它。
出于安全原因,pg_dump
将 search_path
设置为空,因此如果在没有模式限定的情况下引用系统模式 pg_catalog
中的对象,则只会找到它们。
现在您的 SQL 函数使用没有架构的数据类型 earth
(可能 public
),因此您会收到错误消息。
您将必须更改函数以使用 public.earth
等限定名称作为扩展对象。或者,可能更好的方法是修复函数的 search_path
:
ALTER FUNCTION myfun SET search_path = public;
无论如何这是个好主意,否则如果用户更改 search_path
,您的功能将停止工作。根据您定义或使用函数的方式,这甚至可能构成安全问题(这就是 pg_dump
这样做的原因)。
我一直 运行 陷入转储和恢复我的一个数据库的问题,我认为是因为 public 模式中的一些扩展。引发错误的扩展似乎是 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())*sin(radians())),earth()*sin(radians()))::earth
QUERY: SELECT cube(cube(cube(earth()*cos(radians())*cos(radians())),earth()*cos(radians())*sin(radians())),earth()*sin(radians()))::earth
CONTEXT: SQL function "ll_to_earth" during inlining
Command was: REFRESH MATERIALIZED VIEW public.locationsearch
我自己编写的一些函数也遇到了类似的不同问题,最终问题出在搜索路径上,因此将这些函数的搜索路径明确设置为 public 解决了我的问题。我对 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)
时,它失败了,因为该函数不在其搜索路径中或尚未恢复,但是这难道不表明扩展是首先要恢复的东西吗?这可以修复吗?
这是我编写的脚本的一部分,该脚本会将数据库转储到我的生产环境中,并每天在我的测试环境中恢复数据库,以便它们匹配。它工作了几个月,直到我tar开始使用这个扩展,我不知道如何纠正它。
出于安全原因,pg_dump
将 search_path
设置为空,因此如果在没有模式限定的情况下引用系统模式 pg_catalog
中的对象,则只会找到它们。
现在您的 SQL 函数使用没有架构的数据类型 earth
(可能 public
),因此您会收到错误消息。
您将必须更改函数以使用 public.earth
等限定名称作为扩展对象。或者,可能更好的方法是修复函数的 search_path
:
ALTER FUNCTION myfun SET search_path = public;
无论如何这是个好主意,否则如果用户更改 search_path
,您的功能将停止工作。根据您定义或使用函数的方式,这甚至可能构成安全问题(这就是 pg_dump
这样做的原因)。