3 为数据库升级主键

概述

自Zabbix 6.0起,主键会应用于新安装 Zabbix 数据库的所有表。

在这之前安装过的Zabbix,本章节将提供手动升级所有表主键的说明。

此章节适用于如下数据库:

此页面上提供的说明专为高级用户设计。请注意,这些说明可能需要根据您的特定配置进行调整。

重要提示

  • 确保在升级前备份数据库。
  • 如果数据库使用分区,请联系数据库管理员或 Zabbix 支持团队寻求帮助。
  • 强烈建议在升级时停止 Zabbix 服务器。 但是,如果绝对必要,有一种方法可以在服务器运行时执行升级(仅适用于没有 TimescaleDB 的 MySQL、MariaDB 和 PostgreSQL)。
  • 成功升级到主键后,可以删除 CSV 文件。
  • 可选地,Zabbix 前端可以切换到维护模式
  • 升级到主键应该在将 Zabbix 服务器升级到 6.0 之后完成。
  • 在代理上,未使用的历史表可以通过执行 history_pk_prepare.sql 进行升级。

MySQL

导出和导入必须在 tmux/screen 中执行,以确保会话不会被丢弃。

另请参阅:重要说明

MySQL 8.0+ 和 mysqlsh

此方法可用于正在运行的 Zabbix 服务器,但建议在升级时停止服务器。 MySQL Shell (mysqlsh) 必须 已安装 并且能够连接到数据库。

  • 以 root(推荐)或任何具有 FILE 权限的用户身份登录 MySQL 控制台。

  • 启用 local_infile 变量启动 MySQL。

  • 通过运行 history_pk_prepare.sql 重命名旧表并创建新表。

  1. mysql -uzabbix -p<password> zabbix < /usr/share/zabbix-sql-scripts/mysql/history_pk_prepare.sql
  • 导出和导入数据。

通过 mysqlsh 连接。 如果使用套接字连接,可能需要指定路径。

· sudo mysqlsh -uroot -S /run/mysqld/mysqld.sock —no-password -Dzabbix

运行(CSVPATH可根据需要更改):

  1. CSVPATH="/var/lib/mysql-files";
  2. util.exportTable("history_old", CSVPATH + "/history.csv", { dialect: "csv" });
  3. util.importTable(CSVPATH + "/history.csv", {"dialect": "csv", "table": "history" });
  4. util.exportTable("history_uint_old", CSVPATH + "/history_uint.csv", { dialect: "csv" });
  5. util.importTable(CSVPATH + "/history_uint.csv", {"dialect": "csv", "table": "history_uint" });
  6. util.exportTable("history_str_old", CSVPATH + "/history_str.csv", { dialect: "csv" });
  7. util.importTable(CSVPATH + "/history_str.csv", {"dialect": "csv", "table": "history_str" });
  8. util.exportTable("history_log_old", CSVPATH + "/history_log.csv", { dialect: "csv" });
  9. util.importTable(CSVPATH + "/history_log.csv", {"dialect": "csv", "table": "history_log" });
  10. util.exportTable("history_text_old", CSVPATH + "/history_text.csv", { dialect: "csv" });
  11. util.importTable(CSVPATH + "/history_text.csv", {"dialect": "csv", "table": "history_text" });

没有 mysqlsh 的 MariaDB/MySQL 8.0+

这种升级方法需要更多时间,只有在无法使用 mysqlsh 进行升级时才应使用。

表升级
  • 以 root(推荐)或任何具有 FILE 权限的用户身份登录 MySQL 控制台。

  • 启用 local_infile 变量启动 MySQL。

  • 通过运行 history_pk_prepare.sql 重命名旧表并创建新表:

  1. mysql -uzabbix -p<password> zabbix < /usr/share/zabbix-sql-scripts/mysql/history_pk_prepare.sql
停止服务器的迁移

max_execution_time 必须在迁移数据之前禁用以避免迁移期间超时。

  1. SET @@max_execution_time=0;
  2. INSERT IGNORE INTO history SELECT * FROM history_old;
  3. INSERT IGNORE INTO history_uint SELECT * FROM history_uint_old;
  4. INSERT IGNORE INTO history_str SELECT * FROM history_str_old;
  5. INSERT IGNORE INTO history_log SELECT * FROM history_log_old;
  6. INSERT IGNORE INTO history_text SELECT * FROM history_text_old;

Follow post-migration instructions to drop the old tables.

Migration with running server

Check for which paths import/export is enabled:

  1. mysql> SELECT @@secure_file_priv;
  2. +-----------------------+
  3. | @@secure_file_priv · |
  4. +-----------------------+
  5. | /var/lib/mysql-files/ |
  6. +-----------------------+

