我正在尝试维护一个有关玩家信息的postgres数据库,当我遇到一个玩家的问题时。玩家来到我们这里说他无法将他的角色加载到游戏世界中。我做了一个小的SELECT语句来提取玩家信息没有问题。但是,当他们尝试使用角色时,我们会更新行中表示玩家角色处于活动状态的字段。但是我们注意到我们无法在该行上运行更新或删除语句。表中的每一行都会被修改而没有任何问题。
我们的数据库管理员认为它是在该行上应用的锁,但经过进一步调查后,看不到任何可能锁定该行的内容。
非常感谢任何建议或建议。
答案 0 :(得分:0)
这当然听起来像锁。
“大锤”方法是弹跳(停止/启动)数据库以杀死任何正在运行的查询。
“手术刀”方法是运行show full processlist;
并尝试查找正在运行的可能已创建锁定的查询。请注意,查询本身可能不会锁定该行,但同一事务中的早期查询可能已将其锁定。任何长时间运行的查询都是可疑的。
我在postgres中发现了一个问题,即使在重启之后也会锁定。以下是您查找和修复它的方法:
运行此查询:
select * from pg_prepared_xacts
Here's the doc for this system view
如果有任何行,则表示存在孤立/悬空事务,即使在重新启动postgres 后也可以保存锁。
要杀死它们,每行都会获得gid
(一个很长的UUID),然后执行:
ROLLBACK PREPARED '<paste gid here>'
那应该清理一下。
如果您使用的是* nix平台,则可以运行此命令执行该操作:
psql -U postgres mydatabase -c "select * from pg_prepared_xacts" | grep -v transaction | grep \| | awk '{print $3}' | xargs -I % psql -U postgres mydatabase -c "ROLLBACK PREPARED '%'"
答案 1 :(得分:0)
如果您的表player
很大且列status
经常更新(如您暗示的那样),而其他列不经常更新,则可能是最好有一张额外的桌子player_status
。
同样如此如果您在UPDATE
到player
时触发了很多复杂的触发器(可能会导致问题)。
由于PostgreSQL's MVCC,每个UPDATE
实际上相当于“INSERT
new,DELETE
old”。旧的行将在稍后被吸尘。这会导致一些表和索引膨胀和磁盘写入。如果只发生在像
CREATE TABLE (
player_id integer references player (player_id)
, status bool -- or integer for more possible states?
);
..它可能会快得多。它可能会或可能不会缓解您所看到的问题。
用于诊断即时问题:pgAdmin具有“服务器状态”工具,您可以使用该工具方便地检查所有连接的状态。选择数据库并使用Tools -> Server Status
。