Mecanismo de bloqueio MySQL (bloqueio de tabela e bloqueio de linha)
Definição de fechadura
Um bloqueio é um mecanismo para um computador coordenar vários processos ou threads para acessar simultaneamente um determinado recurso.
- No banco de dados, além da contenção por recursos de computação tradicionais (como CPU, RAM, I / O, etc.), os dados também são um recurso compartilhado. Como garantir a consistência e eficácia do acesso simultâneo aos dados é uma obrigação para todos os bancos de dados.
- O conflito de bloqueios é um fator importante que afeta o desempenho do acesso simultâneo ao banco de dados. Nessa perspectiva, os bloqueios são particularmente importantes para o banco de dados e também são mais complicados.
Classificação de fechaduras
A partir do tipo de operação dos dados é dividido em: um bloqueio de leitura (bloqueio compartilhado) e um bloqueio de gravação (bloqueio exclusivo)
Bloqueio de leitura : para os mesmos dados, a operação de leitura dos dados pode ser realizada ao mesmo tempo sem ser afetada.
Bloqueio de gravação : antes que a operação de gravação seja concluída, outras operações de leitura e gravação serão bloqueadas.
Desde a operação é dividido em um tamanho de partícula de dados: um bloqueio de tabela e bloqueio de linha
Fechadura de mesa
Recursos de bloqueio de mesa
MylSAM引擎
O uso de bloqueios de tabela tem baixa sobrecarga, bloqueio rápido, sem deadlocks, alta força de bloqueio e a maior probabilidade de conflitos de bloqueio.- Concorrência mais baixa
- Não suporta transações
Dados de simulação
create table mylock (
id int not null primary key auto_increment,
name varchar(20) default ''
) engine myisam;
insert into mylock(name) values('a');
insert into mylock(name) values('b');
insert into mylock(name) values('c');
insert into mylock(name) values('d');
insert into mylock(name) values('e');
select * from mylock;
Ver o bloqueio do banco de dados
SHOW OPEN TABLES in hanyxx; --查看数据库hanyxx中的表是否加锁
LOCK TABLE book read , phone write -- book表加读锁,phone表加写锁
--全部解锁
UNLOCK TABLES;
Bloqueio de mesa (ler bloqueio)
O Host A adiciona um bloqueio de tabela (bloqueio de leitura) à tabela
- Tanto o host A quanto outros hosts podem ler as informações da tabela
- O Host A não pode ler as informações de outras tabelas, mas outros hosts podem ler as informações de outras tabelas na biblioteca
- O Host A não pode modificar a tabela bloqueada
- Outros hosts modificam a tabela e serão bloqueados até que o bloqueio da tabela (bloqueio de leitura) seja liberado
Bloqueio de tabela (bloqueio de gravação)
O Host A adiciona um bloqueio de tabela (bloqueio de gravação) à tabela
- O Host A pode ler as informações da tabela, mas quando outros hosts as lerem, ele entrará em um estado de bloqueio até que o bloqueio da tabela (bloqueio de gravação) seja liberado
- O Host A não pode ler as informações de outras tabelas, mas outros hosts não podem ler as informações desta tabela, mas podem ler as informações de outras tabelas
- O Host A pode modificar a tabela
- Outros hosts não podem modificar a tabela e serão bloqueados até que o bloqueio da tabela (bloqueio de gravação) seja liberado
Resumindo
O bloqueio de leitura não bloqueia leituras, apenas gravações. Mas o bloqueio de gravação bloqueará a leitura e a gravação.
Análise de bloqueio de mesa
Trava de linha (ênfase)
Características de bloqueio de linha
- Sobrecarga alta, algemas lentas, bloqueios
- A menor granularidade de bloqueio, a menor probabilidade de conflitos de bloqueio e o mais alto grau de simultaneidade
A maior diferença entre InnoDB e MyISAM
- Assuntos de suporte
- Usar bloqueio de linha
Problemas causados por transações simultâneas
- Leitura suja
- Não repetível
- Leitura fantasma
Nível de isolamento de transação
- Ver o nível de isolamento do banco de dados
show variables like 'tx_isolation'; -- MySQL 5.7之前的版本
show variables like 'transaction_isolation'; -- MySQL 5.7之后的版本
Nível de isolamento padrão do banco de dados MySQL:REPEATABLE-READ
Dados de simulação
-- 创建表
CREATE TABLE test_innodb_lock (a INT(11),b VARCHAR(16))ENGINE=INNODB;
-- 插入数据
INSERT INTO test_innodb_lock VALUES(1,'b2');
INSERT INTO test_innodb_lock VALUES(3,'3');
INSERT INTO test_innodb_lock VALUES(4, '4000');
INSERT INTO test_innodb_lock VALUES(5,'5000');
INSERT INTO test_innodb_lock VALUES(6, '6000');
INSERT INTO test_innodb_lock VALUES(7,'7000');
INSERT INTO test_innodb_lock VALUES(8, '8000');
INSERT INTO test_innodb_lock VALUES(9,'9000');
INSERT INTO test_innodb_lock VALUES(1,'b1');
-- 创建索引
CREATE INDEX test_innodb_a_ind ON test_innodb_lock(a);
CREATE INDEX test_innodb_lock_b_ind ON test_innodb_lock(b);
-- InnnDB事务自动提交,如果需要演示行锁,需要关闭自动提交
SET autocommit=0;
Demonstração básica de bloqueio de linha
Conclusão da demonstração de bloqueio de linha
Se dois clientes modificarem o mesmo registro
- Depois que o cliente A é modificado, ele não é enviado (não confirmado). Neste momento, a modificação do cliente B será bloqueada
- Depois que o cliente A for modificado e enviado, o cliente B irá modificá-lo novamente, ele não será bloqueado
- Se dois clientes modificarem linhas de registro diferentes, respectivamente, eles não serão bloqueados
Falha de índice
O índice é inválido, o bloqueio de linha se torna o bloqueio de tabela (use o tipo varchar sem aspas simples para tornar o índice inválido)
Quando o índice é inválido, mesmo se vários clientes não estiverem operando no mesmo registro, se não for enviado, outros clientes entrarão no estado de bloqueio
Então, para evitar falha de índice
Por que o bloqueio de linha inválido do índice altera o bloqueio da tabela
- Os bloqueios de nível de linha do InnoDB são implementados bloqueando os itens do índice no índice. Os bloqueios de nível de linha do InnoDB usam bloqueios de nível de linha apenas quando os dados são recuperados por meio de condições de índice.
- Caso contrário, o InnoDB usa bloqueios de tabela ao consultar sem condições de índice (chave primária), o InnoDB usa bloqueios de tabela em vez de bloqueios de linha.
Gap lock
O que é um gap lock
Demonstração de Gap Lock
Os perigos dos bloqueios de lacunas
Pergunta da entrevista: como bloquear uma linha
Análise de bloqueio de linha
InnoDB_row_lock
- Analise a competição de bloqueio de linha verificando a variável de estado InnoDB_row_lock
show STATUS like 'innodb_row_lock%'; -- 查看InnoDB_row_lock状态变量
Descrição do campo
Campo | Descrição |
---|---|
Innodb_row_lock_current_waits | O número de bloqueios atualmente esperando |
Innodb_row_lock_time (importante) |
Há quanto tempo o sistema está bloqueado desde o início do sistema |
Innodb_row_lock_time_avg (importante) |
Tempo médio por bloqueio |
Innodb_row_lock_time_max | O maior tempo de bloqueio |
Innodb_row_lock_waits (importante) |
Desde que o sistema foi iniciado, quantas vezes ele foi bloqueado? |
Sugestão de otimização
- Tente fazer a recuperação de dados completa por meio de índices, evite nenhum índice e atualize bloqueios de linha para bloqueios de tabela
- Projete o índice de maneira razoável e reduza o escopo do bloqueio
- Reduza as condições de recuperação tanto quanto possível para evitar bloqueios de lacunas
- Controle o tamanho da transação tanto quanto possível, reduza a quantidade de recursos bloqueados e o tempo
- Use um nível de isolamento de transação de baixo nível, tanto quanto possível
Resumindo
Bloqueio de página (suplemento):
- A sobrecarga e o tempo de bloqueio estão entre os bloqueios da tabela e os bloqueios de linha, e ocorrerão conflitos
- A granularidade do bloqueio ocorre entre os bloqueios de tabela e de linha, com simultaneidade geral