日常使用过程中出现业务报错:ERROR: wait transaction 1257273 sync time exceed 600s. 就是这种等待某个事物超时的情况。这样的问题我们可以用以下的思路进行排查,最后也有应急手段。

【定位手段】

  1. 连接到cn : gsql -r -m -p 25308 -dpostgres
  2. 打开维护模式(方式因事物同步导致死等):set xc_maintenance_mode=on;
  3. 查找对应的事务id,如果报错有对应的某个dn号,比如(dn_6019_6020),执行如下语句:

    execute direct on (dn_6019_6020) ‘select * from pg_running_xacts where next_xid=1257273 ‘;

    结果举例如下,结果中可能有我们要找的内容,也可能没有我们要找的内容,如果没有,需要把报错实例重启:

    handle |  gxid   | state |     node     |  xmin   | vacuum | timeline | prepare_xid |       pid       | next_xid

——–+———+——-+————–+———+——–+———-+————-+—————–+———-

-1 |       0 | 0     | dn_6019_6020 |       0 | f      |      126 |           0 | 140399511328512 |        0

-1 | 1257273 | 0     | dn_6019_6020 | 1257257 | f      |      126 |           0 | 140401591711488 |  1257273

-1 | 1257271 | 0     | dn_6019_6020 | 1257257 | f      |      126 |           0 | 140402329892608 |  1257271

4. 可以看到我们找到了目前事务id对应的pid,pid会与一个query_id对应,使用以下语句进行查询:

postgres=# execute direct on (dn_6019_6020) ‘select * from pg_stat_activity where pid=140401591711488  ‘;

得到结果如下:

 

datid  | datname |       pid       | usesysid | usename | application_name |   client_addr   | client_hostname | client_port |         backend_start         |          xact_start

|          query_start          |         state_change         | waiting | enqueue | state  | resource_pool | query_id |                       query

——–+———+—————–+———-+———+——————+—————–+—————–+————-+——————————-+————————

——-+——————————-+——————————+———+———+——–+—————+———-+—————————————————

682833 | tn_db   | 140401591711488 |       10 | omm     | cn_5003          | 100.185.178.185 |                 |       43429 | 2017-01-21 05:35:17.731086+08 | 2017-01-21 05:35:17.691

271+08 | 2017-01-21 05:35:17.693154+08 | 2017-01-21 05:35:27.97316+08 | f       |         | active | default_pool  | 54548065 | insert into supplier select * from supplier_load;

【应急手段】

  1. 如果在上述第3步中,找到了对应的pid以及后续的queryid,可以保留一定信息之后,通过select pg_terminate_backend(pid)将对应的语句取消之后,其余等待锁的业务就会恢复正常,后续需排查该语句在单节点上一直执行不释放锁的原因。
  2. 如果第3步之后没有找到对应的语句,那么需要将报错的实例重启,比如6019,

    1)cm_ctl query -Cvd | grep 6019 先找到6019对应的节点以及对应的目录,比如02节点,目录/srv/Bigdata/mppdb/data1/master1

    2)登录到对应的02节点上,ps -ef | grep /srv/Bigdata/mppdb/data1/master1,找到对应的pid

    3)kill -9 pid

    4)等待该dn实例重新拉起

3)该情况可能也会在cn出现,按照上述处理即可。