尽管Postgres pg_upgrade损坏了索引UK值,但基于索引的选择丢失了记录

问题描述

在9.6-> 12.3 pg_upgrade之后,我们标记了一些严重的选择,导致结果丢失! 重新索引或删除/创建健康的问题。

升级项目符号

  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个UNIQUE损坏索引。每个索引遗漏了大约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 函数! >

是的,如果找到损坏的索引,该函数将引发异常。

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

解决方法

索引为什么出错?

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

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

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

尽管使用ICU归类的功能可以部分解决该问题,但这不是Postgres可以直接影响的。但是,如果操作系统的ICU版本已更新(例如,由于系统补丁而再次隐含),那么那里也会有同样的问题(但似乎ICU库的更新频率不及glibc库)

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...