[comment]: # ({c4cea8a3-5b27abf6})
# 4 Preparando la tabla auditlog para particionado

[comment]: # ({/c4cea8a3-5b27abf6})

[comment]: # ({f697fbbd-9f4e8194})
#### Descripción general

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

Esta sección proporciona instrucciones para modificar la clave primaria de la tabla `auditlog`.

[comment]: # ({/f697fbbd-9f4e8194})

[comment]: # ({496f4662-399f6b3f})
::: noteimportant
Las instrucciones proporcionadas en esta página están diseñadas para usuarios avanzados.
Tenga en cuenta que estas instrucciones pueden necesitar ser ajustadas para su configuración específica.
Modificar la clave primaria también puede ser incompatible con futuros parches de actualización, por lo que puede ser necesario gestionar manualmente futuras actualizaciones.
<br><br>
Modificar la clave primaria puede ser una operación que consume muchos recursos y que lleva mucho tiempo dependiendo del tamaño de la tabla `auditlog`.
Se recomienda detener el servidor Zabbix y cambiar el frontend de Zabbix a [modo de mantenimiento](/manual/web_interface/maintenance_mode) durante el tiempo que dure la modificación.
Sin embargo, si es absolutamente necesario, existe una forma de modificar la clave primaria sin tiempo de inactividad (ver más abajo).
:::

[comment]: # ({/496f4662-399f6b3f})

[comment]: # ({388a49dd-762f2fc8})
La partición de la tabla `auditlog` puede mejorar, por ejemplo, el mantenimiento en instalaciones grandes.
Aunque actualmente el [mantenimiento](/manual/web_interface/frontend_sections/administration/housekeeping) de Zabbix no puede aprovechar las tablas particionadas (excepto para TimescaleDB), puede desactivar el mantenimiento de Zabbix y eliminar particiones utilizando scripts.

