aprs.me/priv/repo/migrations/20250715183117_optimize_packet_counters_autovacuum.exs
Graham McIntire 400e444eaa
Fix packet_counters table bloat with sequence-based counter
- Add aggressive autovacuum settings for packet_counters table
- Replace table-based counter with PostgreSQL sequence to eliminate bloat
- Sequences are designed for high-frequency counter operations
- Maintains backward compatibility through get_packet_count() function

The packet_counters table was experiencing severe bloat due to 350K+ updates
on a single row. PostgreSQL sequences avoid this issue entirely.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 13:34:15 -05:00

52 lines
1.6 KiB
Elixir

defmodule Aprsme.Repo.Migrations.OptimizePacketCountersAutovacuum do
use Ecto.Migration
def up do
# Set aggressive autovacuum settings for the packet_counters table
# This table has only one row that gets updated frequently
execute """
ALTER TABLE packet_counters SET (
autovacuum_vacuum_scale_factor = 0.0,
autovacuum_vacuum_threshold = 100,
autovacuum_analyze_scale_factor = 0.0,
autovacuum_analyze_threshold = 100,
autovacuum_vacuum_cost_delay = 0,
autovacuum_vacuum_cost_limit = 10000
);
"""
# Add a fillfactor to reduce page splits during updates
execute """
ALTER TABLE packet_counters SET (fillfactor = 50);
"""
# Note: VACUUM FULL cannot run in a transaction, so we'll skip it here
# You can run it manually after the migration:
# VACUUM FULL packet_counters;
# Create a more efficient counter mechanism using unlogged table for high-frequency updates
# This is an alternative approach if the above doesn't solve the bloat issue
execute """
COMMENT ON TABLE packet_counters IS 'Single-row table for packet counts. Configured with aggressive autovacuum due to high update frequency.';
"""
end
def down do
# Reset to default autovacuum settings
execute """
ALTER TABLE packet_counters RESET (
autovacuum_vacuum_scale_factor,
autovacuum_vacuum_threshold,
autovacuum_analyze_scale_factor,
autovacuum_analyze_threshold,
autovacuum_vacuum_cost_delay,
autovacuum_vacuum_cost_limit,
fillfactor
);
"""
execute """
COMMENT ON TABLE packet_counters IS NULL;
"""
end
end