当前位置: 首页 > news >正文

PostgreSQL 索引损坏问题排查以及修复

此处仅记录最近遇到的一次索引损坏的排查流程,诸位可以参考

起因:

        在日志中发现了报错

org.postgresql.util.PSQLException ERROR
DATA MAY BECOME OUT OF SYNC: UPDATE table_auc SET start_price = 0 WHERE auc_id = 660;
ERROR: table tid from new index tuple (2213537,1) overlaps with invalid duplicate tuple at offset 67 of block 97335 in index "inactive_idx_name"org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2468)org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2211)org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:309)org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:446)org.postgresql.jdbc.PgStatement.execute(PgStatement.java:370)org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:311)org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:297)org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:274)org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:246)lib_db.DbConnectPostgresql.update(DbConnectPostgresql.java:146)lib_db.DbConnectPostgresql.update(DbConnectPostgresql.java:194)lib_db.table.Table.update(Table.java:47)lib_generic.object.GenericObjectTable.updateValue(GenericObjectTable.java:160)

由上面的日志可以知道,索引结构出现了逻辑冲突,也就是 索引页(block)中有重复或无效的 tuple。这通常和系统崩溃、硬盘 I/O 问题或旧版本 PostgreSQL 的 bug 有关。

确认问题

用 PostgreSQL 自带的 amcheck 扩展检查索引是否真的坏了:

CREATE EXTENSION IF NOT EXISTS amcheck;-- 检查索引结构(轻量级)
SELECT bt_index_check('idx_name', true);-- 深度检查父子页、排序等一致性
SELECT bt_index_parent_check('idx_name', true, true);

有输出的话就是有问题

修复

REINDEX INDEX CONCURRENTLY idx_name;

出现的原因排查

简单分析了可能的原因,有一下几种情况

        

  • 数据库或系统 非正常关机

  • 磁盘坏块 / 文件系统错误

  • PostgreSQL 旧版本的 btree bug

  • 或者 硬件(RAID 控制器 / SSD)异常

  • 排序规则版本不匹配

一般我们使用排除法,这里我排查了以上所有的情况,最后 判定为是 排序规则版本不匹配。

上面的排除方式就不细讲了,这里只写怎么确认是排序规则不匹配的

排序规则版本不匹配

升级 PostgreSQL/操作系统(glibc/ICU)后,文本类 B-tree 索引的排序顺序可能与新版本库不一致,会被要求 REINDEX 并刷新排序规则版本。

由于近期迁移了系统,所以首先想到的是环境变化

新旧环境对比

# 确认这个库到底走 glibc 还是 ICU
SELECT datname, datlocprovider, datcollate, datctype
FROM pg_database
WHERE datname = current_database();# Glibc版本
ldd --version
环境PostgreSQLglibc 版本datlocprovider排序规则
旧机≤ 142.26(字段不存在,隐式 glibc)en_US.UTF-8
新机162.34c (glibc)en_US.UTF-8

这样的话,能确认都是 使用的GLIBC,但是版本不同

在旧机器环境下执行排序(version:2.26)

dynadot=# WITH vals AS (SELECT * FROM (VALUES ('009-1tv.com'), ('0091tv.com')) v(s)
),
c_sorted AS (SELECT 'C' AS coll, s,row_number() OVER (ORDER BY s COLLATE "C") AS ordFROM vals
),
default_sorted AS (SELECT 'default' AS coll, s,row_number() OVER (ORDER BY s COLLATE "default") AS ordFROM vals
)
SELECT coll, s
FROM (SELECT * FROM c_sortedUNION ALLSELECT * FROM default_sorted
) u
ORDER BY coll, ord;coll   |      s      
---------+-------------C       | 009-1C       | 0091default | 009-1default | 0091
(4 rows)

在新机器环境下执行排序(version:2.34)

dynadot=# WITH vals AS (SELECT * FROM (VALUES ('009-1tv.com'), ('0091tv.com')) v(s)
),
c_sorted AS (SELECT 'C' AS coll, s,row_number() OVER (ORDER BY s COLLATE "C") AS ordFROM vals
),
default_sorted AS (SELECT 'default' AS coll, s,row_number() OVER (ORDER BY s COLLATE "default") AS ordFROM vals
)
SELECT coll, s
FROM (SELECT * FROM c_sortedUNION ALLSELECT * FROM default_sorted
) u
ORDER BY coll, ord;coll   |      s      
---------+-------------C       | 009-1C       | 0091default | 0091default | 009-1
(4 rows)

由此可见,我们使用的default的排序规则,新旧环境是不一样的

glibc由2.26升级到2.34后,排序规则有所变更。

“1”与“-”的权重发生了变化

结论

新系统中,pg使用glibc2.34版本去做排序,但是索引是使用2.26的排序规则生成的,所以就会报索引损坏。

解决方案

对有问题的索引执行reindex即可。

http://www.dtcms.com/a/550574.html

相关文章:

  • 网站建设步骤和流程秦皇岛市属于哪个省
  • 低价自适应网站建设贵阳建站
  • Rust 泛型参数的使用:从类型抽象到编译期优化的深度实践
  • 【Rust编程】深入解析 Rust gRPC 框架:Tonic
  • 建设银行指定网站wordpress站群模板
  • CSP-J教程——第一阶段——第二课:变量与数据类型
  • ie6网站模板西固网站建设平台
  • 网站建设公司大型区域工业互联网平台
  • Linux文件层次结构
  • qRT-PCR 分析
  • python进阶教程1:枚举值和类型标注
  • 网站及备案wordpress 2.5
  • 机器视觉在半导体行业的重要性(以51camera晶圆隐裂检测系统为例)
  • ComfyUI 参数说明手册:核心节点与参数详细说明
  • 浅析数据库多租户
  • 【数据库】增删改查 高阶(超级详细)保姆级教学
  • 宁波市网站建设福鼎整站优化
  • 做网站服务器用国外的wordpress访问插件
  • AI如何赋能EDI?智能映射与EDI异常自动处理新趋势
  • AI助力药企降本增效:寒冬期破局关键
  • 数据科学中的特征工程
  • 800G 光模块:AI 算力洪流的 “超级传动轴”
  • (四)9. 统计推断-ALMOND算法(模拟实验)
  • 网站运营目的东方购物全部商品
  • 深入理解 Cargo.toml:Rust 构建体系的核心解密
  • 生态环境影响评价技术应用及典型实践案例分析
  • 离线部署大模型结合知识库,提取ICD-10编码与诊断信息实践,涵踩坑记录
  • 网站建设报告家教总结做网站宽高怎么决定
  • linux命令-sar-5
  • 做鞋的垂直网站淄博网站建设 百度知道