AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 9569
Accepted
Jacket
Jacket
Asked: 2011-12-22 13:57:03 +0800 CST2011-12-22 13:57:03 +0800 CST 2011-12-22 13:57:03 +0800 CST

Maneira mais rápida de verificar se a tabela InnoDB foi alterada

  • 772

Meu aplicativo é muito intensivo em banco de dados. Atualmente, estou executando o MySQL 5.5.19 e usando o MyISAM, mas estou migrando para o InnoDB. O único problema que resta é o desempenho da soma de verificação.

Meu aplicativo faz cerca de 500-1000 CHECKSUM TABLEinstruções por segundo em horários de pico, porque a GUI do cliente está pesquisando constantemente o banco de dados em busca de alterações (é um sistema de monitoramento, portanto deve ser muito responsivo e rápido).

Com o MyISAM, existem somas de verificação ao vivo que são pré-calculadas na modificação da tabela e são MUITO rápidas. No entanto, não existe tal coisa no InnoDB. Então, CHECKSUM TABLEé MUITO lento.

Eu esperava poder verificar o horário da última atualização da tabela, infelizmente, isso também não está disponível no InnoDB. Estou preso agora, porque os testes mostraram que o desempenho do aplicativo cai drasticamente.

Existem simplesmente muitas linhas de código que atualizam as tabelas, portanto, implementar a lógica no aplicativo para registrar as alterações da tabela está fora de questão.

Existe algum método rápido para detectar alterações nas tabelas do InnoDB?

mysql performance
  • 7 7 respostas
  • 63737 Views