如果 secure_file_priv 值是目录路径,则将对该目录中的文件执行导出/导入。 在这种情况下,相应地编辑查询中文件的路径或将secure_file_priv 值设置为升级时间的空字符串。

如果 secure_file_priv 值为空,则可以从任何位置执行导出/导入。

如果 secure_file_priv 值为 NULL,将其设置为包含导出表数据的路径(上例中的“/var/lib/mysql-files/”)。

有关详细信息,请参阅 MySQL 文档

max_execution_time 必须在导出数据之前禁用以避免导出期间超时。

  1. SET @@max_execution_time=0;
  2. SELECT * INTO OUTFILE '/var/lib/mysql-files/history.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_old;
  3. LOAD DATA INFILE '/var/lib/mysql-files/history.csv' IGNORE INTO TABLE history FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';
  4. SELECT * INTO OUTFILE '/var/lib/mysql-files/history_uint.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_uint_old;
  5. LOAD DATA INFILE '/var/lib/mysql-files/history_uint.csv' IGNORE INTO TABLE history_uint FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';
  6. SELECT * INTO OUTFILE '/var/lib/mysql-files/history_str.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_str_old;
  7. LOAD DATA INFILE '/var/lib/mysql-files/history_str.csv' IGNORE INTO TABLE history_str FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';
  8. SELECT * INTO OUTFILE '/var/lib/mysql-files/history_log.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_log_old;
  9. LOAD DATA INFILE '/var/lib/mysql-files/history_log.csv' IGNORE INTO TABLE history_log FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';
  10. SELECT * INTO OUTFILE '/var/lib/mysql-files/history_text.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_text_old;
  11. 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_pk_prepare.sql 重命名表:
  1. sudo -u zabbix psql zabbix < /usr/share/zabbix-sql-scripts/postgresql/history_pk_prepare.sql

停止服务器的迁移

  • 导出当前历史,将其导入临时表,然后将数据插入新表,同时忽略重复项:
  1. INSERT INTO history SELECT * FROM history_old ON CONFLICT (itemid,clock,ns) DO NOTHING;
  2. INSERT INTO history_uint SELECT * FROM history_uint_old ON CONFLICT (itemid,clock,ns) DO NOTHING;
  3. INSERT INTO history_str SELECT * FROM history_str_old ON CONFLICT (itemid,clock,ns) DO NOTHING;
  4. INSERT INTO history_log SELECT * FROM history_log_old ON CONFLICT (itemid,clock,ns) DO NOTHING;
  5. INSERT INTO history_text SELECT * FROM history_text_old ON CONFLICT (itemid,clock,ns) DO NOTHING;

查看提高 INSERT 性能的技巧:PostgreSQL:批量加载大量数据检查点距离 和 WAL 的数量

