4 Preparando la tabla de registro de auditoría para particionado

Descripción general

Algunas bases de datos (por ejemplo, MySQL) requieren que la columna de partición sea parte de la "constraint" única de la tabla. Por lo tanto, para particionar la tabla auditlog por tiempo, la clave principal debe cambiarse de auditid a una clave compuesta auditid + clock.

Esta sección proporciona instrucciones para modificar la clave principal de la tabla "auditlog".

Las instrucciones proporcionadas en esta página están diseñadas para usuarios avanzados. Tenga en cuenta que es posible que sea necesario ajustar estas instrucciones para su configuración específica. La modificación de la clave principal también puede ser incompatible con futuros parches de actualización, por lo que puede ser necesario gestionar manualmente futuras actualizaciones.

Modificar la clave principal puede ser una operación que consume muchos recursos y lleva mucho tiempo dependiendo del tamaño de la tabla "auditlog". Se recomienda detener el servidor Zabbix y cambiar la interfaz de Zabbix a modo de mantenimiento durante el momento de la modificación. Sin embargo, si es absolutamente necesario, existe una manera de modificar la clave principal sin tiempo de inactividad (ver más abajo).

Particionar la tabla "auditlog" puede mejorar, por ejemplo, la limpieza en configuraciones grandes. Aunque la limpieza de Zabbix actualmente no puede aprovechar las tablas particionadas (excepto TimescaleDB), puede desactivar la limpieza de Zabbix y eliminar particiones mediante scripts.

Desde Zabbix 7.0, la tabla auditlog para TimescaleDB se ha convertido en una hipertabla, lo que permite al administrador eliminar datos por partes. Para actualizar la tabla auditlog existente a una hipertabla, vuelva a ejecutar el script postgresql/timescaledb/schema.sql antes de iniciar el servidor Zabbix. El servidor Zabbix registrará una advertencia si se inicia sin ejecutar este script primero. Consulte también: Configuración de TimescaleDB.

MySQL

Notas importantes sobre la reconstrucción de índices

MySQL reconstruye automáticamente los índices de la clave principal durante la operación "ALTER TABLE". Sin embargo, se recomienda encarecidamente reconstruir también los índices manualmente con la instrucción "OPTIMIZE TABLE" para garantizar un rendimiento óptimo de la base de datos.

La reconstrucción de índices puede requerir temporalmente tanto espacio en disco adicional como el que utiliza la propia tabla. Para obtener el tamaño actual de datos e índices, puede ejecutar las siguientes declaraciones:

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

Si le preocupa el espacio disponible en disco, siga las instrucciones Alteración de la clave principal sin tiempo de inactividad. Otras opciones también están disponibles:

  • Aumentar el parámetro MySQL sort_buffer_size puede ayudar a reducir el uso de espacio en disco al reconstruir índices manualmente. Sin embargo, modificar esta variable puede afectar el uso general de la memoria de la base de datos.
  • Considere la posibilidad de liberar espacio eliminando datos potencialmente innecesarios.
  • Considere disminuir el parámetro Período de almacenamiento de datos housekeeper antes de ejecutar el housekeeper.
Alteración de la clave principal con tiempo de inactividad

1. Elimine la clave principal de la tabla auditlog actual y agregue la nueva clave principal.

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

2. Reconstruir índices (opcional pero muy recomendado, consulte Notas importantes sobre la reconstrucción de índices).

OPTIMIZE TABLE auditlog;
Modificación de la clave principal sin tiempo de inactividad

El método manual para modificar la clave principal se describe aquí. Alternativamente, puede utilizar el kit de herramientas pt-online-schema-change de Percona. Este kit de herramientas realiza las siguientes acciones automáticamente y al mismo tiempo minimiza el espacio utilizado para modificar la tabla "auditlog".

1. Cree una nueva tabla con la nueva clave principal y cree índices.

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. Intercambie las tablas.

RENAME TABLE auditlog TO auditlog_old, auditlog_new TO auditlog;

3. Copie los datos de la tabla anterior a la tabla nueva.

INSERT INTO auditlog SELECT * FROM auditlog_old;

Esto se puede hacer en fragmentos (múltiples declaraciones INSERT INTO con cláusulas WHERE clock según sea necesario) para evitar el uso excesivo de recursos.

4. Elimine la antigua tabla.

DROP TABLE auditlog_old;

PostgreSQL

Notas importantes sobre la reconstrucción de índices

PostgreSQL reconstruye automáticamente los índices de la clave principal durante la operación "ALTER TABLE". Sin embargo, se recomienda encarecidamente reconstruir también los índices manualmente con la instrucción REINDEX TABLE CONCURRENTLY para garantizar un rendimiento óptimo de la base de datos.

La reconstrucción de índices puede requerir temporalmente hasta tres veces el espacio en disco que utilizan actualmente los índices. Para obtener el tamaño actual de los índices, puede ejecutar la siguiente consulta:

SELECT pg_size_pretty(pg_indexes_size('auditlog'));

Si le preocupa el espacio disponible en disco, siga las instrucciones Alteración de la clave principal sin tiempo de inactividad. Otras opciones también están disponibles:

  • Aumentar el parámetro PostgreSQL maintenance_work_mem puede ayudar a reducir el uso de espacio en disco cuando se realiza manualmente reconstruir índices. Sin embargo, modificar esta variable puede afectar el uso general de la memoria de la base de datos.
  • Si tiene otro disco o espacio de tabla con más espacio disponible, podría considerar cambiar la ubicación de almacenamiento temporal para la reconstrucción del índice. Puede configurar el parámetro temp_tablespaces de PostgreSQL para especificar un espacio de tabla diferente para objetos temporales.
  • Considere la posibilidad de liberar espacio eliminando datos potencialmente innecesarios.
  • Considere disminuir el parámetro Período de almacenamiento de datos housekeeper antes de ejecutar el housekeeper.
Alteración de la clave principal con tiempo de inactividad

1. Elimine la clave principal de la tabla auditlog actual y agregue la nueva clave principal.

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

2. Reconstruya índices (opcional pero muy recomendable; consulte Notas importantes sobre la reconstrucción de índices).

REINDEX TABLE CONCURRENTLY auditlog;
Modificación de la clave principal sin tiempo de inactividad

El método manual para modificar la clave principal se describe aquí. Alternativamente, se puede considerar la extensión pg_repack para crear una nueva tabla, copiar datos e intercambiar tablas.

1. Cree una nueva tabla con la nueva clave principal y cree índices.

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. Intercambiar tablas.

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

3. Copie los datos de la tabla anterior a la tabla nueva.

INSERT INTO auditlog SELECT * FROM auditlog_old;

Esto se puede hacer en fragmentos (múltiples declaraciones INSERT INTO con cláusulas WHERE clock según sea necesario) para evitar el uso excesivo de recursos.

4. Elimine la antigua tabla.

DROP TABLE auditlog_old;

Oracle

Notas importantes sobre la reconstrucción de índices

Oracle reconstruye automáticamente los índices de la clave principal durante la operación "ALTER TABLE". Sin embargo, se recomienda encarecidamente reconstruir también los índices manualmente con las declaraciones ALTER INDEX <index> REBUILD PARALLEL para garantizar un rendimiento óptimo de la base de datos.

La reconstrucción de índices puede requerir temporalmente una cantidad significativa de espacio en disco.

Si le preocupa el espacio disponible en el disco, siga las instrucciones Alteración de la clave principal sin tiempo de inactividad. Otras opciones también están disponibles:

  • Aumentar el parámetro de Oracle SORT_AREA_SIZE puede ayudar a reducir el uso de espacio en disco al reconstruir índices manualmente . Sin embargo, modificar esta variable afectará el uso general de la memoria de la base de datos.
  • Puede establecer el grado de paralelo usando la cláusula PARALLEL, por ejemplo: ALTER INDEX auditlog_1 REBUILD PARALLEL 4
  • Considere la posibilidad de liberar espacio eliminando datos potencialmente innecesarios.
  • Considere disminuir el parámetro Período de almacenamiento de datos housekeeper antes de ejecutar el housekeeper.
Alteración de la clave principal con tiempo de inactividad

1. Recupera el nombre de la restricción.

SELECT CONSTRAINT_NAME FROM all_constraints WHERE TABLE_NAME = 'AUDITLOG' AND CONSTRAINT_TYPE = 'P';

2. Elimine la clave principal de la tabla auditlog actual y agregue la nueva clave principal.

ALTER TABLE auditlog DROP CONSTRAINT <constraint_name>;
       ALTER TABLE auditlog ADD CONSTRAINT auditlog_pk PRIMARY KEY (auditid, clock);

3. Reconstruya índices (opcional pero muy recomendado, consulte Notas importantes sobre la reconstrucción de índices).

3.1. Obtenga nombres de índice.

SELECT index_name FROM user_indexes WHERE table_name='AUDITLOG';

3.2. Reconstruya cada índice.

ALTER INDEX auditlog_pk REBUILD PARALLEL;
       ALTER INDEX auditlog_1 REBUILD PARALLEL;
       ALTER INDEX auditlog_2 REBUILD PARALLEL;
       ALTER INDEX auditlog_3 REBUILD PARALLEL;
Modificación de la clave principal sin tiempo de inactividad

1. Cree una nueva tabla con la nueva clave principal y cree índices.

CREATE TABLE auditlog_new (
         auditid              nvarchar2(25)                             ,
         userid               number(20)                                NULL,
         username             nvarchar2(100)  DEFAULT ''                ,
         clock                number(10)      DEFAULT '0'               NOT NULL,
         ip                   nvarchar2(39)   DEFAULT ''                ,
         action               number(10)      DEFAULT '0'               NOT NULL,
         resourcetype         number(10)      DEFAULT '0'               NOT NULL,
         resourceid           number(20)                                NULL,
         resource_cuid        nvarchar2(25)                             ,
         resourcename         nvarchar2(255)  DEFAULT ''                ,
         recordsetid          nvarchar2(25)                             ,
         details              nclob           DEFAULT ''                ,
         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. Intercambio de tablas.

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

3. Copie los datos de la tabla anterior a la tabla nueva.

INSERT INTO auditlog SELECT * FROM auditlog_old;

Esto se puede hacer en fragmentos (múltiples declaraciones INSERT INTO con cláusulas WHERE clock según sea necesario) para evitar el uso excesivo de recursos.

4. Elimine la antigua tabla.

DROP TABLE auditlog_old;

Ver también