jueves, 12 de noviembre de 2020

Usando su archivo FRM para obtener Schema y luego importar archivos idb ..

Este es un tema que, en general, nunca debería tener que hacer ... ¿Por qué? Porque creó las copias de seguridad correctamente ... Ha probado y sabe que las copias de seguridad funcionan, por lo que puede restaurar esas copias de seguridad y obtener su esquema perdido y los datos relacionados ... 

Sin embargo, esa instancia en la oficina de la esquina ... nunca llegaste a configurar ... no es tan importante ... simplemente se bloqueó y ahora te das cuenta de how lo usas realmente ... 

No todo está perdido ..  

MySQL lanzó sus utilidades de MySQL hace un tiempo y desde entonces ha sido reemplazado por MySQL Shell.  

mysqlfrm sigue siendo muy útil cuando se necesita extraer el esquema de un archivo FRM en un comando rápido y simple y es una instalación simple. 

mysqlfrm --diagnostic city.frm
# WARNING: Cannot generate character set or collation names without the --server option. # CAUTION: The diagnostic mode is a best-effort parse of the .frm file. As such, it may not identify all of the components of the table correctly. This is especially true for damaged files. It will also not read the default values for the columns and the resulting statement may not be syntactically correct.
# Reading .frm file for city.frm:
# The .frm file is a TABLE.
# CREATE TABLE Statement:

