spe*_*und 5 postgresql sql-server type-conversion
我正在尝试将大型 Postgres DB (500 GB) 转换为 SQL Server 2012。在研究了一些第三方工具并对功能、性能或两者都感到失望后,我开始寻求简单的 pg_dump/批量导入解决方案。事情看起来很有希望,直到我意识到 pg_dump 将明文中的 NULL 表示为“\N”,这会导致批量插入在类型不匹配的情况下出现错误。即使我要自动执行 pg_dump 过程来为每个表生成一个文件,所涉及的一些单独的表也非常大(20-50 GB),并且使用 Linux 中的快速文件编辑选项执行全面的查找替换,或者Perl 脚本给导入/导出所需的时间增加了太多开销。
我希望有一种方法可以修改我不知道的 pg_dump 输出中的 NULL 表示,或者如果失败,可以在工具或策略方面获得一些关于此过程的替代方法的建议。在此先感谢您的帮助。
我认为最适合您的情况是COPY ... TO为每个表使用一个文件,并且pg_dump仅用于模式。
COPY您可以更改输出格式(包括NULL),例如:
COPY foo TO '/path/to/foo.output' WITH NULL '<your null>';
Run Code Online (Sandbox Code Playgroud)
您甚至可以使用 CSV 或其他格式(我不知道 MSSQL 能识别什么)。
为了实现自动化,您可以使用 shell 脚本轻松检查所有表。为此,首先根据需要编辑以下内容并保存在getcommand.sql:
SELECT 'COPY '||c.oid::regclass||' TO ''/path/to/'||c.oid::regclass||''' WITH NULL '''';'
FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE c.relkind='r' AND n.nspname !~ '^(information_schema$|pg_)';Run Code Online (Sandbox Code Playgroud)
这样,您可以使用以下命令来执行副本(您甚至可以使用xargs它来并行化它):
psql <conn_info> -XAtf getcommand.sql | psql <conn_info>Run Code Online (Sandbox Code Playgroud)
它将生成并执行COPY命令以导出所有表数据。
EDIT1:添加regclass到文件名并更正生成的 COPY 命令的语法错误(位于WITH NULL末尾,而不是开头)。添加 -X 以psql避免通过管道进行意外输入。
EDIT2:并行性
我对其进行了并行化测试xargs,结果如下:
psql -XAtf getcommand.sql | xargs -d '\n' -L 1 -P <num jobs> psql -c
Run Code Online (Sandbox Code Playgroud)
在我进行的一个简单测试中,我使用一个小型数据库进行测试(~800MB),在没有并行性的情况下,需要 6 秒才能完成,而在有 4 个作业的情况下,只需要 1 秒多一点。我想对于一台好的服务器上的 500GB 数据库来说,差异会更大。如果你想比较:
time ( psql -XAtf getcommand.sql | xargs -d '\n' -L 1 -P 4 psql -c )
time psql -XAtf getcommand.sql | psql
Run Code Online (Sandbox Code Playgroud)
注意:对于那些考虑使用它进行并行备份(例如替代pg_dump)的人:不要这样做!由于此解决方案对每个表使用不同的会话(和事务),因此如果有其他用户在数据库上工作,则它无法提供结果的一致性。在 PG 9.2+ 上我们可以使用事务快照来保证一致性,但是 PG 9.3(仍然是 beta)已经在pg_dump.