4 Vorbereitung der auditlog-Tabelle für die Partitionierung

Überblick

Einige Datenbanken (zum Beispiel MySQL) erfordern, dass die Partitionierungsspalte Teil der eindeutigen Einschränkung der Tabelle ist. Daher muss zum Partitionieren der Tabelle auditlog nach Zeit der Primärschlüssel von auditid in einen zusammengesetzten Schlüssel auditid + clock geändert werden.

Dieser Abschnitt enthält Anweisungen zum Ändern des Primärschlüssels der Tabelle auditlog.

Die auf dieser Seite bereitgestellten Anweisungen sind für fortgeschrittene Benutzer gedacht. Beachten Sie, dass diese Anweisungen möglicherweise an Ihre spezifische Konfiguration angepasst werden müssen. Das Ändern des Primärschlüssels kann außerdem mit zukünftigen Upgrade-Patches inkompatibel sein, sodass zukünftige Upgrades möglicherweise manuell durchgeführt werden müssen.

Das Ändern des Primärschlüssels kann je nach Größe der Tabelle auditlog ein ressourcenintensiver und zeitaufwändiger Vorgang sein. Es wird empfohlen, den Zabbix Server anzuhalten und das Zabbix Frontend für die Dauer der Änderung in den Wartungsmodus zu versetzen. Falls jedoch unbedingt erforderlich, gibt es eine Möglichkeit, den Primärschlüssel ohne Ausfallzeit zu ändern (siehe unten).

Die Partitionierung der Tabelle auditlog kann beispielsweise das Housekeeping in großen Umgebungen verbessern. Obwohl das Zabbix-Housekeeping derzeit partitionierte Tabellen nicht nutzen kann (außer bei TimescaleDB), können Sie das Zabbix-Housekeeping deaktivieren und Partitionen mithilfe von Skripten löschen.

Seit Zabbix 7.0 wurde die Tabelle auditlog für TimescaleDB in eine Hypertabelle umgewandelt, wodurch der Housekeeper Daten in Chunks löschen kann. Informationen zum Upgrade der bestehenden Tabelle auditlog auf eine Hypertabelle finden Sie unter Upgrading TimescaleDB schema.

MySQL

Wichtige Hinweise zum Neuaufbau von Indizes

MySQL baut Indizes für den Primärschlüssel während des Vorgangs ALTER TABLE automatisch neu auf. Es wird jedoch dringend empfohlen, Indizes zusätzlich manuell mit der Anweisung OPTIMIZE TABLE neu aufzubauen, um eine optimale Datenbankleistung sicherzustellen.

Für den Neuaufbau von Indizes kann vorübergehend zusätzlicher Speicherplatz in der Größe erforderlich sein, die auch die Tabelle selbst belegt. Um die aktuelle Größe von Daten und Indizes zu ermitteln, können Sie die folgenden Anweisungen ausführen:

ANALYZE TABLE auditlog;
SHOW TABLE STATUS LIKE 'auditlog';

Wenn der verfügbare Speicherplatz ein Problem darstellt, folgen Sie den Anweisungen unter Primärschlüssel ohne Ausfallzeit ändern. Es stehen auch weitere Optionen zur Verfügung:

  • Eine Erhöhung des MySQL-Parameters sort_buffer_size kann helfen, die Speicherplatznutzung beim manuellen Neuaufbau von Indizes zu verringern. Das Ändern dieser Variablen kann sich jedoch auf die gesamte Speichernutzung der Datenbank auswirken.
  • Ziehen Sie in Betracht, Speicherplatz freizugeben, indem Sie möglicherweise nicht benötigte Daten löschen.
  • Ziehen Sie in Betracht, den housekeeper-Parameter Data storage period vor der Ausführung des housekeepers zu verringern.
Ändern des Primärschlüssels mit Ausfallzeit

1. Entfernen Sie den aktuellen Primärschlüssel der Tabelle auditlog und fügen Sie den neuen Primärschlüssel hinzu.

ALTER TABLE auditlog DROP PRIMARY KEY, ADD PRIMARY KEY (auditid, clock);

2. Erstellen Sie die Indizes neu (optional, aber dringend empfohlen, siehe Wichtige Hinweise zum Neuaufbau von Indizes).

OPTIMIZE TABLE auditlog;
Primärschlüssel ohne Ausfallzeit ändern

Die manuelle Methode zum Ändern des Primärschlüssels wird hier beschrieben. Alternativ können Sie das Toolkit pt-online-schema-change von Percona verwenden. Dieses Toolkit führt die folgenden Aktionen automatisch aus und minimiert dabei zugleich den für die Änderung der Tabelle auditlog verwendeten Speicherplatz.

1. Eine neue Tabelle mit dem neuen Primärschlüssel erstellen und Indizes anlegen.

CREATE TABLE `auditlog_new` (
  `auditid`            varchar(25)                               NOT NULL,
  `userid`             bigint unsigned                           NULL,
  `username`           varchar(100)    DEFAULT ''                NOT NULL,
  `clock`              integer         DEFAULT '0'               NOT NULL,
  `ip`                 varchar(39)     DEFAULT ''                NOT NULL,
  `action`             integer         DEFAULT '0'               NOT NULL,
  `resourcetype`       integer         DEFAULT '0'               NOT NULL,
  `resourceid`         bigint unsigned                           NULL,
  `resource_cuid`      varchar(25)                               NULL,
  `resourcename`       varchar(255)    DEFAULT ''                NOT NULL,
  `recordsetid`        varchar(25)                               NOT NULL,
  `details`            longtext                                  NOT NULL,
  PRIMARY KEY (auditid,clock)
) ENGINE=InnoDB;
CREATE INDEX `auditlog_1` ON `auditlog_new` (`userid`,`clock`);
CREATE INDEX `auditlog_2` ON `auditlog_new` (`clock`);
CREATE INDEX `auditlog_3` ON `auditlog_new` (`resourcetype`,`resourceid`);

