PostgreSQLrotatetable自動清理排程-約束,觸發器
標籤
PostgreSQL , rotate table , 自動清理 , 觸發器 , insert into on conflict
背景
時序場景,這個需求很常見:
1、自動清理過期的歷史資料,並且要保證清理速度夠快,不產生WAL日誌。
要麼DROP,要麼truncate。
2、我們知道PG支援分割槽表,如果是通過分割槽的方法來實現,最好不過了,但是需要不停的建立分割槽,這個目前pg_pathman能夠滿足自動建立分割槽。但是自動刪除分割槽還是不夠自動。
所以怎麼做呢?
一個做法是這樣的:
1、固定一個週期的所有分割槽表(類似list分割槽),比如以小時為結尾的表,只需要24個。以周為單位的表,只需要7個。以分鐘為單位的表,需要60個。
2、自動根據資料插入的時間,觸發,並清理(truncate)舊的資料。
這種方法,寫入程式碼是固定的不需要變更。
資料表是一次性建立的,不需要後續再增加。
例子
1、建立週期內的所有明細分割槽表
以10分鐘為單位,建立6個表,代表每個10分鐘。
create table t1_0 (id int, info text, crt_time timestamp, check (substring(to_char(crt_time,`yyyymmddhh24miss`), 11, 1)=`0`));
create table t1_1 (id int, info text, crt_time timestamp, check (substring(to_char(crt_time,`yyyymmddhh24miss`), 11, 1)=`1`));
create table t1_2 (id int, info text, crt_time timestamp, check (substring(to_char(crt_time,`yyyymmddhh24miss`), 11, 1)=`2`));
create table t1_3 (id int, info text, crt_time timestamp, check (substring(to_char(crt_time,`yyyymmddhh24miss`), 11, 1)=`3`));
create table t1_4 (id int, info text, crt_time timestamp, check (substring(to_char(crt_time,`yyyymmddhh24miss`), 11, 1)=`4`));
create table t1_5 (id int, info text, crt_time timestamp, check (substring(to_char(crt_time,`yyyymmddhh24miss`), 11, 1)=`5`));
2、建立約束表,或者說排程表(因為我們不能每條記錄都觸發一個TRUNCATE事件)
以10分鐘為週期,清除10分鐘前的資料。
create table t_const(crt_time timestamp primary key);
3、建立分割槽表的觸發器,將資料按週期截斷後,寫入約束表。
create or replace function tg() returns trigger as $$
declare
begin
insert into t_const values (to_timestamp(substring(to_char(NEW.crt_time,`yyyymmddhh24miss`), 1, 11)||`000`,`yyyymmddhh24miss`)) on conflict (crt_time) do nothing;
return null;
end;
$$ language plpgsql strict;
create trigger tg1 after insert on t1_0 for each row execute procedure tg();
create trigger tg1 after insert on t1_1 for each row execute procedure tg();
create trigger tg1 after insert on t1_2 for each row execute procedure tg();
create trigger tg1 after insert on t1_3 for each row execute procedure tg();
create trigger tg1 after insert on t1_4 for each row execute procedure tg();
create trigger tg1 after insert on t1_5 for each row execute procedure tg();
4、建立約束表觸發器,觸發清除明細表分割槽的規則。
create or replace function tg_truncate() returns trigger as $$
declare
suffix int := substring(to_char(NEW.crt_time,`yyyymmddhh24miss`), 11, 1)::int;
begin
set lock_timeout = `1s`;
for i in 0..5 loop
if i=suffix then
continue;
end if;
if suffix=0 and i=5 then
continue;
end if;
if i=suffix-1 then
continue;
end if;
execute `truncate t1_`||i;
raise notice `truncated %`, `t1_`||i;
end loop;
return null;
end;
$$ language plpgsql strict;
create trigger tg1 after insert on t_const for each row execute procedure tg_truncate();
試一試
自動清除
postgres=# insert into t1_0 values (1,now(),`2018-01-02 10:00:40`);
NOTICE: truncated t1_1
NOTICE: truncated t1_2
NOTICE: truncated t1_3
NOTICE: truncated t1_4
INSERT 0 1
如果後面再寫入同一個區,不會觸發自動清除,符合要求(僅第一條觸發)。
postgres=# insert into t1_0 values (1,now(),`2018-01-02 10:00:40`);
INSERT 0 1
postgres=# insert into t1_0 values (1,now(),`2018-01-02 10:01:50`);
INSERT 0 1
小結
使用分割槽,實現了資料的分割槽存放。(目前如果使用原生分割槽表的話,寫入會對主表和所有子分割槽加共享鎖,導致無法truncate。建議方法:使用pg_pathman分割槽,或者直接寫子分割槽。)
《分割槽表鎖粒度差異 – pg_pathman VS native partition table》
使用TRUNCATE,使得清理資料時不會產生WAL日誌。
使用觸發器,實現了自動的資料清理。
參考
《PostgreSQL 資料rotate用法介紹 – 按時間覆蓋歷史資料》
《PostgreSQL APP海量FEED LOG實時質量統計CASE(含percentile_disc) – 含rotate 分割槽表》
相關文章
- 淺談APS生產排程在自動化排產考慮的約束
- SQL Server約束和DML觸發器的比較SQLServer觸發器
- 修改表名索引約束觸發器等物件不會失效索引觸發器物件
- Spark中shuffle的觸發和排程Spark
- MySQL 配置InnoDB清理排程MySql
- Oracle中檢視無效的物件、約束、觸發器和索引(Helloblock寫作)Oracle物件觸發器索引BloC
- Go語言排程器之主動排程(20)Go
- MySQL自增約束MySql
- 觸發器實現表資料自動更新觸發器
- Flink排程之排程器、排程策略、排程模式模式
- 如何在MySQL後設資料庫裡檢視索引,約束,觸發器,儲存過程和事件的相關資訊MySql資料庫索引觸發器儲存過程事件
- 快速部署crontab自動排程任務
- oracle自動生成編譯所有函式、儲存過程、觸發器的語句Oracle編譯函式儲存過程觸發器
- 【SQL】15 SQL 約束(Constraints)、NOT NULL 約束、UNIQUE 約束、PRIMARY KEY 約束、FOREIGN KEY 約束、CHECK 約束、DEFAULT約束SQLAINull
- TeamCity : 自動觸發 BuildUI
- Oracle RAC 利用RMAN自動排程備份Oracle
- Go排程器系列(2)巨集觀看排程器Go
- impdp做資料匯入時約束和觸發器引起資料匯入後應用故障觸發器
- Vue實現自動觸發功能Vue
- oracle儲存過程和觸發器Oracle儲存過程觸發器
- pbootcms模板自動清理runtime快取,自動清理快取boot快取
- 關於SQLServer2005的學習筆記——約束、Check、觸發器的執行順序SQLServer筆記觸發器
- 關於作業自動排程失敗後自動發郵件給操作員的問題
- 【freertos】005-啟動排程器分析
- Go排程器系列(3)圖解排程原理Go圖解
- 七、函式-儲存過程-觸發器函式儲存過程觸發器
- mysql 觸發器/過程中的變數!!MySql觸發器變數
- 儲存過程 檢視 觸發器 序列儲存過程觸發器
- Javaweb-約束-外來鍵約束JavaWeb
- goroutine 排程器(scheduler)Go
- MYSQL事件排程器MySql事件
- Oracle Windows平臺自動排程備份指令碼OracleWindows指令碼
- Go runtime 排程器精講(二):排程器初始化Go
- 排程器簡介,以及Linux的排程策略Linux
- Go語言排程器之排程main goroutine(14)GoAI
- Pod的排程是由排程器(kube-scheduler)
- Go runtime 排程器精講(五):排程策略Go
- Oracle目錄由於TFA觸發bug導致jdb檔案未自動清理引起空間不足Oracle