主要观点:模式更改困难,有多种失败模式,包括对模式的不兼容更改和长时间锁定数据库对象导致应用不可用。重点讨论了长时间运行的查询与 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 语句导致的锁问题。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。