【问题标题】:Automate Native Range Partitioning in PostgreSQL 10 for Zabbix 3.4在 PostgreSQL 10 for Zabbix 3.4 中自动化本机范围分区
【发布时间】:2018-05-16 19:39:01
【问题描述】:

我想使用 PostgreSQL 的本机范围分区自动化分区 Zabbix 3.4 数据库的过程。

编写 SQL 函数来执行以下操作或使用 shell/python 脚本会更明智吗?

  • 确保在需要之前至少创建一个分区。
  • 删除任何早于 x 周/月的分区; history 7 天和 trends 1 年

【问题讨论】:

  • 欢迎您!目前还不清楚你在问什么。您的代码是否存在特定问题,还是遇到特定错误?
  • 感谢@kisert 的欢迎;我正在寻求帮助来为所提供的代码开发脚本。我更新了帖子;希望现在更清楚了。
  • DribblzAroundU82 - 感谢更新。该站点更适合程序员获取有关他们的代码遇到的问题的答案。这不是一个真正邀请某人为您编写程序的地方。如果您为解决此问题而编写的代码有问题,请分享代码,让我们知道问题所在。
  • @kisert 好的,感谢您的更新

标签: postgresql plpgsql zabbix database-partitioning postgresql-10


【解决方案1】:

以下是我想出的从没有分区的 PSQL 9.4 填充数据库过渡到 PSQL 10 本机范围分区的解决方案。

A.创建一个 Zabbix 空 PSQL 10 数据库。

确保您首先创建一个空的 Zabbix PSQL 10 DB。

# su postgres
postgres@<>:~$ createuser -P -s -e zabbix
postgres@<>:~$ psql
postgres# create database zabbix;
postgres# grant all privileges on database zabbix to zabbix;

B.在clock 列上创建表和本机范围分区

在 Zabbix DB 中创建表并为时钟列实现原生范围分区。下面是一个手动 SQL 脚本的示例,它可以用于history 表。对要通过范围分区的所有 history 表执行此操作。

zabbix=# CREATE TABLE public.history
(
    itemid bigint NOT NULL,
    clock integer NOT NULL DEFAULT 0,
    value numeric(20,0) NOT NULL DEFAULT (0)::numeric,
    ns integer NOT NULL DEFAULT 0
) PARTITION BY RANGE (clock);

zabbix=# CREATE TABLE public.history_old PARTITION OF public.history
    FOR VALUES FROM (MINVALUE) TO (1522540800);
zabbix=# CREATE TABLE public.history_y2018m04 PARTITION OF public.history
    FOR VALUES FROM (1522540800) TO (1525132800);
zabbix=# CREATE TABLE public.history_y2018m05 PARTITION OF public.history
    FOR VALUES FROM (1525132800) TO (1527811200);

zabbix=# CREATE INDEX ON public.history_old USING btree (itemid, clock);
zabbix=# CREATE INDEX ON public.history_y2018m04 USING btree (itemid, clock);
zabbix=# CREATE INDEX ON public.history_y2018m05 USING btree (itemid, clock);

C.自动化它!

我使用了一个 shell 脚本,因为它是在 PSQL 10 中处理创建新分区的最简单方法之一。请确保您始终比所需分区至少提前一个分区。

让我们调用脚本auto_history_tables_monthly.sh

在运行 PSQL 10 的 Debian 8 Flavor 操作系统上,确保脚本位于具有正确权限 (chown postgres:postgres /usr/local/bin/auto_history_tables_monthly.sh) 的某个目录中(我使用了 /usr/local/bin)并使其可执行(chmod u+x /usr/local/bin/auto_history_tables_monthly.sh 作为 postgres 用户) .

postgres 用户创建一个 cron 作业 (crontab -e),并使用以下内容:

0 0 1 * * /usr/local/bin/auto_history_tables_monthly.sh | psql -d zabbix

这将在每个月的第一天运行 shell 脚本。

