Postgresql 为什么在AWS ECS中pg_还原会自动失败?

Postgresql 为什么在AWS ECS中pg_还原会自动失败?,postgresql,amazon-web-services,amazon-ecs,Postgresql,Amazon Web Services,Amazon Ecs,考虑这个pg_restore命令: pg_restore -h 123.123.123.123 -d my_database -U my_user --no-owner --no-privileges --no-password -t specific_table 616f6d35-202104.backup 当我在本地运行它时,它会工作。但当我运行它时,我的ECS实例不会恢复。没有错误,退出代码为0 如果我在语句中创建db(通过添加--create标志并将我的_数据库更改为postgres)

考虑这个pg_restore命令:

pg_restore -h 123.123.123.123 -d my_database -U my_user --no-owner --no-privileges --no-password -t specific_table 616f6d35-202104.backup
当我在本地运行它时,它会工作。但当我运行它时,我的ECS实例不会恢复。没有错误,退出代码为0

如果我在语句中创建db(通过添加--create标志并将我的_数据库更改为postgres),如下所示:

它在本地仍然有效。当我在ECS中运行它时,它会创建db,但仍然不会还原表。如果我不包括特定表格:

pg_restore -h 123.123.123.123 -d my_database -U my_user --no-owner --no-privileges --no-password 616f6d35-202104.backup
然后它就起作用了。但是它加载了我不想要的整个数据库。所以这与-t标志有关,它在本地工作,但在我的ECS实例中不工作

编辑: 似乎确实存在版本不匹配。我能得到的最接近的环境是ECS上的PostgreSQLv10.16,以及拥有Postgres服务器123.123.123.123的目标EC2上的v10.4。还是不行。这可能是问题所在吗?如果是,我如何安装postgresql或postgresql客户端的特定次要版本

对于docker文件中的ECS,我有:

RUN apt-get update
RUN apt-get install -y curl ca-certificates gnupg
RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
RUN echo "deb http://apt.postgresql.org/pub/repos/apt buster-pgdg main" | tee /etc/apt/sources.list.d/docker.list
RUN apt-get update
RUN apt-get install -y postgresql-10
这让我看到了ECS上的v10.16(它仍然不工作)。但是,如果我更改最后一行来指定特定的次要版本(以便更接近EC2的版本),它将找不到它

RUN apt-get install -y postgresql-10.5

E: Unable to locate package postgresql-10.5
E: Couldn't find any package by glob 'postgresql-10.5'
E: Couldn't find any package by regex 'postgresql-10.5'
同样,它在本地工作——我在本地拥有的版本是v10.5

编辑-2: 我对这件事有了更多的了解。看起来它输出这两行,然后停止-仍然没有错误:

pg_restore: connecting to database for restore
pg_restore: implied data-only restore

不过,“仅隐式数据恢复”似乎并没有引起问题——之后应该会有输出。但是在我的例子中,输出就停止了。

我从来没有弄明白为什么-t/--table标志不能远程工作。但我找到了一个完全符合我需要的不同解决方案。我是用Python实现的,但也可以用bash或其他语言实现

我换上了国旗

pg_restore-l
输出一个.list文件,该文件如下所示:

;
; Archive created at 2021-04-23 08:06:25
;     dbname: abc
;     TOC Entries: 2069
;     Compression: -1
;     Dump Version: 1.13-0
;     Format: CUSTOM
;     Integer: 4 bytes
;     Offset: 8 bytes
;     Dumped from database version: 9.6.16
;     Dumped by pg_dump version: 9.6.16
;
;
; Selected TOC Entries:
;
7380; 1262 16390 DATABASE - db9j0aedvewevi6fw ury3p1vgqirfm2wq
3; 2615 2200 SCHEMA - public ury3p1vgqirfm2wq
7381; 0 0 COMMENT - SCHEMA public ury3p1vgqirfm2wq
1; 3079 13308 EXTENSION - plpgsql 
7382; 0 0 COMMENT - EXTENSION plpgsql 
185; 1259 168687 TABLE public tableA ury3p1vgqirfm2wq
186; 1259 168693 TABLE public tableB ury3p1vgqirfm2wq
187; 1259 168699 TABLE public tableC ury3p1vgqirfm2wq
188; 1259 168702 TABLE public tableZ ury3p1vgqirfm2wq
此文件的目的是让开发人员可以通过排除进行恢复。他们可以查看此文件并使用
进行注释他们不想要的行。然后他们使用
-L/--use list
pg\U restore--use list=my\U list.list-U username…

因为我只需要几个表和它们的数据(并且需要以编程方式完成),所以我使用生成的
.list
文件来生成我自己的缩写文件。我(通过反复试验)了解到,负责创建表并填充其数据的行分别是:
table public tablename
table data public tablename

table_create = 'TABLE public '
table_data = 'TABLE DATA public '
因此,我在
pg_restore-l
提供的
.list
文件上循环,寻找所需表格的行。当我找到正确的行时,我将它们添加到列表中

table_names = ['tablename1', 'tablename2']
full_list = 'list1.list'
list_lines = []
with open(full_list) as topo_file:
    for line in topo_file:
        for table_name in table_names:
            if table_data + table_name + ' ' in line or table_create + table_name + ' ' in line:
                print(line)
                list_lines.append(line)
然后我用这个列表创建了我自己的
.list
文件

restore_list = 'list2.list'
with open(restore_list, 'w') as f:
    for item in list_lines:
        f.write("%s\n" % item)
我发现标题是不必要的。因此,如果我只需要一个表及其数据,那么该文件将看起来非常简单:

426; 1259 169557 TABLE public tablename1 ury3p1vgqirfm2wq
7130; 0 169557 TABLE DATA public tablename1 ury3p1vgqirfm2wq
如果您注意到
注释内容。因此,pg_restore之后的任何事情都不关心。
最后,我在
pg_restore
命令中使用了该列表文件

restore_command = f'pg_restore --use-list={restore_list} --host=localhost --username=postgres --dbname=test --no-owner --no-privileges --verbose "{backup_file}"'
os.system(restore_command)

是关键-尽管我希望在
.list
文件语法和结构方面有更多的上下文。

该表是否有ECS数据库上可能不存在的依赖项?我如何找到?我查阅了“postgres表依赖项”,发现了关于依赖项()的postgres文档。但它没有描述如何筛选表中的任何/所有依赖项。因此,它不是外键,您是否在该表中为任何列使用任何用户定义的数据类型?似乎您没有收到任何错误,我怀疑,由于您使用本地ip连接到服务器,您正在连接到另一台服务器或实例什么是“用户定义的数据类型”?正确我正在从ECS容器连接到EC2实例。
426; 1259 169557 TABLE public tablename1 ury3p1vgqirfm2wq
7130; 0 169557 TABLE DATA public tablename1 ury3p1vgqirfm2wq
restore_command = f'pg_restore --use-list={restore_list} --host=localhost --username=postgres --dbname=test --no-owner --no-privileges --verbose "{backup_file}"'
os.system(restore_command)