sábado, 13 de julho de 2019

MySQL Como você restaura o tablespace

MySQL Como você restaura o tablespace?

Esta não é uma informação nova, mas eu não a abordei tanto, então dirijo-a agora para aqueles que precisam dela.

Se você perder seus arquivos ibd ... você perderá seus dados. Portanto, se você tiver uma cópia de uma disponível ... ou mesmo se estiver sincronizando a partir de outro banco de dados, ainda poderá importá-la. O que / como você perde o tablespace?

Aqui está um exemplo simples para recuperar o espaço de tabelas.



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;


Agora nós armazenamos alguns dados ...


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 agora vamos quebrar ..


# 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`.


Espaço de tabelas quebrado e perdido ... Agora podemos recuperá-lo ..


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 agora que nós também temos outro erro .. Isto geralmente está ligado ao espaço disponível para o tmpdir, e o reparo não funciona para o .ibd de qualquer maneira.


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

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

# systemctl restart mysqld
# mysql demo


OK usou o diretório mysql-files apenas por exemplo.
Agora podemos tentar novamente.


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 funcionou.
Agora, tudo isso é legal e simples se você tiver apenas uma tabela. Mas e quanto aos 100s ...

Automatize, é claro, e use seu information_schema para ajudar.

Faça mais algumas cópias para teste.

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)


Quebre todos eles ..

demo]# mv *.ibd /tmp/


Agora, usando sua tabela information_schema.tables, você pode construir todos os comandos necessários.

# 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)



E funcionou. 

sexta-feira, 12 de julho de 2019

MySQL Binlogs :: Como recuperar

Então percebi que não havia feito um post sobre isso depois dessa situação que surgiu recentemente.

Aqui está o cenário: Um backup foi feito à meia-noite, eles usaram o MySQL Dumps por banco de dados. Então, às dez da manhã do dia seguinte, o banco de dados caiu. Uma série de eventos aconteceu antes de eu ser chamado, mas eles conseguiram uma versão do banco de dados com tabelas MyISAM e os arquivos IBD faltando no tablespace.

Portanto, a opção 1, a restauração do backup, nos levaria à meia-noite e perderíamos horas de dados. Opção 2, nós reimportamos os milhares de arquivos ibd e mantemos tudo. Em seguida, tivemos a opção 3, restaurar a partir do backup e, em seguida, aplicar os logs binários para alterações recentes.

Para torná-lo mais interessante, eles não tinham todos os arquivos ibd que me contaram, e eu vi alguns desaparecidos. Portanto, não tenho certeza de como isso foi possível, mas a opção 2 se tornou uma opção inválida. Eles, claro, queriam a menor perda de dados possível, então fomos com a opção 3.

Para fazer isso com segurança, iniciei outra instância do MySQL na porta 3307. Isso me permitiu um local seguro para trabalhar enquanto o tráfego tinha acesso de leitura aos dados do MyISAM na instância da porta 3306.

Depois que todos os arquivos de backup foram descompactados e importados para a instância 3307, consegui me concentrar nos arquivos do log binário.

A princípio, esse conceito parece muito mais arriscado do que realmente é. Na verdade, é bem direto e simples.

Então, primeiro você tem que encontrar os dados depois. Uma revisão dos arquivos binlogs lhe dá uma vantagem sobre quais arquivos são relevantes. No meu caso, de alguma forma eles conseguiram redefinir o log binário para que o arquivo 117 tivesse 2 intervalos de datas dentro dele.

Primeiro para a revisão do binlog, o comando a seguir exibe os dados em formato legível.
mysqlbinlog --defaults-file=/root/.my.cnf --base64-output=DECODE-ROWS --verbose mysql-bin.000117 > review_mysql-bin.000117.sql

* Nota ... Tenha cuidado ao executar o comando acima. Observe que eu tenho que despejar o arquivo diretamente no mesmo local que o log binário. Então, VALIDAR que seu nome de arquivo é válido. Este mysql-bin.000117.sql é diferente deste mysql-bin.000117 .sql. Você perderá seu log binário com a 2ª opção e um espaço antes de .sql.

