由 Andrew Farries 撰写的模式更改和 Postgres 锁队列

主要观点:模式更改困难,有多种失败模式,包括对模式的不兼容更改和长时间锁定数据库对象导致应用不可用。重点讨论了长时间运行的查询与 DDL 语句一起可能会锁定表的读写,导致应用停机。
关键信息:

  • 有两种数据库迁移时可能出现的损坏类别:对模式的不兼容更改和长时间锁定数据库对象。
  • 示例中,看似无害的模式更改可能因锁定表的读写而导致应用停机,如SELECT语句获取ACCESS SHARE锁,DDL 语句尝试获取ACCESS EXCLUSIVE锁,可能导致其他语句排队等待。
  • Postgres 的lock_timeout设置可控制语句获取锁的等待时间,设置后若超时则语句失败,如ALTER TABLE语句设置lock_timeout后在超时后失败,其他语句可继续执行。
  • 使用pgroll工具,其具有指数退避策略可自动重试锁获取失败,降低 DDL 语句阻塞读写的风险。
    重要细节:
  • ACCESS SHARE锁是 Postgres 中最不激进的锁类型,不与除ACCESS EXCLUSIVE锁之外的其他锁冲突。
  • ACCESS EXCLUSIVE锁是最激进的锁类型,与所有其他锁类型冲突,DDL 语句尝试获取此锁时会阻塞直到获取成功。
  • pg_locks表记录不同进程持有的锁信息,pg_blocking_pids函数可结合pg_backend_pid找到被阻塞进程的进程 ID。
  • DDL 语句在迁移会话中应设置合适的lock_timeout值,通常小于 2 秒,以确保读写不会在阻塞的 DDL 语句后排队导致应用停机。
  • pgroll工具通过指数退避策略自动重试锁获取失败,降低 DDL 语句阻塞的风险。
    结论:数据库迁移有两种常见失败模式,pgroll工具可尝试解决这两种模式,通过提供数据库模式的两个版本减少模式更改对应用的影响,并正确处理 DDL 语句导致的锁问题。
阅读 11
0 条评论