2. Tabellen austauschen.

RENAME TABLE auditlog TO auditlog_old, auditlog_new TO auditlog;

3. Daten aus der alten Tabelle in die neue Tabelle kopieren.

INSERT INTO auditlog SELECT * FROM auditlog_old;

Dies kann in Blöcken erfolgen (mehrere INSERT INTO-Anweisungen mit WHERE clock-Klauseln nach Bedarf), um eine übermäßige Ressourcennutzung zu vermeiden.

4. Die alte Tabelle löschen.

DROP TABLE auditlog_old;

PostgreSQL

Wichtige Hinweise zum Neuaufbau von Indizes

PostgreSQL baut Indizes für den Primärschlüssel während des Vorgangs ALTER TABLE automatisch neu auf. Es wird jedoch dringend empfohlen, Indizes zusätzlich manuell mit der Anweisung REINDEX TABLE CONCURRENTLY neu aufzubauen, um eine optimale Datenbankleistung sicherzustellen.

Für den Neuaufbau von Indizes kann vorübergehend bis zum Dreifachen des derzeit von Indizes belegten Speicherplatzes erforderlich sein. Um die aktuelle Größe der Indizes zu ermitteln, können Sie die folgende Abfrage ausführen:

SELECT pg_size_pretty(pg_indexes_size('auditlog'));

Falls der verfügbare Speicherplatz ein Problem darstellt, folgen Sie den Anweisungen unter Primärschlüssel ohne Ausfallzeit ändern. Es stehen auch weitere Optionen zur Verfügung:

  • Eine Erhöhung des PostgreSQL-Parameters maintenance_work_mem kann helfen, die Speicherplatznutzung beim manuellen Neuaufbau von Indizes zu verringern. Eine Änderung dieser Variablen kann sich jedoch auf die gesamte Speichernutzung der Datenbank auswirken.
  • Wenn Sie über eine weitere Festplatte oder einen weiteren Tablespace mit mehr verfügbarem Speicherplatz verfügen, können Sie in Erwägung ziehen, den temporären Speicherort für den Neuaufbau der Indizes zu ändern. Sie können den PostgreSQL-Parameter temp_tablespaces festlegen, um einen anderen Tablespace für temporäre Objekte anzugeben.
  • Ziehen Sie in Betracht, Speicherplatz freizugeben, indem Sie möglicherweise nicht benötigte Daten löschen.
  • Ziehen Sie in Betracht, den Parameter Datenspeicherungszeitraum des housekeeper vor der Ausführung des housekeeper zu verringern.
Primärschlüssel mit Ausfallzeit ändern

1. Den aktuellen Primärschlüssel der Tabelle auditlog löschen und den neuen Primärschlüssel hinzufügen.

ALTER TABLE auditlog DROP CONSTRAINT auditlog_pkey;
ALTER TABLE auditlog ADD PRIMARY KEY (auditid,clock);

2. Indizes neu erstellen (optional, aber dringend empfohlen, siehe Wichtige Hinweise zum Neuerstellen von Indizes).

REINDEX TABLE CONCURRENTLY auditlog;
Primärschlüssel ohne Ausfallzeit ändern

Die manuelle Methode zum Ändern des Primärschlüssels wird hier beschrieben. Alternativ kann die Erweiterung pg_repack in Betracht gezogen werden, um eine neue Tabelle zu erstellen, Daten zu kopieren und die Tabellen auszutauschen.

1. Erstellen Sie eine neue Tabelle mit dem neuen Primärschlüssel und erstellen Sie Indizes.

CREATE TABLE auditlog_new (
  auditid              varchar(25)                               NOT NULL,
  userid               bigint                                    NULL,
  username             varchar(100)    DEFAULT ''                NOT NULL,
  clock                integer         DEFAULT '0'               NOT NULL,
  ip                   varchar(39)     DEFAULT ''                NOT NULL,
  action               integer         DEFAULT '0'               NOT NULL,
  resourcetype         integer         DEFAULT '0'               NOT NULL,
  resourceid           bigint                                    NULL,
  resource_cuid        varchar(25)                               NULL,
  resourcename         varchar(255)    DEFAULT ''                NOT NULL,
  recordsetid          varchar(25)                               NOT NULL,
  details              text            DEFAULT ''                NOT NULL,
  PRIMARY KEY (auditid,clock)
);
CREATE INDEX auditlog_new_1 ON auditlog_new (userid,clock);
CREATE INDEX auditlog_new_2 ON auditlog_new (clock);
CREATE INDEX auditlog_new_3 ON auditlog_new (resourcetype,resourceid);

2. Tauschen Sie die Tabellen aus.

ALTER TABLE auditlog RENAME TO auditlog_old;
ALTER TABLE auditlog_new RENAME TO auditlog;

3. Kopieren Sie die Daten aus der alten Tabelle in die neue Tabelle.

INSERT INTO auditlog SELECT * FROM auditlog_old;

Dies kann in Blöcken erfolgen (mehrere INSERT INTO-Anweisungen mit WHERE clock-Klauseln nach Bedarf), um eine übermäßige Ressourcennutzung zu vermeiden.

4. Löschen Sie die alte Tabelle.

DROP TABLE auditlog_old;

Siehe auch