Remove all TimescaleDB features from migrations
- Convert snmp_sensor_readings to standard table - Convert snmp_interface_stats to standard table - Disable snmp_sensor_aggregates (continuous aggregates) - Disable snmp_interface_aggregates (continuous aggregates) All TimescaleDB commercial features (hypertables, continuous aggregates, retention/compression policies) are disabled. Using standard PostgreSQL tables with proper indexing instead.
This commit is contained in:
parent
94ce596319
commit
4216a5b7bf
4 changed files with 22 additions and 182 deletions
|
|
@ -2,11 +2,9 @@ defmodule Towerops.Repo.Migrations.CreateSnmpSensorReadings do
|
|||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
# Create the table with composite primary key (id, checked_at)
|
||||
# This is required for TimescaleDB hypertables
|
||||
create table(:snmp_sensor_readings, primary_key: false) do
|
||||
add :id, :binary_id, null: false
|
||||
|
||||
# Note: TimescaleDB features removed due to Apache license restrictions
|
||||
# Using standard PostgreSQL table instead
|
||||
create table(:snmp_sensor_readings) do
|
||||
add :sensor_id, references(:snmp_sensors, type: :binary_id, on_delete: :delete_all),
|
||||
null: false
|
||||
|
||||
|
|
@ -17,33 +15,11 @@ defmodule Towerops.Repo.Migrations.CreateSnmpSensorReadings do
|
|||
timestamps(type: :utc_datetime, updated_at: false)
|
||||
end
|
||||
|
||||
# Add composite primary key
|
||||
execute("ALTER TABLE snmp_sensor_readings ADD PRIMARY KEY (id, checked_at)")
|
||||
|
||||
# Convert to TimescaleDB hypertable (partitioned by checked_at)
|
||||
execute("SELECT create_hypertable('snmp_sensor_readings', 'checked_at')")
|
||||
|
||||
# Create indexes
|
||||
# Create indexes for query performance
|
||||
create index(:snmp_sensor_readings, [:sensor_id])
|
||||
create index(:snmp_sensor_readings, [:sensor_id, :checked_at])
|
||||
create index(:snmp_sensor_readings, [:status])
|
||||
|
||||
# Add retention policy: automatically drop data older than 90 days
|
||||
execute("""
|
||||
SELECT add_retention_policy('snmp_sensor_readings', INTERVAL '90 days')
|
||||
""")
|
||||
|
||||
# Add compression policy: compress chunks older than 7 days
|
||||
execute("""
|
||||
ALTER TABLE snmp_sensor_readings SET (
|
||||
timescaledb.compress,
|
||||
timescaledb.compress_segmentby = 'sensor_id'
|
||||
)
|
||||
""")
|
||||
|
||||
execute("""
|
||||
SELECT add_compression_policy('snmp_sensor_readings', INTERVAL '7 days')
|
||||
""")
|
||||
create index(:snmp_sensor_readings, [:checked_at])
|
||||
end
|
||||
|
||||
def down do
|
||||
|
|
|
|||
|
|
@ -2,11 +2,9 @@ defmodule Towerops.Repo.Migrations.CreateSnmpInterfaceStats do
|
|||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
# Create the table with composite primary key (id, checked_at)
|
||||
# This is required for TimescaleDB hypertables
|
||||
create table(:snmp_interface_stats, primary_key: false) do
|
||||
add :id, :binary_id, null: false
|
||||
|
||||
# Note: TimescaleDB features removed due to Apache license restrictions
|
||||
# Using standard PostgreSQL table instead
|
||||
create table(:snmp_interface_stats) do
|
||||
add :interface_id, references(:snmp_interfaces, type: :binary_id, on_delete: :delete_all),
|
||||
null: false
|
||||
|
||||
|
|
@ -21,32 +19,10 @@ defmodule Towerops.Repo.Migrations.CreateSnmpInterfaceStats do
|
|||
timestamps(type: :utc_datetime, updated_at: false)
|
||||
end
|
||||
|
||||
# Add composite primary key
|
||||
execute("ALTER TABLE snmp_interface_stats ADD PRIMARY KEY (id, checked_at)")
|
||||
|
||||
# Convert to TimescaleDB hypertable (partitioned by checked_at)
|
||||
execute("SELECT create_hypertable('snmp_interface_stats', 'checked_at')")
|
||||
|
||||
# Create indexes
|
||||
# Create indexes for query performance
|
||||
create index(:snmp_interface_stats, [:interface_id])
|
||||
create index(:snmp_interface_stats, [:interface_id, :checked_at])
|
||||
|
||||
# Add retention policy: automatically drop data older than 90 days
|
||||
execute("""
|
||||
SELECT add_retention_policy('snmp_interface_stats', INTERVAL '90 days')
|
||||
""")
|
||||
|
||||
# Add compression policy: compress chunks older than 7 days
|
||||
execute("""
|
||||
ALTER TABLE snmp_interface_stats SET (
|
||||
timescaledb.compress,
|
||||
timescaledb.compress_segmentby = 'interface_id'
|
||||
)
|
||||
""")
|
||||
|
||||
execute("""
|
||||
SELECT add_compression_policy('snmp_interface_stats', INTERVAL '7 days')
|
||||
""")
|
||||
create index(:snmp_interface_stats, [:checked_at])
|
||||
end
|
||||
|
||||
def down do
|
||||
|
|
|
|||
|
|
@ -1,70 +1,16 @@
|
|||
defmodule Towerops.Repo.Migrations.CreateSnmpSensorAggregates do
|
||||
use Ecto.Migration
|
||||
|
||||
# Disable DDL transaction for TimescaleDB continuous aggregates
|
||||
@disable_ddl_transaction true
|
||||
@disable_migration_lock true
|
||||
# Note: TimescaleDB continuous aggregates require commercial license
|
||||
# This migration is disabled - aggregates are computed in real-time instead
|
||||
|
||||
def up do
|
||||
# Hourly continuous aggregate for sensor readings
|
||||
execute("""
|
||||
CREATE MATERIALIZED VIEW snmp_sensor_readings_hourly
|
||||
WITH (timescaledb.continuous) AS
|
||||
SELECT
|
||||
sensor_id,
|
||||
time_bucket('1 hour', checked_at) AS bucket,
|
||||
COUNT(*) AS total_readings,
|
||||
AVG(value) AS avg_value,
|
||||
MIN(value) AS min_value,
|
||||
MAX(value) AS max_value,
|
||||
COUNT(*) FILTER (WHERE status = 'ok') AS ok_readings,
|
||||
COUNT(*) FILTER (WHERE status = 'warning') AS warning_readings,
|
||||
COUNT(*) FILTER (WHERE status = 'critical') AS critical_readings
|
||||
FROM snmp_sensor_readings
|
||||
GROUP BY sensor_id, bucket
|
||||
""")
|
||||
|
||||
# Add refresh policy for hourly aggregate (refresh every hour)
|
||||
execute("""
|
||||
SELECT add_continuous_aggregate_policy('snmp_sensor_readings_hourly',
|
||||
start_offset => INTERVAL '3 hours',
|
||||
end_offset => INTERVAL '1 hour',
|
||||
schedule_interval => INTERVAL '1 hour')
|
||||
""")
|
||||
|
||||
# Daily continuous aggregate for sensor readings
|
||||
execute("""
|
||||
CREATE MATERIALIZED VIEW snmp_sensor_readings_daily
|
||||
WITH (timescaledb.continuous) AS
|
||||
SELECT
|
||||
sensor_id,
|
||||
time_bucket('1 day', checked_at) AS bucket,
|
||||
COUNT(*) AS total_readings,
|
||||
AVG(value) AS avg_value,
|
||||
MIN(value) AS min_value,
|
||||
MAX(value) AS max_value,
|
||||
COUNT(*) FILTER (WHERE status = 'ok') AS ok_readings,
|
||||
COUNT(*) FILTER (WHERE status = 'warning') AS warning_readings,
|
||||
COUNT(*) FILTER (WHERE status = 'critical') AS critical_readings
|
||||
FROM snmp_sensor_readings
|
||||
GROUP BY sensor_id, bucket
|
||||
""")
|
||||
|
||||
# Add refresh policy for daily aggregate (refresh every day)
|
||||
execute("""
|
||||
SELECT add_continuous_aggregate_policy('snmp_sensor_readings_daily',
|
||||
start_offset => INTERVAL '3 days',
|
||||
end_offset => INTERVAL '1 day',
|
||||
schedule_interval => INTERVAL '1 day')
|
||||
""")
|
||||
|
||||
# Create indexes on the materialized views
|
||||
create index(:snmp_sensor_readings_hourly, [:sensor_id, :bucket])
|
||||
create index(:snmp_sensor_readings_daily, [:sensor_id, :bucket])
|
||||
# TimescaleDB continuous aggregates disabled due to license restrictions
|
||||
# Metrics are calculated on-demand in the application
|
||||
:ok
|
||||
end
|
||||
|
||||
def down do
|
||||
execute("DROP MATERIALIZED VIEW IF EXISTS snmp_sensor_readings_daily")
|
||||
execute("DROP MATERIALIZED VIEW IF EXISTS snmp_sensor_readings_hourly")
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,74 +1,16 @@
|
|||
defmodule Towerops.Repo.Migrations.CreateSnmpInterfaceAggregates do
|
||||
use Ecto.Migration
|
||||
|
||||
# Disable DDL transaction for TimescaleDB continuous aggregates
|
||||
@disable_ddl_transaction true
|
||||
@disable_migration_lock true
|
||||
# Note: TimescaleDB continuous aggregates require commercial license
|
||||
# This migration is disabled - aggregates are computed in real-time instead
|
||||
|
||||
def up do
|
||||
# Hourly continuous aggregate for interface stats
|
||||
execute("""
|
||||
CREATE MATERIALIZED VIEW snmp_interface_stats_hourly
|
||||
WITH (timescaledb.continuous) AS
|
||||
SELECT
|
||||
interface_id,
|
||||
time_bucket('1 hour', checked_at) AS bucket,
|
||||
COUNT(*) AS total_samples,
|
||||
AVG(if_in_octets) AS avg_in_octets,
|
||||
MAX(if_in_octets) AS max_in_octets,
|
||||
AVG(if_out_octets) AS avg_out_octets,
|
||||
MAX(if_out_octets) AS max_out_octets,
|
||||
SUM(if_in_errors) AS total_in_errors,
|
||||
SUM(if_out_errors) AS total_out_errors,
|
||||
SUM(if_in_discards) AS total_in_discards,
|
||||
SUM(if_out_discards) AS total_out_discards
|
||||
FROM snmp_interface_stats
|
||||
GROUP BY interface_id, bucket
|
||||
""")
|
||||
|
||||
# Add refresh policy for hourly aggregate (refresh every hour)
|
||||
execute("""
|
||||
SELECT add_continuous_aggregate_policy('snmp_interface_stats_hourly',
|
||||
start_offset => INTERVAL '3 hours',
|
||||
end_offset => INTERVAL '1 hour',
|
||||
schedule_interval => INTERVAL '1 hour')
|
||||
""")
|
||||
|
||||
# Daily continuous aggregate for interface stats
|
||||
execute("""
|
||||
CREATE MATERIALIZED VIEW snmp_interface_stats_daily
|
||||
WITH (timescaledb.continuous) AS
|
||||
SELECT
|
||||
interface_id,
|
||||
time_bucket('1 day', checked_at) AS bucket,
|
||||
COUNT(*) AS total_samples,
|
||||
AVG(if_in_octets) AS avg_in_octets,
|
||||
MAX(if_in_octets) AS max_in_octets,
|
||||
AVG(if_out_octets) AS avg_out_octets,
|
||||
MAX(if_out_octets) AS max_out_octets,
|
||||
SUM(if_in_errors) AS total_in_errors,
|
||||
SUM(if_out_errors) AS total_out_errors,
|
||||
SUM(if_in_discards) AS total_in_discards,
|
||||
SUM(if_out_discards) AS total_out_discards
|
||||
FROM snmp_interface_stats
|
||||
GROUP BY interface_id, bucket
|
||||
""")
|
||||
|
||||
# Add refresh policy for daily aggregate (refresh every day)
|
||||
execute("""
|
||||
SELECT add_continuous_aggregate_policy('snmp_interface_stats_daily',
|
||||
start_offset => INTERVAL '3 days',
|
||||
end_offset => INTERVAL '1 day',
|
||||
schedule_interval => INTERVAL '1 day')
|
||||
""")
|
||||
|
||||
# Create indexes on the materialized views
|
||||
create index(:snmp_interface_stats_hourly, [:interface_id, :bucket])
|
||||
create index(:snmp_interface_stats_daily, [:interface_id, :bucket])
|
||||
# TimescaleDB continuous aggregates disabled due to license restrictions
|
||||
# Metrics are calculated on-demand in the application
|
||||
:ok
|
||||
end
|
||||
|
||||
def down do
|
||||
execute("DROP MATERIALIZED VIEW IF EXISTS snmp_interface_stats_daily")
|
||||
execute("DROP MATERIALIZED VIEW IF EXISTS snmp_interface_stats_hourly")
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue