3 数据库升级到主键
概述
本节提供了将现有安装中的表手动升级为使用主键的说明。
升级为主键可优化数据的索引和访问方式,从而可能加快查询速度并节省空间。 它还可改进集群环境中的数据管理和同步,有助于扩展,并确保即使部分服务器发生故障,系统仍能保持可靠。
本页提供的说明面向高级用户,可能需要根据您的具体配置进行调整。 升级为主键可能耗时较长且会大量占用资源。 请确保有足够的可用磁盘空间;根据数据库大小和存储的数据量,此过程最多可能需要达到当前历史表已用空间 2.5 倍的空间。
自 Zabbix 6.0 起,所有新安装中的表均使用主键。
数据库不会自动升级为主键;不过,在将 Zabbix 服务器升级到 6.0 或更高版本之后,现有安装可以手动升级。
自 Zabbix 7.0 起,将表升级为主键时,也会将表升级为使用双精度数据类型。
如果您使用的是 Zabbix 7.0(或更高版本),则这些表已使用双精度。
不过,仍可按照本页中的说明将表升级为主键,而不会影响已使用双精度的表。
如果您使用的是 Zabbix 6.4(或更早版本),建议先将表升级为双精度。
更多信息,请参见 Zabbix 7.0 文档中的升级为扩展范围的数值。
可用说明包括:
重要说明
要执行数据库升级:
- 停止 Zabbix 服务器。
强烈建议在升级期间停止 Zabbix 服务器。 但是,如果确有必要,也可以在服务器运行时执行升级(仅适用于 MySQL、MariaDB,以及未使用 TimescaleDB 的 PostgreSQL)。
- 备份您的数据库。
- 安装与您的 Zabbix 版本兼容的最新 zabbix-sql-scripts 软件包(例如,对于 RHEL:
dnf install zabbix-sql-scripts)。 - 运行适用于您的数据库的脚本。
- 启动 Zabbix 服务器。
仅对服务器数据库运行这些脚本。 proxy 不会从此次升级中受益。
如果数据库使用了分区,请联系数据库管理员或 Zabbix 技术支持以获取帮助。
成功升级到主键后,可以删除 CSV 文件。
可选地,可将 Zabbix 前端切换到维护模式。
MySQL
导出和导入必须在 tmux/screen 中执行,以确保会话不会被丢弃。
另请参阅:重要说明
使用 mysqlsh 的 MySQL 8.4+
此方法可在 Zabbix 服务器运行时使用,但建议在升级期间停止服务器。 必须安装 MySQL Shell(mysqlsh),并且能够连接到数据库。
-
以 root 身份登录 MySQL 控制台(推荐),或使用任何具有 FILE 权限的用户登录。
-
启动 MySQL 时启用 local_infile 变量。
-
运行
history_upgrade_prepare.sql,重命名旧表并创建新表。
mysql -uzabbix -p<password> zabbix < /usr/share/zabbix/sql-scripts/mysql/option-patches/history_upgrade_prepare.sql
- 导出并导入数据。
通过 mysqlsh 连接。如果使用 socket 连接,可能需要指定路径。
sudo mysqlsh -uroot -S /run/mysqld/mysqld.sock --no-password -Dzabbix
使用以下命令切换到 JavaScript 模式:
\js
然后运行以下代码(CSVPATH 可根据需要修改):
CSVPATH="/var/lib/mysql-files";
util.exportTable("history_old", CSVPATH + "/history.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history.csv", {"dialect": "csv", "table": "history" });
util.exportTable("history_uint_old", CSVPATH + "/history_uint.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history_uint.csv", {"dialect": "csv", "table": "history_uint" });
util.exportTable("history_str_old", CSVPATH + "/history_str.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history_str.csv", {"dialect": "csv", "table": "history_str" });
util.exportTable("history_log_old", CSVPATH + "/history_log.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history_log.csv", {"dialect": "csv", "table": "history_log" });
util.exportTable("history_text_old", CSVPATH + "/history_text.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history_text.csv", {"dialect": "csv", "table": "history_text" });
如果收到“JavaScript is not supported”消息,则表示当前安装的 MySQL Shell 不支持 JS。 在这种情况下,请安装 Oracle 官方提供的 MySQL Shell package(或从源码构建),以启用 JavaScript 模式。
- 按照迁移后说明删除旧表。
不使用 mysqlsh 的 MariaDB/MySQL 8.4+
此升级方法耗时更长,仅应在无法使用 mysqlsh 升级时使用。
表升级
-
以 root(推荐)或任何具有 FILE 权限的用户身份登录 MySQL 控制台。
-
如果在 Zabbix 服务器运行期间执行迁移,请在启动 MySQL 时启用 local_infile 变量。
-
运行
history_upgrade_prepare.sql,重命名旧表并创建新表:
mysql -uzabbix -p<password> zabbix < /usr/share/zabbix/sql-scripts/mysql/option-patches/history_upgrade_prepare.sql
在服务器停止时迁移
在迁移数据之前,必须禁用 max_execution_time(MySQL 中)或 max_statement_time(MariaDB 中),以避免迁移期间超时。
对于 MySQL:
SET @@max_execution_time=0;
对于 MariaDB:
SET @@max_statement_time=0;
INSERT IGNORE INTO history SELECT * FROM history_old;
INSERT IGNORE INTO history_uint SELECT * FROM history_uint_old;
INSERT IGNORE INTO history_str SELECT * FROM history_str_old;
INSERT IGNORE INTO history_log SELECT * FROM history_log_old;
INSERT IGNORE INTO history_text SELECT * FROM history_text_old;
按照迁移后说明删除旧表。
在服务器运行时迁移
检查已为哪些路径启用导入/导出:
mysql> SELECT @@secure_file_priv;
+-----------------------+
| @@secure_file_priv |
+-----------------------+
| /var/lib/mysql-files/ |
+-----------------------+
如果 secure_file_priv 的值是某个目录路径,则导出/导入将针对该目录中的文件执行。
在这种情况下,请相应地编辑查询中的文件路径,或在升级期间将 secure_file_priv 的值设置为空字符串。
如果 secure_file_priv 的值为空,则可以从任何位置执行导出/导入。
如果 secure_file_priv 的值为 NULL,请将其设置为包含已导出表数据的路径(在上面的示例中为 '/var/lib/mysql-files/')。
更多信息,请参见 MySQL documentation 或 MariaDB documentation。
在导出数据之前,必须禁用 max_execution_time(MySQL 中)或 max_statement_time(MariaDB 中),以避免导出期间超时。
对于 MySQL:
SET @@max_execution_time=0;
对于 MariaDB:
SET @@max_statement_time=0;
SELECT * INTO OUTFILE '/var/lib/mysql-files/history.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_old;
LOAD DATA INFILE '/var/lib/mysql-files/history.csv' IGNORE INTO TABLE history FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';
SELECT * INTO OUTFILE '/var/lib/mysql-files/history_uint.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_uint_old;
LOAD DATA INFILE '/var/lib/mysql-files/history_uint.csv' IGNORE INTO TABLE history_uint FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';
SELECT * INTO OUTFILE '/var/lib/mysql-files/history_str.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_str_old;
LOAD DATA INFILE '/var/lib/mysql-files/history_str.csv' IGNORE INTO TABLE history_str FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';
SELECT * INTO OUTFILE '/var/lib/mysql-files/history_log.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_log_old;
LOAD DATA INFILE '/var/lib/mysql-files/history_log.csv' IGNORE INTO TABLE history_log FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';
SELECT * INTO OUTFILE '/var/lib/mysql-files/history_text.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_text_old;
LOAD DATA INFILE '/var/lib/mysql-files/history_text.csv' IGNORE INTO TABLE history_text FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';
按照迁移后说明删除旧表。
PostgreSQL
必须在 tmux/screen 中执行导出和导入,以确保会话不会中断。
对于安装了 TimescaleDB 的环境,请跳过本节并继续阅读 PostgreSQL + TimescaleDB。
另请参见:重要说明
表升级
- 使用
history_upgrade_prepare.sql重命名表:
sudo -u zabbix psql zabbix < /usr/share/zabbix/sql-scripts/postgresql/option-patches/history_upgrade_prepare.sql
在停止服务器的情况下迁移
- 导出当前历史数据,将其导入临时表,然后在忽略重复项的情况下将数据插入新表:
INSERT INTO history SELECT * FROM history_old ON CONFLICT (itemid,clock,ns) DO NOTHING;
INSERT INTO history_uint SELECT * FROM history_uint_old ON CONFLICT (itemid,clock,ns) DO NOTHING;
INSERT INTO history_str SELECT * FROM history_str_old ON CONFLICT (itemid,clock,ns) DO NOTHING;
INSERT INTO history_log SELECT * FROM history_log_old ON CONFLICT (itemid,clock,ns) DO NOTHING;
INSERT INTO history_text SELECT * FROM history_text_old ON CONFLICT (itemid,clock,ns) DO NOTHING;
有关提高 INSERT 性能的建议,请参见:PostgreSQL: Bulk Loading Huge Amounts of Data、Checkpoint Distance and Amount of WAL。
- 按照迁移后说明删除旧表。
迁移正在运行的server
- 导出当前历史,将其导入临时表,然后将数据插入新表,同时忽略重复项:
\copy history_old TO '/tmp/history.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history (
· itemid · bigint · NOT NULL,
· clock · integer · DEFAULT '0' · NOT NULL,
· value · DOUBLE PRECISION DEFAULT '0.0000' · NOT NULL,
· ns · integer · DEFAULT '0' · NOT NULL
);
\copy temp_history FROM '/tmp/history.csv' DELIMITER ',' CSV
INSERT INTO history SELECT * FROM temp_history ON CONFLICT (itemid,clock,ns) DO NOTHING;
\copy history_uint_old TO '/tmp/history_uint.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history_uint (
· itemid · bigint · NOT NULL,
· clock · integer · DEFAULT '0' · NOT NULL,
· value · numeric(20) · DEFAULT '0' · NOT NULL,
· ns · integer · DEFAULT '0' · NOT NULL
);
\copy temp_history_uint FROM '/tmp/history_uint.csv' DELIMITER ',' CSV
INSERT INTO history_uint SELECT * FROM temp_history_uint ON CONFLICT (itemid,clock,ns) DO NOTHING;
\copy history_str_old TO '/tmp/history_str.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history_str (
· itemid · bigint · NOT NULL,
· clock · integer · DEFAULT '0' · NOT NULL,
· value · varchar(255) · DEFAULT '' · NOT NULL,
· ns · integer · DEFAULT '0' · NOT NULL
);
\copy temp_history_str FROM '/tmp/history_str.csv' DELIMITER ',' CSV
INSERT INTO history_str (itemid,clock,value,ns) SELECT * FROM temp_history_str ON CONFLICT (itemid,clock,ns) DO NOTHING;
\copy history_log_old TO '/tmp/history_log.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history_log (
· itemid · bigint · NOT NULL,
· clock · integer · DEFAULT '0' · NOT NULL,
· timestamp · integer · DEFAULT '0' · NOT NULL,
· source · varchar(64) · DEFAULT '' · NOT NULL,
· severity · integer · DEFAULT '0' · NOT NULL,
· value · text · DEFAULT '' · NOT NULL,
· logeventid · integer · DEFAULT '0' · NOT NULL,
· ns · integer · DEFAULT '0' · NOT NULL
);
\copy temp_history_log FROM '/tmp/history_log.csv' DELIMITER ',' CSV
INSERT INTO history_log SELECT * FROM temp_history_log ON CONFLICT (itemid,clock,ns) DO NOTHING;
\copy history_text_old TO '/tmp/history_text.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history_text (
· itemid · bigint · NOT NULL,
· clock · integer · DEFAULT '0' · NOT NULL,
· value · text · DEFAULT '' · NOT NULL,
· ns · integer · DEFAULT '0' · NOT NULL
);
\copy temp_history_text FROM '/tmp/history_text.csv' DELIMITER ',' CSV
INSERT INTO history_text SELECT * FROM temp_history_text ON CONFLICT (itemid,clock,ns) DO NOTHING;
- 按照 post-migration instructions 删除旧表。
PostgreSQL + TimescaleDB
必须在 tmux/screen 中执行导出和导入操作,以确保会话不会中断。 升级期间,Zabbix 服务器应处于停止状态。
另请参见:重要说明
-
使用
history_upgrade_prepare.sql重命名表。- 如果启用了压缩(默认安装情况下),请运行
/usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression中的脚本:cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_prepare.sql | sudo -u zabbix psql zabbix - 如果禁用了压缩,请运行
/usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression中的脚本:cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_prepare.sql | sudo -u zabbix psql zabbix
- 如果启用了压缩(默认安装情况下),请运行
-
根据压缩设置运行 TimescaleDB hypertable 迁移脚本:
- 如果启用了压缩(默认安装情况下),请运行
/usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression中的脚本:cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_uint.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_log.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_str.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_text.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/trends_upgrade.sql | sudo -u zabbix psql zabbix - 如果禁用了压缩,请运行
/usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression中的脚本:cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_uint.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_log.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_str.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_text.sql | sudo -u zabbix psql zabbix cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/trends_upgrade.sql | sudo -u zabbix psql zabbix
- 如果启用了压缩(默认安装情况下),请运行
另请参见:有关提高 INSERT 性能的提示。
- 按照迁移后说明删除旧表。
迁移后
对于所有数据库,迁移完成后,请执行以下操作:
-
验证一切是否按预期运行。
-
删除旧表:
DROP TABLE history_old;
DROP TABLE history_uint_old;
DROP TABLE history_str_old;
DROP TABLE history_log_old;
DROP TABLE history_text_old;
- 对于 TimescaleDB,还需删除以下旧表:
DROP TABLE trends_old;