0

我正在运行 Postgres 8.3,但在运行 ALTER TABLE ADD COLUMN 语句时遇到问题,当我运行此查询时,该语句似乎被 AccessShareLock 阻止

SELECT t.relname,l.locktype,page,virtualtransaction,pid,mode,granted FROM pg_locks l, pg_stat_all_tables t WHERE l.relation=t.relid ORDER BY relation asc;

该表的名称是经销商。

    relname      | locktype | page | virtualtransaction |  pid  |        mode         | granted
dealer           | relation |      | 2/40               | 12719 | AccessExclusiveLock | f
dealer           | relation |      | -1/154985751       |       | AccessShareLock     | t

我也跑了

SELECT * FROM pg_prepared_xacts    

那回来了

transaction |                                             gid                                              |           prepared            |  owner   |      database      
  154985751 | 131075_MS1hMzIwM2E3OmIwMjM6NTQxMGY0MzE6MWM1ZTg5OQ==_YTMyMDNhNzpiMDIzOjU0MTBmNDMxOjFjNWU4OWM= | 2014-09-19 08:01:49.650957+10 | user     | database

事务 id 154985751 看起来类似于 pg_locks 表中的虚拟事务 -1/154985751

我运行了这个命令来查看任何可能在数据库上运行查询的进程

ps axu | grep postgres | grep -v idle 

并确认没有其他进程在数据库上运行查询。

运行查询后,日志文件会显示此内容

2014-11-14 17:25:00.794 EST (pid: 12719) LOG:  statement: BEGIN;
2014-11-14 17:25:00.794 EST (pid: 12719) LOG:  statement: ALTER TABLE dealer ADD bullet1 varchar;
2014-11-14 17:25:01.795 EST (pid: 12719) LOG:  process 12719 still waiting for AccessExclusiveLock on relation 2321398 of database 2321293 after 1000.133 ms
2014-11-14 17:25:01.795 EST (pid: 12719) STATEMENT:  ALTER TABLE dealer ADD bullet1 varchar;

什么可能导致经销商桌上出现 AccessShareLock?我猜它与事务 154985751 有关有没有办法使用虚拟 ID 来终止事务?

4

1 回答 1

1

你有一个准备好的交易。准备好的事务——那些PREPARE TRANSACTION尚未运行COMMIT PREPAREDROLLBACK PREPARED已经运行的事务——持有锁,就像正常运行的事务一样。

XA 事务管理器、JTA 等可能会使用准备好的事务,而不必直接由您的应用程序使用。许多排队系统也使用它们。如果您不知道事务是什么并且您提交或回滚它,您可能会破坏依赖两阶段提交的某些内容。


如果你确定你知道它是什么,你可以:

COMMIT PREPARED '131075_MS1hMzIwM2E3OmIwMjM6NTQxMGY0MzE6MWM1ZTg5OQ==_YTMyMDNhNzpiMDIzOjU0MTBmNDMxOjFjNWU4OWM='

或者

ROLLBACK PREPARED '131075_MS1hMzIwM2E3OmIwMjM6NTQxMGY0MzE6MWM1ZTg5OQ==_YTMyMDNhNzpiMDIzOjU0MTBmNDMxOjFjNWU4OWM='

取决于您是希望提交还是中止准备好的 xact。

您无法检查交易以查看它做了什么/做了什么,您需要弄清楚是什么应用程序/工具创建了它,以及如果您不知道它是什么,为什么。


标识符看起来很可疑,[number]_[base64]_[base64]所以让我们看看我们可以用它做什么:

postgres=> SELECT decode((string_to_array('131075_MS1hMzIwM2E3OmIwMjM6NTQxMGY0MzE6MWM1ZTg5OQ==_YTMyMDNhNzpiMDIzOjU0MTBmNDMxOjFjNWU4OWM=','_'))[2], 'base64');
                              decode                              
------------------------------------------------------------------
 \x312d613332303361373a623032333a35343130663433313a31633565383939
(1 row)

postgres=> SELECT decode((string_to_array('131075_MS1hMzIwM2E3OmIwMjM6NTQxMGY0MzE6MWM1ZTg5OQ==_YTMyMDNhNzpiMDIzOjU0MTBmNDMxOjFjNWU4OWM=','_'))[3], 'base64');
                            decode                            
--------------------------------------------------------------
 \x613332303361373a623032333a35343130663433313a31633565383963
(1 row)

嗯,看起来像 ASCII 或类似的,让我们看看:

postgres=> SELECT convert_from(decode((string_to_array('131075_MS1hMzIwM2E3OmIwMjM6NTQxMGY0MzE6MWM1ZTg5OQ==_YTMyMDNhNzpiMDIzOjU0MTBmNDMxOjFjNWU4OWM=','_'))[2], 'base64'), 'utfpostgres=> SELECT convert_from(decode((string_to_array('131075_MS1hMzIwM2E3OmIwMjM6NTQxMGY0MzE6MWM1ZTg5OQ==_YTMyMDNhNzpiMDIzOjU0MTBmNDMxOjFjNWU4OWM=','_'))[2], 'base64'), 'utf-8');
          convert_from           
---------------------------------
 1-a3203a7:b023:5410f431:1c5e899
(1 row)

postgres=> SELECT convert_from(decode((string_to_array('131075_MS1hMzIwM2E3OmIwMjM6NTQxMGY0MzE6MWM1ZTg5OQ==_YTMyMDNhNzpiMDIzOjU0MTBmNDMxOjFjNWU4OWM=','_'))[3], 'base64'), 'utf-8');
         convert_from          
-------------------------------
 a3203a7:b023:5410f431:1c5e89c
(1 row)

看起来模糊的 GUID/UUID-ish,具有奇怪的格式和分组。

也许这些标识符会帮助您找出 xact 的来源。


顺便说一句,8.3 已经过时了。计划您的升级。

于 2014-11-14T07:37:42.527 回答