Limpiado automatizado de tablas Prestashop para mejorar rendimiento con Core-Admin


#1

1. Introducción

El siguiente artículo explica cómo limpiar tablas de Prestashop que se suelen llenar y que contienen datos que no son vitales para el funcionamiento de la web. Con el tiempo, a medida que se llenan, pueden causar problemas de rendimiento.

El proceso se puede hacer de dos formas:

  • Automatizada, con la herramienta crad-prestashop-mgr.pyc, que hace la limpieza, la optimización de la base de datos y además deja programada la automatización diaria de ambas (ver punto 4).
  • Manual, desde el gestor de #MySQL de Core-Admin, tabla a tabla (ver punto 3). Este apartado se mantiene para que quede visible exactamente qué hace el proceso automático.
ADVERTENCIA: antes de cualquier cambio, haz una copia de seguridad:

2. Tablas involucradas

Las siguientes tablas serán el blanco del borrado manual o automatizado para mantener fresco el Prestashop:

  • ps_guest
  • ps_connections
  • ps_connections_page
  • ps_connections_source
  • ps_page_viewed
  • ps_layered_filter_block
  • ps_log
  • ps_statssearch
  • ps_pagenotfound
  • ps_smarty_cache
  • ps_layered_price_index (y sus variantes numeradas: ps_layered_price_index_2, ps_layered_price_index_3, …)

Todas ellas son tablas de estadísticas, logs, cachés o índices que Prestashop vuelve a generar por sí mismo, por lo que vaciarlas es seguro.

2.1. Cuidado con el prefijo de las tablas

ps_ es el prefijo por defecto, pero no todas las instalaciones lo usan: al instalar Prestashop se puede elegir otro (psx_, pshop_, un prefijo aleatorio, etc.). El prefijo real de cada tienda está en su fichero de configuración:

  • Prestashop 1.7.x / 8.x / 9.x: app/config/parameters.php → 'database_prefix' => 'ps_',
  • Prestashop 1.6.x: config/settings.inc.php → define('_DB_PREFIX_', 'ps_');

Si se trabaja a mano, hay que sustituir ps_ por el prefijo que use esa tienda. La herramienta lo lee automáticamente del fichero de configuración de la instalación, por lo que no hay que indicárselo.

2.2. Variantes de layered_price_index

El módulo de búsqueda por facetas (ps_facetedsearch) mantiene un índice de precios por tienda y por ranura de reconstrucción. Por eso, además de ps_layered_price_index, una instalación puede tener ps_layered_price_index_2, ps_layered_price_index_3, etc.

Todas ellas son índices reconstruibles y hay que limpiarlas y programarlas igual que la tabla base: si sólo se trata la base, la variante más grande se queda fuera del mantenimiento en silencio (es un caso que hemos visto con la variante ocupando varios GB mientras la tabla base estaba vacía).

La herramienta detecta y trata todas las variantes automáticamente. Sólo se consideran los sufijos numéricos, de manera que tablas como ps_layered_price_index_backup o ps_layered_price_index_old no se vacían nunca.

2.3. Tablas que NO se vacían: ps_cart_rule_combination

ps_cart_rule_combination guarda, por cada cupón/regla de carrito declarada como “restringida”, con qué otras reglas se puede combinar: una fila por cada par. Prestashop reescribe esas filas cada vez que se guarda un cupón y propaga la compatibilidad al resto, de modo que la tabla crece de forma cuadrática respecto al número de cupones restringidos y acaba siendo, con frecuencia, la tabla más grande de una tienda antigua (varios GB frente a unos pocos MB de ps_cart_rule).

Esta tabla no se debe vaciar nunca. El back-office pinta las casillas de compatibilidad leyendo precisamente esta tabla: si se trunca, todos los cupones restringidos pasan a ser no combinables y, al guardar cualquiera de ellos, ese estado se consolida (guardar no restaura la selección anterior, persiste lo que muestre el formulario).

