【问题标题】:After I restart PostgreSQL all my tables are empty (zero rows)重新启动 PostgreSQL 后,我的所有表都是空的(零行)
【发布时间】:2015-04-27 09:28:20
【问题描述】:

使用 Mac OS X 10.10 (Yosemite) 和 Homebrew (0.9.5),我安装了 PostgreSQL 9.4.1。基本上截至本文发布时的所有当前版本...

我已经成功地导入了一个极其庞大的数据库(5600 万条记录 - 导入 15 小时),并编写了一个在本地使用它的应用程序。我找到了一个应用程序 pgAdmin3,它可以让我使用 GUI 执行各种管理任务。一切都很好。

每次我重新启动计算机时,一次是由于 USB 火线音频接口的内核崩溃,一次是由于电源故障,两次是由于用户启动的重新启动 - 每次重新启动后,数据库都是空的。数据库用户/角色仍然存在,表和关系仍然存在,但是,所有表都是空的。 0 条记录。没有什么。 pgAdmin3 甚至显示该表已为数百万条记录分配 的空间,具有“未定义”计数。刷新计数,显示 0 条记录。浏览数据显示 0 条记录。我的 Mac 应用程序(使用 libpq)成功连接到数据库,并从其任何/所有 SELECT 语句中获得 0 结果。提到每次重新导入数据库需要 15 个小时是多余的吗? (反问)

任何和所有建议都表示赞赏。

Mac OS X 10.0.2(优胜美地) 自制 0.9.5 x86_64-apple-darwin14.1.0 上的 PostgreSQL 9.4.1,由 Apple LLVM 版本 6.0 (clang-600.0.56)(基于 LLVM 3.5svn)编译,64 位

【问题讨论】:

  • 您是否将它们创建为UNLOGGED 表?如果是这样,这是不正常关机时的预期行为。为其中一张表显示\d mytable - 它是“Table mytable”还是“Unlogged table mytable”?
  • 是的,这些表没有记录。那么,假设您要保留的表已记录似乎是安全的,而且我没有想到一个好的用例用于临时表并且可以消失,但这就是您使用未记录表的原因?
  • 手册对此进行了说明。未记录的表非常适合数据加载、物化视图、多会话临时表等。尤其是在必要时可以重建数据但很耗时的情况,因此您宁愿不这样做。它们具有显着的性能优势并且不会被复制——这有时可以避免不必要的复制开销。与大多数功能一样,它只是合理地使用它们并用于正确的事情。
  • 克雷格谢谢你,我真的应该花更多的时间阅读精美的手册,当我有时间的时候我会这样做。我找到了一个现有的 python 脚本来导入数据库(一个定期更新并经常重新导入的知识共享开放许可证数据库),并且说脚本将所有表声明为 UNLOGGED。我错过了什么告诉数据库不要在重启时刷新这些?可能我猜测正常的 Mac 重启过程与正确关闭数据库无关?我想我可以将它们全部记录下来,但我担心性能问题是什么。谢谢大家。

标签: database macos postgresql


【解决方案1】:

您描述的行为将与您的表一致,即UNLOGGED

未记录的表介于普通表和临时表之间。这就像一张普通的桌子:

  • 它可以在多个会话中使用
  • 会话退出时不清除
  • 它存储在主表空间中,而不是临时表空间中

但它就像一个临时表:

  • 它不是碰撞安全的。 UNLOGGED 表的内容在 PostgreSQL 关闭并重新启动时被保留,但前提是它完全关闭。在非正常关闭时,UNLOGGED 表可能会被截断,因此它们仍然存在但包含零行。

  • 写入它不会在pg_xlog 中产生预写日志记录

  • 无法通过流式复制或基于日志的复制将其复制到其他节点

  • 写入未记录的表会导致大约一半的磁盘 I/O 是常规表

the manual

猜测一下,您的表被定义为UNLOGGED,当您的 Mac 关闭时,您并没有完全关闭 PostgreSQL。所以它会截断未记录的表,因为它不能确定它们是否处于一致状态。

彻底关闭 PostgreSQL(例如pg_ctl -m fast -w stop,或使 sue 执行此操作的启动配置)。或者不要使用未记录的表。或者愿意在您重新启动时重新加载您的数据。

既然您想知道未记录表的用途:

  • 它们非常适合数据加载和转换,您可以在其中加载一堆数据,然后提取并转换它以加载到其他表中。

  • 报告表

  • 工作队列和任务队列用于整个系统可以重新启动的任何事物,因此您无需将正在进行的任务列表等设置为安全的

【讨论】:

  • 我也在使用 UNLOGGED 表,我偶尔也会遇到同样的问题,尽管我总是通过 systemd 服务 (service postgresql restart) 完全关闭 postgresql。单元文件中的停止命令如下所示:ExecStop=/usr/bin/pg_ctlcluster --skip-systemctl-redirect -m smart %i stop。知道为什么表在重新启动期间会被截断吗?
  • @user35934 基于该命令,它绝对不应该。诡异的。尝试以更高的调试级别运行一段时间(log_min_messages = 'debug2' 或类似的)。还可以考虑将pg_controldata /path/to/your/postgres/datadir/ 的输出记录为启动脚本中的预启动命令。如果您发现问题再次发生,请向邮件列表报告日志和 controldata 输出。
【解决方案2】:

Craig Ringer 关于 UNLOGGED 表的建议很棒,另一件要检查的事情是你已经提交了加载数据的任何操作。

【讨论】:

  • Ron 我是除**SQL 之外的多种语言的开发人员,还没有RTFM,所以请原谅我的无知,如何提交加载数据的操作。我遵循的步骤是:使用发出 postgresql 命令的 python 脚本创建 db,使用 python/psycopg2 导入 db 以读取 20MB 的 XML(15 小时),运行发出 SQL 以索引数据库的 python 脚本,运行 VACUUM ANALYZE;在数据上。我已经完成了 ANALYZE SELECT foo FROM bar;事情有足够的时间来计算额外的索引。我有一个 Mac 应用程序敲击数据库以获得良好的结果,并且有理由期望它可以在 iOS 上运行,但我是 Postgres 新手……
  • 我认为你有一些问题,Walt :) 如果加载 20Mb 需要 15 个小时,那一定是非常复杂的 XML,我通常会在几秒钟内看到数据加载的大小。我刚刚阅读了您对 Craig 建议的回复,您需要从 CREATE 查询中删除 UNLOGGED 子句。这将在重新启动后保留您的数据。然后我们可以看看你的性能问题。你能分享创建数据库/表的 Python 脚本的 URL 吗?
  • 错字。意味着20GB!我可以轻松地对 python 进行排序并将创建更改为记录,这不是问题。我很好奇为什么原作者将其创建为未记录的(可能是因为他让他的数据库 24/7 保持运行状态并每月更新一次?)。无论如何,数据库是来自 www.discogs.com 的公共数据库(每月数据转储在 discogs.com/data),导入脚本称为 discogs-xml2db(在 github.com/philipmat/discogs-xml2db 找到)
猜你喜欢
  • 2021-07-05
  • 1970-01-01
  • 2017-03-28
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-09
  • 1970-01-01
相关资源
最近更新 更多