Como el n. ° 1 requiere copiar datos del maestro al hijo mientras está en un entorno de producción activo, personalmente fui con el n. ° 2 (crear un nuevo maestro). Esto evita interrupciones en la tabla original mientras está en uso activo y si hay algún problema, puedo eliminar fácilmente el nuevo maestro sin problemas y continuar usando la tabla original. Estos son los pasos para hacerlo:
Crear nueva tabla maestra.
CREATE TABLE new_master (
id serial,
counter integer,
dt_created DATE DEFAULT CURRENT_DATE NOT NULL
);
Crea hijos que hereden del maestro.
CREATE TABLE child_2014 (
CONSTRAINT pk_2014 PRIMARY KEY (id),
CONSTRAINT ck_2014 CHECK ( dt_created < DATE '2015-01-01' )
) INHERITS (new_master);
CREATE INDEX idx_2014 ON child_2014 (dt_created);
CREATE TABLE child_2015 (
CONSTRAINT pk_2015 PRIMARY KEY (id),
CONSTRAINT ck_2015 CHECK ( dt_created >= DATE '2015-01-01' AND dt_created < DATE '2016-01-01' )
) INHERITS (new_master);
CREATE INDEX idx_2015 ON child_2015 (dt_created);
...
Copie todos los datos históricos a la nueva tabla maestra
INSERT INTO child_2014 (id,counter,dt_created)
SELECT id,counter,dt_created
from old_master
where dt_created < '01/01/2015'::date;
Pause temporalmente nuevas inserciones / actualizaciones en la base de datos de producción
Copie los datos más recientes a la nueva tabla maestra
INSERT INTO child_2015 (id,counter,dt_created)
SELECT id,counter,dt_created
from old_master
where dt_created >= '01/01/2015'::date AND dt_created < '01/01/2016'::date;
Cambie el nombre de las tablas para que new_master se convierta en la base de datos de producción.
ALTER TABLE old_master RENAME TO old_master_backup;
ALTER TABLE new_master RENAME TO old_master;
Agregue la función para las instrucciones INSERT a old_master para que los datos pasen a la partición correcta.
CREATE OR REPLACE FUNCTION fn_insert() RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.dt_created >= DATE '2015-01-01' AND
NEW.dt_created < DATE '2016-01-01' ) THEN
INSERT INTO child_2015 VALUES (NEW.*);
ELSIF ( NEW.dt_created < DATE '2015-01-01' ) THEN
INSERT INTO child_2014 VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'Date out of range';
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
Agregue el disparador para que esa función se invoque en INSERTOS
CREATE TRIGGER tr_insert BEFORE INSERT ON old_master
FOR EACH ROW EXECUTE PROCEDURE fn_insert();
Establezca la exclusión de restricción en ON
SET constraint_exclusion = on;
Vuelva a habilitar ACTUALIZACIONES e INSERTOS en la base de datos de producción
Configure el disparador o cron para que se creen nuevas particiones y la función se actualice para asignar nuevos datos a la partición correcta. Consulte este artículo para ver ejemplos de código
Eliminar old_master_backup