Lo que sí se puede borrar, y es lo que hace la herramienta, son las filas que ya no pueden tener ningún efecto:

Grupo Significado ¿Se borra?
Huérfanas uno de los dos cupones ya no existe Siempre (basura pura)
Caducadas hace tiempo uno de los dos cupones caducó hace más de N días (180 por defecto) Sí, política por defecto
Caducadas/desactivadas recientes uno de los dos cupones está desactivado o caducó hace poco Sólo con --include-expired
Vivas los dos cupones son utilizables Nunca

El grupo de “caducadas hace tiempo” ignora a propósito el flag active: un cupón desactivado con fecha de fin futura es una campaña pausada y, si se reactiva, aparecería con su lista de compatibilidades vacía. Por eso esos casos sólo se tocan pidiéndolo explícitamente.

Borrar pares caducados no tiene efecto en la tienda mientras el cupón siga caducado: CartRule::checkValidity() rechaza el cupón antes de llegar a comprobar la combinabilidad.

3. Borrado manual

Este es el proceso manual, equivalente a lo que hace la automatización, útil para revisar tabla a tabla qué se está tocando.

  1. Para borrar estas tablas arranca el gestor de #MySQL. Para ello necesitas ser administrador de la máquina o tener un usuario administrador de plataforma:

  2. Dentro, localizar la base de datos asociada a tu Prestashop, y en la pestaña de tablas, buscarlas para poder pinchar sobre ellas:

  3. Dentro de la ficha de la tabla usar el botón de “Limpiar tabla de BD”: OJO: selecciona bien!:

Lo que hace ese botón es, simplemente, un TRUNCATE TABLE sobre la tabla seleccionada. El equivalente por consola sería:

TRUNCATE TABLE ps_guest;
TRUNCATE TABLE ps_connections;
TRUNCATE TABLE ps_connections_page;
TRUNCATE TABLE ps_connections_source;
TRUNCATE TABLE ps_page_viewed;
TRUNCATE TABLE ps_layered_filter_block;
TRUNCATE TABLE ps_log;
TRUNCATE TABLE ps_statssearch;
TRUNCATE TABLE ps_pagenotfound;
TRUNCATE TABLE ps_smarty_cache;
TRUNCATE TABLE ps_layered_price_index;

Recuerda ajustar el prefijo (punto 2.1) y añadir las variantes numeradas de ps_layered_price_index que tenga esa tienda (punto 2.2). Para saber cuáles hay:

SHOW TABLES LIKE 'ps\_layered\_price\_index%';

4. Automatizar el borrado

4.1. Desde el interfaz web

Para automatizar el borrado, simplemente completa los de configuración de hora de borrado y luego pulsa a editar. Esto creará una configuración periódica, diaria, para el borrado de la tabla:

Hay que repetirlo para cada una de las tablas del punto 2.

4.2. Con crad-prestashop-mgr.pyc (recomendado)

Todo lo anterior (limpieza, optimización y programación diaria de ambas) se puede hacer en un único comando. Es la forma recomendada porque no se olvida ninguna tabla, aplica el prefijo real de la tienda y recoge las variantes de índices:

crad-prestashop-mgr.pyc --optimize-tables example.com --dry-run

Con --dry-run sólo informa: qué tablas existen, cuáles se van a limpiar, cuáles no están presentes y qué programación se dejaría puesta, sin tocar nada. Cuando el informe sea el esperado, se aplica:

crad-prestashop-mgr.pyc --optimize-tables example.com --yes

La tienda se puede identificar por dominio, por nombre de hosting o por la ruta de la instalación.

Los pasos que ejecuta son:

  1. Limpieza de todas las tablas de rendimiento que existan en esa base de datos (TRUNCATE), incluyendo todas las variantes de layered_price_index.
  2. Poda de los pares muertos de cart_rule_combination (huérfanos + caducados hace más de 180 días), volcando antes las filas borradas a una copia restaurable. Este paso sólo se activa si la tabla supera los 100 MB.
  3. Optimización de toda la base de datos, que además reconstruye la tabla podada para que el espacio vuelva al disco.
  4. Programación de la limpieza diaria automática de cada tabla (por defecto a las 04:00).
  5. Programación de la optimización diaria automática de la base de datos (por defecto a las 05:00).

