diff --git a/CHANGELOG.md b/CHANGELOG.md index 24c260a93281..d1d5a1f4d43a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,7 @@ #### Core - Postgres TTL cleanup timer will now only run on traditional and control plane nodes that have enabled the Admin API. +- Postgres TTL cleanup timer now deletes maximum of 50.000 rows per table per cleanup round. ## 3.2.0 diff --git a/kong/db/strategies/postgres/connector.lua b/kong/db/strategies/postgres/connector.lua index cadfbe221712..834e97edf71f 100644 --- a/kong/db/strategies/postgres/connector.lua +++ b/kong/db/strategies/postgres/connector.lua @@ -325,13 +325,17 @@ function _mt:init_worker(strategies) local table_name = table_names[i] local column_name = table_name == "cluster_events" and expire_at_escaped or ttl_escaped - cleanup_statements[i] = concat { - " DELETE FROM ", - self:escape_identifier(table_name), - " WHERE ", - column_name, - " < CURRENT_TIMESTAMP AT TIME ZONE 'UTC';" - } + local table_name_escaped = self:escape_identifier(table_name) + + cleanup_statements[i] = fmt([[ + WITH rows AS ( + SELECT ctid + FROM %s + WHERE %s < CURRENT_TIMESTAMP AT TIME ZONE 'UTC' +ORDER BY %s LIMIT 50000 FOR UPDATE SKIP LOCKED) + DELETE + FROM %s + WHERE ctid IN (TABLE rows);]], table_name_escaped, column_name, column_name, table_name_escaped) end local cleanup_statement = concat(cleanup_statements, "\n")