7 respostas

  • Voted
  1. RolandoMySQLDBA
    2011-12-22T14:12:49+08:002011-12-22T14:12:49+08:00

    Para a tabela mydb.mytable, execute esta consulta:

    SELECT update_time
    FROM information_schema.tables
    WHERE table_schema='mydb'
    AND table_name='mytable';
    

    Se você quiser saber quais tabelas foram alteradas nos últimos 5 minutos, execute isto:

    SELECT table_schema,table_name,update_time
    FROM information_schema.tables
    WHERE update_time > (NOW() - INTERVAL 5 MINUTE);
    

    De uma chance !!!

    ATUALIZAÇÃO 2011-12-21 20:04 EDT

    Meu empregador (empresa de hospedagem DB/Wweb) tem um cliente com 112.000 tabelas InnoDB. É muito difícil ler INFORMATION_SCHEMA.TABLES durante os horários de pico. Tenho uma sugestão alternativa:

    Se você tiver o innodb_file_per_table habilitado e todas as tabelas do InnoDB estiverem armazenadas em .ibdarquivos, existe uma maneira de verificar a hora da última atualização (até o minuto).

    Para a tabela mydb.mytable, faça o seguinte no sistema operacional:

    $ cd /var/lib/mysql/mydb
    $ ls -l mytable.ibd | awk '{print $4,$5}'
    

    Este carimbo de data/hora é do sistema operacional. Você não pode errar neste.

    ATUALIZAÇÃO 2011-12-21 22:04 EDT [mysqld] innodb_max_dirty_pages_pct=0;

    Adicione isso ao my.cnf, reinicie o mysql e todas as tabelas do InnoDB experimentarão descargas rápidas do buffer pool.

    Para evitar reiniciar, basta executar

    mysql> SET GLOBAL innodb_max_dirty_pages_pct=0;
    

    ATUALIZAÇÃO 2013-06-27 07:15 EDT

    Quando se trata de recuperar a data e hora de um arquivo, ls tem a --time-styleopção:

    $ cd /var/lib/mysql/mydb
    $ ls -l --time-style="+%s" mytable.ibd | awk '{print $6}'
    

    Você pode comparar o carimbo de data/hora do arquivo com UNIX_TIMESTAMP(NOW()) .

    • 25
  2. Best Answer
    Jacket
    2012-01-03T23:56:02+08:002012-01-03T23:56:02+08:00

    Acho que encontrei a solução. Por algum tempo eu estava olhando para o Percona Server para substituir meus servidores MySQL, e agora acho que há uma boa razão para isso.

    O servidor Percona introduz muitas novas tabelas INFORMATION_SCHEMA como INNODB_TABLE_STATS, que não está disponível no servidor MySQL padrão. Quando você faz:

    SELECT rows, modified FROM information_schema.innodb_table_stats WHERE table_schema='db' AND table_name='table'
    

    Você obtém a contagem real de linhas e um contador. A documentação oficial diz o seguinte sobre este campo:

    Se o valor da coluna modificada exceder “rows / 16” ou 2000000000, o recálculo das estatísticas é feito quando innodb_stats_auto_update == 1. Podemos estimar a antiguidade das estatísticas por este valor.

    Portanto, esse contador é encapsulado de vez em quando, mas você pode fazer uma soma de verificação do número de linhas e do contador e, a cada modificação da tabela, você obtém uma soma de verificação exclusiva. Por exemplo:

    SELECT MD5(CONCAT(rows,'_',modified)) AS checksum FROM information_schema.innodb_table_stats WHERE table_schema='db' AND table_name='table';
    

    Eu ia atualizar meus servidores para o servidor Percona de qualquer maneira, então esse limite não é um problema para mim. Gerenciar centenas de gatilhos e adicionar campos a tabelas é um grande problema para esse aplicativo, porque está muito atrasado no desenvolvimento.

    Esta é a função PHP que criei para garantir que as tabelas possam ser somadas com qualquer mecanismo e servidor usado:

    function checksum_table($input_tables){
        if(!$input_tables) return false; // Sanity check
        $tables = (is_array($input_tables)) ? $input_tables : array($input_tables); // Make $tables always an array
        $where = "";
        $checksum = "";
        $found_tables = array();
        $tables_indexed = array();
        foreach($tables as $table_name){
            $tables_indexed[$table_name] = true; // Indexed array for faster searching
            if(strstr($table_name,".")){ // If we are passing db.table_name
                $table_name_split = explode(".",$table_name);
                $where .= "(table_schema='".$table_name_split[0]."' AND table_name='".$table_name_split[1]."') OR ";
            }else{
                $where .= "(table_schema=DATABASE() AND table_name='".$table_name."') OR ";
            }
        }
        if($where != ""){ // Sanity check
            $where = substr($where,0,-4); // Remove the last "OR"
            $get_chksum = mysql_query("SELECT table_schema, table_name, rows, modified FROM information_schema.innodb_table_stats WHERE ".$where);
            while($row = mysql_fetch_assoc($get_chksum)){
                if($tables_indexed[$row[table_name]]){ // Not entirely foolproof, but saves some queries like "SELECT DATABASE()" to find out the current database
                    $found_tables[$row[table_name]] = true;
                }elseif($tables_indexed[$row[table_schema].".".$row[table_name]]){
                    $found_tables[$row[table_schema].".".$row[table_name]] = true;
                }
                $checksum .= "_".$row[rows]."_".$row[modified]."_";
            }
        }
    
        foreach($tables as $table_name){
            if(!$found_tables[$table_name]){ // Table is not found in information_schema.innodb_table_stats (Probably not InnoDB table or not using Percona Server)
                $get_chksum = mysql_query("CHECKSUM TABLE ".$table_name); // Checksuming the old-fashioned way
                $chksum = mysql_fetch_assoc($get_chksum);
                $checksum .= "_".$chksum[Checksum]."_";
            }
        }
    
        $checksum = sprintf("%s",crc32($checksum)); // Using crc32 because it's faster than md5(). Must be returned as string to prevent PHPs signed integer problems.
    
        return $checksum;
    }
    

    Você pode usar assim:

    // checksum a signle table in the current db
    $checksum = checksum_table("test_table");
    
    // checksum a signle table in db other than the current
    $checksum = checksum_table("other_db.test_table");
    
    // checksum multiple tables at once. It's faster when using Percona server, because all tables are checksummed via one select.
    $checksum = checksum_table(array("test_table, "other_db.test_table")); 
    

    Espero que isso economize alguns problemas para outras pessoas com o mesmo problema.

    • 4
  3. Gamesh
    2013-09-25T22:02:05+08:002013-09-25T22:02:05+08:00

    Você deve atualizar para o Mysql v5.6+ nessa versão innodb também tem suporte para tabela de checksum. http://dev.mysql.com/doc/refman/5.6/en/checksum-table.html

    fora isso, a solução ideal seria se o seu cliente não estivesse pesquisando os resultados constantemente, mas você enviasse dados novos e alterados quando e se estivessem disponíveis. Seria mais rápido e menos carga estaria no servidor. se você estiver usando gui baseado na web, você deve procurar no APE http://ape-project.org/ ou outros projetos semelhantes.

    • 1
  4. sanmai
    2015-04-30T17:48:55+08:002015-04-30T17:48:55+08:00

    Se você estiver adicionando principalmente a uma tabela, você pode ligar AUTO_INCREMENT como uma medida de atualização.

    SELECT `AUTO_INCREMENT` FROM `information_schema`.`tables` 
    WHERE `table_schema` = DATABASE() AND `table_name` = 'YOUR_TABLE';
    

    Mas eu prefiro me referir a uma fonte externa como um contador no Memcached, que você incrementará toda vez que alterar algo no banco de dados.

    • 1
  5. Romuald Brunet
    2014-09-05T08:03:20+08:002014-09-05T08:03:20+08:00

    Você pode tentar fazer o seguinte:

    SELECT rows_changed
    FROM information_schema.table_statistics
    WHERE table_schema = 'mydb' AND table_name='mytable';
    

    Isso retorna um número que aumenta a cada atualização da tabela, acompanhar isso permitirá detectar a alteração.

    Nota importante: o valor é alterado imediatamente após um UPDATE, não após COMMIT. Portanto, você pode não ver as alterações se as modificações foram feitas dentro de outra transação que não foi concluída.

    • 0
  6. Steve Padgett
    2015-03-25T09:31:53+08:002015-03-25T09:31:53+08:00

    Esta resposta não tem nada a ver com versões ou tipos de banco de dados mysql, eu queria saber se as instruções de atualização estavam fazendo alterações E fazer isso no meu código php ..

    1. Criei uma tabela fictícia com um registro e um campo que eu consultaria para obter o valor do current_timestamp do mysql.

    2. Para a tabela de dados que está sendo atualizada, adicionei um campo timestamp e usei a opção mysql "ON UPDATE CURRENT_TIMESTAMP"

    3. Comparado #1 e #2

    Isso não funcionará 100% do tempo, mas para minha aplicação foi uma solução simples e ótima. Espero que isso ajude alguém

    • 0
  7. Marinos An
    2021-02-18T03:45:20+08:002021-02-18T03:45:20+08:00

    Caso você queira verificar se a viewmudou, você pode verificar a alteração mais recente entre as tabelas envolvidas na visualização:

    select max(t.update_time) last_involved_table_update 
    from view_table_usage vtu 
    join tables t on (t.table_name=vtu.table_name and t.table_schema=vtu.table_schema)  
    where vtu.view_name='name_of_view' and vtu.view_schema='schema_name_of_view';
    

    Observe que pode haver alguns falsos positivos, por exemplo, no caso de uma coluna de uma tabela (incluída na exibição) ter sido atualizada sem que a própria coluna faça parte da exibição. Nesse caso, a exibição será exibida como atualizada na consulta acima.

    • 0

relate perguntas

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

    • 2 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve