在PostgreSQL 10 for Zabbix 3.4中自动执行本机范围分区

在PostgreSQL 10 for Zabbix 3.4中自动执行本机范围分区,postgresql,plpgsql,zabbix,database-partitioning,postgresql-10,Postgresql,Plpgsql,Zabbix,Database Partitioning,Postgresql 10,我想使用PostgreSQL的本机范围分区自动化对Zabbix 3.4数据库进行分区的过程 编写一个SQL函数来执行下面的操作,还是使用shell/python脚本更明智 确保至少提前创建了一个分区 删除任何超过x周/月的分区;对于历史7天和趋势1年 以下是我提出的解决方案,用于从PSQL 9.4填充数据库(无分区)过渡到PSQL 10本机范围分区 A.创建一个Zabbix空PSQL 10数据库 确保首先创建一个空的Zabbix PSQL 10 DB # su postgres postgre

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

编写一个SQL函数来执行下面的操作,还是使用shell/python脚本更明智

  • 确保至少提前创建了一个分区
  • 删除任何超过x周/月的分区;对于
    历史
    7天和
    趋势
    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;
自动化它

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

让我们调用脚本
auto\u history\u tables\u monthly.sh

在运行PSQL 10的Debian 8操作系统上,确保脚本位于特定目录(我使用了
/usr/local/bin
)中,并具有正确的权限(
chown postgres:postgres/usr/local/bin/auto_history_tables\u monthly.sh
)并使其可执行(
chmodu+x/usr/local/bin/auto\u history\u tables\u monthly.sh
as
postgres
user)

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

0 0 1 * * /usr/local/bin/auto_history_tables_monthly.sh | psql -d zabbix
这将在每个月的第一天运行shell脚本

下面是脚本。它使用
date
命令来利用UTC历元值。它提前一个月创建一个表,并在2个月前删除一个分区。这似乎与根据我的需要定制的
history
的31天保留期配合使用,效果很好。确保PSQL 10 DB在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
然后从中的旧数据库转储数据。我使用了
pg\u dump/pg\u restore

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


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

我已经详细说明了如何使用PostgreSQL 11版和作为本机表分区机制的Zabbix(截至本文撰写之时为3.4版)


欢迎!不清楚你在问什么。你的代码有什么特别的问题,还是有什么特别的错误?谢谢你的欢迎@kismert;我正在寻找帮助为提供的代码开发脚本。我更新了帖子,希望现在更清楚了。DribblzAroundU82-谢谢你的更新。这个网站更适合你或程序员获得关于他们的代码问题的答案。这不是一个真正的地方,请他人为您编写程序。如果您在为解决此问题而编写的代码中遇到问题,请共享代码,并让我们知道问题所在。@kismert ok谢谢您的更新
#!/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