Las horas se pueden cambiar:

crad-prestashop-mgr.pyc --optimize-tables example.com --cleanup-time 03:30 --optimize-time 04:30 --yes

Es decir, una sola ejecución deja la tienda limpia y el mantenimiento diario configurado, que es lo que en el punto 4.1 habría que hacer tabla a tabla desde el interfaz.

4.3. Dónde queda configurada la automatización

La programación de los pasos 4 y 5 no es un temporizador interno: se materializa en ficheros de cron reales, que la propia herramienta muestra al final de la ejecución:

Qué Dónde
Limpieza diaria, un fichero por tabla /etc/cron.d/mysql-manager-auto-cleanup-<tabla>-<basededatos>-<servidor>
Script que ejecuta cada uno de ellos /var/beep/core-admin/client-agent/scripts/mysql-manager-auto-cleanup-<tabla>-<basededatos>-<servidor>.py
Optimización diaria de la base de datos /etc/cron.d/mysql-manager-auto-optimize-<basededatos>-<servidor>

Los nombres se normalizan: los espacios y los guiones bajos pasan a guiones y todo va en minúsculas. Por ejemplo, la tabla ps_guest de la base de datos tienda_portatilmovil en el servidor MySQL Default queda en:

/etc/cron.d/mysql-manager-auto-cleanup-ps-guest-tienda-portatilmovil-default

Para revisarlos todos de golpe:

cat /etc/cron.d/mysql-manager-auto-cleanup-*
cat /etc/cron.d/mysql-manager-auto-optimize-*

El script que lanza cada cron de limpieza es un pequeño fichero generado que hace un TRUNCATE TABLE de esa tabla, y el cron de optimización llama a crad-mysql-dump-all.pyc -o.

Para desactivar la automatización, hay que quitar la hora de limpieza/optimización desde el gestor de #MySQL del interfaz web: eso borra los ficheros. Si se borran a mano, la opción sigue marcada como activa en el gestor y volvería a escribirlos en la siguiente edición.

5. Optimización de tablas por borrados recurrentes

Otro aspecto a tener en cuenta a la hora optimizar la base de datos de un prestashop es que algunas tablas puede llegar a crecer mucho se almacen información que fluctúa mucho, es decir, muchos añadidos unidos a muchos borrados.

Esto pasa especialmente para tablas de índices. Son tablas con mucha información pero que no podemos borrar.

Sin embargo, en dichos casos, si exportamos la información de dichas tablas vemos que no hay una relación directamente entre el uso y el tamaño de la base de datos. El motivo es que InnoDB no devuelve al sistema de ficheros las páginas que libera un DELETE: hay que reconstruir la tabla para recuperar ese espacio.

En dichos casos, recomendamos seguir procedimiento de optimización:

El paso 3 de --optimize-tables (punto 4.2) ya hace esto sobre toda la base de datos, y deja además la optimización diaria programada.

6. Limpieza de combinaciones de cupones (cart_rule_combination)

Cuando la tienda usa muchos cupones restringidos, esta tabla suele ser la que más ocupa de toda la base de datos. Como se explica en el punto 2.3, no se puede vaciar, pero sí se pueden podar los pares que ya no sirven.

Primero, para ver la situación sin tocar nada:

crad-prestashop-mgr.pyc --clean-cart-rule-combinations example.com --dry-run

La salida desglosa los cuatro grupos (huérfanos, caducados hace tiempo, caducados recientes y vivos) con filas y MB de cada uno, además del número de cupones totales y cuántos están desactivados o caducados. Para aplicar la poda:

crad-prestashop-mgr.pyc --clean-cart-rule-combinations example.com --yes

