From b17d3dc6d8db91049e3ae8cd1d09f49432258bfc Mon Sep 17 00:00:00 2001 From: Oneric Date: Mon, 3 Jun 2024 23:09:17 +0200 Subject: [PATCH 1/3] Fix changelog Apparently got jumbled during some rebase(s) --- CHANGELOG.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a272d4a2..366716e40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## UNRELEASED + +## Added +- Implement [FEP-67ff](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md) (federation documentation) +- Meilisearch: it is now possible to use separate keys for search and admin actions + +## Fixed +- Meilisearch: order of results returned from our REST API now actually matches how Meilisearch ranks results + ## 2024.04.1 (Security) ## Fixed @@ -11,15 +20,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Issue allowing use of non-media objects as attachments and crashing timeline rendering - Issue allowing webfinger spoofing in certain situations -## Added -- Implement [FEP-67ff](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md) (federation documentation) - -## Added -- Meilisearch: it is now possible to use separate keys for search and admin actions - -## Fixed -- Meilisearch: order of results returned from our REST API now actually matches how Meilisearch ranks results - ## 2024.04 ## Added From a3840e7d1fc4f41a73db9b5d70f3957d283a6f35 Mon Sep 17 00:00:00 2001 From: Oneric Date: Thu, 2 May 2024 21:52:09 +0200 Subject: [PATCH 2/3] Raise minimum PostgreSQL version to 12 This lets us: - avoid issues with broken hash indices for PostgreSQL <10 - drop runtime checks and legacy codepaths for <11 in db search - always enable custom query plans for performance optimisation PostgreSQL 11 is already EOL since 2023-11-09, so in theory everyone should already have moved on to 12 anyway. --- CHANGELOG.md | 3 ++ config/config.exs | 6 ++- docs/docs/configuration/postgresql.md | 18 -------- .../installation/generic_dependencies.include | 2 +- lib/pleroma/application.ex | 25 ++--------- lib/pleroma/search/database_search.ex | 43 ++----------------- test/pleroma/search/database_search_test.exs | 15 ------- 7 files changed, 15 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 366716e40..b69cd6734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## UNRELEASED +## BREAKING +- Minimum PostgreSQL version is raised to 12 + ## Added - Implement [FEP-67ff](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md) (federation documentation) - Meilisearch: it is now possible to use separate keys for search and admin actions diff --git a/config/config.exs b/config/config.exs index e0a5eccb1..f2f5d4c0f 100644 --- a/config/config.exs +++ b/config/config.exs @@ -813,8 +813,10 @@ config :pleroma, :modules, runtime_dir: "instance/modules" config :pleroma, configurable_from_database: false config :pleroma, Pleroma.Repo, - parameters: [gin_fuzzy_search_limit: "500"], - prepare: :unnamed + parameters: [ + gin_fuzzy_search_limit: "500", + plan_cache_mode: "force_custom_plan" + ] config :pleroma, :majic_pool, size: 2 diff --git a/docs/docs/configuration/postgresql.md b/docs/docs/configuration/postgresql.md index 6e4596603..420ba7319 100644 --- a/docs/docs/configuration/postgresql.md +++ b/docs/docs/configuration/postgresql.md @@ -11,21 +11,3 @@ It is also recommended to not use "Network Storage" option. If your server runs other services, you may want to take that into account. E.g. if you have 4G ram, but 1G of it is already used for other services, it may be better to tell PGTune you only have 3G. In the end, PGTune only provides recomended settings, you can always try to finetune further. - -## Disable generic query plans - -When PostgreSQL receives a query, it decides on a strategy for searching the requested data, this is called a query plan. The query planner has two modes: generic and custom. Generic makes a plan for all queries of the same shape, ignoring the parameters, which is then cached and reused. Custom, on the contrary, generates a unique query plan based on query parameters. - -By default PostgreSQL has an algorithm to decide which mode is more efficient for particular query, however this algorithm has been observed to be wrong on some of the queries Akkoma sends, leading to serious performance loss. Therefore, it is recommended to disable generic mode. - - -Akkoma already avoids generic query plans by default, however the method it uses is not the most efficient because it needs to be compatible with all supported PostgreSQL versions. For PostgreSQL 12 and higher additional performance can be gained by adding the following to Akkoma configuration: -```elixir -config :pleroma, Pleroma.Repo, - prepare: :named, - parameters: [ - plan_cache_mode: "force_custom_plan" - ] -``` - -A more detailed explaination of the issue can be found at . diff --git a/docs/docs/installation/generic_dependencies.include b/docs/docs/installation/generic_dependencies.include index d7701a28f..87669bd23 100644 --- a/docs/docs/installation/generic_dependencies.include +++ b/docs/docs/installation/generic_dependencies.include @@ -1,6 +1,6 @@ ## Required dependencies -* PostgreSQL 9.6+ +* PostgreSQL 12+ * Elixir 1.14+ (currently tested up to 1.16) * Erlang OTP 25+ (currently tested up to OTP26) * git diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index e0fff6dd7..bd69e4b8f 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -95,10 +95,10 @@ defmodule Pleroma.Application do opts = [strategy: :one_for_one, name: Pleroma.Supervisor, max_restarts: max_restarts] - with {:ok, data} <- Supervisor.start_link(children, opts) do - set_postgres_server_version() - {:ok, data} - else + case Supervisor.start_link(children, opts) do + {:ok, data} -> + {:ok, data} + e -> Logger.error("Failed to start!") Logger.error("#{inspect(e)}") @@ -106,23 +106,6 @@ defmodule Pleroma.Application do end end - defp set_postgres_server_version do - version = - with %{rows: [[version]]} <- Ecto.Adapters.SQL.query!(Pleroma.Repo, "show server_version"), - {num, _} <- Float.parse(version) do - num - else - e -> - Logger.warning( - "Could not get the postgres version: #{inspect(e)}.\nSetting the default value of 9.6" - ) - - 9.6 - end - - :persistent_term.put({Pleroma.Repo, :postgres_version}, version) - end - def load_custom_modules do dir = Config.get([:modules, :runtime_dir]) diff --git a/lib/pleroma/search/database_search.ex b/lib/pleroma/search/database_search.ex index 3735a5fab..c6c43afd7 100644 --- a/lib/pleroma/search/database_search.ex +++ b/lib/pleroma/search/database_search.ex @@ -21,19 +21,12 @@ defmodule Pleroma.Search.DatabaseSearch do offset = Keyword.get(options, :offset, 0) author = Keyword.get(options, :author) - search_function = - if :persistent_term.get({Pleroma.Repo, :postgres_version}) >= 11 do - :websearch - else - :plain - end - try do Activity |> Activity.with_preloaded_object() |> Activity.restrict_deactivated_users() |> restrict_public() - |> query_with(index_type, search_query, search_function) + |> query_with(index_type, search_query) |> maybe_restrict_local(user) |> maybe_restrict_author(author) |> maybe_restrict_blocked(user) @@ -72,25 +65,7 @@ defmodule Pleroma.Search.DatabaseSearch do ) end - defp query_with(q, :gin, search_query, :plain) do - %{rows: [[tsc]]} = - Ecto.Adapters.SQL.query!( - Pleroma.Repo, - "select current_setting('default_text_search_config')::regconfig::oid;" - ) - - from([a, o] in q, - where: - fragment( - "to_tsvector(?::oid::regconfig, ?->>'content') @@ plainto_tsquery(?)", - ^tsc, - o.data, - ^search_query - ) - ) - end - - defp query_with(q, :gin, search_query, :websearch) do + defp query_with(q, :gin, search_query) do %{rows: [[tsc]]} = Ecto.Adapters.SQL.query!( Pleroma.Repo, @@ -108,19 +83,7 @@ defmodule Pleroma.Search.DatabaseSearch do ) end - defp query_with(q, :rum, search_query, :plain) do - from([a, o] in q, - where: - fragment( - "? @@ plainto_tsquery(?)", - o.fts_content, - ^search_query - ), - order_by: [fragment("? <=> now()::date", o.inserted_at)] - ) - end - - defp query_with(q, :rum, search_query, :websearch) do + defp query_with(q, :rum, search_query) do from([a, o] in q, where: fragment( diff --git a/test/pleroma/search/database_search_test.exs b/test/pleroma/search/database_search_test.exs index 2387ac29b..91bb4cfdf 100644 --- a/test/pleroma/search/database_search_test.exs +++ b/test/pleroma/search/database_search_test.exs @@ -18,21 +18,6 @@ defmodule Pleroma.Search.DatabaseSearchTest do assert result.id == post.id end - test "using plainto_tsquery on postgres < 11" do - old_version = :persistent_term.get({Pleroma.Repo, :postgres_version}) - :persistent_term.put({Pleroma.Repo, :postgres_version}, 10.0) - on_exit(fn -> :persistent_term.put({Pleroma.Repo, :postgres_version}, old_version) end) - - user = insert(:user) - {:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"}) - {:ok, _post2} = CommonAPI.post(user, %{status: "it's wednesday my bros"}) - - # plainto doesn't understand complex queries - assert [result] = DatabaseSearch.search(nil, "wednesday -dudes") - - assert result.id == post.id - end - test "using websearch_to_tsquery" do user = insert(:user) {:ok, _post} = CommonAPI.post(user, %{status: "it's wednesday my dudes"}) From 2180d068aef147ab544e2e17f6f420ed4fd2a71c Mon Sep 17 00:00:00 2001 From: Oneric Date: Thu, 2 May 2024 21:58:02 +0200 Subject: [PATCH 3/3] Raise log level for start failures --- lib/pleroma/application.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index bd69e4b8f..4a97dc5ae 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -100,8 +100,8 @@ defmodule Pleroma.Application do {:ok, data} e -> - Logger.error("Failed to start!") - Logger.error("#{inspect(e)}") + Logger.critical("Failed to start!") + Logger.critical("#{inspect(e)}") e end end