MySQL Fabric Guía para administrar MySQL Alta disponibilidad y Escalabilidad

Tamaño: px
Comenzar la demostración a partir de la página:

Download "MySQL Fabric Guía para administrar MySQL Alta disponibilidad y Escalabilidad"

Transcripción

1 MySQL Fabric Guía para administrar MySQL Alta disponibilidad y Escalabilidad Informe de MySQL Septiembre de 2014 Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados.

2 Tabla de contenidos 1 RESUMEN EJECUTIVO QUÉ PROPORCIONA MYSQL FABRIC ALTA DISPONIBILIDAD Diferentes puntos de alta disponibilidad Duplicación MySQL Qué agrega MySQL Fabric en términos de alta disponibilidad ESCALABILIDAD, PARTICIONAMIENTO APROVISIONAMIENTO DEL SERVIDOR DÓNDE SE SITÚA MYSQL FABRIC CON LAS OTRAS OFERTAS MYSQL DE ORACLE LIMITACIONES ACTUALES DISEÑADO PARA LA EXTENSIBILIDAD CÓMO PRACTICAR, TUTORIALES AGREGAR ALTA DISPONIBILIDAD AGREGAR ESCALABILIDAD CON PARTICIONAMIENTO PRÁCTICAS OPERATIVAS RECOMENDADAS ORACLE UNIVERSITY CONSULTORÍA MYSQL MySQL Enterprise Edition y MySQL Cluster Carrier Grade Edition (CGE) CONCLUSIÓN RECURSOS ADICIONALES Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 2

3 1 Resumen ejecutivo MySQL es famosa por ser una base de datos muy sencilla de utilizar y con el motor de almacenamiento InnoDB que brinda gran desempeño, funcionalidad y confiabilidad. MySQL/InnoDB ahora escala muy bien a medida que se agregan más núcleos al servidor y esto mejora con cada lanzamiento pero hasta un punto que se alcanza el límite y el escalamiento no es suficiente. Puede ocurrir que esté utilizando la máquina más grande que está disponible o que sea más económico utilizar servidores múltiples y de bajo costo. La escalabilidad es una tarea sencilla si utiliza duplicación MySQL, obtenga un servidor MySQL maestro para lidiar con todas las operaciones de escritura y luego establezca un balance a través de cuantos servidores esclavos MySQL necesite. Qué sucede cuando un maestro único falla? La alta disponibilidad (HA) también hace frente a las fallas con la conexión a aplicaciones móviles y servicios globales, el concepto de ventana de mantenimiento donde el tiempo de inactividad del sistema puede ser programado es una cosa del pasado para la mayoría de las aplicaciones. Tradicionalmente ha sido el trabajo de la aplicación o de DBA el detectar fallas y promocionar uno de los esclavos para que sea el nuevo maestro. El hecho de que el sistema completo se haga altamente disponible puede volverse complejo y virar el desarrollo y los recursos operativos lejos de las tareas de valores más altos que generan ingresos. Mientras que la duplicación MySQL proporciona el mecanismo para escalar las operaciones de lectura, un único servidor debe manejar todas las operaciones de escritura y a medida que las aplicaciones modernas se vuelven cada vez más interactivas, la proporción de las operaciones de escritura seguirá en aumento. La ubicuidad de los medios sociales implica que la antigüedad de la publicación y la lectura de un sitio web están finalizadas. Añádase a esto la promesa que ofrecen las plataformas en la nube, una escalabilidad masiva y elástica de la infraestructura subyacente y se obtiene una enorme demanda de escalabilidad a docenas, cientos o incluso miles de servidores. La manera más común de escalabilidad es el particionamiento de los datos entre múltiples servidores MySQL, esto puede realizarse verticalmente (cada servidor contiene un subconjunto discreto de tablas para un conjunto específico de funciones) u horizontalmente donde cada servidor tiene un subconjunto de filas para una tabla dada. A pesar de ser efectivo, el particionamiento requiere que los desarrolladores y DBA dediquen sus esfuerzos en la construcción y el mantenimiento de lógica compleja en capas de aplicación y administración, y una vez más detractar actividades de valor más alto. La introducción de MySQL Fabric hace que todo sea más simple. MySQL Fabric está diseñada para administrar grupos de servidores MySQL, ya sea para pocos de alta disponibilidad o miles para lidiar con la escalabilidad de aplicaciones web. Para la alta disponibilidad, MySQL Fabric administrará las relaciones de replicación, detectará la falla del maestro y promocionará automáticamente uno de los esclavos para que sea el nuevo maestro. Esto es completamente transparente para la aplicación. Para la escalabilidad, MySQL Fabric automatiza el particionamiento con los requisitos de conectores de enrutamiento para el servidor (o servidores si también utiliza MySQL Fabric para alta disponibilidad) basado en una clave de particionamiento proporcionada por la aplicación. Si una partición incrementa de tamaño, MySQL Fabric puede dividir la partición a medida que garantiza que los requisitos continúan enviándose a la ubicación correcta. MySQL Fabric proporciona una opción simple y efectiva para la alta disponibilidad como así también la opción de escalabilidad y de incremento gradual. Realiza esto sin sacrificar la potencia de MySQL e InnoDB; lo que requiere cambios importantes para la aplicación o necesita los equipos de desarrollo de operaciones para pasar a tecnologías desconocidas o abandonar sus herramientas favoritas. Este informe se enfoca en las capacidades de MySQL Fabric con mayor profundidad para luego pasar a ofrecer un ejemplo práctico de su uso, inicialmente para proporcionar alta disponibilidad y luego añadir el particionamiento. Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 3

