Commit b0e5408f authored by Ignacio's avatar Ignacio
Browse files

Añade partman y pg_cron

Añade extensiones para hacer particiones en las
tablas por hora y autolimpieza con pg_cron
parent 1e67bba2
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
FROM mdillon/postgis:10-alpine
FROM mdillon/postgis:11-alpine

LABEL maintainer="info@redmic.es"

ENV PG_CRON_VERSION="1.1.4" \
	PG_PARTMAN_VERSION="4.0.0"

RUN apk add --no-cache --virtual .build-deps build-base ca-certificates openssl tar \
	    && wget -O /pg_cron.tgz https://github.com/citusdata/pg_cron/archive/v${PG_CRON_VERSION}.tar.gz \
	    && tar xvzf /pg_cron.tgz && cd pg_cron-$PG_CRON_VERSION \
	    && sed -i.bak -e 's/-Werror//g' Makefile \
	    && sed -i.bak -e 's/-Wno-implicit-fallthrough//g' Makefile \
	    && make && make install \
	    && cd .. && rm -rf pg_cron.tgz && rm -rf pg_cron-* \
	    && wget -O /pg_partman.tgz https://github.com/pgpartman/pg_partman/archive/v${PG_PARTMAN_VERSION}.tar.gz \
	    && tar xvzf /pg_partman.tgz \
	    && cd pg_partman-$PG_PARTMAN_VERSION \
	    && make \
	    && make install \
	    && cd .. && rm -rf pg_partman.tgz && rm -rf pg_partman-* \
	    && echo -e "shared_preload_libraries='pg_partman_bgw,pg_cron'" >> /usr/local/share/postgresql/postgresql.conf.sample

COPY /scripts/ /docker-entrypoint-initdb.d/
 No newline at end of file
