暂无图片
关于pg_squeeze,当表有更新操作,squeeze_table会被卡住,请问这个线上环境如何使用?
我来答
分享
暂无图片 匿名用户
关于pg_squeeze,当表有更新操作,squeeze_table会被卡住,请问这个线上环境如何使用?

当再终端开启2个会话,其中会话1 执行


begin;


update  t  set ....;

模拟线上有写操作,但是没有完成

会话2 执行

SELECT squeeze.squeeze_table('public', 'test', null, null, null); 

发现会话2 ,会因为锁等待而卡住,请问都说线上环境用这个工具不影响业务,请问这个咋理解呢?

我来答
添加附件
收藏
分享
问题补充
1条回答
默认
最新
dbaking

在PostgreSQL中,pg_squeeze 是一个用于在线表重组的扩展工具,它可以有效减少表膨胀(bloat),从而提高性能。然而,当表有频繁的更新、删除或插入操作时,pg_squeeze.squeeze_table 可能会被阻塞或卡住,主要原因是它需要获取某些锁(如 ACCESS EXCLUSIVE 锁)来完成表的重组工作。

在实际的生产环境中,为了安全高效地使用 pg_squeeze,需要采取以下策略来避免或最小化对业务的影响:


1. 使用 pg_squeeze 的基础原理

pg_squeeze 的工作机制通常分为以下几个阶段:

  1. 创建一个新的临时表。
  2. 将源表的数据逐行复制到临时表中(考虑并发事务)。
  3. 替换原始表的物理存储。
  4. 丢弃临时表。

其中,在某些阶段需要短暂获取较高级别的锁(如 ACCESS EXCLUSIVE),这可能导致阻塞或等待。


2. 问题分析

当表有频繁的更新操作时,以下问题可能会导致 pg_squeeze.squeeze_table 被卡住:

  • 锁冲突pg_squeeze 在进行表替换时需要获取 ACCESS EXCLUSIVE 锁,而此锁会阻塞其他操作(如查询、更新、删除等)。如果表上有活跃事务,这个锁可能会一直等待。
  • 长事务影响:如果有长时间运行的事务占用资源,会导致 pg_squeeze 无法获取所需锁。
  • 表数据量大:对于非常大的表,pg_squeeze 的数据复制阶段可能会耗时较长,从而增加锁定和冲突的可能性。

3. 线上环境的最佳实践

为了在生产环境中安全有效地使用 pg_squeeze,可以采取以下措施:

3.1 降低锁冲突风险

  • 使用 squeeze_freeze 参数
    设置 squeeze_freezeTRUE 时,pg_squeeze 会尝试冻结表的元数据以避免长时间占用锁。

    SELECT squeeze_table('schema_name', 'table_name', squeeze_freeze := TRUE);
    复制
  • 限制锁等待时间
    通过设置 lock_timeout 参数,限制 ACCESS EXCLUSIVE 锁的等待时间。如果超时未能获取锁,pg_squeeze 将取消操作。

    SET lock_timeout = '10s'; SELECT squeeze_table('schema_name', 'table_name');
    复制
  • 使用 pg_try_advisory_lock
    在运行之前检查是否可以安全地获取锁,避免直接将 pg_squeeze 卡住。


3.2 避免高峰期执行

  • 选择业务低峰期
    在业务访问量较低的时间段(如深夜)运行 pg_squeeze,以最小化对正常业务的影响。

  • 分批处理
    对于数据量较大的表,可以按分区(如果有)或逐步迁移的方式进行重组,而不是一次性处理整个表。


3.3 配置合适的参数

  • 调整 pg_squeeze 参数
    配置合适的参数以减少对业务的影响。例如:

    • squeeze_triggered_by_table_bloat: 触发表膨胀的阈值。
    • squeeze_max_retry_count: 遇到锁冲突时的最大重试次数。
    • squeeze_vacuum_cost_delay: 控制 VACUUM 操作的延迟,避免过多资源占用。
  • 加速复制过程
    使用 parallel_workers 参数(如果可用)来加快数据复制阶段,减少所需时间。

    SELECT squeeze_table('schema_name', 'table_name', parallel_workers := 4);
    复制

3.4 监控与诊断

  • 监控锁信息
    在执行 pg_squeeze 的过程中,实时监控锁的状态,确保没有长时间的锁等待。

    SELECT * FROM pg_locks WHERE relation::regclass = 'schema_name.table_name'::regclass;
    复制
  • 查看活动事务
    检查当前的活跃事务,避免长时间事务阻塞 pg_squeeze

    SELECT * FROM pg_stat_activity WHERE state = 'active';
    复制
  • 日志分析
    打开 pg_squeeze 的日志记录功能,分析问题根源。


3.5 自动化调度

  • 使用调度器
    配置 pg_squeeze 与调度器(如 cronpg_cron)结合,定期清理膨胀,但是要确保调度任务的时间避开业务高峰期。

    示例:

    INSERT INTO squeeze.tables (schemaname, tablename, enabled) VALUES ('schema_name', 'table_name', TRUE); -- pg_squeeze 将自动在后台运行
    复制

4. 替代方案

如果表的更新频率非常高,或者表特别大,可以考虑以下替代方法:

  1. 逻辑重建:通过创建新表、复制数据,然后切换到新表的方式手动完成重组。
  2. 分区表:对大表进行分区,可以减少膨胀,并降低表重组的复杂性。
  3. VACUUM FULL:虽然会锁表,但对于一些极端膨胀的表,VACUUM FULL 可能是更快的解决方法。

暂无图片 评论
暂无图片 有用 2
打赏 0
回答交流
Markdown


请输入正文
提交
相关推荐
怎么清除psql的历史命令?
回答 1
已采纳
psql的历史命令存储在/.psqlhistory文件中
oracle和pg中,在循环日志下,日志文件系统满了后,会有啥结果??
回答 1
会hung.等待日志归档。
pgadmin4 backup server 后如何恢复?
回答 1
backup对应的有restore菜单
postgreSQL pg_cron对数据库有没有影响?
回答 1
没有
opengauss 创建新的数据类型
回答 1
您可以参考官方文档《开发者指南》,SQL语法关于CREATETYPE的描述
pg_settings中的作用级别?
回答 1
有个列 context postmaster时重启才生效,这个是实例层面的如果contextuser 则这个参数可能被session设置过,setting<>
pg如何查看库中是否有失效的索引
回答 1
selectindexrelid,indrelidfrompgindexwhereindisvalid‘f’;
Postgre 逻辑复制,这个表里已经有数据了,再新加数据,新加的数据同步不过去,这是什么原因?
回答 1
1、检查复制用户的对表的查询权限和schema的使用权限2、检查发布和订阅的配置和状态信息3、检查订阅节点是不是被手工中断4、如果是新加的表,请看看那是否在订阅节点上进行了refreshpublica
postgresql 中造成索引失效的形成有哪些可能的原因?
回答 1
可能存在以下原因,仅供参考1、任何计算、函数、类型转换2、!3、NOT,相当于使用函数4、模糊查询通配符在开头5、索引字段在表中占比较高6、多字段btree索引查询条件不包含第一列7、多字段索引查询条
如何设置PG用户pg_dump权限?在用户拥有DQL,DML,DDL的权限下,如果禁止其pg_dump的权限
回答 1
已采纳
PG权限管理类似mysql,你无法禁止用户对属于自己的schema的导出权限。
问题信息
请登录之后查看
邀请回答
暂无人订阅该标签,敬请期待~~