4 2 Qué proporciona MySQL Fabric MySQL Fabric está construida alrededor de un marco extensible para la administración de granjas de servidores de MySQL. Actualmente se han implementado dos funciones: la alta disponibilidad y la escalabilidad con la utilización de particionamiento de datos. Estas funciones se pueden utilizar separadas o en combinación. Ambas funciones se implementan en dos capas: El proceso de mysqlfabric que procesa los requisitos de administración, si recibe a través de mysqlfabric command-line-interface (documentado en el manual de referencia 1 ) u otro proceso a través de la interfaz suministrada XML/RPC. Al utilizar la función de HA (alta disponibilidad), este proceso puede ser responsable de monitorear el servidor maestro y de iniciar la conmutación por error para promocionar un esclavo para que sea el nuevo maestro en caso de que falle. El estado de la granja de servidores se lleva a cabo en el almacén de estado (una base de datos MySQL) y el proceso mysqlfabric es responsable de proporcionar la información almacenada de enrutamiento a los conectores. Los MySQL Connectors son utilizados por el código de aplicación para acceder a las bases de datos, lo que convierte las instrucciones de un lenguaje de programación específico al protocolo de cables MySQL, que se utiliza para comunicar con los procesos de servidores MySQL. Un conector compatible con Fabric almacena un caché de la información de enrutamiento que se recolecta desde MySQL Fabric y luego utiliza esa información para enviar transacciones o consultas al servidor MySQL correcto. Actualmente los tres conectores MySQL compatibles con Fabric son para PHP, Python y Java (y a su vez los marcos de doctrina e hibernación mapeo objeto relacional). Este enfoque significa que la latencia y la potencia del cuello de botella para enviar todas las consultas a través de un proxy pueden ser evitadas. MySQL Fabric también proporciona el aprovisionamiento del servidor con la utilización de marcos en la nube como OpenStack. 2.1 Alta disponibilidad Alta disponibilidad (HA) se refiere a la capacidad que tiene un sistema para proporcionar un servicio continuo, un servicio que está disponible mientras ese servicio se puede utilizar. El nivel de disponibilidad se expresa generalmente en términos de cantidad de nueves, por ejemplo, un nivel de HA de 99,999% significa que el servicio puede ser utilizado durante el 99,999% del tiempo, es decir, en promedio, el servicio no está disponible por 5,25 minutos por año (eso incluye el tiempo de inactividad programado y no programado) Diferentes puntos de alta disponibilidad La Figura 1 representa las diferentes capas en el sistema que deben estar disponibles para que se proporcione el servicio. En la parte inferior están los datos en los que se basa el servicio. Obviamente si se pierden los datos, el servicio no funcionará de manera correcta y entonces es importante garantizar que haya al menos una copia extra de esos datos. Estos datos se pueden duplicar en la capa de almacenamiento misma pero con MySQL son comúnmente duplicados con la capa de arriba: el servidor MySQL que utiliza la duplicación MySQL. El servidor MySQL proporciona acceso a los datos, no tiene sentido que los datos estén allí si no se puede acceder a ellos. Es un error común pensar que tener redundancia en estos dos niveles es suficiente para tener un sistema de HA pero también es necesario tener en cuenta el sistema de manera vertical. Figura 1 Alta disponibilidad superpuesta 1 Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 4

5 Para tener un servicio de HA, debe haber redundancia en la capa de aplicación, en sí mismo esto es muy fácil, simplemente debe equilibrar todas las solicitudes de servicio a través de un grupo de servidores de aplicaciones que se ejecutan todos con la misma lógica de la aplicación. Si el servicio fuera algo tan simple como un generador de números aleatorios entonces esto estaría bien, pero las aplicaciones más útiles necesitan acceder a los datos, y a medida que se mueve más allá de un único servidor de base de datos (por ejemplo, porque tiene que ser HA), entonces se requiere una forma para conectar el servidor de aplicaciones a la fuente de datos correcta. En un sistema de HA, el enrutamiento no es una función estática, si un servidor de base de datos falla (o que sea tomado por mantenimiento) la aplicación debe dirigirse en cambio a una base de datos alternativa. Algunos sistemas de HA implementan esta función de enrutamiento al introducir un proceso de proxy entre la aplicación y los servidores de base de datos, otros utilizan una dirección IP virtual que puede ser migrada al servidor correcto. Cuando utiliza MySQL Fabric, esta función de enrutamiento se implementa dentro de la biblioteca del conector MySQL compatible con Fabric que se utiliza para los procesos del servidor de aplicaciones Duplicación MySQL La duplicación MySQL se implementa al configurar una instancia como maestra, con una o más instancias adicionales configuradas como esclavas. El maestro registra los cambios en la base de datos que luego son enviados y aplicados a los esclavos de manera inmediata o luego de un tiempo de intervalo. La Figura 2 ilustra este flujo de duplicación. Figura 2 Duplicación MySQL Además de HA, la duplicación MySQL generalmente se emplea para escalar la base de datos a través de un clúster de servidores físicos, como se ilustra en la figura de abajo. Todas las operaciones de escritura (y cualquier lectura que deba ser garantizada para recuperar los cambios más recientes) se dirigen al maestro, mientras que otras declaraciones SELECT son dirigidas a los esclavos con la consulta de enrutamiento que se implementa a través del conector apropiado MySQL (por ejemplo el conector/j JDBC o PHP drivers) o con la lógica de la aplicación. La duplicación MySQL se puede implementar en un rango de topologías para admitir escalabilidad diversa y requisitos HA. Para obtener más información acerca de estas opciones y de cómo configurar la duplicación MySQL, consulte el informe de duplicación 1. La duplicación MySQL es un enfoque maduro y comprobado para cargas de trabajo de escalabilidad que proporciona la base para HA. 1 Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 5

