postgres ALTER TABLE被阻止

时间:2014-11-14 07:20:11

标签: postgresql postgresql-8.3

我正在运行Postgres 8.3,我在运行AN 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表中的virtualtransaction -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终止事务?

1 个答案:

答案 0 :(得分: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的来源。


BTW,8.3非常过时。计划升级。