sql >> Base de Datos >  >> RDS >> MariaDB

Uso de Sysbench para generar datos de prueba para tablas fragmentadas en MySQL

Sysbench es una excelente herramienta para generar datos de prueba y realizar evaluaciones comparativas MySQL OLTP. Comúnmente, uno haría un ciclo de preparación-ejecución-limpieza cuando se realiza una evaluación comparativa con Sysbench. De forma predeterminada, la tabla generada por Sysbench es una tabla base estándar sin partición. Este comportamiento puede extenderse, por supuesto, pero debe saber cómo escribirlo en el script LUA.

En esta publicación de blog, mostraremos cómo generar datos de prueba para una tabla particionada en MySQL usando Sysbench. Esto puede usarse como un patio de juegos para que podamos profundizar en la causa-efecto de la partición de tablas, la distribución de datos y el enrutamiento de consultas.

Particionamiento de tablas de servidor único

La partición de un solo servidor simplemente significa que todas las particiones de la tabla residen en el mismo servidor/instancia de MySQL. Al crear la estructura de la tabla, definiremos todas las particiones a la vez. Este tipo de partición es buena si tiene datos que pierden su utilidad con el tiempo y se pueden eliminar fácilmente de una tabla particionada eliminando la partición (o particiones) que contienen solo esos datos.

Cree el esquema de Sysbench:

mysql> CREATE SCHEMA sbtest;

Cree el usuario de la base de datos sysbench:

mysql> CREATE USER 'sbtest'@'%' IDENTIFIED BY 'passw0rd';
mysql> GRANT ALL PRIVILEGES ON sbtest.* TO 'sbtest'@'%';

En Sysbench, se usaría el comando --prepare para preparar el servidor MySQL con estructuras de esquema y generar filas de datos. Tenemos que saltarnos esta parte y definir la estructura de la tabla manualmente.

Cree una tabla particionada. En este ejemplo, vamos a crear solo una tabla llamada sbtest1 y será dividida por una columna llamada "k", que es básicamente un número entero entre 0 y 1,000,000 (basado en la opción --table-size que estamos va a usar en la operación de solo inserción más adelante):

mysql> CREATE TABLE `sbtest1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `k` int(11) NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`,`k`)
  )
  PARTITION BY RANGE (k) (
    PARTITION p1 VALUES LESS THAN (499999),
    PARTITION p2 VALUES LESS THAN MAXVALUE
  );

Vamos a tener 2 particiones - La primera partición se llama p1 y almacenará datos donde el valor en la columna "k" es inferior a 499,999 y la segunda partición, p2, almacenará los valores restantes . También creamos una clave principal que contiene ambas columnas importantes:"id" es para el identificador de fila y "k" es la clave de partición. En la partición, una clave principal debe incluir todas las columnas en la función de partición de la tabla (donde usamos "k" en la función de partición de rango).

Verifique que las particiones estén ahí:

mysql> SELECT TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, TABLE_ROWS 
       FROM INFORMATION_SCHEMA.PARTITIONS 
       WHERE TABLE_SCHEMA='sbtest2' 
       AND TABLE_NAME='sbtest1';
+--------------+------------+----------------+------------+
| TABLE_SCHEMA | TABLE_NAME | PARTITION_NAME | TABLE_ROWS |
+--------------+------------+----------------+------------+
| sbtest       | sbtest1    | p1             |          0 |
| sbtest       | sbtest1    | p2             |          0 |
+--------------+------------+----------------+------------+

Luego podemos iniciar una operación de solo inserción de Sysbench como se muestra a continuación:

$ sysbench \
/usr/share/sysbench/oltp_insert.lua \
--report-interval=2 \
--threads=4 \
--rate=20 \
--time=9999 \
--db-driver=mysql \
--mysql-host=192.168.11.131 \
--mysql-port=3306 \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=passw0rd \
--tables=1 \
--table-size=1000000 \
run

Observe cómo crecen las particiones de la tabla a medida que se ejecuta Sysbench:

mysql> SELECT TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, TABLE_ROWS 
       FROM INFORMATION_SCHEMA.PARTITIONS 
       WHERE TABLE_SCHEMA='sbtest2' 
       AND TABLE_NAME='sbtest1';