CREATE TABLE `city` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Name` char(160) DEFAULT NULL,
  `CountryCode` char(12) NOT NULL,
  `District` char(80) NOT NULL,
  `Population` int(11) NOT NULL,
PRIMARY KEY `PRIMARY` (`ID`),
KEY `CountryCode` (`CountryCode`),
KEY `popkey` (`Population`)
) ENGINE=InnoDB;

#...done.


Entonces, ahora que tiene el esquema que perdió ... reconstruya la base de datos o la tabla. Por el bien del ejemplo, diré que acabamos de perder los datos de la ciudad de la base de datos mundial. 

$ cp  ciudad.ibd  / tmp /  

$ cp city.ibd /tmp/
mysql> LOCK TABLES city WRITE;
mysql> ALTER TABLE city DISCARD TABLESPACE;

cp city.ibd /edb/local/mysql/data/rundeck/
chown tmdba:dba /edb/local/mysql/data/rundeck/city.ibd

mysql> ALTER TABLE city IMPORT TABLESPACE;
mysql> UNLOCK TABLES;
mysql> SELECT COUNT(*) FROM city;


lunes, 21 de septiembre de 2020

MySQL mysql_config_editor y esperar

 Esta es solo una nota para ayudar a cualquiera que desee utilizar el comando mysql_config_editor en sus herramientas de automatización. 

mysql_config_editor no acepta un argumento de contraseña, por lo que las herramientas de automatización pueden haber establecido antes su contraseña en el archivo .my.cnf al intentar usar mysql_config_editor fallan. 

Es posible y bastante simple, aunque con la herramienta de espera. 

 yum -y install expect  

también funciona para apt-get. 


Entonces, en este ejemplo, mostraré una versión simple del script bash. 

Primero ... mi ruta de acceso no funciona ... 

mysql --login-path=local

ERROR 1045 (28000): Access denied for user


Establecer esto con esperar 

Ejecutarías esto a través de tu script bash.  

expect <<EOD

spawn mysql_config_editor set --login-path=local --host=localhost --user=root --password 

expect "password"

send  -- "<PASSWORD>\r"

interact

EOD


Ahora funciona ...

mysql --login-path=local

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1002


domingo, 15 de marzo de 2020

MySQL y Dockers ... una configuración simple

MySQL y Dockers ... no son conceptos nuevos, la gente se ha mudado a Dockers desde hace algún tiempo. Para alguien que solo se está moviendo hacia esto para el desarrollo, puede tener algunos obstáculos.

Si bien MySQL funciona bien localmente, si está probando código en diferentes versiones de MySQL, es bueno tener varias versiones fácilmente disponibles.

Una opción durante años ha sido, por supuesto, https://mysqlsandbox.net/ de Giuseppe Maxia. Esta es una solución muy válida para poder obtener varias instancias y probar la replicación, etc.

Los Dockers ahora también son otro escenario de uso frecuente cuando se trata de probar en diferentes versiones de MySQL. A continuación se detallan algunos de los pasos para instalar fácilmente varias versiones. Yo uso OSX, así que estos ejemplos son para OSX.

Necesita Docker para comenzar y, por supuesto, Docker Desktop es una herramienta útil para que pueda acceder fácilmente.

Una vez que configuré Docker, puedo preparar mi entorno para MySQL.

Aquí creé una carpeta Docker que contiene los directorios de datos MySQL, los archivos de configuración y el directorio de archivos mysql si lo necesitaba.

mkdir ~/Docker ;

mkdir ~/Docker/mysql_data;
mkdir ~/Docker/mysql-files;
mkdir ~ / Docker / cnf;

Ahora dentro de mysql_data


cd ~/Docker/mysql_data;
mkdir 8.0;
mkdir 5.7;
mkdir 5.6;
mkdir 5.5;


Ahora configuro archivos cnf simples para este ejemplo. Lo principal a tener en cuenta es la dirección de enlace. Esto está configurado para garantizar que esté abierto para que podamos llegar a MySQL fuera del docker. También puede observar que estos archivos se pueden usar para configurar información de configuración adicional como mejor le parezca por instancia de Docker de MySQL.



cd ~/Docker/cnf;

cat my.8.0.cnf
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= /var/lib/mysql-files
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
bind-address = 0.0.0.0
port=3306
server-id=80


# Custom config should go here
!includedir /etc/mysql/conf.d/

cat my.5.7.cnf
[mysqld]
bind-address = 0.0.0.0
server-id=57
max_allowed_packet=32M

$ cat my.5.6.cnf
[mysqld]
bind-address = 0.0.0.0
server-id=56

$ cat my.5.5.cnf
[mysqld]
bind-address = 0.0.0.0
server-id=55


Bien, ahora que tenemos configurados los archivos de configuración, necesitamos construir los acopladores. Algunas cosas a tener en cuenta para los comandos de compilación.

--name Establecimos una referencia con nombre para la ventana acoplable.

Aquí estamos asignando los archivos de configuración, el directorio de datos y los directorios de archivos mysql al docker. Esto nos permite ajustar el archivo my.cnf y etc. fácilmente.
-v ~ / Docker / cnf / my.8.0.cnf: /etc/mysql/my.cnf
-v ~ / Docker / mysql_data / 8.0: / var / lib / mysql
-v ~ / Docker / mysql-files: / var / lib / mysql-files

Queremos poder llegar a estas instancias de MySQL fuera del docker, por lo que debemos publicar y asignar el puerto en consecuencia.
-p 3306: 3306 Esto significa 3306 local a 3306 dentro de la ventana acoplable
-p 3307: 3306 Esto significa 3307 local a 3306 dentro de la ventana acoplable
-p 3308: 3306 Esto significa 3308 local a 3306 dentro de la ventana acoplable
-p 3309: 3306 Esto significa 3309 local a 3306 dentro de la ventana acoplable

Luego también pasamos un par de variables de entorno.
-e MYSQL_ROOT_HOST =% -e MYSQL_ROOT_PASSWORD = <establezca una contraseña aquí>

Poniendo todo junto ...


docker run --restart always --name mysql8.0 -v ~/Docker/cnf/my.8.0.cnf:/etc/mysql/my.cnf -v ~/Docker/mysql_data/8.0:/var/lib/mysql -v ~/Docker/mysql-files:/var/lib/mysql-files -p 3306:3306 -d -e MYSQL_ROOT_HOST=% -e MYSQL_ROOT_PASSWORD=<set a password here> mysql:8.0

docker run --restart always --name mysql5.7 -v ~/Docker/cnf/my.5.7.cnf:/etc/mysql/my.cnf -v ~/Docker/mysql_data/5.7:/var/lib/mysql -v ~/Docker/mysql-files:/var/lib/mysql-files -p 3307:3306 -d -e MYSQL_ROOT_HOST=% -e MYSQL_ROOT_PASSWORD=<set a password here> mysql:5.7

docker run --restart always --name mysql5.6 -v ~/Docker/cnf/my.5.6.cnf:/etc/mysql/my.cnf -v ~/Docker/mysql_data/5.6:/var/lib/mysql -v ~/Docker/mysql-files:/var/lib/mysql-files -p 3308:3306 -d -e MYSQL_ROOT_HOST=% -e MYSQL_ROOT_PASSWORD=<set a password here> mysql:5.6

docker run --restart always --name mysql5.5 -v ~/Docker/cnf/my.5.5.cnf:/etc/mysql/my.cnf -v ~/Docker/mysql_data/5.5:/var/lib/mysql -v ~/Docker/mysql-files:/var/lib/mysql-files -p 3309:3306 -d -e MYSQL_ROOT_HOST=% -e MYSQL_ROOT_PASSWORD=<set a password here> mysql:5.5

Después de cada ejecución de los comandos anteriores, debe obtener una identificación devuelta.
ejemplo: 3cb07d7c21476fbf298648986208f3429ec664167d8eef7fed17bf9ee3ce6316

Puede iniciar / reiniciar y acceder a cada terminal acoplable fácilmente a través del escritorio de Docker o simplemente tomar nota de las ID relacionadas y ejecutar a través del terminal.

Docker Desktop también le muestra todas las variables que pasó para que pueda validar.
Por supuesto, también puede acceder a la CLI aquí, detenerla, iniciarla o destruirla fácilmente.


$ docker exec -it 3cb07d7c21476fbf298648986208f3429ec664167d8eef7fed17bf9ee3ce6316 /bin/sh; exit
# mysql -p

Si el contenedor Docker ya se está ejecutando, ahora puede acceder a MySQL a través de su terminal localhost.

$ mysql --host=localhost --protocol=tcp --port=3306 -p -u root

Ahora, si tiene problemas de acceso, recuerde asegurarse de que las cuentas de MySQL sean correctas y de que sus puertos y mapas estén correctos.
  • Se perdió la conexión con el servidor MySQL al "leer el paquete de comunicación inicial"
  • ERROR 1045 (28000): acceso denegado para el usuario 'root'@'192.168.0.5' (usando la contraseña: SÍ)

Ahora puede ver que todos están activos y disponibles, y que los Id. De servidor coinciden con lo que configuramos por archivo de cnf.

$ mysql --host=localhost --protocol=tcp --port=3306 -e "Select @@hostname, @@version, @@server_id "
+--------------+-----------+-------------+
| @@hostname | @@version | @@server_id |
+--------------+-----------+-------------+
| 58e9663afe8d | 8.0.19 | 80 |
+--------------+-----------+-------------+
$ mysql --host=localhost --protocol=tcp --port=3307 -e "Select @@hostname, @@version, @@server_id "
+--------------+-----------+-------------+
| @@hostname | @@version | @@server_id |
+--------------+-----------+-------------+
| b240917f051a | 5.7.29 | 57 |
+--------------+-----------+-------------+
$ mysql --host=localhost --protocol=tcp --port=3308 -e "Select @@hostname, @@version, @@server_id "
+--------------+-----------+-------------+
| @@hostname | @@version | @@server_id |
+--------------+-----------+-------------+
| b4653850cfe9 | 5.6.47 | 56 |
+--------------+-----------+-------------+
$ mysql --host=localhost --protocol=tcp --port=3309 -e "Select @@hostname, @@version, @@server_id "
+--------------+-----------+-------------+
| @@hostname | @@version | @@server_id |
+--------------+-----------+-------------+
| 22e169004583 | 5.5.62 | 55 |
+--------------+-----------+-------------+


sábado, 13 de julio de 2019

MySQL ¿Cómo restaurar tablespace?

MySQL ¿Cómo restaurar tablespace?

Esta no es información nueva, pero no la he cubierto mucho, así que la dirijo ahora para aquellos que la necesitan.

Si pierdes tus archivos ibd ... pierdes tus datos. Entonces, si tiene una copia de una disponible ... o incluso si está sincronizando desde otra base de datos, aún puede importarla. ¿Qué / cómo pierdes tablespace?

Aquí hay un ejemplo simple para recuperar tablespace.



mysql> Create database demo;

mysql> use demo;

mysql> CREATE TABLE `demotable` (
-> `id` int(11) NOT NULL AUTO_INCREMENT,
-> `dts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-> PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB;


