欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

pg修改数据库表结构不成功如何解决?

程序员文章站 2024-01-13 14:45:52
...

起因

​ 某天发布版本的时候需要修改表的某些字段,数据库用的是postgresql,执行alter table命令长时间没有返回执行成功,好像卡住了一样,也不报错,良久,还不成功,于是结束执行这个命令。

问题分析

​ 在网上查找了一些资料,大概意思就是说当要修改表结构时,pg会申请一个排他锁“ACCESS EXCLUSIVE”,把整个表锁起来,而此时如果这张表还有一些其他的操作正在进行,比如查询等,则pg会等待这些操作完成之后,才能进行修改表结构的操作,而一旦其他操作一直没有完成的话,我们这个修改表结构的操作也就完成不了,于是就出现了上面的现象。

解决办法

​ 查看数据库的每一个连接的状态,执行的是什么sql,执行的时间等。

SELECT * FROM pg_stat_activity WHERE datname='数据库名字';

​ 执行上面的sql,发现有一个查询执行了一个月都还没结束,按道理来说再慢的查询应该也返回结果了吧,顿时心中千万只cnm飘过。。。

​ 话不多说,找到那个连接的pid字段,直接用下面的sql把这个连接杀死。

select pg_terminate_backend(pid);

​ 杀死之后再重新执行alter table,几秒钟之后,黑窗口返回执行成功,大喜。

补充

​ postgresql八种表锁。

表级锁模式 解释
ACCESS SHARE 只与“ACCESS EXCLUSIVE” 锁模式冲突;
查询命令(Select command)将会在它查询的表上获取”Access Shared” 锁,一般地,任何一个对表上的只读查询操作都将获取这种类型的锁。
ROW SHARE 与”Exclusive’和”Access Exclusive”锁模式冲突;
”Select for update”和”Select for share”命令将获得这种类型锁,并且所有被引用但没有 FOR UPDATE 的表上会加上”Access shared locks”锁。
ROW EXCLUSIVE 与 “Share,Shared roexclusive,Exclusive,Access exclusive”模式冲突;
“Update,Delete,Insert”命令会在目标表上获得这种类型的锁,并且在其它被引用的表上加上”Access shared”锁,一般地,更改表数据的命令都将在这张表上获得”Row exclusive”锁。
SHARE UPDATE EXCLUSIVE ”Share update exclusive,Share,Share row ,exclusive,exclusive,Access exclusive”模式冲突,这种模式保护一张表不被并发的模式更改和VACUUM;
“Vacuum(without full), Analyze ”和 “Create index concurrently”命令会获得这种类型锁。
SHARE 与“Row exclusive,Shared update exclusive,Share row exclusive ,Exclusive,Access exclusive”锁模式冲突,这种模式保护一张表数据不被并发的更改;
“Create index”命令会获得这种锁模式。
SHARE ROW EXCLUSIVE 与“Row exclusive,Share update exclusive,Shared,Shared row exclusive,Exclusive,Access Exclusive”锁模式冲突;
任何Postgresql 命令不会自动获得这种锁。
EXCLUSIVE 与” ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE”模式冲突,这种索模式仅能与Access Share 模式并发,换句话说,只有读操作可以和持有”EXCLUSIVE”锁的事务并行;
任何Postgresql 命令不会自动获得这种类型的锁;
ACCESS EXCLUSIVE 与所有模式锁冲突(ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE),这种模式保证了当前只有一个事务访问这张表;“ALTER TABLE, DROP TABLE, TRUNCATE, REINDEX, CLUSTER, VACUUM FULL” 命令会获得这种类型锁,在Lock table 命令中,如果没有申明其它模式,它也是缺省模式。