Agora, salve os dados para que possam ser aplicados. Desde que eu tinha vários binlogs eu criei um arquivo e queria verificar novamente os intervalos de tempo de qualquer maneira.


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"

Agora eu apliquei todos os dados desses binlogs para os intervalos de tempo fornecidos. O cliente checou novamente todos os dados e ficou muito feliz em tê-los de volta.

Várias opções diferentes existiam para esta situação, isso aconteceu para treinar melhor com o cliente.

Uma vez que o validado estava tudo bem na versão restaurada, era simples parar ambos os bancos de dados, mover os diretórios de dados (queria manter os padrões de datadir intactos), chover os diretórios apenas para serem seguros e iniciar o MySQL. Agora a instância restaurada estava na porta 3306. 

segunda-feira, 17 de junho de 2019

Replicação de Grupo do MySQL

Então a replicação de grupo do MySQL foi lançada com o MySQL 5.7. Agora isso já está um pouco fora, enquanto as pessoas estão começando a perguntar mais sobre isso.
Abaixo está um exemplo de como configurar isso e alguns exemplos de pontos de dor como eu cutuquei com ele.
Eu estou usando três 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
Então agora podemos adicionar mais 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)


Então tudo isso é ótimo, mas nem sempre significa que eles ficam on-line, eles geralmente podem se sentar no modo de recuperação.
Eu vi essa falha com falhas do MySQL até agora, então preciso garantir isso estável.
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 lateral para abordar alguns desses fatores -
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)
- Então, comece novamente do comando Change master
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-mais-transações-executadas-do-que-presente-no-grupo/


[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


Meus pensamentos...
Tenha em mente que a replicação de grupo pode ser configurada no modo primário único ou em vários nós
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
você obviamente obterá um erro se escrever em nenhum nó primário.


group-replication-single-primary-mode = off <- adicionado aos arquivos cnf.
mysql> SELECT * FROM performance_schema.replication_group_members;
+ --------------------------- + --------------------- ----------------- + ------------- + ------------- + ---- ---------- + ------------- + ---------------- +
| NOME DO CANAL               | MEMBER_ID                             | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+ --------------------------- + --------------------- ----------------- + ------------- + ------------- + ---- ---------- + ------------- + ---------------- +
| group_replication_applier | 1ab30239-5ef6-11e9-9b4a-08002712f4b1 | centosa     |         3306 | RECUPERANDO   | PRIMÁRIO     | 8,0.15         |
| group_replication_applier | 572ca2fa-5eff-11e9-8df9-08002712f4b1 | centosb     |         3306 | CONECTADOS       | PRIMÁRIO     | 8,0.15         |
| group_replication_applier | c5f3d1d2-8dd8-11e9-858d-08002773d1b6 | centosc     |         3306 | RECUPERANDO   | PRIMÁRIO     | 8,0.15         |
+ --------------------------- + --------------------- ----------------- + ------------- + ------------- + ---- ---------- + ------------- + ---------------- +

3 linhas no set (0,00 seg)


Agora é, no entanto, se você usa Keepalived, MySQL router, ProxySQL etc para lidar com o tráfego para rolar automaticamente em caso de um failover. Podemos ver de baixo que falhou imediatamente quando parei o primário.

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)


Agora a recuperação ainda era um problema, já que não seria simplesmente voltar atrás. Tive que rever todas as contas e etapas novamente, mas eu consegui de volta eventualmente.

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)


Eu preciso testar mais com isso, como eu não estou 100% vendido ainda como a necessidade disso como eu me inclino para replicação Galera ainda.

