Thank you. That $amount_partitions part is what I missed. It seems to be working exactly as you described then. Creating 10 partitions ahead and not deleting any older partitions until they are at least x days/months old. And the timezone is exactly as you said, so we are good there.
Ad Widget
Collapse
MySQL Partitioning recommendations request
Collapse
X
-
-
Awesome.
Don't forget to verify now if the script works nightly as scheduled in cron.
If you ever run into failures, the partitions are not created and you run out of pre-created partitions then just run the script as soon as you detect the problems and you should be good. But the best is to set up a Zabbix log item for monitoring of the failures in the log.
So I wish you good luck!Comment
-
First, I apologize for reviving an older thread, but this is exactly the situation I'm running into.
I'm performing a new installation of Zabbix 4.0.3 on MySQL 8.0.13, Centos 7 and I'm trying to get the external partitioning script working. I've gotten past the initial issue of it reporting that "MySQL does not support partitioning", but now I get the following message in /var/log/messages for all tables when I run the script from the command line:
mysql_zbx_part[123048]: Partitioning for "history" is not found! The table might be not partitioned.
mysql_zbx_part[123048]: Partitioning for "history_log" is not found! The table might be not partitioned.
mysql_zbx_part[123048]: Partitioning for "history_str" is not found! The table might be not partitioned.
mysql_zbx_part[123048]: Partitioning for "history_text" is not found! The table might be not partitioned.
mysql_zbx_part[123048]: Partitioning for "history_uint" is not found! The table might be not partitioned.
mysql_zbx_part[123048]: Partitioning for "trends" is not found! The table might be not partitioned.
mysql_zbx_part[123048]: Partitioning for "trends_uint" is not found! The table might be not partitioned.
The history* and trends* tables are partitioned:
SoCode:# ll /var/lib/mysql/zabbix/*2019* -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_04.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_05.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_06.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_07.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_08.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_09.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_10.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_11.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_12.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_13.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_log#P#p2019_01_14.ibd -rw-r-----. 1 mysql mysql 10485760 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_04.ibd -rw-r-----. 1 mysql mysql 27262976 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_05.ibd -rw-r-----. 1 mysql mysql 28311552 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_06.ibd -rw-r-----. 1 mysql mysql 29360128 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_07.ibd -rw-r-----. 1 mysql mysql 31457280 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_08.ibd -rw-r-----. 1 mysql mysql 32505856 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_09.ibd -rw-r-----. 1 mysql mysql 32505856 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_10.ibd -rw-r-----. 1 mysql mysql 32505856 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_11.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_12.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:08 /var/lib/mysql/zabbix/history#P#p2019_01_13.ibd -rw-r-----. 1 mysql mysql 12582912 Jan 14 11:19 /var/lib/mysql/zabbix/history#P#p2019_01_14.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_04.ibd -rw-r-----. 1 mysql mysql 180224 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_05.ibd -rw-r-----. 1 mysql mysql 180224 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_06.ibd -rw-r-----. 1 mysql mysql 212992 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_07.ibd -rw-r-----. 1 mysql mysql 212992 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_08.ibd -rw-r-----. 1 mysql mysql 229376 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_09.ibd -rw-r-----. 1 mysql mysql 229376 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_10.ibd -rw-r-----. 1 mysql mysql 229376 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_11.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_12.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_13.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 11:07 /var/lib/mysql/zabbix/history_str#P#p2019_01_14.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_04.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_05.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_06.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_07.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_08.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_09.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_10.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_11.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_12.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_13.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_text#P#p2019_01_14.ibd -rw-r-----. 1 mysql mysql 7340032 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_04.ibd -rw-r-----. 1 mysql mysql 19922944 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_05.ibd -rw-r-----. 1 mysql mysql 19922944 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_06.ibd -rw-r-----. 1 mysql mysql 24117248 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_07.ibd -rw-r-----. 1 mysql mysql 37748736 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_08.ibd -rw-r-----. 1 mysql mysql 41943040 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_09.ibd -rw-r-----. 1 mysql mysql 41943040 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_10.ibd -rw-r-----. 1 mysql mysql 41943040 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_11.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_12.ibd -rw-r-----. 1 mysql mysql 131072 Jan 14 08:07 /var/lib/mysql/zabbix/history_uint#P#p2019_01_13.ibd -rw-r-----. 1 mysql mysql 13631488 Jan 14 11:19 /var/lib/mysql/zabbix/history_uint#P#p2019_01_14.ibd -rw-r-----. 1 mysql mysql 14680064 Jan 14 11:02 /var/lib/mysql/zabbix/trends#P#p2019_01.ibd -rw-r-----. 1 mysql mysql 15728640 Jan 14 11:10 /var/lib/mysql/zabbix/trends_uint#P#p2019_01.ibd
I'm curious what sections were removed from the script. I commented out the sub check_have_partition { ...} and the call to the check_have_partition section.That helped a lot. So I removed some sections of the script and it seems to have worked. However, it didn't do what I expected and so I am wondering if I am understanding what it should do correctly. What it did was create the next 10 partitions into the future. I expected it would just create today's partitions and delete any older than I set in the time section (30 days, or 3 months or whatever). Did I misunderstand and it is working correctly, or did I edit it wrong somehow? Either way, it seems to be working, just surprised me a bit on it's behavior.
Code:#!/usr/bin/perl use strict; use Data::Dumper; use DBI; use Sys::Syslog qw(:standard :macros); use DateTime; use POSIX qw(strftime); openlog("mysql_zbx_part", "ndelay,pid", LOG_LOCAL0); my $db_schema = 'zabbix'; my $dsn = 'DBI:mysql:'.$db_schema.':mysql_socket=/var/lib/mysql/mysql.sock'; my $db_user_name = 'zbx_part'; my $db_password = '<Zabbix partitioning DB user password>'; my $tables = { 'history' => { 'period' => 'day', 'keep_history' => '30'}, 'history_log' => { 'period' => 'day', 'keep_history' => '30'}, 'history_str' => { 'period' => 'day', 'keep_history' => '30'}, 'history_text' => { 'period' => 'day', 'keep_history' => '30'}, 'history_uint' => { 'period' => 'day', 'keep_history' => '30'}, 'trends' => { 'period' => 'month', 'keep_history' => '12'}, 'trends_uint' => { 'period' => 'month', 'keep_history' => '12'}, }; my $amount_partitions = 10; my $curr_tz = 'Europe/Riga'; my $part_tables; my $dbh = DBI->connect($dsn, $db_user_name, $db_password); #unless ( check_have_partition() ) { #print "Your installation of MySQL does not support table partitioning.\n"; #syslog(LOG_CRIT, 'Your installation of MySQL does not support table partitioning.'); #exit 1; #} my $sth = $dbh->prepare(qq{SELECT table_name, partition_name, lower(partition_method) as partition_method, rtrim(ltrim(partition_expression)) as partition_expression, partition_description, table_rows FROM information_schema.partitions WHERE partition_name IS NOT NULL AND table_schema = ?}); $sth->execute($db_schema); while (my $row = $sth->fetchrow_hashref()) { $part_tables->{$row->{'table_name'}}->{$row->{'partition_name'}} = $row; } $sth->finish(); foreach my $key (sort keys %{$tables}) { unless (defined($part_tables->{$key})) { syslog(LOG_ERR, 'Partitioning for "'.$key.'" is not found! The table might be not partitioned.'); next; } create_next_partition($key, $part_tables->{$key}, $tables->{$key}->{'period'}); remove_old_partitions($key, $part_tables->{$key}, $tables->{$key}->{'period'}, $tables->{$key}->{'keep_history'}) } delete_old_data(); $dbh->disconnect(); #sub check_have_partition { #my $result = 0; # #my $sth = $dbh->prepare(qq{SELECT plugin_status FROM information_schema.plugins WHERE plugin_name = 'partition'}); # #$sth->execute(); # #my $row = $sth->fetchrow_array(); # #$sth->finish(); # #return 1 if $row eq 'ACTIVE'; #} sub create_next_partition { my $table_name = shift; my $table_part = shift; my $period = shift; for (my $curr_part = 0; $curr_part < $amount_partitions; $curr_part++) { my $next_name = name_next_part($tables->{$table_name}->{'period'}, $curr_part); my $found = 0; foreach my $partition (sort keys %{$table_part}) { if ($next_name eq $partition) { syslog(LOG_INFO, "Next partition for $table_name table has already been created. It is $next_name"); $found = 1; } } if ( $found == 0 ) { syslog(LOG_INFO, "Creating a partition for $table_name table ($next_name)"); my $query = 'ALTER TABLE '."$db_schema.$table_name".' ADD PARTITION (PARTITION '.$next_name. ' VALUES less than (UNIX_TIMESTAMP("'.date_next_part($tables->{$table_name}->{'period'}, $curr_part).'") div 1))'; syslog(LOG_DEBUG, $query); $dbh->do($query); } } } sub remove_old_partitions { my $table_name = shift; my $table_part = shift; my $period = shift; my $keep_history = shift; my $curr_date = DateTime->now; $curr_date->set_time_zone( $curr_tz ); if ( $period eq 'day' ) { $curr_date->add(days => -$keep_history); $curr_date->add(hours => -$curr_date->strftime('%H')); $curr_date->add(minutes => -$curr_date->strftime('%M')); $curr_date->add(seconds => -$curr_date->strftime('%S')); } elsif ( $period eq 'week' ) { } elsif ( $period eq 'month' ) { $curr_date->add(months => -$keep_history); $curr_date->add(days => -$curr_date->strftime('%d')+1); $curr_date->add(hours => -$curr_date->strftime('%H')); $curr_date->add(minutes => -$curr_date->strftime('%M')); $curr_date->add(seconds => -$curr_date->strftime('%S')); } foreach my $partition (sort keys %{$table_part}) { if ($table_part->{$partition}->{'partition_description'} <= $curr_date->epoch) { syslog(LOG_INFO, "Removing old $partition partition from $table_name table"); my $query = "ALTER TABLE $db_schema.$table_name DROP PARTITION $partition"; syslog(LOG_DEBUG, $query); $dbh->do($query); } } } sub name_next_part { my $period = shift; my $curr_part = shift; my $name_template; my $curr_date = DateTime->now; $curr_date->set_time_zone( $curr_tz ); if ( $period eq 'day' ) { my $curr_date = $curr_date->truncate( to => 'day' ); $curr_date->add(days => 1 + $curr_part); $name_template = $curr_date->strftime('p%Y_%m_%d'); } elsif ($period eq 'week') { my $curr_date = $curr_date->truncate( to => 'week' ); $curr_date->add(days => 7 * $curr_part); $name_template = $curr_date->strftime('p%Y_%m_w%W'); } elsif ($period eq 'month') { my $curr_date = $curr_date->truncate( to => 'month' ); $curr_date->add(months => 1 + $curr_part); $name_template = $curr_date->strftime('p%Y_%m'); } return $name_template; } sub date_next_part { my $period = shift; my $curr_part = shift; my $period_date; my $curr_date = DateTime->now; $curr_date->set_time_zone( $curr_tz ); if ( $period eq 'day' ) { my $curr_date = $curr_date->truncate( to => 'day' ); $curr_date->add(days => 2 + $curr_part); $period_date = $curr_date->strftime('%Y-%m-%d'); } elsif ($period eq 'week') { my $curr_date = $curr_date->truncate( to => 'week' ); $curr_date->add(days => 7 * $curr_part + 1); $period_date = $curr_date->strftime('%Y-%m-%d'); } elsif ($period eq 'month') { my $curr_date = $curr_date->truncate( to => 'month' ); $curr_date->add(months => 2 + $curr_part); $period_date = $curr_date->strftime('%Y-%m-%d'); } return $period_date; } sub delete_old_data { $dbh->do("DELETE FROM sessions WHERE lastaccess < UNIX_TIMESTAMP(NOW() - INTERVAL 1 MONTH)"); $dbh->do("TRUNCATE housekeeper"); $dbh->do("DELETE FROM auditlog_details WHERE NOT EXISTS (SELECT NULL FROM auditlog WHERE auditlog.auditid = auditlog_details.auditid)"); }Comment
-
I did a little more digging and I found another section to remove/comment out.
This allowed the partitions to be created. I sure there is good reason to have that in for error checking, but it is broken for MySQL 8.Code:foreach my $key (sort keys %{$tables}) { #unless (defined($part_tables->{$key})) { #syslog(LOG_ERR, 'Partitioning for "'.$key.'" is not found! The table might be not partitioned.'); #next; #} create_next_partition($key, $part_tables->{$key}, $tables->{$key}->{'period'}); remove_old_partitions($key, $part_tables->{$key}, $tables->{$key}->{'period'}, $tables->{$key}->{'keep_history'}) }
Here is my "working" script file.
Code:#!/usr/bin/perl use strict; use Data::Dumper; use DBI; use Sys::Syslog qw(:standard :macros); use DateTime; use POSIX qw(strftime); openlog("mysql_zbx_part", "ndelay,pid", LOG_LOCAL0); my $db_schema = 'zabbix'; my $dsn = 'DBI:mysql:'.$db_schema.':mysql_socket=/var/lib/mysql/mysql.sock'; my $db_user_name = 'zbx_part'; my $db_password = '<Zabbix partitioning DB user password>'; my $tables = { 'history' => { 'period' => 'day', 'keep_history' => '30'}, 'history_log' => { 'period' => 'day', 'keep_history' => '30'}, 'history_str' => { 'period' => 'day', 'keep_history' => '30'}, 'history_text' => { 'period' => 'day', 'keep_history' => '30'}, 'history_uint' => { 'period' => 'day', 'keep_history' => '30'}, 'trends' => { 'period' => 'month', 'keep_history' => '12'}, 'trends_uint' => { 'period' => 'month', 'keep_history' => '12'}, }; my $amount_partitions = 10; my $curr_tz = 'Europe/Riga'; my $part_tables; my $dbh = DBI->connect($dsn, $db_user_name, $db_password); my $sth = $dbh->prepare(qq{SELECT table_name, partition_name, lower(partition_method) as partition_method, rtrim(ltrim(partition_expression)) as partition_expression, partition_description, table_rows FROM information_schema.partitions WHERE partition_name IS NOT NULL AND table_schema = ?}); $sth->execute($db_schema); while (my $row = $sth->fetchrow_hashref()) { $part_tables->{$row->{'table_name'}}->{$row->{'partition_name'}} = $row; } $sth->finish(); foreach my $key (sort keys %{$tables}) { create_next_partition($key, $part_tables->{$key}, $tables->{$key}->{'period'}); remove_old_partitions($key, $part_tables->{$key}, $tables->{$key}->{'period'}, $tables->{$key}->{'keep_history'}) } delete_old_data(); $dbh->disconnect(); sub create_next_partition { my $table_name = shift; my $table_part = shift; my $period = shift; for (my $curr_part = 0; $curr_part < $amount_partitions; $curr_part++) { my $next_name = name_next_part($tables->{$table_name}->{'period'}, $curr_part); my $found = 0; foreach my $partition (sort keys %{$table_part}) { if ($next_name eq $partition) { syslog(LOG_INFO, "Next partition for $table_name table has already been created. It is $next_name"); $found = 1; } } if ( $found == 0 ) { syslog(LOG_INFO, "Creating a partition for $table_name table ($next_name)"); my $query = 'ALTER TABLE '."$db_schema.$table_name".' ADD PARTITION (PARTITION '.$next_name. ' VALUES less than (UNIX_TIMESTAMP("'.date_next_part($tables->{$table_name}->{'period'}, $curr_part).'") div 1))'; syslog(LOG_DEBUG, $query); $dbh->do($query); } } } sub remove_old_partitions { my $table_name = shift; my $table_part = shift; my $period = shift; my $keep_history = shift; my $curr_date = DateTime->now; $curr_date->set_time_zone( $curr_tz ); if ( $period eq 'day' ) { $curr_date->add(days => -$keep_history); $curr_date->add(hours => -$curr_date->strftime('%H')); $curr_date->add(minutes => -$curr_date->strftime('%M')); $curr_date->add(seconds => -$curr_date->strftime('%S')); } elsif ( $period eq 'week' ) { } elsif ( $period eq 'month' ) { $curr_date->add(months => -$keep_history); $curr_date->add(days => -$curr_date->strftime('%d')+1); $curr_date->add(hours => -$curr_date->strftime('%H')); $curr_date->add(minutes => -$curr_date->strftime('%M')); $curr_date->add(seconds => -$curr_date->strftime('%S')); } foreach my $partition (sort keys %{$table_part}) { if ($table_part->{$partition}->{'partition_description'} <= $curr_date->epoch) { syslog(LOG_INFO, "Removing old $partition partition from $table_name table"); my $query = "ALTER TABLE $db_schema.$table_name DROP PARTITION $partition"; syslog(LOG_DEBUG, $query); $dbh->do($query); } } } sub name_next_part { my $period = shift; my $curr_part = shift; my $name_template; my $curr_date = DateTime->now; $curr_date->set_time_zone( $curr_tz ); if ( $period eq 'day' ) { my $curr_date = $curr_date->truncate( to => 'day' ); $curr_date->add(days => 1 + $curr_part); $name_template = $curr_date->strftime('p%Y_%m_%d'); } elsif ($period eq 'week') { my $curr_date = $curr_date->truncate( to => 'week' ); $curr_date->add(days => 7 * $curr_part); $name_template = $curr_date->strftime('p%Y_%m_w%W'); } elsif ($period eq 'month') { my $curr_date = $curr_date->truncate( to => 'month' ); $curr_date->add(months => 1 + $curr_part); $name_template = $curr_date->strftime('p%Y_%m'); } return $name_template; } sub date_next_part { my $period = shift; my $curr_part = shift; my $period_date; my $curr_date = DateTime->now; $curr_date->set_time_zone( $curr_tz ); if ( $period eq 'day' ) { my $curr_date = $curr_date->truncate( to => 'day' ); $curr_date->add(days => 2 + $curr_part); $period_date = $curr_date->strftime('%Y-%m-%d'); } elsif ($period eq 'week') { my $curr_date = $curr_date->truncate( to => 'week' ); $curr_date->add(days => 7 * $curr_part + 1); $period_date = $curr_date->strftime('%Y-%m-%d'); } elsif ($period eq 'month') { my $curr_date = $curr_date->truncate( to => 'month' ); $curr_date->add(months => 2 + $curr_part); $period_date = $curr_date->strftime('%Y-%m-%d'); } return $period_date; } sub delete_old_data { $dbh->do("DELETE FROM sessions WHERE lastaccess < UNIX_TIMESTAMP(NOW() - INTERVAL 1 MONTH)"); $dbh->do("TRUNCATE housekeeper"); $dbh->do("DELETE FROM auditlog_details WHERE NOT EXISTS (SELECT NULL FROM auditlog WHERE auditlog.auditid = auditlog_details.auditid)"); }Comment
-
It worked for me without the Key section you mention above, but that may have something to do with the minor changes between versions for all I know. Either way, glad it is working for you. The sub check_have_partition { ...} and the call to the check_have_partition section were the two major points it hung up on for me.
-
-
It looks like the "working" was very loosely used. It does create the additional partitions, but the check to see if the partition already exists, doesn't seem to work properly.
Expected behavior is that if the partition is already created, it would output the info to the syslog. Currently, it is not recognizing that the exist. I ran the script twice, both times it claimed it created the partitions. The second time, the partitions already existed.Code:sub create_next_partition { my $table_name = shift; my $table_part = shift; my $period = shift; for (my $curr_part = 0; $curr_part < $amount_partitions; $curr_part++) { my $next_name = name_next_part($tables->{$table_name}->{'period'}, $curr_part); my $found = 0; foreach my $partition (sort keys %{$table_part}) { if ($next_name eq $partition) { syslog(LOG_INFO, "Next partition for $table_name table has already been created. It is $next_name"); $found = 1; } } if ( $found == 0 ) { syslog(LOG_INFO, "Creating a partition for $table_name table ($next_name)"); my $query = 'ALTER TABLE '."$db_schema.$table_name".' ADD PARTITION (PARTITION '.$next_name. ' VALUES less than (UNIX_TIMESTAMP("'.date_next_part($tables->{$table_name}->{'period'}, $curr_part).'") div 1))'; syslog(LOG_DEBUG, $query); $dbh->do($query); } } }
I suspect this will lead to old partitions not being removed as the script won't see they exist.Code:Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_02) Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_03) Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_04) Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_05) Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_06) Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_07) Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_08) Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_09) Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_10) Jan 14 14:12:42 mysql_zbx_part[6106]: Creating a partition for trends table (p2019_11) ......... Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_02) Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_03) Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_04) Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_05) Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_06) Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_07) Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_08) Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_09) Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_10) Jan 14 14:57:01 mysql_zbx_part[9022]: Creating a partition for trends table (p2019_11)
Hopefully someone with strong Perl and MySQL skills will be able to help with this.
Comment
-
The partitions show up in the file system:
And the MySQL DB shows the partitions as well.Code:# ll /var/lib/mysql/zabbix/trends#P* -rw-r-----. 1 mysql mysql 14680064 Jan 14 15:01 /var/lib/mysql/zabbix/trends#P#p2019_01.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_02.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_03.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_04.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_05.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_06.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_07.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_08.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_09.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_10.ibd -rw-r-----. 1 mysql mysql 114688 Jan 14 14:14 /var/lib/mysql/zabbix/trends#P#p2019_11.ibd
To me it looks like they exist.Code:mysql> SELECT TABLE_NAME, PARTITION_NAME from INFORMATION_SCHEMA.PARTITIONs where (table_name)='trends'; +------------+----------------+ | TABLE_NAME | PARTITION_NAME | +------------+----------------+ | trends | p2019_01 | | trends | p2019_02 | | trends | p2019_03 | | trends | p2019_04 | | trends | p2019_05 | | trends | p2019_06 | | trends | p2019_07 | | trends | p2019_08 | | trends | p2019_09 | | trends | p2019_10 | | trends | p2019_11 | +------------+----------------+ 11 rows in set (0.00 sec)
Comment
-
Yes, but they are not duplicates. It is the next 11 months of partitions. I don't see any p2019_01 multiple times, for example. That is the same way my system works.Last edited by steeladept; 15-01-2019, 00:01.
-
-
Correct, I suspect that the secondary create is failing because the partition already exists. Instead, it should see that it exists and not even attempt to create it. Thanks for your time looking into this.Comment
-
I tried to partitioned already running zabbix server but I stuck on this error "Table has no partition for value 1547596818". I followed the doc on zabbix wiki.
Any clue?
Code:MariaDB [zabbix]> ALTER TABLE `history` PARTITION BY RANGE (clock) (PARTITION p2019_01_15 VALUES LESS THAN (UNIX_TIMESTAMP("2019-01-16 00:00:00")) ENGINE = InnoDB); ERROR 1526 (HY000): Table has no partition for value 1547596818Code:MariaDB [zabbix]> SELECT FROM_UNIXTIME(MIN(clock)) FROM `history`; +---------------------------+ | FROM_UNIXTIME(MIN(clock)) | +---------------------------+ | 2019-01-15 08:00:14 | +---------------------------+ 1 row in set (2.026 sec)
Comment
-
It is because time value 1547596818 equals 2019-01-16T00:00:18 UTC. Therefore you need the command to include that day as well.
However, you might want to partition multiple days at once as per the doc, otherwise you will end up having all your current history in one partition and that should not be what you really want.Code:ALTER TABLE `history` PARTITION BY RANGE (clock) (PARTITION p2019_01_16 VALUES LESS THAN (UNIX_TIMESTAMP("2019-01-17 00:00:00")) ENGINE = InnoDB);Comment
-
I'm using the perl script partitioning, if I have items with :The list goes from oldest date up till today. Ascending that is. You were missing entry for the last day (today).
https://zabbix.org/wiki/Docs/howto/mysql_partitioning
should I edit these lines to match with my items?Code:history storage period: 30d trend storage period: 365d
thanksCode:my $tables = { 'history' => { 'period' => 'day', 'keep_history' => '30'}, 'history_log' => { 'period' => 'day', 'keep_history' => '30'}, 'history_str' => { 'period' => 'day', 'keep_history' => '30'}, 'history_text' => { 'period' => 'day', 'keep_history' => '30'}, 'history_uint' => { 'period' => 'day', 'keep_history' => '30'}, 'trends' => { 'period' => 'month', 'keep_history' => '2'}, 'trends_uint' => { 'period' => 'month', 'keep_history' => '2'},Comment
-
Yes, set values for trends and trends_uint tables to 12 months before running the script. Otherwise all your trend values older than 2 months will be lost.Comment
-
By no means is that manual for new users anyways. Moreover on the live production. You got to understand the whole concept, do it few times on some test system before going into production.Comment

Comment