Arquitetura MySQL e Módulos Internos (5)

Trabalhem juntos para criar e crescer juntos! Este é o 30º dia da minha participação no "Nuggets Daily New Plan·August Update Challenge", clique para ver os detalhes do evento

Estrutura de memória InnoDB e estrutura de disco

O mais recente diagrama de arquitetura do site oficial. Portal clique em mim!

imagem.png

estrutura de memória

As principais estruturas de memória são Buffer Pool, Change Buffer, Log Buffer e AHI.

imagem.png

Conjunto de buffers

O Buffer Pool armazena em cache as informações da página.

Verifique o status do servidor, há muitas informações relacionadas ao Buffer Pool:

SHOW STATUS LIKE '%innodb_buffer_pool%';
复制代码

imagem.png

Detalhes desses status podem ser encontrados no site oficial. clique em mim!

O tamanho padrão do Buffer Pool é 128M (134217728 bytes), que pode ser ajustado.

Parâmetros de visualização (variáveis ​​do sistema):

SHOW VARIABLES like '%innodb_buffer_pool%';
复制代码

(refazer)Log Buffer

Como a sujeira não é em tempo real, se as páginas sujas no Buffer Pool não tiverem sido liberadas para o disco, o banco de dados será desativado ou reiniciado e os dados serão perdidos.

Os dados na memória devem ter uma medida persistente.

Para evitar esse problema, o InnoDB grava todas as operações de modificação de página em um arquivo de log dedicado.

Se houver dados que não foram sincronizados com o disco, o banco de dados se recuperará desse arquivo de log quando for inicializado (para obter segurança contra falhas). O D (persistência) no ACID da transação que estamos falando é implementado com ele.

imagem.png

Este arquivo de log é o redo log (chamado de redo log) do disco, correspondente a ib_logfile0 e ib_logfile1 no diretório /var/lib/mysql/, com 2 arquivos por padrão, cada um com 48M.

show variables like 'innodb_log%';
复制代码

imagem.png

parâmetro significado
innodb_log_file_size Especifique o tamanho de cada arquivo, o padrão é 48M
innodb_log_files_in_group Especifica o número de arquivos, o padrão é 2
innodb_log_group_home_dir Especifica o caminho onde o arquivo está localizado, relativo ou absoluto. Se não for especificado, o caminho datadir

同样是写磁盘,为什么不直接写到 db file 里面去?为什么先写日志再写磁盘?写日志文件和和写到数据文件有什么区别?

如果我们所需要的数据是随机分散在磁盘上不同页的不同扇区中,那么找到相应的数据需要等到磁臂旋转到指定的页,然后盘片寻找到对应的扇区,才能找到我们所需要的一块数据,一次进行此过程直到找完所有数据,这个就是随机 IO,读取数据速度较慢。

假设我们已经找到了第一块数据,并且其他所需的数据就在这一块数据后边,那么就不需要重新寻址,可以依次拿到我们所需的数据,这个就叫顺序 IO。

刷盘是随机 I/O,而记录日志是顺序 I/O(连续写的),顺序 I/O 效率更高。因此先把修改写入日志文件,在保证了内存数据的安全性的情况下,可以延迟刷盘时机,进而提升系统吞吐。

  • redo log 有什么特点?

1、redo log 是 InnoDB 存储引擎实现的,并不是所有存储引擎都有。支持崩溃恢复是 InnoDB 的一个特性。

2、redo log 是物理日志,记录的是“在某个数据页上做了什么修改”。

3、redo log 的大小是固定的,前面的内容会被覆盖,一旦写满,就会触发 buffer pool到磁盘的同步,以便腾出空间记录后面的修改。

redo log 的内容主要是用于崩溃恢复。磁盘的数据文件,数据来自 buffer pool(只有 redo log 写满了,不能再记录更多内存的数据了,才把 buffer pool 刷盘,然后覆盖redo log)。

除了 redo log 之外,还有一个跟修改有关的日志,叫做 undo log。redo log 和 undo log 与事务密切相关,统称为事务日志。

undo log tablespace

dev.mysql.com/doc/refman/… dev.mysql.com/doc/refman/…

undo log(撤销日志或回滚日志)记录了事务发生之前的数据状态(不包括 select)。如果修改数据时出现异常,可以用 undo log 来实现回滚操作(保持原子性)。

在执行 undo 的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,属于逻辑格式的日志。

undo log 的数据默认在系统表空间 ibdata1 文件中,因为共享表空间不会自动收缩,也可以单独创建一个 undo 表空间。

show global variables like '%undo%';
复制代码
含义
innodb_undo_directory undo 文件的路径
innodb_undo_log_truncate 设置为 1,即开启在线回收(收缩)undo log 日志文 件
innodb_max_undo_log_size 如果 innodb_undo_log_truncate 设置为 1,超过这个大 小的时候会触发 truncate 回收(收缩)动作,如果 page 大小是 16KB,truncate 后空间缩小到 10M。默认 1073741824 字节=1G
innodb_undo_logs 回滚段的数量, 默认 128,这个参数已经过时
innodb_undo_tablespaces 表空间格式,最大 95,这个参数已经过时

有了这些日志之后,我们来总结一下一个更新操作的流程,这是一个简化的过程。name 原值是 zhangsan。

update user set name = 'wangwu' where id=1;
复制代码

1、事务开始,内存(buffer pool)或磁盘(data file)取到这条数据,返回给 Server的执行器;

2、Server 的执行器修改这一行数据的值为 penyuyan;

3、记录 name=qingshan 到 undo log;

4、记录 name=penyuyan 到 redo log;

5、调用存储引擎接口,在内存(Buffer Pool)中修改 name=penyuyan;

6、事务提交。

内存和磁盘之间,工作着很多后台线程。

  • 后台线程

后台线程的主要作用是负责刷新内存池中的数据和把修改的数据页刷新到磁盘。后台线程分为:master thread,IO thread,purge thread,page cleaner thread。

除了 InnoDB 架构中的日志文件,MySQL 的 Server 层也有一个日志文件,叫做binlog,它可以被所有的存储引擎使用。

Binlog

官网传送门,click me!

binlog 以事件的形式记录了所有的 DDL 和 DML 语句,比如“给 ID=1 这一行的count 字段加 1 ”,因为它记录的是操作而不是数据值,属于逻辑日志)。binlog 可以用来做主从复制和数据恢复。

跟 redo log 不一样,它的文件内容是可以追加的,没有固定大小限制。

在开启了 binlog 功能的情况下,我们可以把 binlog 导出成 SQL 语句,把所有的操作重放一遍,来实现数据的(归档)恢复。

binlog 的另一个功能就是用来实现主从复制,它的原理就是从服务器读取主服务器的 binlog,然后执行一遍。

imagem.png

有了这两个日志之后,我们来看一下一条更新语句是怎么执行的(这里省略了undo):

例如一条语句:update teacher set name='张三' where id=1;

imagem.png 1、先从内存或者磁盘拿到这条数据。

2、把 name 改成张三,然后调用存储引擎的 API 接口,写入这一行数据到内存,同时记录 redo log。这时 redo log 进入 prepare 状态,然后告诉执行器,执行完成了,可以随时提交。

3、执行器收到通知后记录 binlog

4、然后调用存储引擎接口,设置 redo log 为 commit 状态。更新完成。

总结一下这张图片的重点:

1、先记录到内存(buffer pool),再写日志文件。

2、记录 redo log 分为两个阶段(preparecommit)。

3 存储引擎e, serverrespectivamente , gravam logs diferentes.

3. gravar redo, gravar binlog.

おすすめ

転載: juejin.im/post/7135578910741233701