URLs de interesse


  • 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/

  • segunda-feira, 3 de junho de 2019

    Max_connections 214 4.15.0-46-genérico # 49-Ubuntu



    Assim, o problema de max_connections cair do valor definido em seu arquivo my.cnf para 214 existe há algum tempo no Ubuntu.

    Como exemplo, foi observado aqui em 2015



    Eu corri para isso novamente recentemente e foi resolvido com os seguintes passos.


    # 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


    Uma vez que essas etapas foram concluídas, as conexões do MySQL ficaram estáveis ​​no parâmetro fornecido no arquivo my.cnf.

    domingo, 14 de abril de 2019

    Configuração simples do KeepaliveD

    Então keepalived tem sido em torno de um bom tempo agora .... no entanto, ainda é um mistério para muitos.
    Portanto, este é um exemplo muito simples de como o keepalived pode funcionar com o MySQL. Espero que isso possa ajudar as pessoas com dúvidas.

    Nós teremos um mestre simples para configurar escravos. Significado .. nós escrevemos para um a menos que tenhamos failover para o segundo para algum evento.

    1º - instalar keepalived


    # yum search keepalived
    keepalived .x86_64: Balanceador de carga e serviço de alta disponibilidade

      Apenas para nomes e resumos, use "pesquisar todos" para tudo.
    # yum -y install keepalived

    Agora você deve ter um arquivo de configuração

    # ls -ltr /etc/keepalived/keepalived.conf  

    Mantenha o original como você sempre faz backup .. certo ....
    # cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.orig

    Então você precisa descobrir um ipaddress que você pode usar para o seu ip virtual. Eu escolhi 192.168.0.123 para este exemplo.

    Em seguida, vamos configurar um script para ser usado em nosso novo arquivo de configuração.

    Algumas coisas que fiz aqui ..
    Eu deixei um arquivo .cnf para keepalived e um log all no / etc / keepalived.
    Isso simplifica o exemplo para que você possa fazer isso ou usar seus próprios arquivos cnf.

    Um roteiro:

    cat /etc/keepalived/keepalived_check.sh  
    #! / bin / bash

    # monitorar o status do mysql

    # se este nó mysql estiver morto

    # e seu escravo está vivo, então pare seu keepalived. O outro nó ligará o IP.



    exportar MYSQL_HOME = / etc / keepalived /

    Exportar PATH = $ MYSQL_HOME / bin: $ PATH



    mysql = "/ usr / bin / mysql"

    mysqladmin = "/ usr / bin / mysqladmin"

    delay_file = "$ MYSQL_HOME / slave_delay_second.log"

    slave_host = $ 1





    ALIVE = $ ($ mysqladmin --defaults-file = $ MYSQL_HOME / .my.localhost.cnf   ping | grep alive | wc -l);

    REMOTEALIVE = $ ($ mysqladmin --defaults-file = $ MYSQL_HOME / .my.remotehost.cnf   ping | grep alive | wc -l);



    if [[$ ALIVE -ne 1]]

    então

    #echo "MySQL está inoperante"

            if [[$ REMOTEALIVE-eq 1]]

            então

    #         eco "Shutdown keep alive"

                systemctl stop keepalived  

    #       echo "stop keepalived"

            fi

    #outro

    #echo "MySQL está ativo"

    #encontro

    fi



    sair 0 #todo feito

    Novo arquivo de configuração

    cat /etc/keepalived/keepalived.conf
    global_defs {



          notification_email {

            anothermysqldba@gmail.com  

          }



          notification_email_from anothermysqldba@gmail.com  

          smtp_server localhost

          smtp_connect_timeout 30



          }







    vrrp_script check_mysql {

       script "/etc/keepalived/keepalived_check.sh"

       intervalo 2

       peso 2

    }







    vrrp_instance VI_1 {



          estado MESTRE

          interface enp0s8   # <--- O NOME DA INTERFACE REALIZA SEU IP REAL / sbin / ifconfig

            # encontrado com show ip link

          virtual_router_id 51

          prioridade 101

          advert_int 1

          nopreempt   # somente necessário no nó de prioridade mais alta

          autenticação {

            auth_type PASS

            auth_pass 1111

          }





          track_script {

            check_mysql

          }



          virtual_ipaddress {

            192.168.0.123  

          }




    }



    Isso tudo é ótimo, mas funciona ...

    Então nós temos 2 hosts

    [root @ centosa keepalived] # hostname

    centosa

    [root @ centosb keepalived] # hostname
    centosb

    Comece a manter o serviço

    [root @ centosa keepalived] # systemctl status keepalived
    ● keepalived.service - Monitor de alta disponibilidade de LVS e VRRP
       Carregado: carregado (/usr/lib/systemd/system/keepalived.service; desativado; predefinido do fornecedor: desativado)
       Ativo: inativo (morto)
    [root @ centosa keepalived] # systemctl restart keepalived
    [root @ centosa keepalived] # systemctl status keepalived
    keepalived.service - Monitor de alta disponibilidade de LVS e VRRP
       Carregado: carregado (/usr/lib/systemd/system/keepalived.service; desativado; predefinido do fornecedor: desativado)
        Ativo: ativo (em execução)

    [root @ centosa keepalived] # ssh 192.168.0.123 'hostname'
    Senha: root@192.168.0.123:  

    centosa

    Prove as conexões já funcionam

    [root @ centosa keepalived] # mysql --defaults-file = .my.remotehost.cnf --host = 192.168.0.101   -e "selecione @@ hostname"
    + ------------ +
    | @@ hostname |
    + ------------ +
    | centosb     |
    + ------------ +
    [root @ centosa keepalived] # mysql --defaults-file = .my.remotehost.cnf --host = 192.168.0.102   -e "selecione @@ hostname"
    + ------------ +
    | @@ hostname |
    + ------------ +
    | centosa     |
    + ------------ +

    Verifique se está funcionando ...

    [root @ centosa keepalived] # status do systemctl keepalived | grep active
        Ativo: ativo  

    [root @ centosb keepalived] # status do systemctl keepalived | grep active
        Ativo: ativo  

    Teste o VIP atual .. pare o mysql e veja os mesmos hosts de mudança do VIP ...

    [root @ centosa keepalived] # mysql --defaults-file = .my.remotehost.cnf --host = 192.168.0.123   -e "selecione @@ hostname"
    + ------------ +
    | @@ hostname |
    + ------------ +
    | centosa     |
    + ------------ +
    [root @ centosa keepalived] # systemctl pára o mysqld  
    [root @ centosa keepalived] # mysql --defaults-file = .my.remotehost.cnf --host = 192.168.0.123   -e "selecione @@ hostname"
    + ------------ +
    | @@ hostname |
    + ------------ +
    | centosb     |
    + ------------ +

    terça-feira, 9 de abril de 2019

    Às vezes, o banco de dados lento .. não é o banco de dados ...

    Então eu fui recentemente perguntado por que o MySQL 5 atualizado, .6 era mais lento que o mais antigo 5.5

    Então eu comecei a olhar por cima das variáveis ​​padrão e caches e etc.

    O caso de teste era uma rotina simples que levava cerca de duas vezes mais tempo para ser executada em 5.6 do que em 5.5.

    Para adicionar ao mix .. a versão 5.6 tinha o dobro do Innodb_buffer_pool_size e, claro, mais ram geral.

    Então eu comecei alguns testes com o MySQLslap ...

    Testes do Mysqlslap mostram mais lento em 5.6

    5,6:
    mysqlslap --defaults-file =. /. my.cnf --concurrency = 150 --iterações = 130 - consulta = / teste.sql --create-schema = applicationdata --verbose
    Referência
    Número médio de segundos para executar todas as consultas: 0,028 segundos
    Número mínimo de segundos para executar todas as consultas: 0,019 segundos
    Número máximo de segundos para executar todas as consultas: 0,071 segundos
    Número de clientes executando consultas: 150
    Número médio de consultas por cliente: 1

    5,5:
    mysqlslap --defaults-file =. /. my.cnf --concurrency = 150 --iterações = 130 --query = / test.sql --create-schema = applicationdata --verbose
    Referência
    Número médio de segundos para executar todas as consultas: 0,015 segundos
    Número mínimo de segundos para executar todas as consultas: 0,011 segundos
    Número máximo de segundos para executar todas as consultas: 0,024 segundos
    Número de clientes executando consultas: 150
    Número médio de consultas por cliente: 1


    Tudo isso vai contra os benchmarks públicos
    http://dimitrik.free.fr/blog/archives/2013/02/mysql-performance-mysql-56-ga-vs-mysql-55-32cores.html

    Então eu verifiquei o nível do disco -

    5,6:
    # dd if = / dev / zero de = teste bs = 1048576 contagem = 2048
    2048 + 0 registros em
    2048 + 0 registra
    2147483648 bytes (2,1 GB) copiados, 25,7401 s, 83,4 MB / s

    # dd if = teste de = / dev / null bs = 1048576
    2048 + 0 registros em
    2048 + 0 registra
    2147483648 bytes (2,1 GB) copiados, 29,1527 s, 73,7 MB / s

    5,5:
    # dd if = / dev / zero de = teste bs = 1048576 contagem = 2048
    2048 + 0 registros em
    2048 + 0 registra
    2147483648 bytes (2,1 GB) copiados, 19,9214 segundos, 108 MB / s

    # dd if = teste de = / dev / null bs = 1048576
    2048 + 0 registros em
    2048 + 0 registra
    2147483648 bytes (2,1 GB) copiados, 20,0243 segundos, 107 MB / s



    Aqui os discos com 5.5 são mais lentos independentemente do MySQL. Então, neste caso .... Olhe para corrigir a velocidade do disco .. MySQL estava funcionando bem e vontade.

    quarta-feira, 23 de maio de 2018

    Proxy MySQL :: HAproxy || ProxySQL e KeepAlived

    Então, quando se trata de rotear seu tráfego MySQL, existem várias opções. 

    Agora eu tenho visto HAproxy usado com mais freqüência com os clientes, é bastante simples de configurar. Percona tem um exemplo para os interessados:

    Pessoalmente eu gosto de ProxySQL. Percona também tem alguns blogs sobre isso também
    Percona também tem versão ProxySQL disponível

    Eu estava pensando em escrever alguns exemplos, mas no geral Percona explicou tudo muito bem. Eu não quero tirar nada desses posts, em vez disso, salientar que muita informação boa está disponível através desses URLs. Então, em vez de reescrever o que já foi escrito, vou criar uma coleção de informações para os interessados.

    Primeiro compare e decida por si mesmo o que você precisa e quer. O link a seguir, claro, vai ser inclinado para o ProxySQL, mas dá-lhe um escopo geral para você considerar.
    Se você tem um cluster ou mestre para dominar e não se importa com qual servidor as leituras versus leituras serão feitas, contanto que você tenha uma conexão; então o HAproxy é provavelmente um simples e rápido setup para você.

    O bônus com o ProxySQL é a capacidade de classificar o tráfego de maneira ponderada, FÁCIL. Assim, você pode escrever no nó 1 e selecionar pull do nó 2 e do nó 3. A documentação pode ser encontrada aqui:
    Sim, isso pode ser feito com o HAproxy, mas você deve instruir o aplicativo de acordo.
    Isso é tratado no ProxySQL com base em suas regras de consulta.

    Agora a pergunta óbvia aqui: OK, então como você mantém ProxySQL de se tornar o único ponto de falha?

    Você pode investir é um balanceador de carga robusto e etc etc etc ... Lançar hardware nele ... Ou tornar mais fácil em si mesmo e apoiar open source e usar KeepAlive d. Isso é muito fácil de configurar e tudo está documentado novamente aqui:
    Se você já lidou com lua e mysql-proxy , ProxySQL e Keepalived devem ser muito simples para você. Se você ainda quiser, por algum motivo: https://launchpad.net/mysql-proxy

    Independentemente de você escolher HAproxy, ProxySQL ou outra solução, você precisa garantir que não substitua um único ponto de falha por outro e que keepalived seja ótimo para isso. Tão pouco motivo para não fazer isso se você estiver usando um proxy.

    Então, mais algumas coisas no ProxySQL.
    http://anothermysqldba.blogspot.com/2018/05/proxy-mysql-haproxy-proxysql-keepalived.html