6 Duplicación semi simultánea MySQL La duplicación semi simultánea puede utilizarse como alternativa a la duplicación asincrónica predeterminada de MySQL que sirve para mejorar la integración de los datos. Al utilizar la duplicación semi simultánea, se envía una confirmación al cliente únicamente cuando el esclavo recibe la actualización. Por lo tanto se asegura que los datos existan en el maestro y en al menos un esclavo (tenga en cuenta que el esclavo recibirá la actualización pero no se aplica necesariamente cuando se envía una confirmación al maestro). Es posible combinar los diferentes modos de duplicación como algunos esclavos MySQL que están configurados con duplicación asincrónica mientras que otros utilizan duplicación semi simultánea. Esto significa que el desarrollador / DBA puede determinar el nivel apropiado de consistencia de datos y el rendimiento en la base por esclavo. Los diferentes modos de duplicación que se describen arriba pueden mostrar la diferencia con la duplicación simultánea completa por medio del cual los datos son enviados a dos o más instancias al mismo tiempo con la utilización del protocolo commit de dos fases. La duplicación simultánea brinda consistencia garantizada a través de sistemas múltiples y puede facilitar los tiempos de conmutación por error más rápidos pero puede agregar gastos generales de rendimiento como resultado de mensajería adicional entre los nodos. La duplicación simultánea es únicamente posible con MySQL Cluster 1 que actualmente no es parte de MySQL Fabric Qué agrega MySQL Fabric en términos de alta disponibilidad MySQL Fabric tiene el concepto de un grupo HA, que es un grupo de dos o más servidores MySQL, y en un momento determinado, uno de esos servidores es el primario (duplicación maestra MySQL) y otros son secundarios (duplicación esclava MySQL). El rol de un grupo HA es garantizar el acceso a los datos albergados dentro de ese grupo para que estén siempre disponibles. Mientras que la duplicación MySQL permite que los datos permanezcan seguros mediante la duplicación de los mismos, para una solución HA se requieren de dos componentes extras y MySQL Fabric los proporciona: La detección de fallas y la promoción: el proceso MySQL Fabric monitorea el primario dentro del grupo HA y en el caso de que ese servidor falle selecciona uno de los secundarios y lo promueve para que sea primario (con todos los otros esclavos en el grupo HA que recibirán actualizaciones del nuevo maestro). Tenga en cuenta que los conectores pueden informar a MySQL Fabric cuando observan un problema con el Figura 3 MySQL Fabric implementa HA primario y el proceso MySQL Fabric utiliza esa información como parte de ese proceso de toma de decisiones alrededor del estado de los servidores en la granja de servidores. Enrutamiento de solicitudes de base de datos: cuando MySQL Fabric promueve al nuevo primario, actualiza el almacén de estado y esa nueva información de enrutamiento será recolectada por los conectores y almacenada en los cachés. De esta manera, la aplicación no necesita saber que la topología ha cambiado y que las operaciones de escritura se deben enviar a un destino diferente. 1 Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 6

7 2.2 Escalabilidad, particionamiento Cuando se acerca al límite de capacidad o al rendimiento de operaciones de escritura de un único servidor MySQL (o grupo HA) se puede utilizar a MySQL Fabric para escalar los servidores de base de datos con la partición de los datos a través de grupos múltiples de servidores MySQL. Tenga en cuenta que un grupo puede contener un único servidor MySQL o puede ser un grupo HA. El administrador define cómo los datos deben ser particionados dentro de estos servidores, esto se realiza con la creación de las asignaciones de partición. Una asignación de partición se aplica a un conjunto de tablas y para cada tabla el administrador especifica qué columna de esas tablas se debe utilizar como clave de partición (la clave de partición será utilizada por MySQL Fabric para calcular qué partición de una fila específica de una de esas tablas debe ser parte). Debido a que todas estas tablas utilizan la misma clave de partición y asignación, el uso del mismo valor de la columna en esas tablas puede dar lugar a que esas filas estén en la misma partición, lo que permite que con una transacción única se pueda acceder a todas. Por ejemplo, si utiliza la columna de identificación del suscriptor desde varias tablas, todos los datos para un suscriptor específico estarán en la misma partición. El administrador define cómo la clave de partición debe utilizarse para calcular el número de partición: HASH: la función hash se ejecuta en la clave de partición para generar el número de partición. Si los valores en la columna utilizados como la clave de partición no tienden a tener muchos valores repetidos entonces esto resulta en una partición de filas a través de las particiones. RANGO: el administrador define una asignación explícita entre rangos de valores para la clave de partición y las particiones. Esto le da máximo control al usuario de cómo se particionan los datos y qué filas deben ser reubicadas. Cuando la aplicación necesita acceder a la base de datos particionada, establece una propiedad para la conexión que especifica la clave de partición, el conector compatible con Fabric aplicará el rango correcto o la asignación hash y guiará la transacción a la partición correcta. Si necesita más particiones/grupos, MySQL Fabric puede dividir una partición existente en dos y luego actualizar el almacén de estado y los cachés de datos de enrutamiento contenidos por los conectores. De igual manera, una partición puede moverse de un grupo HA a otro. Tenga en cuenta que una única transacción o consulta solo puede acceder a una única partición y es por ello que es importante seleccionar las claves de partición basadas en una comprensión de los datos y los patrones de acceso de la aplicación. No siempre tiene sentido particionar todas las tablas ya que algunas son relativamente pequeñas y tener los contenidos completos disponibles en cada grupo puede ser beneficioso debido a la regla de que no hay consultas de partición cruzada. Estas tablas globales se escriben para un grupo global y otras incorporaciones o cambios de los datos en esas tablas se duplican automáticamente en todos los otros grupos. También se realizan cambios en los esquemas al grupo global y se duplican a todos los demás para garantizar la consistencia. Para obtener la mejor asignación, puede también ser necesario modificar el esquema si no hay una opción natural para las claves de partición. 2.3 Aprovisionamiento del servidor Figura 4 MySQL Fabric implementa HA y el particionamiento MySQL Fabric permite la escalabilidad elástica dentro y fuera de la granja de servidores administrados MySQL con la utilización de marcos en la nube como OpenStack. MySQL Fabric asegura las máquinas de manera transparente desde la nube antes de establecer MySQL y la duplicación e incluye los nuevos servidores. Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 7