+--------------+------------+----------------+------------+
| TABLE_SCHEMA | TABLE_NAME | PARTITION_NAME | TABLE_ROWS |
+--------------+------------+----------------+------------+
| sbtest       | sbtest1    | p1             |       1021 |
| sbtest       | sbtest1    | p2             |       1644 |
+--------------+------------+----------------+------------+

Si contamos el número total de filas usando la función COUNT, corresponderá al número total de filas reportado por las particiones:

mysql> SELECT COUNT(id) FROM sbtest1;
+-----------+
| count(id) |
+-----------+
|      2665 |
+-----------+

Eso es todo. Tenemos listo un particionamiento de tabla de servidor único con el que podemos jugar.

Particionamiento de tablas multiservidor

En el particionamiento de varios servidores, vamos a utilizar varios servidores MySQL para almacenar físicamente un subconjunto de datos de una tabla en particular (sbtest1), como se muestra en el siguiente diagrama:

Vamos a implementar 2 nodos MySQL independientes:mysql1 y mysql2. La tabla sbtest1 se dividirá en estos dos nodos y llamaremos fragmento a esta combinación de partición + host. Sysbench se ejecuta de forma remota en el tercer servidor, imitando el nivel de la aplicación. Dado que Sysbench no reconoce particiones, necesitamos tener un controlador de base de datos o un enrutador para enrutar las consultas de la base de datos al fragmento correcto. Usaremos ProxySQL para lograr este propósito.

Vamos a crear otra nueva base de datos llamada sbtest3 para este propósito:

mysql> CREATE SCHEMA sbtest3;
mysql> USE sbtest3;

Otorgue los privilegios correctos al usuario de la base de datos sbtest:

mysql> CREATE USER 'sbtest'@'%' IDENTIFIED BY 'passw0rd';
mysql> GRANT ALL PRIVILEGES ON sbtest3.* TO 'sbtest'@'%';

En mysql1, cree la primera partición de la tabla:

mysql> CREATE TABLE `sbtest1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `k` int(11) NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`,`k`)
  )
  PARTITION BY RANGE (k) (
    PARTITION p1 VALUES LESS THAN (499999)
  );

A diferencia de la partición independiente, solo definimos la condición para la partición p1 en la tabla para almacenar todas las filas con valores de columna "k" que van desde 0 a 499,999.

En mysql2, cree otra tabla particionada:

mysql> CREATE TABLE `sbtest1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `k` int(11) NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`,`k`)
  )
  PARTITION BY RANGE (k) (
    PARTITION p2 VALUES LESS THAN MAXVALUE
  );

En el segundo servidor, debe contener los datos de la segunda partición almacenando el resto de los valores anticipados de la columna "k".

Nuestra estructura de tabla ahora está lista para ser completada con datos de prueba.

Antes de que podamos ejecutar la operación de solo inserción de Sysbench, debemos instalar un servidor ProxySQL como enrutador de consultas y actuar como puerta de enlace para nuestros fragmentos de MySQL. La fragmentación de varios servidores requiere que las conexiones de la base de datos provenientes de las aplicaciones se enruten al fragmento correcto. De lo contrario, vería el siguiente error:

1526 (Table has no partition for value 503599)

Instale ProxySQL usando ClusterControl, agregue el usuario de la base de datos sbtest en ProxySQL, agregue ambos servidores MySQL en ProxySQL y configure mysql1 como hostgroup 11 y mysql2 como hostgroup 12:

A continuación, debemos trabajar en cómo se debe enrutar la consulta. Una muestra de la consulta INSERT que realizará Sysbench se verá así:

INSERT INTO sbtest1 (id, k, c, pad) 
  VALUES (0, 503502, '88816935247-23939908973-66486617366-05744537902-39238746973-63226063145-55370375476-52424898049-93208870738-99260097520', '36669559817-75903498871-26800752374-15613997245-76119597989')

Así que vamos a utilizar la siguiente expresión regular para filtrar la consulta INSERT para "k" => 500000, para cumplir con la condición de partición:

