Eu estava um pouco surpreso ao descobrir que as instruções DDL ( alter table
, create index
etc) cometer implicitamente a transação atual no MySQL. Vindo do MS SQL Server, a capacidade de fazer alterações no banco de dados em uma transação localmente (que foi revertida) foi uma parte importante do meu fluxo de trabalho. Para integração contínua, a reversão era usada se a migração ocorresse por algum motivo, para que pelo menos não deixássemos o banco de dados em um estado semi-migrado.
Como as pessoas resolvem esses dois problemas ao usar o MySQL com migrações e integração contínua?
mysql
transaction
ddl
rollback
Sennett
fonte
fonte
Respostas:
Para muitas pessoas, o calcanhar de Aquiles do MySQL é um comprometimento implícito.
De acordo com o parágrafo 3 do livro
os seguintes comandos podem e irão interromper uma transação
ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP INDEX
DROP TABLE
RENAME TABLE
TRUNCATE TABLE
LOCK TABLES
UNLOCK TABLES
SET AUTOCOMMIT = 1
START TRANSACTION
SUGESTÃO
Quando se trata de MySQL, qualquer trabalho de Integração Contínua (IC) / Auto-serviço que você constrói deve sempre tornar os trabalhos Transacionais e os scripts DDL mutuamente exclusivos.
Isso lhe dá a oportunidade de criar paradigmas que
START TRANSACTION/COMMIT
blocosAVISO: Se você estiver usando o MyISAM para isso, poderá (des) gentilmente adicionar o MyISAM à lista de coisas que podem quebrar uma transação, talvez não em termos de confirmação implícita, mas definitivamente em termos de consistência dos dados, caso ocorra uma reversão. necessário.
POR QUE NÃO LVM?
Os instantâneos LVM são ótimos e a restauração de instâncias inteiras de bancos de dados sem a necessidade de executar um processamento pesado de SQL é ideal. No entanto, quando se trata de MySQL, você deve considerar dois mecanismos de armazenamento: InnoDB e MyISAM.
Banco de dados All-InnoDB
Veja a arquitetura do InnoDB (Imagem cortesia do Percona CTO Vadim Tkachenko)
O InnoDB possui muitas partes móveis
Tirar uma captura instantânea do LVM de um banco de dados all-InnoDB com alterações não confirmadas flutuando nos caches do Buffer Pool e da Memória produziria um conjunto de dados que exigiria a recuperação de falhas do InnoDB assim que o LUN for restaurado e o mysqld iniciado.
SUGESTÃO PARA O ALL-InnoDB
Se você pode desligar o MySQL antes de tirar o instantâneo
SET GLOBAL innodb_fast_shutdown = 0;
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
service mysql stop
service mysql stop
Se você não pode desligar, mas tirar instantâneo com o MySQL Live
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
SET GLOBAL innodb_max_dirty_pages_pct = 75;
Banco de dados All-MyISAM ou InnoDB / MyISAM Mix
O MyISAM, quando acessado, mantém uma contagem de identificadores de arquivos abertos. Se o MySQL travar, qualquer tabela MyISAM com uma contagem de identificadores de arquivo aberta> 0 será marcada como travamento e precisa de reparo (mesmo que nada esteja errado com os dados).
Tirar um instantâneo LVM de um banco de dados que possui tabelas MyISAM em uso terá uma ou mais tabelas MyISAM que precisam de reparo quando o instantâneo for restaurado e o mysqld iniciado.
SUGESTÃO PARA All-MyISAM ou InnoDB / MyISAM Mix
Se você pode desligar o MySQL antes de tirar o instantâneo
SET GLOBAL innodb_fast_shutdown = 0;
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
service mysql stop
service mysql stop
Se você não pode desligar, mas tirar instantâneo com o MySQL Live
Você pode aplicar uma descarga de determinadas tabelas do InnoDB
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
em tabelas críticas do InnoDBFLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
SET GLOBAL innodb_max_dirty_pages_pct = 75;
A replicação do MySQL poderia ajudar?
Embora você possa restaurar um instantâneo LVM para dois servidores e configurar o MySQL Master / Slave Replication, isso se torna uma fonte extra de limpeza de casa ao restaurar instantâneos.
Se você executar tarefas de IC em um mestre e essas tarefas forem pequenas, a replicação poderá economizar tempo em determinadas circunstâncias. Você pode simplesmente executar
STOP SLAVE;
no escravo, iniciar os trabalhos de IC no mestre e executarSTART SLAVE;
no escravo quando os dados do mestre forem certificados.Se os trabalhos de IC alertarem muitos dados, você poderá restaurar a captura instantânea do LVM e a replicação da configuração do zero. Se você se encontra fazendo isso com frequência, provavelmente poderia fazer com a configuração da replicação do MySQL.
PENSAMENTOS FINAIS
fonte
Se você fala sobre integração contínua, presumo que seja um ambiente de desenvolvimento. Nesse caso, eu diria que a pessoa que está fazendo alterações estruturais precisa testá-las para garantir que não quebrem as coisas para os outros, da mesma forma que alguém atualiza uma biblioteca comum: teste em sua própria caixa de proteção antes de confirmar essas alterações.
Em um processo de implantação de produção, você normalmente passava por ambientes de desenvolvimento, controle de qualidade ou mesmo de pré-produção para testar suas alterações, da mesma forma que faria em qualquer alteração de código.
Observe que isso não é específico do MySQL: os bancos de dados Oracle também implicitamente executariam COMMIT ao emitir 'alter table' etc.
Agora, se você quiser se proteger, é claro que poderá fazer um backup antecipado ou um instantâneo do LVM ou do sistema de arquivos, se o seu sistema puder fazer isso. Você também pode ter um escravo que pode atrasar / parar como segurança antes de operações confidenciais.
fonte