迁移正在运行的服务器

  • 导出当前历史,将其导入临时表,然后将数据插入新表,同时忽略重复项:
  1. \copy history_old TO '/tmp/history.csv' DELIMITER ',' CSV
  2. CREATE TEMP TABLE temp_history (
  3. · itemid · bigint · NOT NULL,
  4. · clock · integer · DEFAULT '0' · NOT NULL,
  5. · value · DOUBLE PRECISION DEFAULT '0.0000' · NOT NULL,
  6. · ns · integer · DEFAULT '0' · NOT NULL
  7. );
  8. \copy temp_history FROM '/tmp/history.csv' DELIMITER ',' CSV
  9. INSERT INTO history SELECT * FROM temp_history ON CONFLICT (itemid,clock,ns) DO NOTHING;
  10. \copy history_uint_old TO '/tmp/history_uint.csv' DELIMITER ',' CSV
  11. CREATE TEMP TABLE temp_history_uint (
  12. · itemid · bigint · NOT NULL,
  13. · clock · integer · DEFAULT '0' · NOT NULL,
  14. · value · numeric(20) · DEFAULT '0' · NOT NULL,
  15. · ns · integer · DEFAULT '0' · NOT NULL
  16. );
  17. \copy temp_history_uint FROM '/tmp/history_uint.csv' DELIMITER ',' CSV
  18. INSERT INTO history_uint SELECT * FROM temp_history_uint ON CONFLICT (itemid,clock,ns) DO NOTHING;
  19. \copy history_str_old TO '/tmp/history_str.csv' DELIMITER ',' CSV
  20. CREATE TEMP TABLE temp_history_str (
  21. · itemid · bigint · NOT NULL,
  22. · clock · integer · DEFAULT '0' · NOT NULL,
  23. · value · varchar(255) · DEFAULT '' · NOT NULL,
  24. · ns · integer · DEFAULT '0' · NOT NULL
  25. );
  26. \copy temp_history_str FROM '/tmp/history_str.csv' DELIMITER ',' CSV
  27. INSERT INTO history_str (itemid,clock,value,ns) SELECT * FROM temp_history_str ON CONFLICT (itemid,clock,ns) DO NOTHING;
  28. \copy history_log_old TO '/tmp/history_log.csv' DELIMITER ',' CSV
  29. CREATE TEMP TABLE temp_history_log (
  30. · itemid · bigint · NOT NULL,
  31. · clock · integer · DEFAULT '0' · NOT NULL,
  32. · timestamp · integer · DEFAULT '0' · NOT NULL,
  33. · source · varchar(64) · DEFAULT '' · NOT NULL,
  34. · severity · integer · DEFAULT '0' · NOT NULL,
  35. · value · text · DEFAULT '' · NOT NULL,
  36. · logeventid · integer · DEFAULT '0' · NOT NULL,
  37. · ns · integer · DEFAULT '0' · NOT NULL
  38. );
  39. \copy temp_history_log FROM '/tmp/history_log.csv' DELIMITER ',' CSV
  40. INSERT INTO history_log SELECT * FROM temp_history_log ON CONFLICT (itemid,clock,ns) DO NOTHING;
  41. \copy history_text_old TO '/tmp/history_text.csv' DELIMITER ',' CSV
  42. CREATE TEMP TABLE temp_history_text (
  43. · itemid · bigint · NOT NULL,
  44. · clock · integer · DEFAULT '0' · NOT NULL,
  45. · value · text · DEFAULT '' · NOT NULL,
  46. · ns · integer · DEFAULT '0' · NOT NULL
  47. );
  48. \copy temp_history_text FROM '/tmp/history_text.csv' DELIMITER ',' CSV
  49. INSERT INTO history_text SELECT * FROM temp_history_text ON CONFLICT (itemid,clock,ns) DO NOTHING;

PostgreSQL + TimescaleDB

导出和导入必须在 tmux/screen 中执行,以确保会话不会被丢弃。Zabbix 服务器应该在升级期间关闭。

另请参阅:重要说明

  • 使用 history_pk_prepare.sql 重命名表。
  1. sudo -u zabbix psql zabbix < /usr/share/zabbix-sql-scripts/postgresql/history_pk_prepare.sql
  • 基于压缩设置运行 TimescaleDB 超表迁移脚本(兼容 TSDB v2.x 和 v1.x 版本): · * 如果启用了压缩(默认安装),从 database/postgresql/tsdb_history_pk_upgrade_with_compression 运行脚本: · {.bash} · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_with_compression/history_pk.sql | sudo -u zabbix psql zabbix · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_with_compression/history_pk_uint.sql | sudo -u zabbix psql zabbix · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_with_compression/history_pk_log.sql | sudo -u zabbix psql zabbix · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_with_compression/history_pk_str.sql | sudo -u zabbix psql zabbix · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_with_compression/history_pk_text.sql | sudo -u zabbix psql zabbix · · * 如果压缩被禁用,从database/postgresql/tsdb_history_pk_upgrade_no_compression运行脚本: · {.bash} · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_no_compression/history_pk.sql | sudo -u zabbix psql zabbix · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_no_compression/history_pk_uint.sql | sudo -u zabbix psql zabbix · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_no_compression/history_pk_log.sql | sudo -u zabbix psql zabbix · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_no_compression/history_pk_str.sql | sudo -u zabbix psql zabbix · cat /usr/share/zabbix-sql-scripts/postgresql/tsdb_history_pk_upgrade_no_compression/history_pk_text.sql | sudo -u zabbix psql zabbix ·

另请参阅:Tips 以提高 INSERT 性能。

Oracle

导出和导入必须在 tmux/screen 中执行,以确保会话不会被丢弃。Zabbix 服务器应该在升级期间关闭。

另请参阅:重要说明

表升级

有关性能提示,请参阅 Oracle Data Pump 文档

  • 使用 history_pk_prepare.sql 重命名表。
  1. cd /usr/share/zabbix/zabbix-sql-scripts/database/oracle
  2. sqlplus zabbix/[email protected]_host/service
  3. sqlplus> @history_pk_prepare.sql

历史表批量迁移

  • 为数据泵准备目录。

Data Pump 必须对这些目录具有读写权限。