^INSERT INTO sbtest1 \(id, k, c, pad\) VALUES \([0-9]\d*, ([5-9]{1,}[0-9]{5}|[1-9]{1,}[0-9]{6,}).*

La expresión anterior simplemente intenta filtrar lo siguiente:

  • [0-9]\d* - Estamos esperando un entero de incremento automático aquí, por lo tanto, comparamos con cualquier entero.

  • [5-9]{1,}[0-9]{5} - El valor coincide con cualquier número entero desde 5 como el primer dígito, y 0-9 en los últimos 5 dígitos, para coincidir con el valor del rango de 500 000 a 999 999.

  • [1-9]{1,}[0-9]{6,} - El valor coincide con cualquier número entero del 1 al 9 como primer dígito y del 0 al 9 en los últimos 6 dígitos o más, para que coincida con el valor de 1 000 000 y más grande.

Crearemos dos reglas de consulta similares. La primera regla de consulta es la negación de la expresión regular anterior. Asignamos a esta regla el ID 51 y el grupo de host de destino debe ser el grupo de host 11 para que coincida con la columna "k" <500 000 y reenviar las consultas a la primera partición. Debería verse así:

Preste atención al "Patrón de coincidencia negativa" en la captura de pantalla anterior. Esa opción es fundamental para el enrutamiento adecuado de esta regla de consulta.

A continuación, cree otra regla de consulta con el ID de regla 52, usando la misma expresión regular y el grupo de host de destino debe ser 12, pero esta vez, deje el "Patrón de coincidencia negada" como falso, como se muestra a continuación:

Entonces podemos iniciar una operación de solo inserción usando Sysbench para generar datos de prueba . La información relacionada con el acceso a MySQL debe ser el host ProxySQL (192.168.11.130 en el puerto 6033):

$ sysbench \
/usr/share/sysbench/oltp_insert.lua \
--report-interval=2 \
--threads=4 \
--rate=20 \
--time=9999 \
--db-driver=mysql \
--mysql-host=192.168.11.130 \
--mysql-port=6033 \
--mysql-user=sbtest \
--mysql-db=sbtest3 \
--mysql-password=passw0rd \
--tables=1 \
--table-size=1000000 \
run

Si no ve ningún error, significa que ProxySQL ha enrutado nuestras consultas al fragmento/partición correcto. Debería ver que los aciertos de la regla de consulta aumentan mientras se ejecuta el proceso de Sysbench:

En la sección Consultas principales, podemos ver el resumen del enrutamiento de consultas:

Para volver a verificar, inicie sesión en mysql1 para buscar la primera partición y verifique el valor mínimo y máximo de la columna 'k' en la tabla sbtest1:

mysql> USE sbtest3;
mysql> SELECT min(k), max(k) FROM sbtest1;
+--------+--------+
| min(k) | max(k) |
+--------+--------+
| 232185 | 499998 |
+--------+--------+

Se ve muy bien. El valor máximo de la columna "k" no supera el límite de 499.999. Verifiquemos el número de filas que almacena para esta partición:

mysql> SELECT TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, TABLE_ROWS 
       FROM INFORMATION_SCHEMA.PARTITIONS 
       WHERE TABLE_SCHEMA='sbtest3' 
       AND TABLE_NAME='sbtest1';
+--------------+------------+----------------+------------+
| TABLE_SCHEMA | TABLE_NAME | PARTITION_NAME | TABLE_ROWS |
+--------------+------------+----------------+------------+
| sbtest3      | sbtest1    | p1             |       1815 |
+--------------+------------+----------------+------------+

Ahora revisemos el otro servidor MySQL (mysql2):

mysql> USE sbtest3;
mysql> SELECT min(k), max(k) FROM sbtest1;
+--------+--------+
| min(k) | max(k) |
+--------+--------+
| 500003 | 794952 |
+--------+--------+

Veamos el número de filas que almacena para esta partición:

mysql> SELECT TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, TABLE_ROWS 
       FROM INFORMATION_SCHEMA.PARTITIONS 
       WHERE TABLE_SCHEMA='sbtest3' 
       AND TABLE_NAME='sbtest1';
+--------------+------------+----------------+------------+
| TABLE_SCHEMA | TABLE_NAME | PARTITION_NAME | TABLE_ROWS |
+--------------+------------+----------------+------------+
| sbtest3      | sbtest1    | p2             |       3247 |
+--------------+------------+----------------+------------+

¡Magnífico! Tenemos una configuración de prueba de MySQL fragmentada con la partición de datos adecuada usando Sysbench para que podamos jugar. ¡Feliz evaluación comparativa!