+42 −81
Original line number Diff line number Diff line
@@ -3,19 +3,31 @@
set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
	CREATE SCHEMA IF NOT EXISTS ais;

	-- Install extensions
	CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
	CREATE EXTENSION IF NOT EXISTS pg_cron;
	CREATE SCHEMA IF NOT EXISTS partman;
	CREATE EXTENSION IF NOT EXISTS pg_partman SCHEMA partman;

	CREATE ROLE partman WITH LOGIN;
	GRANT ALL ON ALL TABLES IN SCHEMA partman TO partman;
	GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA partman TO partman;
	GRANT EXECUTE ON ALL PROCEDURES IN SCHEMA partman TO partman;
	GRANT ALL ON SCHEMA ais TO partman;

	-- Importante callSign y navStat en camelcase para coincidir con el esquema

	CREATE TABLE last_position
	CREATE TABLE ais.location_parent
	(
	  mmsi integer PRIMARY KEY,
	  uuid uuid NOT NULL DEFAULT uuid_generate_v4(),
	  mmsi integer NOT NULL,
	  shape geometry(Point,4326),
	  longitude double precision NOT NULL,
	  latitude double precision NOT NULL,
	  updated timestamp with time zone NOT NULL DEFAULT now(),
	  tstamp timestamp with time zone NOT NULL,
	  uuid uuid NOT NULL DEFAULT uuid_generate_v4(),
	  inserted timestamp with time zone NOT NULL,
	  cog double precision,
	  sog double precision,
@@ -32,103 +44,52 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-E
	  dest text,
	  "callSign" text,
	  eta text,
	  CONSTRAINT "mmsi_date_last_position" UNIQUE ("mmsi", "tstamp")
	)
	  PRIMARY KEY ("mmsi", "tstamp"),
	  CONSTRAINT "mmsi_date_location" UNIQUE ("mmsi", "tstamp")
	) PARTITION BY RANGE (tstamp)
	WITH (
	  OIDS=FALSE
	);

	CREATE INDEX sidx_last_position_shape
	  ON last_position
	CREATE INDEX IF NOT EXISTS sidx_location_shape
	  ON ais.location_parent
	  USING gist (shape);

	CREATE FUNCTION before_insert_or_update_save_change_date()
	RETURNS trigger
    LANGUAGE plpgsql
    AS \$\$
		BEGIN
			IF TG_OP = 'INSERT' THEN
				NEW.inserted := now();
			END IF;
			IF TG_OP = 'UPDATE' THEN
				NEW.inserted := OLD.inserted;
			END IF;
			NEW.updated := now();
			RETURN NEW;
		END;
	\$\$;
	SELECT partman.create_parent('ais.location_parent', 'tstamp', 'native', 'hourly');
	UPDATE partman.part_config SET infinite_time_partitions = true;

	CREATE TRIGGER tracking_before_insert_or_update_save_change_date
	  BEFORE INSERT OR UPDATE
	  ON last_position
	  FOR EACH ROW
	  EXECUTE PROCEDURE before_insert_or_update_save_change_date();
	-- View

	CREATE OR REPLACE FUNCTION create_shape()
	CREATE VIEW ais.location AS
		SELECT * FROM ais.location_parent;

	CREATE OR REPLACE FUNCTION ais.create_shape()
	RETURNS TRIGGER
	LANGUAGE plpgsql
	AS \$\$
		BEGIN
			-- Make geometry
			IF NEW.longitude IS NOT NULL AND NEW.latitude IS NOT NULL THEN
				SELECT ST_SetSRID(ST_MakePoint(NEW.longitude, NEW.latitude), 4326) INTO NEW.shape;
			END IF;

			-- Generate UUID and initialize insert date
			IF TG_OP = 'INSERT' THEN
				NEW.inserted := now();
				NEW.uuid := uuid_generate_v4();
			END IF;

			NEW.updated := now();
			INSERT INTO ais.location_parent SELECT NEW.*;
			RETURN NEW;
		END;
	\$\$;

	CREATE TRIGGER create_shape_last_position
		BEFORE INSERT OR UPDATE
		ON last_position
		FOR EACH ROW EXECUTE PROCEDURE create_shape();

	-- Last Week

	CREATE TABLE last_week
	(
	  uuid uuid NOT NULL DEFAULT uuid_generate_v4(),
	  mmsi integer NOT NULL,
	  shape geometry(Point,4326),
	  longitude double precision NOT NULL,
	  latitude double precision NOT NULL,
	  updated timestamp with time zone NOT NULL DEFAULT now(),
	  tstamp timestamp with time zone NOT NULL,
	  inserted timestamp with time zone NOT NULL,
	  cog double precision,
	  sog double precision,
	  draught double precision,
	  type integer,
	  a double precision,
	  b double precision,
	  c double precision,
	  d double precision,
	  imo integer,
	  heading integer,
	  "navStat" integer,
	  name text,
	  dest text,
	  "callSign" text,
	  eta text,
	  PRIMARY KEY ("mmsi", "tstamp"),
	  CONSTRAINT "mmsi_date_last_week" UNIQUE ("mmsi", "tstamp")
	)
	WITH (
	  OIDS=FALSE
	);

	CREATE INDEX sidx_last_week_shape
	  ON last_week
	  USING gist (shape);


	CREATE TRIGGER tracking_before_insert_or_update_save_change_date
	  BEFORE INSERT OR UPDATE
	  ON last_week
	  FOR EACH ROW
	  EXECUTE PROCEDURE before_insert_or_update_save_change_date();
	CREATE TRIGGER location_create_shape_location
		INSTEAD OF INSERT OR UPDATE
		ON ais.location
		FOR EACH ROW EXECUTE PROCEDURE ais.create_shape();

	SELECT cron.schedule('@hourly', \$\$SELECT partman.run_maintenance_proc(p_analyze := false)\$\$)

	CREATE TRIGGER create_shape_last_week
		BEFORE INSERT OR UPDATE
		ON last_week
		FOR EACH ROW EXECUTE PROCEDURE create_shape();
EOSQL
 No newline at end of file