Níveis de isolamento (WriteSerializable e Serializable)
Delta Lake no Databricks suporta dois níveis de isolamento que controlam como as operações concorrentes em uma determinada tabela interagem:
isolationLevel | Descrição |
|---|---|
Serializável | O nível de isolamento mais alto. Garante que as operações de escrita confirmadas e todas as leituras sejam serializáveis. As operações são permitidas desde que haja uma sequência serial que, quando executada uma de cada vez, gere o mesmo resultado apresentado na tabela. Para operações de escrita, essa sequência serial é a mesma que a ordem vista no histórico da tabela. |
WriteSerializable (padrão) | Um nível de isolamento mais fraco do que o Serializable. Garante que apenas as operações de escrita (e não as de leitura) sejam serializáveis. Isso ainda é mais robusto do que o isolamento do Snapshot . Proporciona um bom equilíbrio entre consistência e disponibilidade de dados para a maioria das operações comuns. |
Quando alterar o nível de isolamento
Mantenha o nível de isolamento WriteSerializable default para a maioria das cargas de trabalho.
Com WriteSerializable, um DELETE, UPDATE ou MERGE que começa antes de uma inserção concorrente ainda pode fazer commit depois dela. As linhas da inserção não são afetadas, mesmo que correspondam à condição da operação. A história da tabela ainda lista a inserção primeiro, portanto, o conteúdo da tabela não corresponde ao resultado da reprodução do commit na ordem da história. Consulte Exemplo: Exclusão e inserção concorrentes.
Altere uma tabela para Serializável se sua carga de trabalho não puder aceitar esse resultado. Por exemplo, se um DELETE deve remover cada linha correspondente que existe quando ele faz o commit, ou se os processos downstream reconstroem o conteúdo da tabela a partir da ordem do commit na história. Com Serializable, a operação posterior falha com um conflito e você deve tentar novamente.
Serializável reduz o throughput para gravações concorrentes. As adições que não leem a tabela nunca entram em conflito em WriteSerializable, mas podem entrar em conflito em Serializable. Veja Simultaneidade em nível de linha.
Como os níveis de isolamento afetam as leituras
As operações de leitura sempre utilizam o isolamento de Snapshot. O nível de isolamento de escrita determina se um leitor pode ver um instantâneo de uma tabela que, segundo a história, "nunca existiu".
- Serializável : O leitor sempre vê apenas as tabelas que se conformam à narrativa.
- WriteSerializable : Um leitor pode ver um estado de tabela que não existe no log Delta.
Exemplo: excluir e inserir concorrente
Considere um cenário onde uma transação de exclusão de longa duração e uma transação de inserção começam ao mesmo tempo e leem a versão v0. A transação de inserção é confirmada primeiro e cria a versão v1. Depois disso, a transação de exclusão tenta commit v2:
t0: deleteTxn_START
t1: insertTxn_START
t2: insertTxn_COMMIT(v1)
t3: deleteTxn_COMMIT(v2)
Neste cenário, deleteTxn não viu os dados inseridos por insertTxn e não os apagou:
- Serializable :
deleteTxnnão tem permissão para commit e ocorre um conflito. - WriteSerializable :
deleteTxntem permissão para commit porque as transações podem ser ordenadas. O estado da tabela resultante é como seinsertTxntivesse ocorrido depois dedeleteTxn, portanto, as linhas inseridas fazem parte da tabela. No entanto, o histórico Delta mostra a ordem física commit (insertTxnem v1 antesdeleteTxnem v2).
Defina o nível de isolamento
Para definir o nível de isolamento, use o comando ALTER TABLE:
ALTER TABLE <table-name> SET TBLPROPERTIES ('delta.isolationLevel' = <level-name>)
Onde <level-name> é Serializable ou WriteSerializable.
Exemplo:
-- Change from default WriteSerializable to Serializable
ALTER TABLE my_table SET TBLPROPERTIES ('delta.isolationLevel' = 'Serializable')
Quando é que Delta Lake commit sem consultar a tabela?
As operações INSERT ou anexação do Delta Lake não leem o estado da tabela antes de fazer o commit se estas condições forem atendidas:
- A lógica é expressa usando lógica SQL
INSERTou modo de acréscimo. - A lógica não contém subconsultas ou condicionais que façam referência à tabela alvo das operações de gravação.
Assim como em outros commits, Delta Lake usa metadados log de transações para validar e resolver as versões das tabelas no momento commit, mas nenhuma versão da tabela é realmente lida.
Muitos padrões comuns usam operações MERGE para inserir dados com base nas condições da tabela. Embora possa ser possível reescrever essa lógica usando instruções INSERT , se alguma expressão condicional fizer referência a uma coluna na tabela de destino, essas instruções terão as mesmas limitações de concorrência que MERGE.