Desde Zabbix 7.0, la tabla `auditlog` para TimescaleDB se ha convertido en una hypertable, lo que permite al housekeeper eliminar datos por bloques.
Para actualizar la tabla `auditlog` existente a una hypertable, consulte [Actualización del esquema de TimescaleDB](/manual/appendix/install/timescaledb#upgrading-timescaledb-schema).

[comment]: # ({/388a49dd-762f2fc8})

[comment]: # ({073b5bd5-271b9416})
#### MySQL

[comment]: # ({/073b5bd5-271b9416})

[comment]: # ({f576f708-e752da32})
##### Notas importantes sobre la reconstrucción de índices {#important-notes-on-rebuilding-indexes-1}

MySQL reconstruye automáticamente los índices de la clave primaria durante la operación `ALTER TABLE`.
Sin embargo, se recomienda encarecidamente reconstruir también manualmente los índices 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 adicional en disco como el que utiliza la propia tabla.
Para obtener el tamaño actual de los datos y los índices, puede ejecutar las siguientes instrucciones:

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

Si el espacio disponible en disco es una preocupación, siga las instrucciones de [Alterar la clave primaria sin tiempo de inactividad](#altering-primary-key-without-downtime-1).
También hay otras opciones disponibles:

-   Aumentar el parámetro MySQL [`sort_buffer_size`](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html) puede ayudar a reducir el uso de espacio en disco al reconstruir manualmente los índices.
    Sin embargo, modificar esta variable puede afectar al uso general de memoria de la base de datos.
-   Considere liberar espacio eliminando datos potencialmente innecesarios.
-   Considere reducir el parámetro *Período de almacenamiento de datos* de [housekeeper](/manual/web_interface/frontend_sections/administration/housekeeping#overview) antes de ejecutar el housekeeper.

[comment]: # ({/f576f708-e752da32})

[comment]: # ({de2a0c3b-e0cfde87})
##### Alteración de la clave primaria con tiempo de inactividad {#altering-primary-key-with-downtime-1}

1\. Elimine la clave primaria actual de la tabla `auditlog` y agregue la nueva clave primaria.

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

2\. Reconstruya los índices (opcional, pero muy recomendable; consulte [Notas importantes sobre la reconstrucción de índices](#important-notes-on-rebuilding-indexes-1)).

```sql
OPTIMIZE TABLE auditlog;
```

[comment]: # ({/de2a0c3b-e0cfde87})

[comment]: # ({19b5a6ba-9fb9cdb0})
##### Alteración de la clave primaria sin tiempo de inactividad {#altering-primary-key-without-downtime-1}

Aquí se describe el método manual para alterar la clave primaria.
Como alternativa, puede usar el toolkit [pt-online-schema-change](https://docs.percona.com/percona-toolkit/pt-online-schema-change.html) de Percona.
Este toolkit realiza automáticamente las siguientes acciones, al mismo tiempo que minimiza el espacio utilizado para alterar la tabla `auditlog`.

1\. Crear una nueva tabla con la nueva clave primaria y crear índices.

```sql
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\. Intercambiar las tablas.

```sql
RENAME TABLE auditlog TO auditlog_old, auditlog_new TO auditlog;
```

3\. Copiar los datos de la tabla antigua a la nueva.

```sql
INSERT INTO auditlog SELECT * FROM auditlog_old;
```

Esto se puede hacer en fragmentos (varias instrucciones `INSERT INTO` con cláusulas `WHERE clock` según sea necesario) para evitar un uso excesivo de recursos.

4\. Eliminar la tabla antigua.

```sql
DROP TABLE auditlog_old;
```

[comment]: # ({/19b5a6ba-9fb9cdb0})

[comment]: # ({dc8ac96e-381b1eee})
#### PostgreSQL

[comment]: # ({/dc8ac96e-381b1eee})

[comment]: # ({64d2938a-30f863e9})
##### Notas importantes sobre la reconstrucción de índices {#important-notes-on-rebuilding-indexes-2}

PostgreSQL reconstruye automáticamente los índices de la clave primaria durante la operación `ALTER TABLE`.
Sin embargo, se recomienda encarecidamente reconstruir también manualmente los índices 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:

```sql
SELECT pg_size_pretty(pg_indexes_size('auditlog'));
```

Si el espacio disponible en disco es una preocupación, siga las instrucciones de [Alterar la clave primaria sin tiempo de inactividad](#altering-primary-key-without-downtime-2).
También hay otras opciones disponibles:

-   Aumentar el parámetro [`maintenance_work_mem`](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) de PostgreSQL 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 memoria de la base de datos.
-   Si dispone de otro disco o tablespace con más espacio disponible, puede considerar cambiar la ubicación del almacenamiento temporal para la reconstrucción del índice.
    Puede establecer el parámetro [`temp_tablespaces`](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-TEMP-TABLESPACES) de PostgreSQL para especificar un tablespace diferente para los objetos temporales.
-   Considere liberar espacio eliminando datos potencialmente innecesarios.
-   Considere reducir el parámetro *Período de almacenamiento de datos* [housekeeper](/manual/web_interface/frontend_sections/administration/housekeeping#overview) antes de ejecutar el housekeeper.

[comment]: # ({/64d2938a-30f863e9})

[comment]: # ({18dc0642-915b5f5f})
##### Alteración de la clave primaria con tiempo de inactividad {#altering-primary-key-with-downtime-2}

1\. Elimine la clave primaria actual de la tabla `auditlog` y agregue la nueva clave primaria.

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

2\. Reconstruya los índices (opcional, pero muy recomendable; consulte [Notas importantes sobre la reconstrucción de índices](#important-notes-on-rebuilding-indexes-2)).

```sql
REINDEX TABLE CONCURRENTLY auditlog;
```

[comment]: # ({/18dc0642-915b5f5f})

[comment]: # ({ab7f639c-998c6861})
##### Alteración de la clave primaria sin tiempo de inactividad {#altering-primary-key-without-downtime-2}

Aquí se describe el método manual para alterar la clave primaria.
Como alternativa, se puede considerar la extensión `pg_repack` para crear una nueva tabla, copiar los datos e intercambiar las tablas.

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

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

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

3\. Copie los datos de la tabla antigua a la nueva.

```sql
INSERT INTO auditlog SELECT * FROM auditlog_old;
```

Esto se puede hacer en fragmentos (varias instrucciones `INSERT INTO` con cláusulas `WHERE clock` según sea necesario) para evitar un uso excesivo de recursos.

4\. Elimine la tabla antigua.

```sql
DROP TABLE auditlog_old;
```

[comment]: # ({/ab7f639c-998c6861})

[comment]: # ({2a8e17b6-2132d968})
#### Oracle

[comment]: # ({/2a8e17b6-2132d968})

[comment]: # ({fe750069-f5959ede})
##### Notas importantes sobre la reconstrucción de índices {#important-notes-on-rebuilding-indexes-3}

Oracle reconstruye automáticamente los índices de la clave primaria durante la operación `ALTER TABLE`.
Sin embargo, se recomienda encarecidamente reconstruir también manualmente los índices con las instrucciones `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 el espacio disponible en disco es una preocupación, siga las instrucciones de [Alterar la clave primaria sin tiempo de inactividad](#altering-primary-key-without-downtime-3).
También hay otras opciones disponibles:

-   Aumentar el parámetro de Oracle [`SORT_AREA_SIZE`](https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/SORT_AREA_SIZE.html) puede ayudar a reducir el uso de espacio en disco al reconstruir manualmente los índices.
    Sin embargo, modificar esta variable afectará el uso total de memoria de la base de datos.
-   Puede establecer el grado de paralelismo mediante la cláusula PARALLEL, por ejemplo: `ALTER INDEX auditlog_1 REBUILD PARALLEL 4`
-   Considere liberar espacio eliminando datos potencialmente innecesarios.
-   Considere reducir el parámetro *Data storage period* [housekeeper](/manual/web_interface/frontend_sections/administration/housekeeping#overview) antes de ejecutar el housekeeper.

[comment]: # ({/fe750069-f5959ede})

[comment]: # ({586dc269-221f8287})
##### Alteración de la clave primaria con tiempo de inactividad {#altering-primary-key-with-downtime-3}

1\. Obtenga el nombre de la restricción.

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

2\. Elimine la clave primaria actual de la tabla `auditlog` y agregue la nueva clave primaria.

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

3\. Reconstruya los índices (opcional, pero muy recomendable; consulte [Notas importantes sobre la reconstrucción de índices](#important-notes-on-rebuilding-indexes-3)).

3.1\. Obtenga los nombres de los índices.

```sql
SELECT index_name FROM user_indexes WHERE table_name='AUDITLOG';
```

3.2\. Reconstruya cada índice.

```sql
ALTER INDEX auditlog_pk REBUILD PARALLEL;
ALTER INDEX auditlog_1 REBUILD PARALLEL;
ALTER INDEX auditlog_2 REBUILD PARALLEL;
ALTER INDEX auditlog_3 REBUILD PARALLEL;
```

[comment]: # ({/586dc269-221f8287})

[comment]: # ({d714ab21-af258bb0})
##### Alterar la clave primaria sin tiempo de inactividad {#altering-primary-key-without-downtime-3}

1\. Crear una nueva tabla con la nueva clave primaria y crear índices.

```sql
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\. Intercambiar las tablas.

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

3\. Copiar los datos de la tabla antigua a la nueva.

```sql
INSERT INTO auditlog SELECT * FROM auditlog_old;
```

Esto se puede hacer en fragmentos (varias instrucciones `INSERT INTO` con cláusulas `WHERE clock` según sea necesario) para evitar un uso excesivo de recursos.

4\. Eliminar la tabla antigua.

```sql
DROP TABLE auditlog_old;
```

[comment]: # ({/d714ab21-af258bb0})

[comment]: # ({33200567-31083cb3})
#### Véase también

-   [Actualización de la base de datos a claves primarias](/manual/appendix/install/db_primary_keys)

[comment]: # ({/33200567-31083cb3})