8 3 Dónde se sitúa MySQL Fabric con las otras ofertas MySQL de Oracle MySQL Fabric es una de las soluciones de MySQL HA y escalabilidad que ofrece Oracle. Estas soluciones están enumeradas en Tabla 1 donde cada una se evalúa por una serie de criterios. Tabla 1 Comparación de las tecnologías de MySQL HA y escalabilidad Se pueden encontrar más detalles sobre otras soluciones en la guía MySQL para soluciones de alta disponibilidad 1. MySQL Fabric tiene un número de funciones que lo hace adecuado para agregar cualquier escalabilidad, HA o ambos a una aplicación basada en MySQL: MySQL Fabric permite que la aplicación utilice el excelente y comprobado motor de almacenamiento InnoDB. La HA está construida sobre la duplicación MySQL que es una tecnología madura y utilizada alrededor del mundo, lo que MySQL Fabric agrega es una capa de administración junto con la conmutación por error automatizada que es transparente para la aplicación. Escalamiento de operaciones de escritura junto con las operaciones de lectura. Las arquitecturas Shared Nothing son ideales para hardware rentable y de mercancía mientras que también aprovechan los servidores con varios núcleos. Todos los elementos de la solución son respaldados por Oracle. 1 Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 8

9 4 Limitaciones actuales La versión inicial de MySQL Fabric está diseñada para que sea simple, robusta y que permita escalar a miles de servidores MySQL. Este enfoque significa que esta versión tiene un número de limitaciones, que se describen aquí: La partición no es completamente transparente para la aplicación. Mientras que la aplicación no necesita saber qué servidor almacena un conjunto de filas y no necesita saber adónde se trasladan los datos, sí necesita proporcionar la clave de partición cuando se accede a la base de datos. Las columnas de incremento automático no pueden ser utilizadas como clave de partición. Todas las transacciones y consultas necesitan ser limitadas al ámbito de las filas que pertenecen a una única partición, junto con las tablas globales (no particionadas). Por ejemplo, las uniones que involucran múltiples particiones no son compatibles. Debido a que los conectores ejecutan la función de enrutamiento, se evita la latencia extra involucrada en las soluciones basadas en el proxy pero eso no significa que se necesiten los conectores compatibles con Fabric, en el momento de escribir estos son parte de PHP, Python y Java. El proceso MySQL Fabric en sí mismo no tolera fallas y debe ser reiniciado en el caso de que falle. Tenga en cuenta que esto no representa un único punto de falla para la granja de servidores (HA y/o particionamiento) ya que los conectores pueden continuar con las operaciones de enrutamiento con la utilización de sus cachés locales mientras que el proceso MySQL Fabric no está disponible. 5 Diseñado para la extensibilidad MySQL Fabric se diseñó para la extensibilidad en un número de niveles. Por ejemplo, en la primera versión, la única opción para la implementación de HA se basa en la duplicación MySQL pero en futuras versiones esperamos añadir más opciones (por ejemplo, MySQL Cluster). También esperamos ver aplicaciones completamente nuevas en todo el manejo de granjas de servidores MySQL, ya sea de Oracle y la comunidad más amplia de MySQL. La Figura 5 ilustra cómo se pueden añadir nuevas aplicaciones y protocolos si se utiliza el marco conectable. Figura 5 Arquitectura extensible MySQL Fabric Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 9

10 6 Cómo practicar: tutoriales Esta sección se enfoca en cómo utilizar MySQL Fabric, inicialmente para proporcionar alta disponibilidad y luego para la escalabilidad con la utilización del particionamiento. Se enfocará en la administración de las tareas pero también se incluirán una serie de ejemplos de código Python para ilustrar lo que la aplicación tiene que hacer. Para que sea más sencillo, este informe no abarca la configuración y el inicio de todos los servidores MySQL (aparte de la que se utiliza para el almacén de estado de MySQL Fabric), un tutorial completo de extremo a extremo (que incluye la configuración y la ejecución de todos los servidores MySQL) que se puede encontrar en MySQL Fabric, que agrega alta disponibilidad y escalabilidad a MySQL 1. Además, si solo se requiere HA esto está documentado en MySQL Fabric, agregar alta disponibilidad a MySQL 2 y si solo se requiere escalabilidad MySQL Fabric, agregar escalabilidad a MySQL 3. Tenga en cuenta que como cualquier servidor MySQL en estos tutoriales puede ser un servidor primario (duplicación maestro MySQL), los archivos de configuración deben permitir ID de transacciones globales así como también registros binarios. A continuación hay un ejemplo de configuración de archivos: [mysql@fab2 myfab]$ cat my2a.cnf [mysqld] datadir=/home/mysql/myfab/data2a basedir=/home/mysql/mysql socket=/home/mysql/myfab/mysqlfab2a.socket binlog-format=row log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=table relay-log-info-repository=table sync-master-info=1 port=3306 report-host=fab2 report-port=3306 server-id=21 log-bin=fab2a-bin.log 6.1 Agregar alta disponibilidad En esta sección se busca introducir MySQL Fabric para agregar alta disponibilidad a MySQL. Figura 6 ilustra la configuración que se creará. Va a haber un grupo único HA que tiene el nombre de group_id-1 que contendrá tres servidores MySQL, cada uno se ejecuta en una máquina diferente (fab2, fab3 y fab4), y en un momento determinado, uno de esos servidores MySQL será el primario (maestro) y los otros serán los secundarios. Si uno de los primarios falla, uno de los secundarios será promovido automáticamente por el proceso MySQL Fabric para que sea el nuevo primario. El proceso MySQL Fabric en sí mismo se ejecutará en una cuarta máquina (fab1) junto con el almacén de estado (otro servidor MySQL) y la aplicación de prueba que utiliza el conector de Python compatible con Fabric Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 10

