Qualquer maneira de selecionar sem causar bloqueio no MySQL?

Inquerir:

SELECT COUNT(online.account_id) cnt from online; 

Mas a tabela on-line também é modificada por um evento, então, com frequência, posso ver o bloqueio executando show processlist .

Existe alguma gramática no MySQL que possa fazer com que a instrução select não cause bloqueios?

E eu esqueci de mencionar acima que está em um database escravo do MySQL.

Depois que eu adicionei no my.cnf:transaction-isolation = READ-UNCOMMITTED o escravo irá encontrar erro:

  Error 'Binary logging not possible. Message: Transaction level 'READ-UNCOMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'' on query 

Então, existe uma maneira compatível de fazer isso?

   

Encontrei um artigo intitulado “MYSQL WITH NOLOCK”

https://web.archive.org/web/20100814144042/http://sqldba.org/articles/22-mysql-with-nolock.aspx

no MSSQL você faria o seguinte:

 SELECT * FROM TABLE_NAME WITH (nolock) 

e o equivalente MYSQL é

 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; SELECT * FROM TABLE_NAME ; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ; 

EDITAR

Michael Mior sugeriu o seguinte (a partir dos comentários)

 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; SELECT * FROM TABLE_NAME ; COMMIT ; 

Se a tabela for InnoDB, consulte http://dev.mysql.com/doc/refman/5.1/en/innodb-consistent-read.html – ela usa o modo de leitura consistente (no-locking mode) para SELECTs ” não especificar FOR UPDATE ou LOCK IN SHARE MODE se a opção innodb_locks_unsafe_for_binlog estiver configurada e o nível de isolamento da transação não estiver configurado como SERIALIZABLE. Portanto, nenhum bloqueio será configurado nas linhas lidas da tabela selecionada “.

Usar

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

Os documentos da versão 5.0 estão aqui .

Versão 5.1 Docs estão aqui .

Você pode querer ler esta página do manual do MySQL. Como uma tabela é bloqueada depende do tipo de tabela.

O MyISAM usa bloqueios de tabela para alcançar uma velocidade de leitura muito alta, mas se você tiver uma instrução UPDATE esperando, os futuros SELECT farão fila atrás do UPDATE.

Tabelas InnoDB usam bloqueio em nível de linha, e você não terá a tabela inteira travada atrás de um UPDATE. Existem outros tipos de problemas de bloqueio associados ao InnoDB, mas você pode achar que ele atende às suas necessidades.

Dependendo do seu tipo de tabela, o bloqueio terá um desempenho diferente, mas também uma contagem SELECT. Para tabelas MyISAM, uma simples tabela SELECT count (*) FROM não deve bloquear a tabela, pois ela acessa metadados para obter a contagem de registros. O Innodb levará mais tempo, pois ele precisa pegar a tabela em um instantâneo para contar os registros, mas isso não deve causar bloqueio.

Você deve pelo menos ter o conjunto de concurrent_insert definido como 1 (padrão). Então, se não houver “lacunas” no arquivo de dados para a tabela preencher, inserções serão anexadas ao arquivo e SELECT e INSERTs podem acontecer simultaneamente com as tabelas MyISAM. Observe que a exclusão de um registro coloca um “intervalo” no arquivo de dados que tentará ser preenchido com inserções e atualizações futuras.

Se você raramente excluir registros, poderá definir o conjunto simultâneo igual a 2, e os inserts serão sempre adicionados ao final do arquivo de dados. Em seguida, as seleções e inserções podem ocorrer simultaneamente, mas seu arquivo de dados nunca ficará menor, independentemente de quantos registros você excluir (exceto todos os registros).

A linha inferior, se você tiver muitas atualizações, inserções e seleções em uma tabela, você deve torná-lo InnoDB. Você pode misturar livremente tipos de tabelas em um sistema.

SELECTs normalmente não fazem nenhum bloqueio que você se preocupa nas tabelas InnoDB. O nível de isolamento de transação padrão significa que as seleções não bloqueiam o material.

Claro que a contenção ainda acontece.

A partir desta referência:

Se você adquirir um bloqueio de tabela explicitamente com LOCK TABLES, poderá solicitar um bloqueio READ LOCAL em vez de um bloqueio READ para permitir que outras sessões executem inserções simultâneas enquanto a tabela estiver bloqueada.

outra maneira de ativar a leitura suja no mysql é adicionar dica: LOCK IN SHARE MODE SELECT * FROM TABLE_NAME LOCK NO SHARE MODE;