Detalles del proceso:

  • Todo lo que se borra se vuelca antes a un fichero .sql.gz restaurable con zcat FICHERO | mysql BASEDEDATOS. Por defecto se escribe en /var/lib/core-admin/prestashop_manager; se puede elegir con --backup-file y saltar con --no-backup (no recomendado: estos datos no los regenera Prestashop). La ejecución se niega a empezar si el sistema de ficheros no tiene sitio para la copia.
  • El borrado se hace por lotes sobre rangos de id_cart_rule_1 (la primera columna de la clave primaria), para que cada sentencia vaya por índice y las transacciones queden acotadas. En tablas de decenas de millones de filas esto evita bloqueos largos.
  • Al terminar se reconstruye la tabla (OPTIMIZE TABLE) para devolver el espacio al disco. Se puede saltar con --skip-optimize.
  • Con --older-than N se cambia el umbral de “caducado hace tiempo” (180 días por defecto).
  • Con --include-expired se borran también los pares de cupones simplemente desactivados o caducados hace poco. Es opcional a propósito: son campañas pausadas y, si se reactivan, habría que volver a marcar a mano su lista de compatibilidades en el back-office.
crad-prestashop-mgr.pyc --clean-cart-rule-combinations example.com --older-than 365 --yes
crad-prestashop-mgr.pyc --clean-cart-rule-combinations example.com --include-expired --yes

7. Eliminar los cupones caducados (causa del crecimiento)

Podar las combinaciones trata el síntoma. Mientras los cupones muertos sigan en ps_cart_rule, cada cupón restringido nuevo vuelve a generar pares contra ellos.

--remove-expired-cart-rules borra los cupones que caducaron hace más de --older-than días (180 por defecto), replicando exactamente lo que hace Prestashop al borrar un cupón (CartRule::delete()): cart_cart_rule, cart_rule_carrier, cart_rule_shop, cart_rule_group, cart_rule_country, cart_rule_lang, cart_rule_combination, cart_rule_product_rule_group, después cart_rule_product_rule y cart_rule_product_rule_value por dependencia, y finalmente cart_rule.

crad-prestashop-mgr.pyc --remove-expired-cart-rules example.com --dry-run
crad-prestashop-mgr.pyc --remove-expired-cart-rules example.com --older-than 365 --yes

Garantías:

  • Nunca toca un cupón que siga siendo válido, que esté simplemente pausado o que no tenga fecha de fin. El criterio es la fecha date_to pasada hace más de N días, nunca active = 0.
  • El histórico de pedidos no se ve afectado: ps_order_cart_rule guarda su propia copia del nombre y el importe del cupón, que es lo que pinta el back-office en un pedido antiguo. La herramienta comprueba que exista esa columna y, si no existe, se niega a tocar los cupones referenciados por pedidos.
  • Todas las filas borradas de todas las tablas se vuelcan antes a una copia restaurable.

Este comando no forma parte de --optimize-tables: hacer desaparecer cupones del back-office es visible para el responsable de la tienda y debe ser una decisión consciente.

8. Revisar el estado antes de actuar

Para ver de un vistazo todos los problemas de rendimiento de una tienda (versión de PHP, opcache, modo debug, ajustes de front-office, recolectores de estadísticas, tablas que crecen sin control, cart_rule_combination, specific_price, carritos abandonados…) sin modificar nada:

crad-prestashop-mgr.pyc --check-performance example.com

El informe termina con las recomendaciones concretas, indicando qué comando de los anteriores aplicar en cada caso. Conviene lanzarlo antes y después del mantenimiento.

Un apunte importante: los recolectores de estadísticas de Prestashop (PS_STATSDATA_*) son los que vuelven a llenar las tablas del punto 2. Si no se usan esas estadísticas, desactivarlos evita el problema de raíz, y eso lo aplica:

crad-prestashop-mgr.pyc --fix-performance example.com

Cómo depurar Prestashop que va lento en el backoffice
Manual recomendaciones para preparar una campaña de visitas