11 El primer paso es instalar el conector Python así como también MySQL Fabric: rpm -i mysql-connector-python el6.noarch.rpm rpm -i mysql-utilities el6.noarch.rpm A continuación, el almacén de estado debe configurarse e iniciarse: [mysql@fab1 myfab]$ mkdir data [mysql@fab1 myfab]$ cat my.cnf [mysqld] datadir=/home/mysql/myfab/data basedir=/home/mysql/mysql socket=/home/mysql/myfab/mysqlfab.socket binlog-format=row log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=table relay-log-info-repository=table sync-master-info=1 port=3306 report-host=fab1 report-port=3306 server-id=1 log-bin=fab-bin.log [mysql@fab1 mysql]$ scripts/mysql_install_db \ --basedir=/home/mysql/mysql/ \ Figura 6 Grupo HA único --datadir=/home/mysql/myfab/data/ \ --defaults-file=/home/mysql/myfab/my.cnf mysql@fab1 ~]$ mysqld --defaults-file=/home/mysql/myfab/my.cnf & La cuenta de usuario que se utilizará por MySQL Fabric se puede crear: mysql@fab1 ~]$ mysql -h P3306 -u root -e \ 'CREATE USER fabric@localhost; GRANT ALL \ ON fabric.* TO fabric@localhost;' Tenga en cuenta que el esquema fabric no ha sido creado todavía, eso se realizará automáticamente por MySQL Fabric. Antes de iniciar MySQL Fabric, el archivo de configuración debe ser evaluado para garantizar que coincida con el entorno real que será utilizado por los servidores MySQL y MySQL Fabric en sí mismo: [root@fab1 mysql]# cat /etc/mysql/fabric.cfg [DEFAULT] prefix = sysconfdir = /etc logdir = /var/log [logging] url = file:///var/log/fabric.log level = INFO [storage] auth_plugin = mysql_native_password database = fabric user = fabric address = localhost:3306 connection_delay = 1 connection_timeout = 6 password = connection_attempts = 6 Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 11

12 [failure_tracking] notification_interval = 60 notification_clients = 50 detection_timeout = 1 detection_interval = 6 notifications = 300 detections = 3 failover_interval = 0 prune_time = 3600 [servers] password = user = fabric [connector] ttl = 1 [protocol.xmlrpc] disable_authentication = no ssl_cert = realm = MySQL Fabric ssl_key = ssl_ca = threads = 5 user = admin address = localhost:32274 password = admin [executor] executors = 5 [sharding] mysqldump_program = /home/mysql/mysql/bin/mysqldump mysqlclient_program = /home/mysql/mysql/bin/mysql Se pueden encontrar más detalles sobre estos parámetros de configuración en la documentación de MySQL Fabric 1. El esquema dentro del almacén de estado puede ahora crearse y comprobarse (opcional): [root@fab1 mysql]# mysqlfabric manage setup --param=storage.user=fabric [INFO] MainThread - Initializing persister: user \ (fabric), server (localhost:3306), database (fabric). [INFO] MainThread - Initial password for admin/xmlrpc set Password set for admin/xmlrpc from configuration file. [INFO] MainThread - Password set for admin/xmlrpc \ from configuration file. [mysql@fab1 ~]$ mysql --protocol=tcp -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 Server version: log MySQL Community Server (GPL) Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. 1 Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 12

