Em quais cenários uma instrução fica "idle in transaction"?
Quando as informações SQL do usuário são consultadas na exibição PGXC_STAT_ACTIVITY, a coluna state no resultado da consulta às vezes exibe idle in transaction. idle in transaction indica que o back-end está em uma transação, mas nenhuma instrução está sendo executada. Esse status indica que uma instrução foi executada. Portanto, o valor de query_id é 0, mas a transação não foi confirmada ou revertida. As instruções nesse estado foram executadas e não ocupam recursos de CPU e I/O, mas ocupam recursos de conexão, como conexões e conexões simultâneas.
Se uma instrução estiver no estado idle in transaction, corrija a falha referindo-se aos seguintes cenários e soluções comuns:
Cenário 1: uma transação é iniciada, mas não comprometida, e a instrução está no estado "idle in transaction"
BEGIN/START TRANSACTION é executada manualmente para iniciar uma transação. Depois que as instruções são executadas, COMMIT/ROLLBACK não é executada. Exiba o PGXC_STAT_ACTIVITY:
1
|
SELECT state, query, query_id FROM pgxc_stat_activity; |
O resultado mostra que a instrução está no estado idle in transaction.
Solução: execute manualmente COMMIT/ROLLBACK na transação iniciada.
Cenário 2: após uma instrução DDL em um procedimento armazenado é executado, outros nós do procedimento armazenado está no estado "idle in transaction"
1 2 3 4 5 6 7 8 9 10 11 |
CREATE OR REPLACE FUNCTION public.test_sleep() RETURNS void LANGUAGE plpgsql AS $$ BEGIN truncate t1; truncate t2; EXECUTE IMMEDIATE 'select pg_sleep(6)'; RETURN; END$$; |
1
|
SELECT coorname,pid,query_id,state,query,usename FROM pgxc_stat_activity WHERE usename='jack'; |
O resultado mostra que truncate t2 está no estado idle in transaction e coorname é ccoordinator2. Isso indica que a instrução foi executada em cn2 e o procedimento armazenado está executando a próxima instrução.
Solução: este problema é causado pela execução lenta do procedimento armazenado. Aguarde até que a execução do procedimento armazenado seja concluída. Você também pode otimizar as instruções que são executadas lentamente no procedimento armazenado.
Cenário 3: um grande número de instruções SAVEPOINT/RELEASE estão no estado "idle in transaction" (versões de cluster anteriores a 8.1.0)
Exiba a visão PGXC_STAT_ACTIVITY:
1
|
SELECT coorname,pid,query_id,state,query,usename FROM pgxc_stat_activity WHERE usename='jack'; |
O resultado mostra que a instrução SAVEPOINT/RELEASE está no estado idle in transaction.
Solução:
As instruções SAVEPOINT e RELEASE são geradas automaticamente pelo sistema quando um procedimento armazenado com EXCEPTION é executado. Em versões posteriores à 8.1.0, o SAVEPOINT não é entregue aos CNs. Os procedimentos armazenados do GaussDB(DWS) com EXCEPTION são implementados com base em subtransações, o mapeamento é o seguinte:
1 2 3 4 5 6 7 8 |
begin (Savepoint s1) DDL/DML exception (Rollback to s1) (Release s1) ... end |
Se houver EXCEPTION em um procedimento armazenado quando ele for iniciado, uma subtransação será iniciada. Se houver uma exceção durante a execução, a transação atual é revertida e a exceção é tratada; se não houver uma exceção, a subtransação é confirmada.
Esse problema pode ocorrer quando há muitos desses procedimentos armazenados e os procedimentos armazenados são aninhados. Semelhante ao cenário 2, você só tem que esperar depois que todo o procedimento armazenado é executado. Se houver um grande número de mensagens RELEAS, o procedimento armazenado aciona várias exceções. Neste caso, você tem que analisar se a lógica do procedimento armazenado é adequada.