MySQL table_cache e Opened_tables

14

Eu já vi pessoas usarem a comparação das tabelas Open_tables e Opened_tables para avaliar se o table_cache é muito pequeno no MySQL. No entanto, acredito que o Opened_tables é cumulativo durante o tempo de atividade, portanto, essa não é uma comparação válida. A única ressalva é que talvez o Opened_tables só tenha problemas - embora mesmo assim, se as tabelas que estão sendo abertas por segundo ainda sejam pequenas, provavelmente não será um problema para o crescimento gradual.

Se comparar Open_tables com Opened_tables não é válido, existe outra maneira de obter dados medidos para isso?

Isso está no MySQL 5.0, mas as diferenças entre as versões também são bem-vindas.

Sam Brightman
fonte
Eu gosto dessa pergunta porque é uma pergunta instigante. Isso recebe um +1 para lembrar os desenvolvedores do MySQL a aproveitar ao máximo as variáveis ​​de status para medir a integridade do servidor de banco de dados.
RolandoMySQLDBA

Respostas:

7

O maior motivo para ter um table_cache grande é para que o LOCK_open mutex não fique quente. O MySQL anterior à 5.5 tem muita contenção quando você está tentando abrir / fechar tabelas, então você deseja restringir isso o máximo possível, ou seja, possui um cache de tabela grande.

Portanto, você não se importa com nenhuma proporção específica de ocorrências / falhas (na verdade, você deve ignorar completamente as proporções - este post do blog explica o porquê ). O que importa é a taxa de erros , porque quanto mais vezes isso acontece por segundo, maior a chance de você ter contenção (um thread precisa aguardar que outro thread solte o bloqueio).

Como você identifica a taxa de erros? Você obtém algumas amostras de Opened_Tables com alguns segundos de diferença durante o período mais movimentado do dia e, se houver aumentos em cada amostra, provavelmente é uma boa ideia ver se você pode aumentar o table_cache.

Nota: Especificamente, não recomendo comparar com o tempo de atividade.

Morgan Tocker
fonte
5

Primeiro, vamos considerar essas variáveis ​​de status:

Abrir tabelas : o número de tabelas que estão abertas.

Opened_tables : o número de tabelas que foram abertas. Se Opened_tables for grande, seu valor table_open_cache provavelmente será muito pequeno.

Surpreendentemente, a resposta para sua pergunta está dentro da própria pergunta.

As duas variáveis ​​só fariam mais sentido se você lançar mais uma variável de status no mix: Uptime (ou Uptime_since_flush status para novas médias após FLUSH STATUS ).

Você deve comparar o Open_tables agsinst (Opened_tables / Uptime) . Se o Open_tables ultrapassar (Opened_tables / Uptime) , agora você tem motivos de preocupação e deve ficar de olho em coisas como as seguintes:

UPDATE 2011-08-31 12:18 EDT

Observe por que também sugeri o uso de Uptime_since_flush_status em vez do Uptime para obter um padrão fixo de crescimento Opened_tables por um determinado período.

Por exemplo, se você executar FLUSH STATUS;toda segunda-feira à meia-noite, poderá gerar um OpenTableFactor:

SELECT *, (Open_tables * Uptime / Opened_Tables) OpenTableFactor FROM
(SELECT variable_value Uptime FROM information_schema.global_status
WHERE variable_name = 'Uptime_since_flush_status') up,
(SELECT variable_value Open_tables FROM information_schema.global_status
WHERE variable_name = 'Open_tables') opn,
(SELECT IF(variable_value=0,1,variable_value) Opened_tables
FROM information_schema.global_status
WHERE variable_name = 'Opened_tables') opnd;

Esse fator de tabela aberta equivale ao número que representa o número de tabelas abertas em um determinado momento em relação ao número médio de tabelas abertas ao longo de um determinado período. Com uma FLUSH HOSTS;semana / dia / host, essa média é contra a semana / dia / hora.

Aqui está uma amostra de um dos clientes do meu empregador:

mysql> SELECT *, (Open_tables * Uptime / Opened_Tables) OpenTableFactor FROM     (SELECT variable_value Uptime FROM information_sc    hema.global_status     WHERE variable_name = 'Uptime_since_flush_status') up,     (SELECT variable_value Open_tables FROM informat    ion_schema.global_status     WHERE variable_name = 'Open_tables') opn,     (SELECT IF(variable_value=0,1,variable_value) Opened_ta    bles     FROM information_schema.global_status     WHERE variable_name = 'Opened_tables') opnd;
+----------+-------------+---------------+-------------------+
| Uptime   | Open_tables | Opened_tables | OpenTableFactor   |
+----------+-------------+---------------+-------------------+
| 14385123 | 16326       | 30429078      | 7717.996519579068 |
+----------+-------------+---------------+-------------------+
1 row in set (0.00 sec)

Esse cliente normalmente mantém cerca de 7745 OpenTableFactor no máximo. Se o OpenTableFactor cair repentinamente (mesmo que um pouco), isso poderá indicar padrões de tráfego mais baixos, altas condições abortadas e assim por diante. Se o OpenTableFactor nunca mudar (mesmo que seja um pouco), poderá oferecer uma oportunidade de alterar essas configurações:

Uma vez ajustado, o OpenTableFactor pode mudar constantemente ou atingir outro teto ou platô. Assim, o uso de unidades diferentes nas variáveis ​​de status torna-se vital para esse tipo de ajuste.

UPDATE 2011-08-31 12:42 EDT

A consulta SQL que eu executei para o OpenTableFactor não funciona para o MySQL 5.0 e vice-versa. Se você estiver usando o MySQL Administrator ou MONyog , poderá personalizar um gráfico usando a fórmula na consulta e no monitor. O MONyog coleta o histórico usando o SQLLite para gráficos históricos posteriores. Isso pode ser feito para qualquer versão do MySQL.

RolandoMySQLDBA
fonte
Algumas boas sugestões, mas não acho que você queira comparar duas coisas com unidades diferentes, assim como não deseja comparar um valor cumulativo com o atual. E a questão de se isso apenas mede erros permanece.
Sam Brightman
3

De um dos comentários do usuário na página de documentação table_cache :

Opened_tables é uma variável de status que mantém um registro constante do número de descritores de arquivos adicionais que foram alocados para abrir tabelas nos momentos em que os descritores de arquivos disponíveis em table_cache foram esgotados. ...

Significando que é incrementado quando você ultrapassa o seu table_cachevalor. Assim, a maneira que eu normalmente verificar isso é para comparar opened_tablescom uptime, mas a chave aqui é levá-la ao longo de um intervalo definido (uma vez por minuto durante 10 minutos, por exemplo). Se estiver aumentando, pode ser uma indicação de que você precisa aumentar sua table_cache.

Algumas advertências para mencionar:

  • Outro comentário na documentação acima: "A variável de status 'Opened_tables' também será incrementada em 2 toda vez que você criar uma tabela temporária." Portanto, se suas consultas exigirem muitas tabelas temporárias, isso pode ser a causa de um rápido aumento de opened_tables. Você pode ver o uso da tabela temporária usando a seguinte consulta:

    SHOW GLOBAL STATUS LIKE '%tmp%';

  • Não aumente o table_cache muito alta

    A razão para esse comportamento é que, se você tiver um número grande. de tabelas com consultas complicadas unindo várias tabelas e várias conexões executando essas consultas complicadas, você pode acabar usando o cache de todos os descritores de arquivos (table_cache). Nesse caso, o MySQL usa um algoritmo para encontrar o descritor menos usado recentemente, fecha-o e substitui com um novo descritor.

Derek Downey
fonte