【问题标题】:Postgres pg_upgrade corrupt indexes (UK) missing values though missing records by index based selectsPostgres pg_upgrade 损坏的索引(英国)缺少值,尽管基于索引的选择缺少记录
【发布时间】:2020-08-26 16:44:43
【问题描述】:

在 9.6->12.3 pg_upgrade 之后,我们标记了一些严重的选择,给出了缺失的结果! REINDEX 或 drop / create 解决了问题。

升级要点

  1. 停止 9.6
  2. rsync 9.6 数据和 bin 文件 Centos7 Centos8(预装12)
  3. pg_upgrade
  4. ./analyze_new_cluster.sh
  5. ./delete_old_cluster.sh

每个数据库我们发现 1-3 个唯一损坏的索引。每个索引缺少大约 20 个值。

我们发现了一个非常有用的工具 amcheck! https://www.postgresql.org/docs/10/amcheck.html

SELECT bt_index_check(c.oid), c.relname, c.relpages
FROM pg_index i
JOIN pg_opclass op ON i.indclass[0] = op.oid
JOIN pg_am am ON op.opcmethod = am.oid
JOIN pg_class c ON i.indexrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE am.amname = 'btree' AND n.nspname = 'pg_catalog'
-- Don't check temp tables, which may be from another session:
AND c.relpersistence != 't'
-- Function may throw an error when this is omitted:
AND i.indisready AND i.indisvalid
ORDER BY c.relpages DESC LIMIT 10;

非常重要:通过验证注释掉 (AND n.nspname = 'pg_catalog' + LIMIT 10) 限制,以便对您的索引也运行 bt_index_check 函数!

是的,如果找到损坏的索引,该函数会抛出异常。

为什么索引会出错? 我们如何确定我们的新数据库是一致的并且升级成功了?

【问题讨论】:

  • 索引列是什么数据类型?如果它们是 textvarchar 这可能是由 CentOS 7 和 8 之间的 glibc 更改引起的。
  • Varchar(255)!非常感谢!那么英国不仅仅是 varchar 索引!

标签: postgresql upgrade postgresql-9.6 postgresql-12


【解决方案1】:

为什么索引会出错?

最可能的解释是 CentOS 7 和 CentOS 8 之间的 glibc 版本不同。

This blog post 对此提供了更多见解。

通常在更改 glibc 版本时(例如,由于系统补丁或操作系统升级),您应该重新索引包括 textvarcharchar 列的所有索引。

这不是 Postgres 可以直接影响的,尽管使用 ICU 排序规则的能力是该问题的部分答案。但是如果操作系统的 ICU 版本被更新(例如,由于系统补丁再次隐式更新)你会在那里遇到同样的问题(但似乎 ICU 库的更新频率低于 glibc 库)

我认为至少有一些工作正在进行中以警告用户。但据我所知,当前版本 12 或即将发布的版本 13 中没有任何承诺。

【讨论】:

  • 是的...我们过滤了所有基于字符的索引,但是 amcheck 标记的 4-5 个索引是错误的。是一些像“$”这样的损坏字符吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2021-12-03
  • 1970-01-01
相关资源
最近更新 更多