下面是脚本。它使用date 命令来利用UTC 纪元值。它提前一个月创建一个表并删除两个月前的分区。这似乎与根据我的需要定制的history 的 31 天保留结合起来效果很好。确保此用例的 PSQL 10 数据库处于 UTC 时间。

#!/bin/bash

month_diff () {
        year=$1
  month=$2
        delta_month=$3
  x=$((12*$year+10#$month-1))
        x=$((x+$delta_month))
        ry=$((x/12))
        rm=$(((x % 12)+1))
        printf "%02d %02d\n" $ry $rm
}

month_start () {
        year=$1
  month=$2
        date '+%s' -d "$year-$month-01 00:00:00" -u
}

month_end () {
        year=$1
  month=$2
        month_start $(month_diff $year $month 1)
}

# Year using date
current_year=$(date +%Y)
current_month=$(date +%m)

# Math
next_date=$(month_diff $current_year $current_month 1)
next_year=$(echo $next_date|sed 's/ .*//')
next_month=$(echo $next_date|sed 's/.* //')

start=$(month_start $next_date)
end=$(month_end $next_date)

#next_month_table="public.history_y${next_year}m${next_month}"

# Create next month table for history, history_uint, history_str, history_log, history_text
sql="
    CREATE TABLE IF NOT EXISTS public.history_y${next_year}m${next_month} PARTITION OF public.history
      FOR VALUES FROM ($start) TO ($end);
    \nCREATE TABLE IF NOT EXISTS public.history_uint_y${next_year}m${next_month} PARTITION OF public.history_uint
      FOR VALUES FROM ($start) TO ($end);
    \nCREATE TABLE IF NOT EXISTS public.history_str_y${next_year}m${next_month} PARTITION OF public.history_str
      FOR VALUES FROM ($start) TO ($end);
    \nCREATE TABLE IF NOT EXISTS public.history_log_y${next_year}m${next_month} PARTITION OF public.history_log
      FOR VALUES FROM ($start) TO ($end);
    \nCREATE TABLE IF NOT EXISTS public.history_text_y${next_year}m${next_month} PARTITION OF public.history_text
      FOR VALUES FROM ($start) TO ($end);
    \nCREATE INDEX on public.history_y${next_year}m${next_month} USING btree (itemid, clock);
    \nCREATE INDEX on public.history_uint_y${next_year}m${next_month} USING btree (itemid, clock);
    \nCREATE INDEX on public.history_str_y${next_year}m${next_month} USING btree (itemid, clock);
    \nCREATE INDEX on public.history_log_y${next_year}m${next_month} USING btree (itemid, clock);
    \nCREATE INDEX on public.history_text_y${next_year}m${next_month} USING btree (itemid, clock);
    "

echo -e $sql

# Math
prev_date=$(month_diff $current_year $current_month -2)
prev_year=$(echo $prev_date|sed 's/ .*//')
prev_month=$(echo $prev_date|sed 's/.* //')

# Drop last month table for history, history_uint, history_str, history_log, history_text
sql="
    DROP TABLE public.history_y${prev_year}m${prev_month};
    \nDROP TABLE public.history_uint_y${prev_year}m${prev_month};
    \nDROP TABLE public.history_str_y${prev_year}m${prev_month};
    \nDROP TABLE public.history_log_y${prev_year}m${prev_month};
    \nDROP TABLE public.history_text_y${prev_year}m${prev_month};
    "

echo -e $sql

D.然后将旧数据库中的数据转储到里面。我用pg_dump/pg_restore

我确信有更复杂的解决方案,但我发现这对于使用 PostgreSQL 10 本机范围分区功能自动分区 Zabbix 数据库的需求来说是最简单的。

如果您需要更多详细信息,请告诉我。

【讨论】:

    【解决方案2】:

    我已经写了关于使用 PostgreSQL 版本 11 和 pgpartman 作为 Zabbix 本地表分区机制的详细说明(撰写本文时版本为 3.4)。

    zabbix-postgres-partitioning

    【讨论】:

      猜你喜欢
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多