Ahora almacenamos algunos datos ...


mysql> INSERT INTO demotable (id) VALUES (NULL);
Query OK, 1 row affected (0.10 sec)

mysql> INSERT INTO demotable (id) VALUES (NULL);
Query OK, 1 row affected (0.08 sec)

mysql> SELECT * FROM demotable;
+----+---------------------+
| id | dts |
+----+---------------------+
| 1 | 2019-07-12 23:31:34 |
| 2 | 2019-07-12 23:31:35 |
+----+---------------------+
2 rows in set (0.00 sec)


OK ahora vamos a romperlo ...


# systemctl stop mysqld
# cd /var/lib/mysql/demo/
# ls -ltr
total 80
-rw-r-----. 1 mysql mysql 114688 Jul 12 23:31 demotable.ibd
# mv demotable.ibd /tmp/

# systemctl start mysqld
# mysql demo

mysql> show tables;
+----------------+
| Tables_in_demo |
+----------------+
| demotable |
+----------------+
1 row in set (0.00 sec)

mysql> desc demotable;
+-------+-----------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| dts | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------------------------+
2 rows in set (0.01 sec)

mysql> INSERT INTO demotable (id) VALUES (NULL);
ERROR 1812 (HY000): Tablespace is missing for table `demo`.`demotable`.


