PostgreSQL 9.3 长 运行 查询
PostgreSQL 9.3 long running queries
select vesseltrav0_.id as id1_0_, vesseltrav0_.created as created2_0_, vesseltrav0_.lastUpdated as lastUpda3_0_, vesseltrav0_.geoFenceId as geoFence4_0_,
vesseltrav0_.geoFenceName as geoFence5_0_, vesseltrav0_.mmsi as mmsi6_0_, vesseltrav0_.position as position7_0_, vesseltrav0_.timestamp as timestam8_0_,
vesseltrav0_.vesselEnteredTime as vesselEn9_0_, vesseltrav0_.vesselExitTime as vesselE10_0_, vesseltrav0_.vesselId as vesselI11_0_
from VESSEL_ENTERED_GEOFENCE vesseltrav0_ where vesseltrav0_.geoFenceId= and vesseltrav0_.vesselId=
我有一个守护进程将记录记录到数据库并定期更新它们,但似乎每小时一两次,这个看起来相当无辜的 SQL 将拒绝完成。
CREATE TABLE public.vessel_entered_geofence
(
id bigint NOT NULL,
geofenceid character varying(36),
geofencename character varying(128),
mmsi character varying(32),
vesselenteredtime timestamp without time zone,
vesselexittime timestamp without time zone,
vesselid character varying(36),
created timestamp without time zone,
lastupdated timestamp without time zone,
"position" geometry(Point,4326),
"timestamp" timestamp without time zone,
CONSTRAINT vessel_entered_geofence_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
CREATE INDEX vessel_entered_geofence_idx
ON public.vessel_entered_geofence
USING btree
(mmsi COLLATE pg_catalog."default");
CREATE INDEX vessel_entered_geofence_gid_idx
ON public.vessel_entered_geofence
USING btree
(geofenceid COLLATE pg_catalog."default");
CREATE INDEX vessel_entered_geofence_vid_idx
ON public.vessel_entered_geofence
USING btree
(vesselid COLLATE pg_catalog."default");
当我 运行 SQL 上的解释计划时,它正在使用索引并手动 运行 快速 SQL returns 一个答案.所有连接都处于空闲状态(编辑:它们都是 "idle in transaction")并且它们没有等待任何东西(根据 pg_stats_activity)。
select * from pg_stat_activity order by backend_start
http://i.stack.imgur.com/0pp8X.png
select a.*, b.relname from pg_locks a left outer join pg_class b on a.relation = b.oid
https://puu.sh/gGE9n/96da69d341.png
我不太确定接下来要看哪里来确定问题出在哪里,它们似乎处于空闲状态,没有等待任何事情,table 上没有导致它们挂起的锁(除非我读错了)。任何帮助将不胜感激。
我想我终于解决了这个问题。 Java 代码中缺少 begin/commit。
entityManager.getTransaction().begin();
//perform query
entityManager.getTransaction().commit();
即使查询只包含一条select语句,如果不封装在事务中也会挂起。
select vesseltrav0_.id as id1_0_, vesseltrav0_.created as created2_0_, vesseltrav0_.lastUpdated as lastUpda3_0_, vesseltrav0_.geoFenceId as geoFence4_0_,
vesseltrav0_.geoFenceName as geoFence5_0_, vesseltrav0_.mmsi as mmsi6_0_, vesseltrav0_.position as position7_0_, vesseltrav0_.timestamp as timestam8_0_,
vesseltrav0_.vesselEnteredTime as vesselEn9_0_, vesseltrav0_.vesselExitTime as vesselE10_0_, vesseltrav0_.vesselId as vesselI11_0_
from VESSEL_ENTERED_GEOFENCE vesseltrav0_ where vesseltrav0_.geoFenceId= and vesseltrav0_.vesselId=
我有一个守护进程将记录记录到数据库并定期更新它们,但似乎每小时一两次,这个看起来相当无辜的 SQL 将拒绝完成。
CREATE TABLE public.vessel_entered_geofence
(
id bigint NOT NULL,
geofenceid character varying(36),
geofencename character varying(128),
mmsi character varying(32),
vesselenteredtime timestamp without time zone,
vesselexittime timestamp without time zone,
vesselid character varying(36),
created timestamp without time zone,
lastupdated timestamp without time zone,
"position" geometry(Point,4326),
"timestamp" timestamp without time zone,
CONSTRAINT vessel_entered_geofence_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
CREATE INDEX vessel_entered_geofence_idx
ON public.vessel_entered_geofence
USING btree
(mmsi COLLATE pg_catalog."default");
CREATE INDEX vessel_entered_geofence_gid_idx
ON public.vessel_entered_geofence
USING btree
(geofenceid COLLATE pg_catalog."default");
CREATE INDEX vessel_entered_geofence_vid_idx
ON public.vessel_entered_geofence
USING btree
(vesselid COLLATE pg_catalog."default");
当我 运行 SQL 上的解释计划时,它正在使用索引并手动 运行 快速 SQL returns 一个答案.所有连接都处于空闲状态(编辑:它们都是 "idle in transaction")并且它们没有等待任何东西(根据 pg_stats_activity)。
select * from pg_stat_activity order by backend_start
select a.*, b.relname from pg_locks a left outer join pg_class b on a.relation = b.oid
我不太确定接下来要看哪里来确定问题出在哪里,它们似乎处于空闲状态,没有等待任何事情,table 上没有导致它们挂起的锁(除非我读错了)。任何帮助将不胜感激。
我想我终于解决了这个问题。 Java 代码中缺少 begin/commit。
entityManager.getTransaction().begin();
//perform query
entityManager.getTransaction().commit();
即使查询只包含一条select语句,如果不封装在事务中也会挂起。