13 Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>show databases; Database information_schema fabric mysql performance_schema test rows in set (0.00 sec) mysql>use fabric;show tables; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed Tables_in_fabric checkpoints error_log group_replication groups permissions role_permissions roles servers shard_maps shard_ranges shard_tables shards user_roles users rows in set (0.00 sec) El proceso MySQL Fabric puede iniciarse (tenga en cuenta que el proceso Fabric se puede ejecutar como daemon al añadir la opción --daemonize: [mysql@fab1 ~]$ mysqlfabric manage start [INFO] MainThread - Fabric node starting. [INFO] MainThread - Initializing persister: user (fabric), server (localhost:3306), database (fabric). [INFO] MainThread - Initial password for admin/xmlrpc set Password set for admin/xmlrpc from configuration file. [INFO] MainThread - Password set for admin/xmlrpc from configuration file. [INFO] MainThread - Loading Services. [INFO] MainThread - Starting Executor. [INFO] MainThread - Setting 5 executor(s). [INFO] Executor-0 - Started. [INFO] Executor-1 - Started. [INFO] Executor-2 - Started. [INFO] Executor-3 - Started. [INFO] MainThread - Executor started. [INFO] Executor-4 - Started. [INFO] MainThread - Starting failure detector. [INFO] XML-RPC-Server - XML-RPC protocol server (' ', 8080) started. [INFO] XML-RPC-Server - Setting 5 XML-RPC session(s). Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 13

14 [INFO] XML-RPC-Session-0 - Started XML-RPC-Session. [INFO] XML-RPC-Session-1 - Started XML-RPC-Session. [INFO] XML-RPC-Session-2 - Started XML-RPC-Session. [INFO] XML-RPC-Session-3 - Started XML-RPC-Session. [INFO] XML-RPC-Session-4 - Started XML-RPC-Session. Inicialmente habrá un solo grupo HA (esto es todo lo que se requiere para HA, después se añadirán grupos adicionales para permitir la escalabilidad a través del particionamiento de los datos): [mysql@fab1 myfab]$ mysqlfabric group create group_id-1 { uuid = 7e0c90ec-f81f-4ff6-80d3-ae4a8e533979, Antes de agregar los servidores MySQL al grupo, es necesario tener un usuario en cada servidor MySQL que pueda acceder al servidor desde la máquina donde se ejecuta el proceso MySQL Fabric (en este ejemplo, fab1/ ). Para que sea más simple este informe utiliza el usuario root, sin contraseña y con el permiso para acceder a todas las tablas desde cualquier host, esto es sólo para la experimentación y debe utilizarse una seguridad más estricta en cualquier base de datos de producción. [mysql@fab2 ~]$ mysql -h P3306 -u root -e 'GRANT ALL ON *.* TO fabric@"%"' [mysql@fab3 ~]$ mysql -h P3306 -u root -e 'GRANT ALL ON *.* TO fabric@"%"' [mysql@fab4 ~]$ mysql -h P3306 -u root -e 'GRANT ALL ON *.* TO fabric@"%"' [mysql@fab2 ~]$ mysql -h P3306 -u root -e 'GRANT ALL ON *.* TO root@"%"' [mysql@fab3 ~]$ mysql -h P3306 -u root -e 'GRANT ALL ON *.* TO root@"%"' [mysql@fab4 ~]$ mysql -h P3306 -u root -e 'GRANT ALL ON *.* TO root@"%"' MySQL Fabric ahora está disponible para acceder y manipular los servidores MySQL, por lo tanto ahora se pueden añadir al grupo HA. [mysql@fab1 myfab]$ mysqlfabric group add group_id :3306 { uuid = 073f421a fd-b839131ea026, [mysql@fab1 myfab]$ mysqlfabric group add group_id :3306 { uuid = b0f5b04a-27e6-46ce-adff-bf1c046829f7, [mysql@fab1 myfab]$ mysqlfabric group add group_id :3306 { uuid = 520d1a7d bbe4-002d0bae5aaa, En este punto, todos los servidores MySQL actúan como secundarios (es decir, ninguno de ellos actúa como maestro de duplicación MySQL). El próximo paso es promover uno de los servidores para que sea primario, en este caso el uuid del servidor que queremos promover es proporcionado pero no requerido, en ese caso MySQL Fabric seleccionará uno. Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 14

15 myfab]$ mysqlfabric group promote group_id-1 \ --slave_id 00f9831f-d602-11e3-b65e cb { uuid = c875371b-890c-49ff-b0a5-6bbc38be7097, [mysql@fab1 myfab]$ mysqlfabric group lookup_servers group_id-1 Command : { success = True return = [ {'status': 'PRIMARY', 'server_uuid': '00f9831f-d602-11e3-b65e cb', \ 'mode': 'READ_WRITE', 'weight': 1.0, 'address': ' :3306', \ {'status': 'SECONDARY', 'server_uuid': 'f6fe224e-d601-11e3-b65d c2', \ 'mode': 'READ_ONLY', 'weight': 1.0, 'address': ' :3306', \ {'status': 'SECONDARY', 'server_uuid': 'fbb5c440-d601-11e3-b65d bafa8', \ 'mode': 'READ_ONLY', 'weight': 1.0, 'address': ' :3306'] Tenga en cuenta que fab4 ahora se muestra como primario, cualquiera de los servidores secundarios también pueden consultarse para confirmar que son efectivamente esclavos de duplicación MySQL del primario. [mysql@fab1 ~]$ mysql -h P3306 -u root -e "show slave status\g" *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: Master_User: fabric Master_Port: 3306 Connect_Retry: 60 Master_Log_File: fab4-bin Read_Master_Log_Pos: 487 Relay_Log_File: fab3-relay-bin Relay_Log_Pos: 695 Relay_Master_Log_File: fab4-bin Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 487 Relay_Log_Space: 898 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 15

16 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 40 Master_UUID: 00f9831f-d602-11e3-b65e cb Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O \ thread to update it Master_Retry_Count: Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 00f9831f-d602-11e3-b65e cb:1-2 Executed_Gtid_Set: 00f9831f-d602-11e3-b65e cb:1-2,\ fbb5c440-d601-11e3-b65d bafa8:1-2 Auto_Position: 1 En esta etapa, la relación de duplicación MySQL está configurada y está ejecutándose pero todavía no hay alta disponibilidad ya que MySQL Fabric no monitorea el estado de los servidores, la configuración final fija que: [mysql@fab1 ~]$ mysqlfabric group activate group_id-1 { uuid = 40a5e023-06ba-4e1e-93de-4d4195f87851, Ahora está todo configurado para detectar si el primario (maestro) falla y en el caso de que lo haga, promover uno de los secundarios para que sea el nuevo primario. Si utiliza uno de los conectores compatibles MySQL Fabric (inicialmente PHP, Python y Java) la conmutación por error puede ser transparente para la aplicación. El código que figura a continuación muestra cómo una aplicación puede acceder a este nuevo grupo HA, en este caso, con la utilización de un conector Python. Primero se crea una tabla de aplicación: [mysql@fab1 myfab]$ cat setup_table_ha.py import mysql.connector from mysql.connector import fabric conn = mysql.connector.connect( fabric={"host" : "localhost", "port" : 32274, "username": "admin", "password" : "admin", user="root", database="test", password="", autocommit=true ) conn.set_property(mode=fabric.mode_readwrite, group="group_id-1") cur = conn.cursor() cur.execute( "CREATE TABLE IF NOT EXISTS subscribers (" " sub_no INT, " " first_name CHAR(40), " " last_name CHAR(40)" ")" ) Tenga en cuenta el siguiente ejemplo de código: El conector se proporciona con la dirección para el proceso MySQL Fabric localhost:32274 antes que cualquier servidor MySQL Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 16

17 La propiedad mode para la conexión se establece en fabric.mode_readwrite lo cual el conector interpretará que la transacción será enviada al primario (es allí donde todas las transacciones de escritura se deben ejecutar para que sean duplicadas a los secundarios) La propiedad group se ajusta a group_id-1 que es el nombre que se le dio al único grupo HA Este código puede ser ejecutado y luego se puede comprobar en uno de los secundarios si la creación de la tabla ha sido duplicada desde el primario. [mysql@fab1 myfab]$ python setup_table_ha.py [mysql@fab1 myfab]$ mysql -h P3306 -u root -e "use test;show tables;" Tables_in_test subscribers El próximo paso es agregar más filas a la tabla: [mysql@fab1 myfab]$ cat add_subs_ha.py import mysql.connector from mysql.connector import fabric def add_subscriber(conn, sub_no, first_name, last_name): conn.set_property(group="group_id-1", mode=fabric.mode_readwrite) cur = conn.cursor() cur.execute( "INSERT INTO subscribers VALUES (%s, %s, %s)", (sub_no, first_name, last_name) ) conn = mysql.connector.connect( fabric={"host" : "localhost", "port" : 32274, "username": "admin", "password" : "admin", user="root", database="test", password="", autocommit=true ) conn.set_property(group="group_id-1", mode=fabric.mode_readwrite) add_subscriber(conn, 72, "Billy", "Fish") add_subscriber(conn, 500, "Billy", "Joel") add_subscriber(conn, 1500, "Arthur", "Askey") add_subscriber(conn, 5000, "Billy", "Fish") add_subscriber(conn, 15000, "Jimmy", "White") add_subscriber(conn, 17542, "Bobby", "Ball") [mysql@fab1 myfab]$ python add_subs_ha.py [mysql@fab1 myfab]$ mysql -h P3306 -u root -e "select * from test.subscribers" sub_no first_name last_name Billy Fish 500 Billy Joel 1500 Arthur Askey 5000 Billy Fish Jimmy White Bobby Ball Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 17

18 Luego los datos pueden ser recuperados (tenga en cuenta que el parámetro mode para la conexión se establece en fabric.mode_readonly y el conector sabe que puede establecer un balance de los requisitos a través de cualquier servidor MySQL en el grupo HA). mysql@fab1 myfab]$ cat read_table_ha.py import mysql.connector from mysql.connector import fabric def find_subscriber(conn, sub_no): conn.set_property(group="group_id-1", mode=fabric.mode_readonly) cur = conn.cursor() cur.execute( "SELECT first_name, last_name FROM subscribers " "WHERE sub_no = %s", (sub_no, ) ) for row in cur: print row conn = mysql.connector.connect( fabric={"host" : "localhost", "port" : 32274, "username": "admin", "password" : "admin", user="root", database="test", password="", autocommit=true ) find_subscriber(conn, 72) find_subscriber(conn, 500) find_subscriber(conn, 1500) find_subscriber(conn, 5000) find_subscriber(conn, 15000) find_subscriber(conn, 17542) [mysql@fab1 myfab]$ python read_table_ha.py (u'billy', u'fish') (u'billy', u'joel') (u'arthur', u'askey') (u'billy', u'fish') (u'jimmy', u'white') (u'bobby', u'ball') Tenga en cuenta que si los servidores secundarios no tienen el mismo rendimiento pueden sesgar la proporción de la cantidad de lecturas que son enviadas a cada uno mediante el comando mysqlfabric server set_weight si se especifica un valor entre 0 y 1 (la predeterminación es 1 para todos los servidores). Además, el comando mysqlfabric server set_mode se puede utilizar para especificar si el primario debe recibir solo las operaciones de lectura (READ_WRITE) o solo las operaciones de escritura (WRITE_ONLY). Debido a que la duplicación de los esclavos no es simultánea, no se puede garantizar que sus operaciones de escritura recuperen los últimos datos comprometidos. Si es esencial que la operación de escritura sea completamente consistente con todas las transacciones comprometidas se debe establecer el modo fabric.mode_readwrite. Para ser breve, estos ejemplos de código no contienen manejo de errores, para una aplicación real el código debe lidiar con cualquier error de la base de datos de manera apropiada. La próxima sección describe cómo esta configuración se puede extender para agregar escalabilidad con la partición de los datos en la tabla (y puede ser omitida si no es necesario). Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 18

19 6.2 Agregar escalabilidad con particionamiento El ejemplo en esta sección se construye sobre el anterior y se agregan más servidores para escalar la capacidad y el rendimiento de las operaciones de lectura/escritura de la base de datos. El primer paso es crear un nuevo grupo (que se denomina global-group en este ejemplo), el grupo global es un grupo especial HA que cumple dos funciones importantes: Los cambios en los esquemas de datos se aplican al grupo global y desde allí se pueden duplicar para cada uno de los otros grupos HA Si hay tablas que contienen datos que deben ser duplicados para todos los grupos HA (antes de que sean particionados) se realizarán inserciones, actualizaciones o eliminaciones en el grupo global y luego serán duplicadas en otros. Esas tablas se denominan tablas globales. Figura 7 ilustra cómo se verá la configuración una vez que el grupo global se haya creado. El grupo global se define y está rellenado con servidores MySQL y luego un primario se promueve en los siguientes pasos: [mysql@fab1]$ mysqlfabric group create global-group { uuid = 5f07e324-ec0a-42b4-98d f607143, Figura 7 Adición de un grupo global [mysql@fab1 ~]$ mysqlfabric group add global-group\ :3316 { uuid = ccf699f5-ba2c-4400-a8a6-f951e10d4315, [mysql@fab1 ~]$ mysqlfabric group add global-group \ :3317 { uuid = 7c476dda a-b94d-4b9e650e5dfe, [mysql@fab1 ~]$ mysqlfabric group add global-group \ :3318 { uuid = 476fadd4-ca4f-49b3-a633-25dbe0ffdd11, Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 19

20 ~]$ mysqlfabric group promote global-group { uuid = e818708e-6e5e-4b90-aff1-79b0b2492c75, [mysql@fab1 ~]$ mysqlfabric group lookup_servers global-group Command : { success = True return = [ {'status': 'PRIMARY', 'server_uuid': '56a08135-d60b-11e3-b69a c2',\ 'mode': 'READ_WRITE', 'weight': 1.0, 'address': ' :3316', \ {'status': 'SECONDARY', 'server_uuid': '5d5f5cf6-d60b-11e3-b69b c2', \ 'mode': 'READ_ONLY', 'weight': 1.0, 'address': ' :3317', \ {'status': 'SECONDARY', 'server_uuid': '630616f4-d60b-11e3-b69b c2', \ 'mode': 'READ_ONLY', 'weight': 1.0, 'address': ' :3318'] Como se creó una tabla de aplicación dentro del grupo original HA, eso necesitará que se copie al nuevo grupo global: mysql@fab1 myfab]$ mysqldump -d -u root --single-transaction -h P3306 \ --all-databases > my-schema.sql [mysql@fab1 myfab]$ mysql -h P3317 -u root -e 'reset master' [mysql@fab1 myfab]$ mysql -h P3317 -u root < my-schema.sql [mysql@fab1 myfab]$ mysql -h P3317 -u root -e 'show create table test.subscribers' Table Create Table subscribers CREATE TABLE `subscribers` ( `sub_no` int(11) DEFAULT NULL, `first_name` char(40) DEFAULT NULL, `last_name` char(40) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin Una asignación de partición es una entidad que se utiliza para definir cómo se deben particionar determinadas tablas entre un conjunto de grupos HA. Es posible tener múltiples asignaciones de partición pero en este ejemplo, se utilizará uno solo. Al definir la asignación de partición, hay dos parámetros clave: El tipo de asignación puede ser HASH o RANGE El grupo global que será utilizado Los comandos a continuación definen la asignación e identifican el número de índice que se asigna a esta asignación (en este ejemplo, 3) de hecho el mismo índice se recupera de dos maneras diferentes: con la utilización del comando mysqlfabric y luego al leer los datos directamente desde el almacén de estado: [mysql@fab1 ~]$ mysqlfabric sharding create_definition HASH global-group { uuid = 78ea7209-b073-4d03-9d8b-bda92cc76f32, return = 1, [mysql@fab1 ~]$ mysqlfabric sharding list_definitions Command : { success = True return = [[3, 'HASH', 'global-group']] Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 20

21 ~]$ mysql -h P3306 -u root \ -e 'SELECT * FROM fabric.shard_maps' shard_mapping_id type_name global_group HASH global-group El próximo paso es definir las columnas de qué tablas deben utilizarse como la clave de partición (el valor en el cual la función HASH se ejecuta o se compara con el RANGE definido). En este ejemplo, solo se ha particionado una tabla (la tabla subscribers con la columna sub_no que se utiliza como la clave de partición) pero el comando puede simplemente ser re-ejecutado para otras tablas. Tenga en cuenta que el identificador para la asignación de partición (3) se pasa en la línea de comandos: [mysql@fab1 ~]$ mysqlfabric sharding add_table 1 test.subscribers sub_no { uuid = 446aadd1-ffa6-4d19-8d f3d7c998, En este punto, la asignación de partición se ha definido pero no hay particiones que se hayan creado por lo que el siguiente paso es la creación de una única partición y que la partición sea almacenada en el grupo HA existente group_id-1): [mysql@fab1]$ mysqlfabric sharding add_shard 1 group_id-1 --state=enabled { uuid = 8a351c36-9e80-41fd-a665-f3369aa3b31b, [mysql@fab1]$ mysql -h P3306 -u root -e 'select * from fabric.shards' shard_id group_id state group_id-1 ENABLED Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 21

22 En este punto, la base de datos se ha particionado pero no ofrece la escalabilidad debido a que existe una única partición. Los pasos a continuación desarrollan esa configuración en una que contiene dos particiones como se muestra en la Figura 8. Figura 8 Particionamiento, granja de servidores HA MySQL Fabric Otro grupo HA (group_id-2) se crea, los tres nuevos servidores se agregan y luego uno de los servidores pasa a ser primario: [mysql@fab1 ~]$ mysqlfabric group create group_id-2 { uuid = 4ec6237a-ca38-497c-b54d-73d1fa7bbe03, [mysql@fab1 ~]$ mysqlfabric group add group_id :3306 { uuid = fe ed-436c-9b7f-3d6f , [mysql@fab1 ~]$ mysqlfabric group add group_id :3306 { uuid = 6fcf7e0c-c092-4d abf2b113c, [mysql@fab1 ~]$ mysqlfabric group add group_id :3306 { uuid = 8e9d4fbb-58ef-470d-81eb-8d ae, Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 22

23 ~]$ mysqlfabric group promote group_id-2 { uuid = 21569d7f-93a3-4bdc-b22b-2125e9b75fca, En este punto, el nuevo grupo de HA existe pero no encuentra el esquema de aplicación y los datos. Antes de asignar una partición al grupo, un reset master debe ser ejecutado en el primario para el grupo (esto es requerido debido a que los cambios se han realizado en ese servidor, para conceder permisos para que uno o varios usuarios se puedan conectar de manera remota). El comando mysqlfabric group lookup_servers se utiliza para comprobar cuál de los tres servidores es el primario en ese momento. [mysql@fab1 ~]$ mysqlfabric group lookup_servers group_id-2 Command : { success = True return = [ {'status': 'PRIMARY', 'server_uuid': '10b086b5-d617-11e3-b6e aedd', \ 'mode': 'READ_WRITE', 'weight': 1.0, 'address': ' :3306', \ {'status': 'SECONDARY', 'server_uuid': '5dc81563-d617-11e3-b6e f', \ 'mode': 'READ_ONLY', 'weight': 1.0, 'address': ' :3306', \ {'status': 'SECONDARY', 'server_uuid': '83cae7b2-d617-11e3-b6ea b127', 'mode': 'READ_ONLY', 'weight': 1.0, 'address': ' :3306'] [mysql@fab1 myfab]$ mysql -h P3306 -uroot -e 'reset master' El paso siguiente es dividir la partición existente al especificar la id de la partición (en este caso 1 que encontramos en la tabla fabric.shards) y el nombre del grupo HA donde se almacenará la nueva partición: [mysql@fab1]$ mysql -h P3306 -u root \ -e 'select * from fabric.shards' shard_id group_id state group_id-1 ENABLED [mysql@fab1]$ mysqlfabric sharding split_shard 1 group_id-2 { uuid = 4c559f6c-0b08-4a57-b b7b, Antes de ver los cambios en el código de aplicación que se necesitan para hacer frente a los datos particionados, se puede ejecutar una simple prueba para confirmar que los datos existentes de la tabla de hecho se hayan dividido entre las dos particiones: [mysql@fab1]$ mysql -h P3306 -uroot -e 'select * from test.subscribers' sub_no first_name last_name Billy Joel 1500 Arthur Askey 5000 Billy Fish Bobby Ball [mysql@fab1]$ mysql -h P3306 -uroot -e 'select * from test.subscribers' Copyright 2014, Oracle y/o sus filiales. Todos los derechos reservados. Página 23