Espacio de tabla roto y perdido ... Ahora podemos recuperarlo ..


demo]# cp /tmp/demotable.ibd .

mysql> ALTER TABLE demotable DISCARD TABLESPACE;

demo]# cp /tmp/demotable.ibd .
demo]# ls -ltr
total 112
-rw-r-----. 1 root root 114688 Jul 12 23:50 demotable.ibd
demo]# chown mysql:mysql demotable.ibd
demo]# mysql demo
mysql> ALTER TABLE demotable IMPORT TABLESPACE;
ERROR 1034 (HY000): Incorrect key file for table 'demotable'; try to repair it

mysql> REPAIR TABLE demotable;
+----------------+--------+----------+---------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+----------------+--------+----------+---------------------------------------------------------+
| demo.demotable | repair | note | The storage engine for the table doesn't support repair |
+----------------+--------+----------+---------------------------------------------------------+


Note que ahora también tenemos otro error. Esto generalmente está vinculado al espacio disponible para tmpdir, y la reparación no funciona para .ibd de todos modos.


mysql> select @@tmpdir;
+----------+
| @@tmpdir |
+----------+
| /tmp |
+----------+

# vi /etc/my.cnf
tmpdir=/var/lib/mysql-files/

# systemctl restart mysqld
# mysql demo


OK usé el directorio mysql-files solo por ejemplo.
Ahora podemos intentarlo de nuevo.


mysql> ALTER TABLE demotable IMPORT TABLESPACE;
Query OK, 0 rows affected, 1 warning (0.61 sec)

mysql> INSERT INTO demotable (id) VALUES (NULL);
Query OK, 1 row affected (0.11 sec)

mysql> SELECT * FROM demotable;
+----+---------------------+
| id | dts |
+----+---------------------+
| 1 | 2019-07-12 23:31:34 |
| 2 | 2019-07-12 23:31:35 |
| 3 | 2019-07-12 23:56:08 |
+----+---------------------+


Ok funcionó
Ahora, todo esto es agradable y simple si solo tienes una mesa. Pero ¿qué hay de los 100?

Automatícelo, por supuesto, y use su esquema de información para ayudar.

Haga algunas copias más para la prueba.

mysql> create table demotable1 like demotable;
Query OK, 0 rows affected (0.51 sec)

mysql> create table demotable2 like demotable;
Query OK, 0 rows affected (1.04 sec)

mysql> create table demotable3 like demotable;
Query OK, 0 rows affected (0.74 sec)

mysql> create table demotable4 like demotable;
Query OK, 0 rows affected (2.21 sec)


Romperlos a todos ..

demo]# mv *.ibd /tmp/


Ahora, utilizando su tabla information_schema.tables, puede construir todos los comandos que necesitará.

# vi build_discard.sql
# cat build_discard.sql
SELECT CONCAT(" ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," DISCARD TABLESPACE; ") as CMD FROM information_schema.TABLES WHERE TABLE_SCHEMA='demo';

# vi build_import.sql
# cat build_import.sql
SELECT CONCAT(" ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," IMPORT TABLESPACE; ") as CMD FROM information_schema.TABLES WHERE TABLE_SCHEMA='demo';



# mysql -N < build_import.sql > import_tablespace.sql
# mysql -N < build_discard.sql | mysql demo

demo]# cp /tmp/*.ibd .
demo]# chown mysql:mysql *.ibd
# systemctl restart mysqld
# mysql demo < import_tablespace.sql
# mysql demo

mysql> INSERT INTO demotable (id) VALUES (NULL);
Query OK, 1 row affected (0.08 sec)

mysql> INSERT INTO demotable1 (id) VALUES (NULL);
Query OK, 1 row affected (0.05 sec)

