Fico confuso com a terminologia como liberar e gravar no disco e sincronizar no disco. Alguém poderia me explicar qual é a diferença entre liberar, gravar e sincronizar no disco, especialmente no contexto do MySQL.
Eu costumava pensar que ambas eram as mesmas operações, mas ao ler vários conceitos isso me confunde.
Por exemplo. A documentação diz para a variável rpl_semi_sync_source_wait_point que, se eu defini-la como AFTER_SYNC , a origem grava as transações primeiro no log bin e na réplica e, em seguida, sincroniza o log binário no disco.
AFTER_SYNC (the default): The source writes each transaction to its binary log and the replica, and syncs the binary log to disk.
Esta afirmação é em si confusa. Primeiro diz source writes each transaction to its binary log and the replica
e depois dizsyncs the binary log to disk.
Então, o que exatamente está acontecendo neste caso. O que exatamente é liberar, sincronizar e gravar no disco no contexto do MySQL? A questão não é sobre sync_binlog ou qualquer outro parâmetro no MySQL. A questão é sobre liberar, sincronizar e escrever e quando essas atividades acontecem?
Novamente quando tentei ler mais, no link a seguir, explica que existe um cache binlog, um cache de página e uma operação fsync. Assim, quando uma transação acontece, se bem entendi, o buffer fica sujo, o conteúdo da transação é gravado no cache do log binário (no nível do MySQL), que é um cache separado para cada sessão, então o cache do log binário é gravado no cache da página ( no nível Linux), dependendo do sync_binlog
valor, ele é liberado/gravado/sincronizado com os arquivos no disco.
https://betterprogramming.pub/understanding-mysqls-binlog-4ac8de4d20ee
Este é um tema complexo, mas vamos tentar falar um pouco sobre ele. Quando se trata de gravações “regulares” (INSERTs, UPDATEs, DELETEs), o processo é o seguinte (e, para deixar claro, não vou esclarecer todos os detalhes, como buffer de gravação dupla e outros).
O aplicativo executa algumas consultas. As linhas modificadas são armazenadas no buffer pool como páginas sujas
As alterações são gravadas nos redo logs (redo log do InnoDB)
As alterações também são armazenadas no log binário, se estiver habilitado
Então, dependendo da
sync_binlog
configuração (1), os logs binários podem ser sincronizados (persistidos, liberados) no disco antes que o COMMIT aconteça, após cada gravação.COMMIT acontece
Dependendo dos
innodb_flush_logs_at_trx_commit
redo logs são:um. Liberado (sincronizado) para o disco no COMMIT (1) b. Gravado no disco no COMMIT, mas liberado após 1 segundo (2) c. Gravado no disco e liberado após 1 segundo (0)
Mais tarde, em algum momento, os dados do buffer pool do InnoDB são gravados nos espaços de tabela e persistem lá eventualmente (limpando páginas sujas no buffer pool)
Agora, qual é a diferença entre gravação e liberação (sincronização)? Escrever é apenas escrever. MySQL grava em um arquivo. Ele vai então para o cache do sistema de arquivos do sistema operacional e permanece lá na memória. Portanto, as gravações não são persistentes. Eles eventualmente serão (cada sistema operacional eventualmente irá gravá-lo no próprio arquivo), mas não imediatamente. Esta é a gravação dos mais rápidos, pois é armazenada em cache na memória. Em seguida, sincronizamos os dados com o disco. Nesse caso, o MySQL tentará forçar a persistência da gravação no disco. Como isso acontece é definido na
innodb_flush_method
variável, padrão para O_DIRECT + fsync() na maioria das distribuições Linux. Nesse caso, a gravação ignora os buffers do sistema de arquivos do sistema operacional e é executada diretamente na unidade de disco. Ou pelo menos é o que o MySQL pensa.Na realidade, você também deve considerar a configuração do sistema operacional, do armazenamento em disco ou até mesmo das próprias unidades de disco. Se você tiver SAN ou algum tipo de controlador RAID, provavelmente a gravação liberada não persistirá no disco, mas no cache do controlador SAN ou RAID. Até mesmo o próprio disco pode “falsificar” a liberação de dados e apenas armazená-los em seu buffer de gravação.
No caso do seu exemplo, se você tiver
sync_binlog=1
qualquer outro cache deverá ser irrelevante. Binlogs são persistidos após cada gravação. Se você tiversync_binlog=N
, o MySQL poderá armazenar em cache N gravações no cache do log binário antes que elas sejam persistidas no disco.Já
rpl_semi_sync_source_wait_point
, define quando o nó de origem está aguardando o ACK das réplicas semi-sincronizadas. É assim no lado do aplicativo:COMEÇAR
Executar consultas
COMPROMETER-SE
A diferença está no ponto 3. Se for
AFTER_SYNC
, o COMMIT será executado somente após as réplicas confirmarem que os dados estão armazenados em uma réplica, garantindo que não importa qual conexão você use na fonte para ler os dados, você verá o mesmo conteúdo . Se forAFTER_COMMIT
, COMMIT será executado enquanto os dados ainda estiverem sendo persistidos nas réplicas. Isso significa que se você se conectar à origem usando outra conexão, verá os dados confirmados, mesmo que o cliente que os cometeu ainda espere que as réplicas confirmem que receberam os dados.