por que o blktrace só grava blocos de 8?

4

Eu quero entender o padrão de E / S que um banco de dados está gravando no disco para decidir quantos discos usar para um melhor desempenho. Para analisar o padrão de I / O, eu quero usar o blktrace e eu tenho que grok primeiro. É isso que eu tento aqui.

Eu tenho um pendrive que eu conecto ao meu computador e ele se torna / dev / sdd. Agora eu começo

dd if=/dev/sdd of=/dev/null

e em uma janela separada eu começo

blktrace -d /dev/sdd -o - | blkparse -i -

e espera ver operações de leitura (R) que são mescladas (M) e colocadas na fila (Q). Isso funciona, mas, no meu entender, o tamanho do bloco é sempre 8:

8,48   6    15257     2.157995037  2470  M   R 816696 + 8 [dd]
8,48   6    15258     2.157996273  2470  Q   R 816704 + 8 [dd]
8,48   6    15259     2.157996520  2470  M   R 816704 + 8 [dd]
8,48   6    15260     2.157997794  2470  Q   R 816712 + 8 [dd]

Agora estou parando tudo e digo ao sistema para ler apenas um byte:

dd if=/dev/sdd of=/dev/null count=1 bs=1
1+0 records in
1+0 records out
1 byte (1 B) copied, 0.00325544 s, 0.3 kB/s

Isso aparece no console do blkparse assim:

8,48   6        1    17.220316681  2543  G   N [dd]
8,48   6        2    17.220317209  2543  I   N 0 (00 ..) [dd]
8,48   6        3    17.220317707  2543  D   N 0 (00 ..) [dd]
8,48   6        4    17.220787473  2543  Q   R 0 + 8 [dd]
8,48   6        5    17.220790545  2543  G   R 0 + 8 [dd]
8,48   6        6    17.220791330  2543  P   N [dd]
8,48   6        7    17.220793515  2543  Q   R 8 + 8 [dd]
8,48   6        8    17.220794597  2543  M   R 8 + 8 [dd]
8,48   6        9    17.220796134  2543  Q   R 16 + 8 [dd]
8,48   6       10    17.220796419  2543  M   R 16 + 8 [dd]
8,48   6       11    17.220797695  2543  Q   R 24 + 8 [dd]
8,48   6       12    17.220797943  2543  M   R 24 + 8 [dd]
8,48   6       13    17.220798862  2543  I   R 0 + 32 [dd]

o que está acontecendo aqui? Por que uma leitura de um byte é exibida como três solicitações "R", cada uma com uma ação Q e M? Por que "parece" ler 32 ou 24 bytes? Onde está a documentação para me educar ainda mais?

    
por Thorsten Staerk 17.12.2013 / 20:11

2 respostas

2

Porque você está fazendo IO em buffer e o cache de páginas funciona em páginas inteiras, que são 4k em PCs ou 8 setores de 512 bytes. O mecanismo readahead do kernel também lê um pouco mais na suposição de que o dd continuará lendo. Se você quiser evitar isso, então você precisa usar o IO direto passando dd a opção iflag = direct, mas você não poderá ler um byte fazendo isso - o IO direto deve estar alinhado com, e um mesmo múltiplo do tamanho do setor.

    
por 14.01.2014 / 17:33
0

No blktrace, a figura após + é o tamanho da requisição no tamanho do setor (que normalmente é de 512 bytes, você pode usar o comando blockdev --report para verificar)

Portanto, no seu rastreio, o total de leituras é de 16kbytes.

Então, por que há 4 'R' pedidos, a razão que eu posso pensar é ler em frente. Eu fiz um teste definindo read ahead para ser 512 bytes usando o seguinte comando:

blockdev --setra 1 /dev/sdd

Olhando para o read_ahead_kb mostra 0

more /sys/block/sdd/queue/read_ahead_kb
0

E o rastreio que recebo da execução do seu comando dd é o seguinte:

8,48   0        1     0.000000000 14412  Q   R 0 + 8 [dd]
8,48   0        2     0.000002577 14412  G   R 0 + 8 [dd]
8,48   0        3     0.000004467 14412  P   N [dd]
8,48   0        4     0.000005627 14412  I   R 0 + 8 [dd]
8,48   0        5     0.000007362 14412  U   N [dd] 1
8,48   0        6     0.000008238 14412  D   R 0 + 8 [dd]
8,48   0        7     0.018772074     0  C   R 0 + 8 [0]
CPU0 (dd_bs1_c1):
Reads Queued:           1,        4KiB  Writes Queued:           0,        0KiB
Read Dispatches:        1,        4KiB  Write Dispatches:        0,        0KiB
Reads Requeued:         0               Writes Requeued:         0
Reads Completed:        1,        4KiB  Writes Completed:        0,        0KiB
Read Merges:            0,        0KiB  Write Merges:            0,        0KiB
Read depth:             1               Write depth:             0
IO unplugs:             1               Timer unplugs:           0

Então, por que ele lê 4kbytes em vez de 1 byte, eu acredito que isso é por causa do tamanho do bloco FS, que é de 4kBytes. Então é o mínimo que será lido.

    
por 14.01.2014 / 12:32