我正在使用Postgrex运行查询并将结果加载到流中,如下所示:
{:ok, host_pid} = Postgrex.start_link(hostname: "somewhere.hostname.io", username: "myuser", password: "mypass", database: "mydb")
Postgrex.transaction(host_pid, fn(conn) ->
# do query that takes 5 seconds
# with timeout set to be really big
query = Postgrex.prepare!(conn, "", "SELECT pg_sleep(5)", timeout: 50_000)
stream = Postgrex.stream(conn, query)
result_to_iodata = fn(%Postgrex.Result{rows: rows}) -> format_query_result(rows) end
Enum.into(stream, File.stream!("eg"), result_to_iodata)
end)但我得到了以下错误:
localhost$ mix run lib/MyPostgrexScript.exs
** (DBConnection.ConnectionError) connection not available and request was dropped
from queue after 2950ms. You can configure how long requests wait in the queue
using :queue_target and :queue_interval. See DBConnection.start_link/2 for more information
(db_connection) lib/db_connection.ex:836: DBConnection.transaction/3
lib/MyPostgrexScript.exs:3: MyPostgrexModule.sleep/0
(elixir) lib/code.ex:767: Code.require_file/2
(mix) lib/mix/tasks/run.ex:147: Mix.Tasks.Run.run/5由于我想要执行繁琐的查询,这肯定需要超过2950 my才能运行,所以我想知道如何配置Postgrex以让我的查询花费更多时间。我在https://hexdocs.pm/postgrex/Postgrex.html#transaction/3上读过关于https://hexdocs.pm/postgrex/Postgrex.html#transaction/3选项的文章,但是我不确定如何包含它,或者它是否是我想要的。
任何指导都是非常感谢的,谢谢!
发布于 2019-07-08 23:41:45
我在https://hexdocs.pm/postgrex/Postgrex.html#transaction/3上读到了:timeout选项,但我不确定如何包含它,
如下所示(参见最后一行):
Postgrex.transaction(
host_pid,
fn(conn) ->
# do query that takes 5 seconds
# with timeout set to be really big
query = Postgrex.prepare!(conn, "", "SELECT pg_sleep(5)", timeout: 50_000)
stream = Postgrex.stream(conn, query)
result_to_iodata = fn(%Postgrex.Result{rows: rows}) ->
format_query_result(rows)
end
Enum.into(stream, File.stream!("eg"), result_to_iodata)
end,
timeout: 30_000 #30 seconds
)每当灵丹妙药文档定义如下函数时:
func_name(arg1, ...argN, opts \\ [] )opts是关键字列表,例如:
[{:a, 1}, {:b, 2}]但是,如果关键字列表是函数调用中的最后一个参数,则关键字列表可以如下所示:
func(arg1, arg2, a: 1, b: 2)函数定义将接收以下三个参数
arg1, arg2, [{:a, 1}, {:b, 2}]在任何情况下,默认的:timeout是:
:timeout - Transaction timeout (default: 15000);错误上说:
连接不可用,请求在2950 was后从队列中删除。
因为2950 < 15000,它看起来不像是:timeout值是错误的来源。
错误消息继续:
没有连接..。可以使用:queue_target和:queue_interval配置请求在队列中等待的时间。有关更多信息,请参见DBConnection.start_link/2
这解释了如何配置这些超时:
在
config/<env>.exs中(其中<env>是dev、test或prod): 配置:my_app,MyApp.Repo,适配器: Ecto.Adapters.Postgres,pool_size: 10,migration_timestamps: type::utc_datetime_usec,migration_lock: nil,queue_target: 5000 是我们最近由于生产中的错误数量增加而不得不做的事情。
也是,
处理请求是通过队列完成的。启动DBConnection时,有两个相关选项来控制队列: :queue_target (毫秒),默认值为50 to (毫秒),默认为1000 to (毫秒) 我们的目标是等待最多的:queue_target连接。如果在:queue_interval期间签出的所有连接都比:queue_target多,那么我们将:queue_target加倍。如果签出连接比新目标花费的时间更长,那么我们就开始删除消息。 例如,默认情况下,我们的目标是50 is。如果所有的连接签出时间都超过50毫秒,我们将目标加倍到100毫秒,如果签出的时间超过新的限制,我们就开始删除消息。 这使我们能够更好地计划过载,因为我们可以在请求被发送到数据库之前拒绝它们,否则会增加数据库的负担,使重载更糟。
但是,如果您没有触及这些缺省值,那么我想知道为什么您在错误消息中看到的是2950ms,而不是更接近50 to或1000 to的东西。
https://stackoverflow.com/questions/56943306
复制相似问题