例子:

  1. mkdir -pv /export/history
  2. chown -R oracle:oracle /export
  • 创建一个目录对象,并将该对象的读写权限授予用于 Zabbix 身份验证的用户(下例中的“zabbix”)。 在 sysdba 角色下,运行:
  1. create directory history as '/export/history';
  2. grant read,write on directory history to zabbix;
  • 导出表。 将 N 替换为所需的线程数。
  1. expdp zabbix/[email protected]_host/service \
  2. · DIRECTORY=history \
  3. · TABLES=history_old,history_uint_old,history_str_old,history_log_old,history_text_old \
  4. · PARALLEL=N
  • 导入表。 将 N 替换为所需的线程数。
  1. impdp zabbix/[email protected]_host/service \
  2. · DIRECTORY=history \
  3. · TABLES=history_uint_old \
  4. REMAP_TABLE=history_old:history,history_uint_old:history_uint,history_str_old:history_str,history_log_old:history_log,history_text_old:history_text \
  5. · data_options=SKIP_CONSTRAINT_ERRORS table_exists_action=APPEND · PARALLEL=N CONTENT=data_only

历史表的单独迁移

  • 为每个历史表准备数据泵目录。Data Pump 必须对这些目录具有读写权限。

例子:

  1. mkdir -pv /export/history /export/history_uint /export/history_str /export/history_log /export/history_text
  2. chown -R oracle:oracle /导出
  • 创建一个目录对象,并将该对象的读写权限授予用于 Zabbix 身份验证的用户(下例中的“zabbix”)。 在 sysdba 角色下,运行:
  1. create directory history as '/export/history';
  2. grant read,write on directory history to zabbix;
  3. create directory history_uint as '/export/history_uint';
  4. grant read,write on directory history_uint to zabbix;
  5. create directory history_str as '/export/history_str';
  6. grant read,write on directory history_str to zabbix;
  7. create directory history_log as '/export/history_log';
  8. grant read,write on directory history_log to zabbix;
  9. create directory history_text as '/export/history_text';
  10. grant read,write on directory history_text to zabbix;
  • 导出和导入每个表。 将 N 替换为所需的线程数。
  1. expdp zabbix/[email protected]_host:1521/xe DIRECTORY=history TABLES=history_old PARALLEL=N
  2. impdp zabbix/[email protected]_host:1521/xe DIRECTORY=history TABLES=history_old REMAP_TABLE=history_old:history data_options=SKIP_CONSTRAINT_ERRORS table_exists_action=APPEND PARALLEL=N CONTENT=data_only
  3. expdp zabbix/[email protected]_host:1521/xe DIRECTORY=history_uint TABLES=history_uint_old PARALLEL=N
  4. impdp zabbix/[email protected]_host:1521/xe DIRECTORY=history_uint TABLES=history_uint_old REMAP_TABLE=history_uint_old:history_uint data_options=SKIP_CONSTRAINT_ERRORS table_exists_action=APPEND PARALLEL=N CONTENT=data_only
  5. expdp zabbix/[email protected]_host:1521/xe DIRECTORY=history_str TABLES=history_str_old PARALLEL=N
  6. impdp zabbix/[email protected]_host:1521/xe DIRECTORY=history_str TABLES=history_str_old REMAP_TABLE=history_str_old:history_str data_options=SKIP_CONSTRAINT_ERRORS table_exists_action=APPEND PARALLEL=N CONTENT=data_only
  7. expdp zabbix/[email protected]_host:1521/xe DIRECTORY=history_log TABLES=history_log_old PARALLEL=N
  8. impdp zabbix/[email protected]_host:1521/xe DIRECTORY=history_log TABLES=history_log_old REMAP_TABLE=history_log_old:history_log data_options=SKIP_CONSTRAINT_ERRORS table_exists_action=APPEND PARALLEL=N CONTENT=data_only
  9. expdp zabbix/[email protected]_host:1521/xe DIRECTORY=history_text TABLES=history_text_old PARALLEL=N
  10. impdp zabbix/[email protected]_host:1521/xe DIRECTORY=history_text TABLES=history_text_old REMAP_TABLE=history_text_old:history_text data_options=SKIP_CONSTRAINT_ERRORS table_exists_action=APPEND PARALLEL=N CONTENT=data_only

迁移后

对于所有数据库,迁移完成后,执行以下操作:

  • 验证一切是否按预期工作。

  • 删除旧表:

  1. DROP TABLE history_old;
  2. DROP TABLE history_uint_old;
  3. DROP TABLE history_str_old;
  4. DROP TABLE history_log_old;
  5. DROP TABLE history_text_old;