DBConnection.ConnectionError PID(XXX) 退出一些 sql 查询
DBConnection.ConnectionError PID(XXX) exited for some sql queries
我目前正在为这个错误而苦苦挣扎,因为我的服务器没有提供太多日志和信息。我有一个名为 /stop 的端点(下面提供了代码示例),在返回 :ok
之前,我在其中执行了很多代码。所有这些代码都包含在多个函数中,并通过多个文件和服务。
离这些函数结束不远了,我正在写入数据库。我有 3 个不同的插件。但是几天后,我遇到了这个错误:Postgrex.Protocol (#PID<0.375.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.543.0> exited
随机出现在这 3 个插入内容之一中。 (它可能是第一个,它可能在第二个中间,或者最后一个。有时(很少)它甚至不会失败)。我唯一能够隔离为 "trigger" 的是当插入的数据稍大时。它以前一直有效,当我试图通过 iex 直接插入那些相同的数据时,它也工作得很好。
在 Postgres 方面,我只有这个日志:LOG: unexpected EOF on client connection with an open transaction
。
控制器代码如下所示:
def stop(conn, params) do
case @influx_caller.end_connexion_performable?(params) do
true ->
handle_end_of_connexion(params)
conn |> send_resp(:ok, [])
false ->
if @influx_caller.connexion_data_from(params["connexion_key"]) == %{} do
update_connexion_with(:influx_empty, params, true)
end
conn |> send_resp(:forbidden, [])
end
end
end
end
故障发生在 handle_end_of_connexion
函数调用的其中一个文件的正常路径(案例的真实选项)中。例如在这个查询中:
Ecto.Changeset.change(connexion, %{
closed_at: Calculation.get_close_time(events),
})
|> Ecto.Changeset.put_assoc(:infos, MyApp.InfosGenerator.perform(obj, obj_type, twi, twl, events))
|> MyApp.Repo.update
可以从我的应用程序(类似于管理面板)中的另一个控制器调用具有完全相同数据的完全相同的文件,并且它工作得很好。所以我认为我的问题来自 /stop 端点。
到目前为止我测试过的东西:
正在检查我的 OTP 版本。当时是 21.3,我发现很多报告都在谈论类似的错误,所以我将其更新为 22.1.7
正在激活 show_sensitive_data_on_connection_error
希望它会添加一些日志来调查,但没有成功。
正在将 phoenix、plug_cowboy、postgrex 和 ecto 更新到最新版本。
在我的 Mix.Config 中添加 http: [protocol_options: [idle_timeout: :infinity]],
,因为我也从 cowboy 了解到超时,因为它是 2.0 版本。
None 的作品。 (当然,我也试过到处记录,但在本地模式下一切正常)
任何帮助或至少引导将不胜感激。提前致谢!
[编辑] 感谢观察者,我设法收集了这些额外信息:
发生此错误时:Postgrex.Protocol (#PID<0.422.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.31212.0> exited
,我在观察器中弹出这些行 =>
11:06:52:783159 (<0.31212.0>) out {lists,reverse,1}
11:06:52:783212 (<0.31212.0>) in {lists,reverse,1}
11:06:52:783218 (<0.31212.0>) << {inet_reply,#Port<0.71>,ok}
11:06:52:783234 (<0.31212.0>) out {prim_inet,send_recv_reply,2}
11:06:52:783243 (<0.31212.0>) in {prim_inet,send_recv_reply,2}
11:06:52:783247 (<0.31212.0>) out {prim_inet,recv0,3}
11:06:52:797698 (<0.31209.0>) in {cowboy_http,loop,1}
11:06:52:797725 (<0.31209.0>) << {tcp_closed,#Port<0.140>}
11:06:52:797750 (<0.31209.0>) getting_unlinked #Port<0.140>
11:06:52:797786 (<0.31209.0>) out {cowboy_children,terminate_loop,2}
11:06:52:797794 (<0.31212.0>) in {prim_inet,recv0,3}
11:06:52:797800 (<0.31212.0>) exit shutdown
11:06:52:797820 (<0.31212.0>) out_exited 0
11:06:52:797905 (<0.31209.0>) in {cowboy_children,terminate_loop,2}
11:06:52:797911 (<0.31209.0>) getting_unlinked <0.31212.0>
11:06:52:797915 (<0.31209.0>) << {'EXIT',<0.31212.0>,shutdown}
11:06:52:797943 (<0.31209.0>) exit {shutdown,{socket_error,closed,'The socket has been closed.'}}
11:06:52:797951 (<0.31209.0>) out_exited 0
进程在此处产生:
11:06:52:304313 (<0.31209.0>) spawn <0.31212.0> as proc_lib:init_p(<0.31209.0>,[<0.447.0>,<0.446.0>,'Elixir.Tracking.Endpoint',<0.414.0>,<0.413.0>],cowboy_stream_h,request_process,[#{body_length => 136,cert => undefined,has_body => true, [etc...]
我真的不明白什么以及为什么这个进程被关闭并且link丢失了:/
事实证明,自最近的牛仔更新以来,请求超时的处理方式有所不同。我发现最好(也是最干净)的解决方法是将调用我的控制器后所做的所有操作包装到一个全新的进程中。
我目前正在为这个错误而苦苦挣扎,因为我的服务器没有提供太多日志和信息。我有一个名为 /stop 的端点(下面提供了代码示例),在返回 :ok
之前,我在其中执行了很多代码。所有这些代码都包含在多个函数中,并通过多个文件和服务。
离这些函数结束不远了,我正在写入数据库。我有 3 个不同的插件。但是几天后,我遇到了这个错误:Postgrex.Protocol (#PID<0.375.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.543.0> exited
随机出现在这 3 个插入内容之一中。 (它可能是第一个,它可能在第二个中间,或者最后一个。有时(很少)它甚至不会失败)。我唯一能够隔离为 "trigger" 的是当插入的数据稍大时。它以前一直有效,当我试图通过 iex 直接插入那些相同的数据时,它也工作得很好。
在 Postgres 方面,我只有这个日志:LOG: unexpected EOF on client connection with an open transaction
。
控制器代码如下所示:
def stop(conn, params) do
case @influx_caller.end_connexion_performable?(params) do
true ->
handle_end_of_connexion(params)
conn |> send_resp(:ok, [])
false ->
if @influx_caller.connexion_data_from(params["connexion_key"]) == %{} do
update_connexion_with(:influx_empty, params, true)
end
conn |> send_resp(:forbidden, [])
end
end
end
end
故障发生在 handle_end_of_connexion
函数调用的其中一个文件的正常路径(案例的真实选项)中。例如在这个查询中:
Ecto.Changeset.change(connexion, %{
closed_at: Calculation.get_close_time(events),
})
|> Ecto.Changeset.put_assoc(:infos, MyApp.InfosGenerator.perform(obj, obj_type, twi, twl, events))
|> MyApp.Repo.update
可以从我的应用程序(类似于管理面板)中的另一个控制器调用具有完全相同数据的完全相同的文件,并且它工作得很好。所以我认为我的问题来自 /stop 端点。
到目前为止我测试过的东西:
正在检查我的 OTP 版本。当时是 21.3,我发现很多报告都在谈论类似的错误,所以我将其更新为 22.1.7
正在激活
show_sensitive_data_on_connection_error
希望它会添加一些日志来调查,但没有成功。正在将 phoenix、plug_cowboy、postgrex 和 ecto 更新到最新版本。
在我的 Mix.Config 中添加
http: [protocol_options: [idle_timeout: :infinity]],
,因为我也从 cowboy 了解到超时,因为它是 2.0 版本。
None 的作品。 (当然,我也试过到处记录,但在本地模式下一切正常)
任何帮助或至少引导将不胜感激。提前致谢!
[编辑] 感谢观察者,我设法收集了这些额外信息:
发生此错误时:Postgrex.Protocol (#PID<0.422.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.31212.0> exited
,我在观察器中弹出这些行 =>
11:06:52:783159 (<0.31212.0>) out {lists,reverse,1}
11:06:52:783212 (<0.31212.0>) in {lists,reverse,1}
11:06:52:783218 (<0.31212.0>) << {inet_reply,#Port<0.71>,ok}
11:06:52:783234 (<0.31212.0>) out {prim_inet,send_recv_reply,2}
11:06:52:783243 (<0.31212.0>) in {prim_inet,send_recv_reply,2}
11:06:52:783247 (<0.31212.0>) out {prim_inet,recv0,3}
11:06:52:797698 (<0.31209.0>) in {cowboy_http,loop,1}
11:06:52:797725 (<0.31209.0>) << {tcp_closed,#Port<0.140>}
11:06:52:797750 (<0.31209.0>) getting_unlinked #Port<0.140>
11:06:52:797786 (<0.31209.0>) out {cowboy_children,terminate_loop,2}
11:06:52:797794 (<0.31212.0>) in {prim_inet,recv0,3}
11:06:52:797800 (<0.31212.0>) exit shutdown
11:06:52:797820 (<0.31212.0>) out_exited 0
11:06:52:797905 (<0.31209.0>) in {cowboy_children,terminate_loop,2}
11:06:52:797911 (<0.31209.0>) getting_unlinked <0.31212.0>
11:06:52:797915 (<0.31209.0>) << {'EXIT',<0.31212.0>,shutdown}
11:06:52:797943 (<0.31209.0>) exit {shutdown,{socket_error,closed,'The socket has been closed.'}}
11:06:52:797951 (<0.31209.0>) out_exited 0
进程在此处产生:
11:06:52:304313 (<0.31209.0>) spawn <0.31212.0> as proc_lib:init_p(<0.31209.0>,[<0.447.0>,<0.446.0>,'Elixir.Tracking.Endpoint',<0.414.0>,<0.413.0>],cowboy_stream_h,request_process,[#{body_length => 136,cert => undefined,has_body => true, [etc...]
我真的不明白什么以及为什么这个进程被关闭并且link丢失了:/
事实证明,自最近的牛仔更新以来,请求超时的处理方式有所不同。我发现最好(也是最干净)的解决方法是将调用我的控制器后所做的所有操作包装到一个全新的进程中。