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

Postgresql在线重建索引REINDEX INDEX CONCURRENTLY出现后缀带_ccnew和_ccold关键字且状态是invaild的索引

PG 12引入REINDEX CONCURRENTLY,https://www.postgresql.org/docs/12/sql-reindex.html

When this option is used, PostgreSQL will rebuild the index without taking any locks that prevent concurrent inserts, updates, or deletes on the table; whereas a standard index rebuild locks out writes (but not reads) on the table until it’s done. There are several caveats to be aware of when using this option
使用此选项时,PostgreSQL 将重建索引,而不在表上采取任何阻止并发插入、更新或删除的锁; 标准的索引重建将会锁定表上的写操作(而不是读操作),直到它完成。

Rebuilding Indexes Concurrently
重建索引可能会影响数据库的常规操作。通常PostgreSQL会锁定重建的表以防止写操作,并通过单次扫描表来执行整个索引构建。 其他事务仍可以读取表,但如果它们尝试在表中插入、更新或删除行,它们将被阻止,直到索引重建完成。 如果系统是实时生产数据库,这可能会产生严重影响。非常大的表可能需要几个小时才能编制索引,即使对于较小的表,索引重建也会锁定编写器,这些时间段对于生产系统来说是不可接受的。PostgreSQL支持以最少的写入锁定来重建索引。此方法通过指定REINDEX的CONCURRENTLY选项来调用。 使用此选项时,PostgreSQL必须对需要重新生成的每个索引执行两次表扫描,并等待可能使用索引的所有现有事务的终止。 此方法需要比标准索引重建更大的工作量,并且需要相当长的时间才能完成,因为它需要等待可能修改索引的未完成的事务。 但是,由于它允许在重建索引时继续正常操作,此方法可用于在生产环境中重建索引。当然,重建索引所需的额外 CPU、内存和 I/O 负载可能会减慢其他操作的速度。
以下步骤发生在并发重建索引中。 每个步骤在单独的事务中运行。 如果要重建多个索引,则每个步骤在进入到下一步之前都要循环遍历所有索引。
1、新的临时索引定义将添加到目录pg_index中。 此定义将用于替换旧索引。 一个SHARE UPDATE EXCLUSIVE会话级别的锁将放在要重建的索引以及其关联的表上,以防止处理时的任何模式修改。
2、为每个新索引完成生成索引的首个操作。 生成索引后,其标志pg_index.indisready切换到“true”使其准备好插入,使其在执行生成的事务完成后对其他会话可见。 此步骤在每个索引的单独事务中完成。
3、然后执行第二个操作以添加在第一个操作运行时添加的元组。此步骤也在每个索引的单独事务中完成。
4、引用索引的所有约束都已更改以引用新的索引定义,并且索引名称也已经更改。 此时,pg_index.indisvalid会为新索引切换到“true”,以及为旧索引切换到“false”,并且缓存无效会导致引用旧索引的所有会话失效。
5、旧索引有pg_index.indisready切换到“false”以防止任何新的元组插入,在等待可能引用旧索引的查询之后完成。
6、旧索引被丢弃。索引和表的SHARE UPDATE EXCLUSIVE会话锁被释放。

如果在重建索引时出现问题,例如唯一索引中的唯一性冲突, REINDEX命令将失败,但会留下一个 “invalid”新索引,在已经存在的索引之外。 出于查询目的此索引将被忽略,因为它可能不完整;但是它仍将消耗更新开销。如果标记为INVALID的索引后缀为ccnew,那么它对应的是并发操作时创建的临时索引,推荐的恢复方法是使用DROP INDEX删除,然后再次尝试 REINDEX CONCURRENTLY。 如果无效索引改为后缀ccold,则对应于无法删除的原始索引; 推荐的恢复方法是删除所述索引,因为正确的重建已经成功。
常规索引创建允许在同一表上的其他常规索引创建同时发生,但在一个表上一次只能发生一个并发索引创建。在这两种情况下,不允许同时对表上其他类型的模式进行修改。 另一个区别是,常规REINDEX TABLE或REINDEX INDEX命令可以在事务块中执行,但REINDEX CONCURRENTLY不能执行。

总之:REINDEX INDEX CONCURRENTLY indexname就是以不阻塞DML的方式重建索引

查询索引XXX是否valid

SELECT pg_class.relname,pg_index.indisvalid FROM pg_class, pg_index WHERE pg_class.relname='XXX' AND pg_index.indexrelid = pg_class.oid;

手工使某个索引XXX失效

update pg_index set indisvalid = false where indexrelid = 'XXX'::regclass

查询某张表XXX上是否有失效的索引

SELECT c.relname tablename,c2.relname indexname,i.indisprimary,i.indisunique,i.indisclustered,i.indisvalid,pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),pg_catalog.pg_get_constraintdef(con.oid, true),contype,condeferrable,condeferred,i.indisreplident,c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2,pg_catalog.pg_index i
  LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))
WHERE c.relname = 'XXX' AND c.oid = i.indrelid AND i.indexrelid = c2.oid
order by 2;

重建索引,会堵塞DML

REINDEX INDEX indexname

重建索引加CONCURRENTLY,不会堵塞dML

REINDEX INDEX CONCURRENTLY indexname

查看索引重建进度

SELECT * FROM pg_stat_progress_create_index;

Postgresql没有禁用某个索引alter index indexname disable这样的功能


http://www.kler.cn/a/550176.html

相关文章:

  • 【撰写技巧】基金项目撰写跟踪交流会
  • 一种动态地址的查询
  • 2.17学习,双向循环链表
  • BFS广度优先搜索——994.腐烂的橘子
  • 通过VSCode直接连接使用 GPT的编程助手
  • 以下是 HTML 与 HTML5 的核心区别及从基础到高级的总结:
  • window中git bash使用conda命令
  • 什么是3D视觉无序抓取?
  • 海康摄像头IPV6模式,手动,自动,路由公告
  • 【力扣Hot 100】回溯1
  • Maven 项⽬⽣命周期
  • 数字化转型实战:Odoo+工业物联网技术破解江苏食品制造行业三大核心痛点
  • Java 运行时常量池笔记(详细版
  • 基础算法# 求一个数的二进制表示当中有几个1 (C++)
  • 解惑Python:一文解决osgeo库安装失败问题
  • 多模态特征提取与融合助力高光谱+LiDAR数据分类性能飞跃
  • 图片属性——位深度
  • 基站天线的优化策略
  • Java 集合数据处理技巧:使用 Stream API 实现多种操作
  • 2025年保安员职业资格考试模拟真题及答案