Karena # 1 memerlukan menyalin data dari master ke anak ketika sedang dalam lingkungan produksi aktif, saya pribadi pergi dengan # 2 (membuat master baru). Ini mencegah gangguan ke tabel asli saat sedang aktif digunakan dan jika ada masalah, saya dapat dengan mudah menghapus master baru tanpa masalah dan terus menggunakan tabel asli. Berikut langkah-langkah untuk melakukannya:
Buat tabel master baru.
CREATE TABLE new_master (
id serial,
counter integer,
dt_created DATE DEFAULT CURRENT_DATE NOT NULL
);
Buat anak-anak yang mewarisi dari tuan.
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);
...
Salin semua data historis ke tabel master baru
INSERT INTO child_2014 (id,counter,dt_created)
SELECT id,counter,dt_created
from old_master
where dt_created < '01/01/2015'::date;
Jeda untuk sementara waktu sisipan / pembaruan baru ke basis data produksi
Salin data terbaru ke tabel master baru
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;
Ganti nama tabel sehingga new_master menjadi basis data produksi.
ALTER TABLE old_master RENAME TO old_master_backup;
ALTER TABLE new_master RENAME TO old_master;
Tambahkan fungsi untuk pernyataan INSERT ke old_master sehingga data diteruskan ke partisi yang benar.
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;
Tambah pemicu sehingga fungsinya dipanggil pada INSERTS
CREATE TRIGGER tr_insert BEFORE INSERT ON old_master
FOR EACH ROW EXECUTE PROCEDURE fn_insert();
Tetapkan pengecualian kendala ke ON
SET constraint_exclusion = on;
Aktifkan kembali UPDAT dan INSER pada basis data produksi
Atur pemicu atau cron agar partisi baru dibuat dan fungsinya diperbarui untuk menetapkan data baru ke partisi yang benar. Referensi artikel ini untuk contoh kode
Hapus old_master_backup