概述

PostgreSQL9.6 版本较之前版本新增了一个参数:idle_in_transaction_session_timeout ,该参数是为了自动查杀存在的空闲事物
idle in transaction。下面我们详细了解下这个参数

参数简介

PG在日常使用中会有 ‘idle in transaction’ 进程,引发这个进程的原因一般都是 代码中忘记关闭已开启的事物,或是系统中存在僵死的进程等。
‘idle in transaction’ 会阻止vacuum,造成数据膨胀,又有可能引起PG的事物ID wraparound的危险

为解决这个问题。9.6新增超时自动查杀空闲事物的功能
默认:idle_in_transaction_session_timeout = 20000
单位毫秒,也就是20秒就会自动查杀空闲事物

这个参数的设置,可以先仔细观察自己系统中是否经常存在空闲事物,要是存在的多,可以设置一下
如果自己的业务逻辑上,在事物开启后需要等待一些时间的话。需要考虑下这个超市设置多少合适,根据自己业务而定。
如果设置的过短,可能会对一些业务产生影响

简单测试

打开参数

该参数并不是默认开启,需要手动配置才能开启此功能。在postgresql.conf文件中找到添加 一行

  1. idle_in_transaction_session_timeout = 20000

修改此参数无需重启数据库,reload即可。应用连接也无需重连

  1. pg_ctl reload

设置之后在命令行可查看该参数设置

  1. postgres=# show idle_in_transaction_session_timeout;
  2. idle_in_transaction_session_timeout
  3. -------------------------------------
  4. 20s
  5. (1 row)

即表示已经启用

测试事物

开启一个事物,创建一张表插入一条数据

  1. postgres=# begin;
  2. BEGIN
  3. postgres=# create table test03(id int, name text);
  4. CREATE TABLE
  5. postgres=# insert into test03 values (1,'dasd');
  6. INSERT 0 1

此时查看事物状态,可以看到 state 为 idle in transaction,此时就触发了上述参数控制的内容。若在超时时间内继续事物操作,则无任何报错。但是一旦超过超时时间。事物就会被强制中断。

  1. select * from pg_stat_activity where pid<>pg_backend_pid();
  2. -[ RECORD 3 ]----+--------------------------------------
  3. datid | 13285
  4. datname | postgres
  5. pid | 2015
  6. usesysid | 10
  7. usename | postgres
  8. application_name | psql
  9. client_addr |
  10. client_hostname |
  11. client_port | -1
  12. backend_start | 2019-04-23 19:16:30.454131+08
  13. xact_start | 2019-04-23 21:25:04.850255+08
  14. query_start | 2019-04-23 21:25:46.20997+08
  15. state_change | 2019-04-23 21:25:46.210208+08
  16. wait_event_type | Client
  17. wait_event | ClientRead
  18. state | idle in transaction
  19. backend_xid | 606
  20. backend_xmin |
  21. query | insert into test03 values (1,'dasd');
  22. backend_type | client backend

超时等待

我们等待20s至事物超时。
再在原事物中随便执行一个命令
可以发现已经报错

  1. postgres=# select 1
  2. FATAL: terminating connection due to idle-in-transaction timeout
  3. server closed the connection unexpectedly
  4. This probably means the server terminated abnormally
  5. before or while processing the request.
  6. The connection to the server was lost. Attempting reset: Succeeded.
  7. postgres=#

我们在看下之前我们创建的表和插入的一条数据,已经不存在了,说明此参数杀事物时采用回滚的方式

结语

该参数在复杂的应用场景中可能会满足客户的业务需求。具体的超时时间需要客户根据自己的业务类型来做出选择。但是宜多不宜少,过少的话会将一些正在进行的事物回滚,导致出错。过多的话只会让清理慢一些。影响相对小一点。

0 评论  
添加一条新评论