如何解决PostgreSQL pg_dump / COPY
对于由于各种原因而无法与Postgresql连接的系统的初始负载,我需要将表的可定义表的内容转储为CSV。
我已经编写了一个脚本来执行此操作,该脚本使用带有-c标志的psql使用psql遍历表列表,以运行psql的\ copY命令将相应的表转储到这样的文件中:
copY table_name TO table_name.csv WITH (FORMAT 'csv',HEADER,QUOTE '\"',DELIMITER '|');
工作正常。但是我确信您已经发现了这个问题:由于该过程需要约57分钟才能处理约60个奇数表,因此一致性的可能性非常接近于绝对零。
我考虑了一下,并怀疑我可以对pg_dump进行一些轻量级更改以执行我想要的操作,即从pg_dump创建多个csv,同时希望表之间的完整性-并能够指定并行转储
我添加了一些标志,以允许我应用文件后缀(日期),设置格式选项并传递相关输出文件的路径。
copY table_name (pkey_id,field1,field2 ... fieldn) TO table_name.csv WITH (FORMAT 'csv',QUOTE '"',DELIMITER '|')
注意:在pg_dump中,列列表已展开
因此,我四处寻找进一步的信息,并找到了这些COPY Tips。
在网络上写文件似乎是不行的。但是我现在在同一台机器上。我觉得写/ tmp可以,因为任何人都可以写。
所以我尝试作弊:
seingramp@seluonkeydb01:~$ ./tp_dump -a -t table_name -D /tmp/ -k "FORMAT 'csv',DELIMITER '|'" -K "_$DATE_POSTFIX"
tp_dump: warning: there are circular foreign-key constraints on this table:
tp_dump: table_name
tp_dump: You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.
tp_dump: Consider using a full dump instead of a --data-only dump to avoid this problem.
--
-- Postgresql database dump
--
-- Dumped from database version 12.3
-- Dumped by pg_dump version 14devel
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;
--
-- Data for Name: material_master; Type: TABLE DATA; Schema: mm; Owner: postgres
--
copY table_name (pkey_id,field2 ... fieldn) FROM stdin;
tp_dump: error: query Failed:
tp_dump: error: query was: copY table_name (pkey_id,field2 ... fieldn) TO PROGRAM 'gzip > /tmp/table_name_20200814.csv.gz' WITH (FORMAT 'csv',DELIMITER '|')
我已经过滤掉了特定于客户的数据。
我发现pg_dump的错误消息不是很有帮助,您对我做错了什么有想法吗? 从〜1900行开始,更改确实很小(请输入代码!),而忽略了在getopt()周围添加的标志。
/*
* Use copY (SELECT ...) TO when dumping a foreign table's data,and when
* a filter condition was specified. For other cases a simple copY
* suffices.
*/
if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
{
/* Note: this Syntax is only supported in 8.2 and up */
appendPQExpBufferStr(q,"copY (SELECT ");
/* klugery to get rid of parens in column list */
if (strlen(column_list) > 2)
{
appendPQExpBufferStr(q,column_list + 1);
q->data[q->len - 1] = ' ';
}
else
appendPQExpBufferStr(q,"* ");
if ( copy_from_spec )
{
if ( copy_from_postfix )
{
appendPQExpBuffer(q,"FROM %s %s) TO PROGRAM 'gzip > %s%s%s.csv.gz' WITH (%s)",fmtQualifiedDumpable(tbinfo),tdinfo->filtercond ? tdinfo->filtercond : "",copy_from_dest ? copy_from_dest : "",copy_from_postfix,copy_from_spec);
}
else
{
appendPQExpBuffer(q,"FROM %s %s) TO PROGRAM 'gzip > %s%s.csv.gz' WITH (%s)",copy_from_spec);
}
}
else
{
appendPQExpBuffer(q,"FROM %s %s) TO stdout;",tdinfo->filtercond ? tdinfo->filtercond : "");
}
}
else
{
if ( copy_from_spec )
{
if ( copy_from_postfix )
{
appendPQExpBuffer(q,"copY %s %s TO PROGRAM 'gzip > %s%s%s.csv.gz' WITH (%s)",column_list,"copY %s %s TO PROGRAM 'gzip > %s%s.csv.gz' WITH (%s)","copY %s %s TO stdout;",column_list);
}
我也尝试了其他一些作弊方法,例如指定postgres拥有的目录。我知道这是一个快速的技巧,但希望您能为您提供帮助。
解决方法
这是pg_restore -f
的用例。
所以:
-- Create custom format dump file
pg_dump -d some_db -U some_user -Fc -f dump.out
-- Move that file to where you need it
-- Dump data only from named table to a file from the dump file.
pg_restore -a -t table_1 -f table_1_data.sql dump.out
pg_dump
将创建表的一致快照,因此在dump.out中数据库处于“冻结”状态。然后,您可以使用pg_restore
“解冻”计划中所需的那些部分。通过使用-a
,您将获得所需的COPY
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。