AlmaLinux9.6 部署 MariaDB10.11 和 Zabbix7.0 完整教程
准备工作
系统要求
-
操作系统: AlmaLinux 9.6 64 位系统
-
内存: 至少 2GB 内存(推荐 4GB+)
-
磁盘空间: 至少 20GB 磁盘空间
-
网络: 网络连接正常
网络配置
Server端:
-
静态 IP 配置: 192.168.1.31
-
子网掩码: 255.255.255.0
-
网关: 192.168.1.1
-
DNS: 8.8.8.8, 8.8.4.4
Agent端:
-
静态 IP 配置: 192.168.1.32
-
子网掩码: 255.255.255.0
-
网关: 192.168.1.2
-
DNS: 8.8.8.8, 8.8.4.4
初始环境配置
# 更新系统
sudo dnf update -y# 安装必要依赖
sudo dnf install -y wget curl vim net-tools firewall# 启用并启动防火墙(测试环境可以不启用防火墙)
sudo systemctl enable firewall
sudo systemctl start firewall# 配置防火墙规则
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=3306/tcp
sudo firewall-cmd --permanent --add-port=10050/tcp
sudo firewall-cmd --permanent --add-port=10051/tcp
sudo firewall-cmd --reload# 关闭SELinux(临时)
sudo setenforce 0# 关闭SELinux(永久)
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
部署 MariaDB 10.11
添加 MariaDB 官方仓库
# 创建MariaDB仓库文件
sudo vim /etc/yum.repos.d/MariaDB.repo# 粘贴以下内容
[mariadb]
name = MariaDB
baseurl = https://mirrors.ustc.edu.cn/mariadb/yum/10.11/rhel/9/x86_64/
enable=1
gpgkey=https://mirrors.ustc.edu.cn/mariadb/yum/RPM-GPG-KEY-MariaDB
gpgcheck=1
说明
可以将gpgcheck设为0
安装 MariaDB 服务器
# 安装MariaDB服务器和客户端
sudo dnf install -y MariaDB-server MariaDB-client MariaDB-devel# 设置MariaDB开机自启并立即启动MariaDB服务
sudo systemctl enable --now mariadb# 检查MariaDB服务状态
sudo systemctl status mariadb
安全配置 MariaDB
重要:
请按照提示设置 root 密码为 YourPwd@123!
mysql -u root -p-- 1. 修改root密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourPwd@123!';-- 2. 删除匿名用户(匿名用户允许无密码登录,存在安全风险)
DELETE FROM mysql.user WHERE User = '';-- 3. 禁止 root 用户远程登录(仅保留本地登录)
-- 注意:若需保留特定 IP 的 root 远程访问,可修改条件(如 Host = '192.168.1.%')
DELETE FROM mysql.user WHERE User = 'root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');-- 4. 删除默认的 test 数据库及访问权限
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db = 'test' OR Db = 'test_%';-- 5. 刷新权限表,使所有配置生效
FLUSH PRIVILEGES;
配置 MariaDB 绑定 IP 地址
# 编辑MariaDB配置文件
sudo vim /etc/my.cnf.d/mariadb-server.cnf# 在[mysqld]部分添加以下内容[mysqld]
bind-address = 192.168.1.31
max_connections = 1000
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2# 重启MariaDB服务
sudo systemctl restart mariadb# 验证配置是否生效
sudo netstat -tlnp | grep 3306
部署 Zabbix 7.0
添加 Zabbix 官方仓库
# 安装Zabbix仓库
sudo rpm -Uvh https://repo.zabbix.com/zabbix/7.0/rhel/9/x86_64/zabbix-release-7.0-2.el9.noarch.rpm# 清理缓存并生成新缓存
sudo dnf clean all
sudo dnf makecache
安装 Zabbix 服务器和 Web 界面
# 安装Zabbix服务器、Web界面和Agent
sudo dnf install -y zabbix-server-mysql zabbix-web-mysql zabbix-nginx-conf zabbix-sql-scripts zabbix-agent
创建 Zabbix 数据库和用户
# 登录MySQLmysql -u root -pYourPwd@123!# 在MySQL命令行中执行以下命令
create database zabbix character set utf8mb4 collate utf8mb4_bin;
create user zabbix@192.168.1.31 identified by 'YourPwd@123!';
GRANT ALL PRIVILEGES ON zabbix.* TO 'zabbix'@'%' IDENTIFIED BY 'YourPwd@123!';
set global log_bin_trust_function_creators = 1;
quit;
导入 Zabbix 数据库架构
# 导入Zabbix数据库架构
zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql --default-character-set=utf8mb4 -u zabbix -pYourPwd@123! zabbix# 重新登录MySQL并禁用log_bin_trust_function_creators
mysql -u root -pYourPwd@123!
set global log_bin_trust_function_creators = 0;
quit;
配置 Zabbix 表自动分区
MySQL 表分区是一种将大型表分割成更小、更易于管理的部分的技术。按天分区可以:
- 提高查询性能:只扫描相关日期的数据
- 简化数据管理:方便按时间范围归档或删除数据
- 优化维护操作:可以单独对某个分区进行备份、优化等操作
安装 Perl DateTime 模块(重要前置步骤)
重要提示:
mysql_zbx_part.pl 脚本依赖 Perl 模块,如果缺少此模块,脚本将无法运行。
# 安装EPEL仓库
sudo dnf install epel-release -y
sudo dnf config-manager --enable crb# 安装perl-DateTime包
sudo dnf install perl-DateTime perl-DBD-MySQL perl-Sys-Syslog -y# 验证安装是否成功
perl -e "use DateTime; print 'DateTime模块安装成功\n';"# 如果上述方法失败,可以使用CPAN安装
# sudo dnf install perl-CPAN -y
# sudo cpan DateTime
下载分区脚本
# 创建脚本目录
sudo mkdir -p /usr/lib/zabbix/scripts
cd /usr/lib/zabbix/scripts# 方法1:直接从GitHub下载(推荐)
sudo wget https://raw.githubusercontent.com/OpensourceICTSolutions/zabbix-mysql-partitioning-perl/master/mysql_zbx_part.pl# 方法2:如果GitHub访问缓慢,可以使用Gitee镜像
# sudo wget https://gitee.com/mirrors/zabbix-mysql-partitioning-perl/raw/master/mysql_zbx_part.pl# 设置权限
sudo chmod 750 mysql_zbx_part.pl
sudo chown zabbix:zabbix mysql_zbx_part.pl
初始化分区表结构(重要)
重要提示:
Zabbix 默认创建的表为非分区表,必须先执行分区初始化操作,否则会出现 “Partition management on a not partitioned table is not possible” 错误。
1. 备份数据库(关键前置步骤)
# 备份zabbix数据库到文件
mysqldump -u root -pYourPwd@123! -h 192.168.1.31 zabbix > /root/zabbix_backup_$(date +%Y%m%d).sql# 检查备份文件
ls -lh /root/zabbix_backup_*.sql
2. 手动执行分区初始化 SQL(必须要做)
mysql -u root -pYourPwd@123! -h 192.168.1.31-- ==================== Zabbix数据库表分区初始化脚本 ====================
-- 注意:执行前请先备份数据库-- mysqldump -u root -pYourPwd@123! -h 192.168.1.31 zabbix > /root/zabbix_backup_$(date +%Y%m%d).sql
USE zabbix;-- ==================== 1. trends表(按月分区)====================ALTER TABLE trends
PARTITION BY RANGE (clock) (PARTITION p2025_11 VALUES LESS THAN (UNIX_TIMESTAMP('2025-12-01 00:00:00'))
);-- ==================== 2. trends_uint表(按月分区)====================ALTER TABLE trends_uint
PARTITION BY RANGE (clock) (PARTITION p2025_11 VALUES LESS THAN (UNIX_TIMESTAMP('2025-12-01 00:00:00'))
);-- ==================== 3. history表(按天分区)====================ALTER TABLE history
PARTITION BY RANGE (clock) (PARTITION p2025_11_16 VALUES LESS THAN (UNIX_TIMESTAMP('2025-11-17 00:00:00'))
);-- ==================== 4. history_uint表(按天分区)====================ALTER TABLE history_uint
PARTITION BY RANGE (clock) (PARTITION p2025_11_16 VALUES LESS THAN (UNIX_TIMESTAMP('2025-11-17 00:00:00'))
);-- ==================== 5. history_text表(按天分区)====================ALTER TABLE history_text
PARTITION BY RANGE (clock) (PARTITION p2025_11_16 VALUES LESS THAN (UNIX_TIMESTAMP('2025-11-17 00:00:00'))
);-- ==================== 6. history_str表(按天分区)====================ALTER TABLE history_str
PARTITION BY RANGE (clock) (PARTITION p2025_11_16 VALUES LESS THAN (UNIX_TIMESTAMP('2025-11-17 00:00:00'))
);-- ==================== 7. history_log表(按天分区)====================ALTER TABLE history_log
PARTITION BY RANGE (clock) (PARTITION p2025_11_16 VALUES LESS THAN (UNIX_TIMESTAMP('2025-11-17 00:00:00'))
);-- ==================== 8. history_bin表(按天分区,Zabbix7.0新增)====================ALTER TABLE history_bin
PARTITION BY RANGE (clock) (PARTITION p2025_11_16 VALUES LESS THAN (UNIX_TIMESTAMP('2025-11-17 00:00:00'))
);
quit;
执行完成后查看分区情况:
mysql -u root -pYourPwd@123! -e "
SELECT TABLE_NAME, PARTITION_NAME, PARTITION_METHOD
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix'
AND PARTITION_NAME IS NOT NULL;"
+--------------+----------------+------------------+
| TABLE_NAME | PARTITION_NAME | PARTITION_METHOD |
+--------------+----------------+------------------+
| trends | p2025_11 | RANGE |
| trends_uint | p2025_11 | RANGE |
| history | p2025_11_16 | RANGE |
| history_uint | p2025_11_16 | RANGE |
| history_text | p2025_11_16 | RANGE |
| history_str | p2025_11_16 | RANGE |
| history_log | p2025_11_16 | RANGE |
| history_bin | p2025_11_16 | RANGE |
+--------------+----------------+------------------+
8 rows in set (0.003 sec)
配置分区脚本
# 编辑分区脚本
sudo vim /usr/lib/zabbix/scripts/mysql_zbx_part.pl
# 调整各表分区及保留期限
my $tables = { 'history' => { 'period' => 'day', 'keep_history' => '365'},'history_log' => { 'period' => 'day', 'keep_history' => '365'},'history_str' => { 'period' => 'day', 'keep_history' => '365'},'history_text' => { 'period' => 'day', 'keep_history' => '365'},'history_uint' => { 'period' => 'day', 'keep_history' => '365'},# 下面这张表history_bin是zabbix7.0以上版本新增的'history_bin' => { 'period' => 'day', 'keep_history' => '365'},'trends' => { 'period' => 'month', 'keep_history' => '24'},'trends_uint' => { 'period' => 'month', 'keep_history' => '24'},};# 第83行,将:
my $dbh = DBI->connect($dsn, $db_user_name, $db_password);
修改为:
my $dbh = DBI->connect($dsn, 'zabbix', 'YourPwd@123!');
# 不然执行的时候会报错,提示密码问题
修改日志输出位置(这部分操作可选,做不做都行)
表分区脚本默认把日志写入到syslog,也就是/var/log/message文件,不便于观察日志,我们手动修改日志路径
在脚本开头手动定义 syslog 相关常量
#!/usr/bin/perl
use strict;
use DBI;
use DateTime;use constant {LOG_EMERG => 0,LOG_ALERT => 1,LOG_CRIT => 2,LOG_ERR => 3,LOG_WARNING => 4,LOG_NOTICE => 5,LOG_INFO => 6,LOG_DEBUG => 7,
};
注释或删除 else 块中与 syslog 相关的代码,改用文件输出:
else {# 注释这两行#use Sys::Syslog qw(:standard :macros);#openlog("mysql_zbx_part", "ndelay,pid", LOG_LOCAL0);#新增这行,将日志写入/var/log/zabbix_partition.logopen(OUTPUT, ">>", "/var/log/zabbix_partition.log") or die "无法打开日志文件: $!";# edit next 5 lines if the script is run directly in your server$db_schema = 'zabbix';$dsn = 'DBI:mysql:'.$db_schema.':mysql_socket=/var/lib/mysql/mysql.sock';$db_user_name = 'zabbix';$db_password = 'password';$curr_tz = 'Etc/UTC';
}
** 修改log_writer函数**
sub log_writer {my $log_line = shift;if ($is_container) {print OUTPUT $log_line . "\n";}else {# 注释下面两行#my $log_priority = shift;#syslog($log_priority, $log_line);# 新增下面这行,确保日志输出到指定位置print OUTPUT $log_line . "\n";}
以上修改完成后,完整脚本如下:
[root@zabbix-server scripts]# cat mysql_zbx_part.pl
#!/usr/bin/perl
use strict;
use DBI;
use DateTime;use constant {LOG_EMERG => 0,LOG_ALERT => 1,LOG_CRIT => 2,LOG_ERR => 3,LOG_WARNING => 4,LOG_NOTICE => 5,LOG_INFO => 6,LOG_DEBUG => 7,
};# the Dockerfile will change the value to 1 in the container build process
my $is_container = 0;
# initializing some variables
my $db_schema;
my $db_host;
my $db_port;
my $dsn;
my $db_user_name;
my $db_password;
my $curr_tz;if ($is_container) {# check if environment variables existsif (not defined $ENV{'DB_HOST'}or not defined $ENV{'DB_PORT'}or not defined $ENV{'DB_DATABASE'}or not defined $ENV{'DB_USER'}or not defined $ENV{'DB_PASSWORD'}or not defined $ENV{'LOG_PATH'}or not defined $ENV{'TZ'}) {print "Environment variables are missing! Exiting...\n";exit 1;}# open log fileopen( OUTPUT, ">>", $ENV{'LOG_PATH'} ) or die $!;# do not manually modify the next 7 lines, they are only used when the script is run in a container$db_schema = $ENV{'DB_DATABASE'};$db_host = $ENV{'DB_HOST'};$db_port = $ENV{'DB_PORT'};$dsn = 'DBI:mysql:'.$db_schema.':host='.$db_host.';port='.$db_port;$db_user_name = $ENV{'DB_USER'};$db_password = $ENV{'DB_PASSWORD'};$curr_tz = $ENV{'TZ'};
}
else {# 注释这两行#use Sys::Syslog qw(:standard :macros);#openlog("mysql_zbx_part", "ndelay,pid", LOG_LOCAL0);#新增这行,将日志写入/var/log/zabbix_partition.logopen(OUTPUT, ">>", "/var/log/zabbix_partition.log") or die "无法打开日志文件: $!";# edit next 5 lines if the script is run directly in your server$db_schema = 'zabbix';$dsn = 'DBI:mysql:'.$db_schema.':mysql_socket=/var/lib/mysql/mysql.sock';$db_user_name = 'zabbix';$db_password = 'password';$curr_tz = 'Etc/UTC';
}my $tables = { 'history' => { 'period' => 'day', 'keep_history' => '60'},'history_log' => { 'period' => 'day', 'keep_history' => '60'},'history_str' => { 'period' => 'day', 'keep_history' => '60'},'history_text' => { 'period' => 'day', 'keep_history' => '60'},'history_uint' => { 'period' => 'day', 'keep_history' => '60'},
# Comment the history_bin line below if you're running Zabbix versions older than 7.0'history_bin' => { 'period' => 'day', 'keep_history' => '60'},'trends' => { 'period' => 'month', 'keep_history' => '12'},'trends_uint' => { 'period' => 'month', 'keep_history' => '12'},# comment next 5 lines if you partition zabbix database starting from 2.2
# they usually used for zabbix database before 2.2# 'acknowledges' => { 'period' => 'month', 'keep_history' => '23'},
# 'alerts' => { 'period' => 'month', 'keep_history' => '6'},
# 'auditlog' => { 'period' => 'month', 'keep_history' => '24'},
# 'events' => { 'period' => 'month', 'keep_history' => '12'},
# 'service_alarms' => { 'period' => 'month', 'keep_history' => '6'},};
my $amount_partitions = 20;# name templates for the different periods
my $partition_name_templates = { 'day' => 'p%Y_%m_%d','week' => 'p%Y_w%V','month' => 'p%Y_%m',};my $part_tables;my $dbh = DBI->connect($dsn, 'zabbix', 'Zhaoll@95598jx');unless ( check_have_partition() ) {print "Your installation of MySQL does not support table partitioning.\n";log_writer('Your installation of MySQL does not support table partitioning.', LOG_CRIT);exit 1;
}my $sth = $dbh->prepare(qq{SELECT table_name as table_name, partition_name as partition_name,lower(partition_method) as partition_method, rtrim(ltrim(partition_expression)) as partition_expression,partition_description as partition_description, table_rowsFROM information_schema.partitionsWHERE 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})) {log_writer('Partitioning for "'.$key.'" is not found! The table might be not partitioned.', LOG_ERR);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 {
# MySQL 5.5
# #my $sth = $dbh->prepare(qq{SELECT variable_value FROM information_schema.global_variables WHERE variable_name = 'have_partitioning'});
#return 1 if $row eq 'YES';
#
# End of Mysql 5.5# MySQL 5.6 + MariaDBmy $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';# End of MySQL 5.6 + MariaDB# MySQL 8.x (NOT MariaDB!)
# my $sth = $dbh->prepare(qq{select version();});
# $sth->execute();
# my $row = $sth->fetchrow_array();# $sth->finish();
# return 1 if $row >= 8;
#
# End of MySQL 8.x# Do not uncomment last }
}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($period, $curr_part);if (grep { $_ eq $next_name } keys %{$table_part}) {log_writer("Next partition for $table_name table has already been created. It is $next_name", LOG_INFO);}else {log_writer("Creating a partition for $table_name table ($next_name)", LOG_INFO);my $query = 'ALTER TABLE '."$db_schema.$table_name".' ADD PARTITION (PARTITION '.$next_name.' VALUES less than (UNIX_TIMESTAMP("'.date_next_part($period, $curr_part).'") div 1))';log_writer($query, LOG_DEBUG);$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( time_zone => $curr_tz );$curr_date->subtract($period.'s' => $keep_history);$curr_date->truncate(to => $period);foreach my $partition (sort keys %{$table_part}) {if ($table_part->{$partition}->{'partition_description'} <= $curr_date->epoch) {log_writer("Removing old $partition partition from $table_name table", LOG_INFO);my $query = "ALTER TABLE $db_schema.$table_name DROP PARTITION $partition";log_writer($query, LOG_DEBUG);$dbh->do($query);}}
}sub name_next_part {my $period = shift;my $curr_part = shift;unless (defined $partition_name_templates->{$period}) {die "unsupported partitioning period '$period'\n";}my $curr_date = DateTime->now( time_zone => $curr_tz );$curr_date->truncate( to => $period );$curr_date->add( $period.'s' => $curr_part );return $curr_date->strftime($partition_name_templates->{$period});
}sub date_next_part {my $period = shift;my $curr_part = shift;my $curr_date = DateTime->now( time_zone => $curr_tz );$curr_date->truncate( to => $period );$curr_date->add( $period.'s' => 1 + $curr_part );return $curr_date->strftime('%Y-%m-%d');
}sub delete_old_data {$dbh->do("DELETE FROM sessions WHERE lastaccess < UNIX_TIMESTAMP(NOW() - INTERVAL 1 MONTH)");$dbh->do("DELETE FROM housekeeper WHERE `tablename` !='events'");# Uncomment the following line for Zabbix 5.4 and earlier
# $dbh->do("DELETE FROM auditlog_details WHERE NOT EXISTS (SELECT NULL FROM auditlog WHERE auditlog.auditid = auditlog_details.auditid)");
}sub log_writer {my $log_line = shift;if ($is_container) {print OUTPUT $log_line . "\n";}else {# 注释下面两行#my $log_priority = shift;#syslog($log_priority, $log_line);# 新增下面这行,确保日志输出到指定位置print OUTPUT $log_line . "\n";}
}
测试分区脚本
# 测试运行分区脚本(--dry-run选项仅显示操作,不实际执行)
sudo /usr/lib/zabbix/scripts/mysql_zbx_part.pl --dry-run# 如果没有错误,执行实际分区
sudo /usr/lib/zabbix/scripts/mysql_zbx_part.pl# 检查日志
journalctl -t mysql_zbx_part
验证分区是否创建成功
mysql -u root -pYourPwd@123! -e "
SELECT TABLE_NAME, PARTITION_NAME, PARTITION_METHOD
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix'
AND PARTITION_NAME IS NOT NULL;"
+--------------+----------------+------------------+
| TABLE_NAME | PARTITION_NAME | PARTITION_METHOD |
+--------------+----------------+------------------+
| history_text | p2025_11_16 | RANGE |
| history_text | p2025_11_17 | RANGE |
| history_text | p2025_11_18 | RANGE |
| history_text | p2025_11_19 | RANGE |
| history_text | p2025_11_20 | RANGE |
| history_text | p2025_11_21 | RANGE |
| history_text | p2025_11_22 | RANGE |
| history_text | p2025_11_23 | RANGE |
| history_text | p2025_11_24 | RANGE |
| history_text | p2025_11_25 | RANGE |
| history_bin | p2025_11_16 | RANGE |
| history_bin | p2025_11_17 | RANGE |
| history_bin | p2025_11_18 | RANGE |
| history_bin | p2025_11_19 | RANGE |
| history_bin | p2025_11_20 | RANGE |
| history_bin | p2025_11_21 | RANGE |
| history_bin | p2025_11_22 | RANGE |
| history_bin | p2025_11_23 | RANGE |
| history_bin | p2025_11_24 | RANGE |
| history_bin | p2025_11_25 | RANGE |
| history_log | p2025_11_16 | RANGE |
| history_log | p2025_11_17 | RANGE |
| history_log | p2025_11_18 | RANGE |
| history_log | p2025_11_19 | RANGE |
| history_log | p2025_11_20 | RANGE |
| history_log | p2025_11_21 | RANGE |
| history_log | p2025_11_22 | RANGE |
| history_log | p2025_11_23 | RANGE |
| history_log | p2025_11_24 | RANGE |
| history_log | p2025_11_25 | RANGE |
| history_str | p2025_11_16 | RANGE |
| history_str | p2025_11_17 | RANGE |
| history_str | p2025_11_18 | RANGE |
| history_str | p2025_11_19 | RANGE |
| history_str | p2025_11_20 | RANGE |
| history_str | p2025_11_21 | RANGE |
| history_str | p2025_11_22 | RANGE |
| history_str | p2025_11_23 | RANGE |
| history_str | p2025_11_24 | RANGE |
| history_str | p2025_11_25 | RANGE |
| history | p2025_11_16 | RANGE |
| history | p2025_11_17 | RANGE |
| history | p2025_11_18 | RANGE |
| history | p2025_11_19 | RANGE |
| history | p2025_11_20 | RANGE |
| history | p2025_11_21 | RANGE |
| history | p2025_11_22 | RANGE |
| history | p2025_11_23 | RANGE |
| history | p2025_11_24 | RANGE |
| history | p2025_11_25 | RANGE |
| history_uint | p2025_11_16 | RANGE |
| history_uint | p2025_11_17 | RANGE |
| history_uint | p2025_11_18 | RANGE |
| history_uint | p2025_11_19 | RANGE |
| history_uint | p2025_11_20 | RANGE |
| history_uint | p2025_11_21 | RANGE |
| history_uint | p2025_11_22 | RANGE |
| history_uint | p2025_11_23 | RANGE |
| history_uint | p2025_11_24 | RANGE |
| history_uint | p2025_11_25 | RANGE |
| trends | p2025_11 | RANGE |
| trends | p2025_12 | RANGE |
| trends | p2026_01 | RANGE |
| trends | p2026_02 | RANGE |
| trends | p2026_03 | RANGE |
| trends | p2026_04 | RANGE |
| trends | p2026_05 | RANGE |
| trends | p2026_06 | RANGE |
| trends | p2026_07 | RANGE |
| trends | p2026_08 | RANGE |
| trends_uint | p2025_11 | RANGE |
| trends_uint | p2025_12 | RANGE |
| trends_uint | p2026_01 | RANGE |
| trends_uint | p2026_02 | RANGE |
| trends_uint | p2026_03 | RANGE |
| trends_uint | p2026_04 | RANGE |
| trends_uint | p2026_05 | RANGE |
| trends_uint | p2026_06 | RANGE |
| trends_uint | p2026_07 | RANGE |
| trends_uint | p2026_08 | RANGE |
+--------------+----------------+------------------+
80 rows in set (0.003 sec)MariaDB [zabbix]>
等配置完agent后,可以查看数据是否正常写入分区:
[root@zabbix-server ~]# mysql -u root -pYourPwd@123! zabbix -e "SELECT PARTITION_NAME, TABLE_ROWSFROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA = 'zabbix'AND TABLE_NAME = 'history';"
+----------------+------------+
| PARTITION_NAME | TABLE_ROWS |
+----------------+------------+
| p2025_11_16 | 4735 |
| p2025_11_17 | 0 |
| p2025_11_18 | 0 |
| p2025_11_19 | 0 |
| p2025_11_20 | 0 |
| p2025_11_21 | 0 |
| p2025_11_22 | 0 |
| p2025_11_23 | 0 |
| p2025_11_24 | 0 |
| p2025_11_25 | 0 |
+----------------+------------+
配置定时任务
# 添加crontab任务
sudo crontab -e# 添加以下内容(每天23:55执行分区脚本)
55 23 * * * /usr/lib/zabbix/scripts/mysql_zbx_part.pl# 创建日志文件
sudo touch /var/log/zabbix_partition.log
sudo chown zabbix:zabbix /var/log/zabbix_partition.log# 配置logrotate
sudo vim /etc/logrotate.d/zabbix-partition# 添加以下内容
/var/log/zabbix_partition.log {dailyrotate 30compressdelaycompressmissingoknotifemptycreate 640 zabbix zabbix
}
配置 Zabbix 服务器
# 编辑Zabbix服务器配置文件
sudo vim /etc/zabbix/zabbix_server.conf# 修改以下配置项DBHost=192.168.1.31
DBName=zabbix
DBUser=zabbix
DBPassword=YourPwd@123!
DBPort=3306# 性能优化参数StartPollers=5
StartPingers=5
StartDiscoverers=5
CacheSize=256M
HistoryCacheSize=128M
TrendCacheSize=64M
HistoryTextCacheSize=16M
ValueCacheSize=128M
配置 Zabbix Web 界面
# 编辑Nginx配置文件
sudo vim /etc/nginx/conf.d/zabbix.conf# 修改server_name为你的服务器IP
server_name 192.168.1.31;# 编辑PHP配置文件
sudo vim /etc/php-fpm.d/zabbix.conf# 修改时区设置
php_value[date.timezone] = Asia/Shanghai# 重启所有相关服务
sudo systemctl restart zabbix-server zabbix-agent nginx php-fpm# 设置开机自启
sudo systemctl enable zabbix-server zabbix-agent nginx php-fpm
访问 Zabbix Web 界面
-
访问地址: http://192.168.1.31/
-
默认用户名: Admin
-
默认密码: zabbix
成功提示:
首次登录后请立即修改默认密码,确保系统安全。
配置 Zabbix Agent
安装 Zabbix Agent
# 在需要监控的服务器上安装Zabbix Agent
sudo rpm -Uvh https://repo.zabbix.com/zabbix/7.0/rhel/9/x86_64/zabbix-release-7.0-2.el9.noarch.rpm
sudo dnf clean all
sudo dnf makecache
sudo dnf install -y zabbix-agent
配置 Zabbix Agent
# 编辑Zabbix Agent配置文件
sudo vim /etc/zabbix/zabbix_agentd.conf# 修改以下配置项
Server=192.168.1.31 #Zabbix服务器端的IP
ServerActive=192.168.1.31 #Zabbix服务器端的IP
Hostname=Zabbix server #希望显示在zabbix页面上的名称,一定要跟页面上添加主机时配置成一样的名称# 启动Zabbix Agent服务
sudo systemctl start zabbix-agent
sudo systemctl enable zabbix-agent# 检查服务状态
sudo systemctl status zabbix-agent# 配置防火墙
sudo firewall-cmd --permanent --add-port=10050/tcp
sudo firewall-cmd --reload
Agent启动后,需要在页面上创建主机,一定要选择模板,不然“可用性”会一直是灰色,处于“未知”状态。
常见问题与解决方案
Perl DateTime 模块缺失
错误信息: Can’t locate DateTime.pm in @INC
# 解决方案
sudo dnf install epel-release -y
sudo dnf config-manager --enable crb
sudo dnf install perl-DateTime -y# 验证安装
perl -e "use DateTime; print 'DateTime模块安装成功\n';"
数据库连接失败
错误信息: Host ‘192.168.1.31’ is not allowed to connect to this MariaDB server
GRANT ALL PRIVILEGES ON zabbix.* TO 'zabbix'@'192.168.1.31' IDENTIFIED BY 'YourPwd@123!';
FLUSH PRIVILEGES;
分区管理错误
错误信息: Partition management on a not partitioned table is not possible
解决方案: 请先执行本教程中的 “初始化分区表结构” 步骤,手动为所有表创建初始分区。
Zabbix 服务启动失败
# 查看Zabbix Server日志
sudo journalctl -u zabbix-server -f# 检查数据库连接
mysql -u zabbix -pYourPwd@123! -h 192.168.1.31 zabbix# 检查配置文件语法
sudo zabbix_server -c /etc/zabbix/zabbix_server.conf -t
验证部署结果
检查服务状态
# 检查MariaDB服务状态
sudo systemctl status mariadb# 检查Zabbix Server服务状态
sudo systemctl status zabbix-server# 检查Zabbix Agent服务状态
sudo systemctl status zabbix-agent# 检查Nginx服务状态
sudo systemctl status nginx
检查端口监听
# 检查MySQL端口
sudo netstat -tlnp | grep 3306# 检查Zabbix Server端口
sudo netstat -tlnp | grep 10051# 检查Zabbix Agent端口
sudo netstat -tlnp | grep 10050# 检查HTTP端口
sudo netstat -tlnp | grep 80
验证分区是否创建成功
-- 查看所有表的分区情况
SELECT TABLE_NAME, PARTITION_NAME, PARTITION_METHOD
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix'
AND PARTITION_NAME IS NOT NULL;-- 查看特定表的分区详情(以trends表为例)
SELECT partition_name, partition_description
FROM information_schema.partitions
WHERE table_schema = 'zabbix' AND table_name = 'trends';
性能优化建议
数据库优化:
-
根据实际监控数据量调整 InnoDB 缓存大小
-
定期分析和优化慢查询
-
监控数据库连接数和线程状态
[mysqld]# InnoDB 缓存配置innodb_buffer_pool_size = 2Ginnodb_log_file_size = 256Minnodb_flush_log_at_trx_commit = 2innodb_flush_method = O_DIRECT# 连接数配置max_connections = 1000max_connect_errors = 10000# 查询优化query_cache_size = 0query_cache_type = 0join_buffer_size = 2Msort_buffer_size = 2M# 日志配置slow_query_log = 1slow_query_log_file = /var/log/mysql/slow.loglong_query_time = 2
Zabbix 优化:
-
根据监控设备数量调整 Pollers 数量
-
合理设置监控项的更新间隔
-
使用 Zabbix Proxy 分散监控压力
# 性能优化参数StartPollers=20StartPingers=10StartDiscoverers=5StartHTTPPollers=5StartVMwareCollectors=2# 缓存配置CacheSize=512MHistoryCacheSize=256MTrendCacheSize=128MValueCacheSize=256M# 历史数据保留HistoryStorageURL=http://localhost:10051HistoryStorageTypes=uint,dbl,str,log,text# 超时配置Timeout=30UnreachablePeriod=15UnavailableDelay=60UnreachableDelay=15
系统优化:
-
配置合适的内核参数
-
优化文件系统性能
-
设置合理的 swap 策略
# /etc/sysctl.d/zabbix.confnet.core.somaxconn = 65535net.ipv4.tcp_max_syn_backlog = 65535net.core.netdev_max_backlog = 5000net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_keepalive_probes = 3net.ipv4.tcp_keepalive_intvl = 15net.ipv4.tcp_max_tw_buckets = 5000net.ipv4.tcp_syncookies = 1net.ipv4.tcp_max_orphans = 3276800# 文件描述符限制fs.file-max = 65535# 应用配置sysctl -p /etc/sysctl.d/zabbix.conf# 文件描述符限制配置echo "* soft nofile 65535" >> /etc/security/limits.confecho "* hard nofile 65535" >> /etc/security/limits.conf
参考资料
-
Zabbix 官方文档: https://www.zabbix.com/documentation/current/
-
MariaDB 官方文档: https://mariadb.com/kb/en/
-
AlmaLinux 官方文档: https://wiki.almalinux.org/
-
Zabbix 表分区脚本: https://github.com/OpensourceICTSolutions/zabbix-mysql-partitioning-perl
免责声明:
本教程仅供学习和参考使用,请在生产环境中谨慎操作。建议在执行任何操作前先进行充分的测试和备份。