mysql> INSERT INTO demotable2 (id) VALUES (NULL);
Query OK, 1 row affected (0.09 sec)

mysql> INSERT INTO demotable3 (id) VALUES (NULL);
^[[AQuery OK, 1 row affected (0.37 sec)

mysql> INSERT INTO demotable4 (id) VALUES (NULL);
Query OK, 1 row affected (0.12 sec)



Y funcionó.

MySQL Binlogs :: Cómo recuperar

Entonces me di cuenta de que no había hecho una publicación sobre esto después de esta situación que surgió recientemente.

Aquí está el escenario: una copia de seguridad se realizó a medianoche, utilizaron volcados de MySQL por base de datos. Luego, a las diez de la mañana del día siguiente, la base de datos se estrelló. Una serie de eventos sucedieron antes de que me llamaran, pero lo llevaron a una versión de la base de datos con tablas MyISAM y los archivos IBD que faltan en el espacio de tablas.

Así que la opción 1, la restauración de la copia de seguridad nos llevaría a la medianoche y perderíamos horas de datos. Opción 2, reimportamos los miles de archivos ibd y guardamos todo. Luego tuvimos la opción 3, restaurar desde la copia de seguridad, luego aplicar los registros bin para los cambios recientes.

Para hacerlo más interesante, no tenían todos los archivos ibd que me dijeron, y vi algunos faltantes. Así que no estoy seguro de cómo fue posible, pero la opción 2 se convirtió en una opción no válida. Ellos, por supuesto, querían la menor pérdida de datos posible, así que optamos por la opción 3.

Para hacerlo de forma segura, inicié otra instancia de MySQL en el puerto 3307. Esto me permitió trabajar en un lugar seguro mientras el tráfico tenía acceso de lectura a los datos de MyISAM en la instancia del puerto 3306.

Una vez que todos los archivos de copia de seguridad se descomprimieron e importaron en la instancia 3307, pude concentrarme en los archivos binlog.

Al principio, este concepto suena mucho más riesgoso de lo que realmente es. En realidad es bastante sencillo y sencillo.

Así que primero tienes que encontrar los datos que buscas. Una revisión de los archivos binlog le da una ventaja en cuanto a qué archivos son relevantes. En mi caso, de alguna manera lograron restablecer el binlog para que el archivo 117 tuviera 2 rangos de fecha dentro.

Primero para la revisión de binlog, el siguiente comando genera los datos en un formato legible.
mysqlbinlog --defaults-file=/root/.my.cnf --base64-output=DECODE-ROWS --verbose mysql-bin.000117 > review_mysql-bin.000117.sql

* Nota ... Tenga cuidado al ejecutar el comando anterior. Tenga en cuenta que lo tengo descargando el archivo directamente en la misma ubicación que binlog. Entonces valida que tu nombre de archivo sea válido. Este mysql-bin.000117.sql es diferente a este mysql-bin.000117 .sql. Perderá su binlog con la segunda opción y un espacio antes de .sql.

Ahora para guardar los datos para que puedan ser aplicados. Como tenía varios binlogs, creé un archivo y, de todos modos, quería volver a verificar los rangos de tiempo.


mysqlbinlog --defaults-file=/root/.my.cnf --start-datetime="2019-07-09 00:00:00" --stop-datetime="2019-07-10 00:00:00" mysql-bin.000117 > binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf mysql-bin.000118 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf mysql-bin.000119 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf --start-datetime="2019-07-10 00:00:00" --stop-datetime="2019-07-10 10:00:00" mysql-bin.000117 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf --stop-datetime="2019-07-10 10:00:00" mysql-bin.000120 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf --stop-datetime="2019-07-10 10:00:00" mysql-bin.000121 >> binlog_restore.sql

mysql --socket=/var/lib/mysql_restore/mysql.sock -e "source /var/lib/mysql/binlog_restore.sql"

Ahora apliqué todos los datos de esos binlogs para los rangos de tiempo dados. El cliente volvió a verificar todos los datos y estaba muy contento de tenerlos todos de vuelta.

Existían varias opciones diferentes para esta situación, esto sucedió para entrenar mejor con el cliente.

Una vez que todo lo validado estaba correcto en la versión restaurada, era simplemente detener ambas bases de datos, mover los directorios de datos (quería mantener los valores predeterminados de datadir intactos), revisar los directorios solo para estar seguro e iniciar MySQL. Ahora la instancia restaurada estaba en el puerto 3306. 

lunes, 17 de junio de 2019

Replicación de Grupos MySQL

Así que la replicación grupal de MySQL salió con MySQL 5.7. Ahora que ha pasado un poco de tiempo, la gente está empezando a preguntar más al respecto.
A continuación se muestra un ejemplo de cómo configurar esto y algunos ejemplos de puntos débiles a medida que lo hurgaba.
Estoy usando tres servidores diferentes,

Servidor CENTOSA

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.02 sec)

vi my.cnf
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE

log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
master_info_repository=TABLE
relay_log_info_repository=TABLE

transaction_write_set_extraction=XXHASH64
group_replication_group_name="90d8b7c8-5ce1-490e-a448-9c8d176b54a8"
group_replication_start_on_boot=off
group_replication_local_address= "192.168.111.17:33061"
group_replication_group_seeds= "192.168.111.17:33061,192.168.111.89:33061,192.168.111.124:33061"
group_replication_bootstrap_group=off

mysql> SET SQL_LOG_BIN=0;
mysql> CREATE USER repl@'%' IDENTIFIED BY 'replpassword';
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%';
mysql> FLUSH PRIVILEGES;
mysql> SET SQL_LOG_BIN=1;


CHANGE MASTER TO
MASTER_USER='repl',
MASTER_PASSWORD='replpassword'
FOR CHANNEL 'group_replication_recovery';


mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)


mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (3.11 sec)


mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)


mysql> SELECT * FROM performance_schema.replication_group_members \G

*************************** 1. row ***************************
CHANNEL_NAME: group_replication_applier
MEMBER_ID: 1ab30239-5ef6-11e9-9b4a-08002712f4b1
MEMBER_HOST: centosa
MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
MEMBER_ROLE: PRIMARY
MEMBER_VERSION: 8.0.15
Así que ahora podemos agregar más servidores.
Servidor CENTOSB

vi my.cnf
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE

log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
master_info_repository=TABLE
relay_log_info_repository=TABLE


transaction_write_set_extraction=XXHASH64
group_replication_group_name="90d8b7c8-5ce1-490e-a448-9c8d176b54a8"
group_replication_start_on_boot=off
group_replication_local_address= "192.168.111.89:33061"
group_replication_group_seeds= "192.168.111.17:33061,192.168.111.89:33061,192.168.111.124:33061"
group_replication_bootstrap_group=off

mysql> CHANGE MASTER TO
MASTER_USER='repl',
MASTER_PASSWORD='replpassword'
FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> CHANGE MASTER TO GET_MASTER_PUBLIC_KEY=1;
Query OK, 0 rows affected (0.02 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (4.03 sec)

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 1ab30239-5ef6-11e9-9b4a-08002712f4b1 | centosa | 3306 | ONLINE | PRIMARY | 8.0.15 |
| group_replication_applier | 572ca2fa-5eff-11e9-8df9-08002712f4b1 | centosb | 3306 | RECOVERING | SECONDARY | 8.0.15 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
2 rows in set (0.00 sec)


Servidor CENTOSC

vi my.cnf
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
master_info_repository=TABLE
relay_log_info_repository=TABLE

transaction_write_set_extraction=XXHASH64
group_replication_group_name="90d8b7c8-5ce1-490e-a448-9c8d176b54a8"
group_replication_start_on_boot=off
group_replication_local_address= "192.168.111.124:33061"
group_replication_group_seeds= "192.168.111.17:33061,192.168.111.89:33061,192.168.111.124:33061"
group_replication_bootstrap_group=off

mysql> CHANGE MASTER TO
-> MASTER_USER='repl',
-> MASTER_PASSWORD='replpassword'
-> FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> CHANGE MASTER TO GET_MASTER_PUBLIC_KEY=1;
Query OK, 0 rows affected (0.02 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (3.58 sec)
mysql> SELECT * FROM performance_schema.replication_group_members \G
*************************** 1. row ***************************
CHANNEL_NAME: group_replication_applier
MEMBER_ID: 1ab30239-5ef6-11e9-9b4a-08002712f4b1
MEMBER_HOST: centosa
MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
MEMBER_ROLE: PRIMARY
MEMBER_VERSION: 8.0.15

*************************** 2. row ***************************
CHANNEL_NAME: group_replication_applier
MEMBER_ID: 572ca2fa-5eff-11e9-8df9-08002712f4b1
MEMBER_HOST: centosb
MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
MEMBER_ROLE: SECONDARY
MEMBER_VERSION: 8.0.15

*************************** 3. row ***************************
CHANNEL_NAME: group_replication_applier
MEMBER_ID: c5f3d1d2-8dd8-11e9-858d-08002773d1b6
MEMBER_HOST: centosc
MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
MEMBER_ROLE: SECONDARY
MEMBER_VERSION: 8.0.15
3 rows in set (0.00 sec)


Así que todo esto es genial, pero no siempre significa que se conecten a Internet, a menudo pueden estar en modo de recuperación.
He visto que esto falla con MySQL hasta ahora, así que necesito asegurarte de que esté estable.
mysql> create database testcentosb;<br> ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement<br>
Nota al margen para abordar algunos de esos factores -
mysql> START GROUP_REPLICATION;
ERROR 3094 (HY000): The START GROUP_REPLICATION command failed as the applier module failed to start.

mysql> reset slave all;
Query OK, 0 rows affected (0.03 sec)
- A continuación, vuelva a empezar desde el comando maestro de cambio
mysql> START GROUP_REPLICATION;
ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error log.

[ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Error on opening a connection to 192.168.111.17:33061 on local port: 33061.'
[ERROR] [MY-011526] [Repl] Plugin group_replication reported: 'This member has more executed transactions than those present in the group. Local transactions: c5f3d1d2-8dd8-11e9-858d-08002773d1b6:1-4 >
[ERROR] [MY-011522] [Repl] Plugin group_replication reported: 'The member contains transactions not present in the group. The member will now exit the group.'

https://ronniethedba.wordpress.com/2017/04/22/this-member-has-more-executed-transactions-than-those-present-in-the-group/


[ERROR] [MY-011620] [Repl] Plugin group_replication reported: 'Fatal error during the recovery process of Group Replication. The server will leave the group.'
[ERROR] [MY-013173] [Repl] Plugin group_replication reported: 'The plugin encountered a critical error and will abort: Fatal error during execution of Group Replication'

SELECT * FROM performance_schema.replication_connection_status\G


Mis pensamientos...
Tenga en cuenta que la replicación de grupo se puede configurar en modo primario único o multinodo
mysql> select @@group_replication_single_primary_mode\G
*************************** 1. row ***************************
@@group_replication_single_primary_mode: 1

mysql> create database testcentosb;
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement
Por supuesto, obtendrá un error si no escribe en ningún nodo primario.


group-replication-single-primary-mode = off <- agregado a los archivos cnf.
mysql> SELECT * FROM performance_schema.replication_group_members;
+ --------------------------- + --------------------- ----------------- + ------------- + ------------- + ---- ---------- + ------------- + ---------------- +
| NOMBRE DEL CANAL               | IDENTIFICACIÓN DE MIEMBRO                             | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+ --------------------------- + --------------------- ----------------- + ------------- + ------------- + ---- ---------- + ------------- + ---------------- +
| replicación_grupo_grupo | 1ab30239-5ef6-11e9-9b4a-08002712f4b1 | centosa     |         3306 | RECUPERANTE   | PRIMARIO     | 8.0.15         |
| replicación_grupo_grupo | 572ca2fa-5eff-11e9-8df9-08002712f4b1 | centosb     |         3306 | EN LÍNEA       | PRIMARIO     | 8.0.15         |
| replicación_grupo_grupo | c5f3d1d2-8dd8-11e9-858d-08002773d1b6 | centosc     |         3306 | RECUPERANTE   | PRIMARIO     | 8.0.15         |
+ --------------------------- + --------------------- ----------------- + ------------- + ------------- + ---- ---------- + ------------- + ---------------- +

3 filas en conjunto (0,00 seg)


Sin embargo, ahora es si utiliza Keepalived, MySQL router, ProxySQL, etc., para manejar su tráfico y reinvertirlo automáticamente en caso de una falla. Podemos ver desde abajo que fracasó de inmediato cuando detuve la primaria.

mysql> SELECT * FROM performance_schema.replication_group_members ;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 1ab30239-5ef6-11e9-9b4a-08002712f4b1 | centosa | 3306 | ONLINE | PRIMARY | 8.0.15 |
| group_replication_applier | 572ca2fa-5eff-11e9-8df9-08002712f4b1 | centosb | 3306 | ONLINE | SECONDARY | 8.0.15 |
| group_replication_applier | c5f3d1d2-8dd8-11e9-858d-08002773d1b6 | centosc | 3306 | ONLINE | SECONDARY | 8.0.15 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
3 rows in set (0.00 sec)

[root@centosa]# systemctl stop mysqld

mysql> SELECT * FROM performance_schema.replication_group_members ;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 572ca2fa-5eff-11e9-8df9-08002712f4b1 | centosb | 3306 | ONLINE | PRIMARY | 8.0.15 |
| group_replication_applier | c5f3d1d2-8dd8-11e9-858d-08002773d1b6 | centosc | 3306 | ONLINE | SECONDARY | 8.0.15 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
2 rows in set (0.00 sec)

[root@centosa]# systemctl start mysqld
[root@centosa]# mysql
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (3.34 sec)

mysql> SELECT * FROM performance_schema.replication_group_members ;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 1ab30239-5ef6-11e9-9b4a-08002712f4b1 | centosa | 3306 | RECOVERING | SECONDARY | 8.0.15 |
| group_replication_applier | 572ca2fa-5eff-11e9-8df9-08002712f4b1 | centosb | 3306 | ONLINE | PRIMARY | 8.0.15 |
| group_replication_applier | c5f3d1d2-8dd8-11e9-858d-08002773d1b6 | centosc | 3306 | ONLINE | SECONDARY | 8.0.15 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
3 rows in set (0.00 sec)


Ahora la recuperación seguía siendo un problema, ya que no se uniría de nuevo. Tuve que revisar todas las cuentas y los pasos nuevamente, pero finalmente lo recuperé.

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 1ab30239-5ef6-11e9-9b4a-08002712f4b1 | centosa | 3306 | ONLINE | SECONDARY | 8.0.15 |
| group_replication_applier | 572ca2fa-5eff-11e9-8df9-08002712f4b1 | centosb | 3306 | ONLINE | PRIMARY | 8.0.15 |
| group_replication_applier | c5f3d1d2-8dd8-11e9-858d-08002773d1b6 | centosc | 3306 | ONLINE | SECONDARY | 8.0.15 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
3 rows in set (0.00 sec)


Necesito probar más con esto, ya que todavía no estoy 100% vendido, y necesito esto ya que me inclino hacia la replicación de Galera.

URLs de interés


  • https://dev.mysql.com/doc/refman/8.0/en/group-replication.html
  • https://dev.mysql.com/doc/refman/8.0/en/group-replication-deploying-in-single-primary-mode.html
  • http://datacharmer.blogspot.com/2017/01/mysql-group-replication-vs-multi-source.html
  • https://dev.mysql.com/doc/refman/8.0/en/group-replication-launching.html
  • https://dev.mysql.com/doc/refman/8.0/en/group-replication-configuring-instances.html
  • https://dev.mysql.com/doc/refman/8.0/en/group-replication-adding-instances.html
  • https://ronniethedba.wordpress.com/2017/04/22/how-to-setup-mysql-group-replication/
  • https://www.digitalocean.com/community/tutorials/how-to-configure-mysql-group-replication-on-ubuntu-16-04
  • https://dev.mysql.com/doc/refman/8.0/en/group-replication-options.html#sysvar_group_replication_group_seeds
  • https://bugs.mysql.com/bug.php?id=90534
  • https://www.percona.com/blog/2017/02/24/battle-for-synchronous-replication-in-mysql-galera-vs-group-replication/
  • https://lefred.be/content/mysql-group-replication-is-sweet-but-can-be-sour-if-you-misunderstand-it/
  • https://www.youtube.com/watch?v=IfZK-Up03Mw
  • https://mysqlhighavailability.com/mysql-group-replication-a-quick-start-guide/
  • lunes, 3 de junio de 2019

    Max_connections 214 4.15.0-46-generic # 49-Ubuntu



    Por lo tanto, el problema de que max_connections se reduzca del valor establecido en su archivo my.cnf a 214 ha existido por un tiempo en Ubuntu.

    Como ejemplo, se señaló aquí en 2015.



    Me encontré con esto nuevamente recientemente y se resolvió con los siguientes pasos.


    # cp /lib/systemd/system/mysql.service /etc/systemd/system/
    # cd /etc/systemd/system/
    # vi mysql.service

    LimitNOFILE=infinity
    LimitMEMLOCK=infinity

    # systemctl daemon-reload
    # systemctl restart mysql


    Una vez que se completaron esos pasos, las conexiones de MySQL se mantuvieron estables en el parámetro dado en el archivo my.cnf.