在 PostgreSQL系数据库中(含GaussDB for OpenGauss),pg_stat_database
视图中的 xact_rollback
计数器表示 事务回滚(rollback)的次数。当这个值增加时,意味着数据库中发生了事务回滚操作。今日有客户的数据库环境监控了该指标,提示回滚率过高,谈谈我的看法。
首先监控回滚率是个不太使用的指标,于其监控 xact_commit 和 xact_rollback 的绝对值,不如监控自上次检查以来这些值的变化。否则,你将无法及时发现潜在的问题:如果已经正常运行了好几个月,那么需要很长时间的异常行为才能明显改变该比率。 不如当多长时间内达到频繁的rollback分析。
常见原因:
原因 | 是否增加 xact_rollback |
---|---|
显式 ROLLBACK | ✅ 是 |
错误导致自动回滚 | ✅ 是 |
客户端断开连接 | ✅ 是 |
ROLLBACK TO SAVEPOINT | ✅ 是(计入) |
触发器/函数异常 | ✅ 是 |
xact_rollback
增长过快,建议:检查数据库日志中的错误信息;
分析应用逻辑是否频繁使用回滚;
优化约束检查、死锁处理等机制;
提高代码健壮性,避免不必要的异常抛出。
下面简单的测试 –环境gaussdb
anbob=# select datname,xact_commit,xact_rollback from pg_stat_database; datname | xact_commit | xact_rollback -----------+-------------+--------------- anbob | 1271208 | 18 gauss | 1273563 | 10 (7 rows) anbob=# select 1; ?column? ---------- 1 (1 row) anbob=# select datname,xact_commit,xact_rollback from pg_stat_database; datname | xact_commit | xact_rollback -----------+-------------+--------------- anbob | 1271210 | 18 gauss | 1273563 | 10 (7 rows) anbob=# select * from tnotfound; ERROR: Relation "tnotfound" does not exist on anbob. LINE 1: select * from tnotfound; ^ anbob=# select datname,xact_commit,xact_rollback from pg_stat_database; datname | xact_commit | xact_rollback -----------+-------------+--------------- anbob | 1271217 | 19 《《《《《《《 gauss | 1273569 | 10 (7 rows) anbob=# create table t(id primary key); ERROR: syntax error at or near "primary" LINE 1: create table t(id primary key); ^ anbob=# select datname,xact_commit,xact_rollback from pg_stat_database; datname | xact_commit | xact_rollback -----------+-------------+--------------- anbob | 1271218 | 19 gauss | 1273569 | 10 (7 rows) anbob=# create table t(id int primary key); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pkey" for table "t" CREATE TABLE anbob=# select datname,xact_commit,xact_rollback from pg_stat_database; datname | xact_commit | xact_rollback -----------+-------------+--------------- anbob | 1271226 | 20 《《《《《《《 gauss | 1273577 | 10 (7 rows) anbob=# insert into t values(1); INSERT 0 1 anbob=# select datname,xact_commit,xact_rollback from pg_stat_database; datname | xact_commit | xact_rollback -----------+-------------+--------------- anbob | 1271228 | 20 《《《《《《《 gauss | 1273577 | 10 (7 rows) anbob=# insert into t values(1); ERROR: Duplicate key value violates unique constraint "t_pkey". DETAIL: Key (id)=(1) already exists. anbob=# select datname,xact_commit,xact_rollback from pg_stat_database; datname | xact_commit | xact_rollback -----------+-------------+--------------- anbob | 1271229 | 21 《《《《《《《 gauss | 1273577 | 10 (7 rows) anbob=# rollback; NOTICE: there is no transaction in progress ROLLBACK anbob=# select datname,xact_commit,xact_rollback from pg_stat_database; datname | xact_commit | xact_rollback -----------+-------------+--------------- anbob | 1271236 | 22 《《《《《《《 gauss | 1273583 | 10 (7 rows) anbob=# insert into t values(null); ERROR: The null value in column "id" violates the not-null constraint. DETAIL: Failing row contains (null). anbob=# select datname,xact_commit,xact_rollback from pg_stat_database; datname | xact_commit | xact_rollback -----------+-------------+--------------- anbob | 1271430 | 23 《《《《《《《 gauss | 1273770 | 10 (7 rows)
分析错误
参数配置 log_min_error_statement 为error (default)
anbob=# show log_min_error_statement anbob-# ; log_min_error_statement ------------------------- error
查找日志
$ grep -A 4 "\[BACKEND\] ERROR" gaussdb-2025-08-29_000000.log
...
2025-08-29 15:45:50.017 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742046 [BACKEND] ERROR: Relation "pg_stat_databae" does not exist on anbob. at character 320
2025-08-29 15:45:50.017 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742046 [BACKEND] CAUSE: Failed to recognize the relation.
2025-08-29 15:45:50.017 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742046 [BACKEND] ACTION: Check whether the specified position has the relation.
2025-08-29 15:45:50.017 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742046 [BACKEND] STATEMENT: select datname,round(100*(xact_rollback::numeric/(case when xact_commit > 0 then xact_commit else 1 end + xact_rollback)),2)||$$ %$$ rollback_ratio, round(100*(blks_hit::numeric/(case when blks_read>0 then blks_read else 1 end + blks_hit)),2)||$$ %$$ hit_ratio, blk_read_time, blk_write_time, conflicts, deadlocks from pg_stat_databae;
2025-08-29 15:45:52.697 gauss postgres localhost 281469869474304 0[0:0#0] 0 [INSTR] LOG: clean statement thread start
--
2025-08-29 15:47:12.238 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742087 [BACKEND] ERROR: Relation "tnotfound" does not exist on anbob. at character 15
2025-08-29 15:47:12.238 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742087 [BACKEND] CAUSE: Failed to recognize the relation.
2025-08-29 15:47:12.238 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742087 [BACKEND] ACTION: Check whether the specified position has the relation.
2025-08-29 15:47:12.238 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742087 [BACKEND] STATEMENT: select * from tnotfound;
2025-08-29 15:47:17.283 gauss postgres localhost 281471150768640 0[0:0#0] 0 [BACKEND] LOG: perf generate flamegraph report: flamegraph-2025-08-29_154711.html
--
2025-08-29 15:47:45.387 gauss anbob [local] 281469886317056 0[0:0#0] 0 [BACKEND] ERROR: syntax error at or near "primary" at character 19
2025-08-29 15:47:45.387 gauss anbob [local] 281469886317056 0[0:0#0] 0 [BACKEND] CAUSE: Syntax error happened.
2025-08-29 15:47:45.387 gauss anbob [local] 281469886317056 0[0:0#0] 0 [BACKEND] ACTION: Check character string.
2025-08-29 15:47:45.387 gauss anbob [local] 281469886317056 0[0:0#0] 0 [BACKEND] STATEMENT: create table t(id primary key);
2025-08-29 15:47:53.332 gauss postgres localhost 281469869474304 0[0:0#0] 0 [INSTR] LOG: clean statement thread start
--
2025-08-29 15:48:53.177 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742112 [BACKEND] ERROR: Duplicate key value violates unique constraint "t_pkey".
2025-08-29 15:48:53.177 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742112 [BACKEND] DETAIL: Key (id)=(1) already exists.
2025-08-29 15:48:53.177 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742112 [BACKEND] CAUSE: Duplicate key values exist.
2025-08-29 15:48:53.177 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742112 [BACKEND] ACTION: Remove the unique restriction, or do not insert the same key.
2025-08-29 15:48:53.177 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742112 [BACKEND] STATEMENT: insert into t values(1);
--
2025-08-29 16:18:15.404 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742661 [BACKEND] ERROR: The null value in column "id" violates the not-null constraint.
2025-08-29 16:18:15.404 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742661 [BACKEND] DETAIL: Failing row contains (null).
2025-08-29 16:18:15.404 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742661 [BACKEND] CAUSE: Not-null constraint check fails.
2025-08-29 16:18:15.404 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742661 [BACKEND] ACTION: Please check null data source.
2025-08-29 16:18:15.404 gauss anbob [local] 281469886317056 0[0:0#0] 1125899910742661 [BACKEND] STATEMENT: insert into t values(null);
— over —