

# Detectar e corrigir violações de chave de índice no DynamoDB
<a name="GSI.OnlineOps.ViolationDetection"></a>

Durante a fase de preenchimento em segundo plano da criação de um índice secundário global, o Amazon DynamoDB examina cada item na tabela para determinar se ele está qualificado para inclusão no índice. Alguns itens podem não ser qualificados, pois causariam violações de chave de índice. Nesses casos, os itens permanecerão na tabela, mas o índice não terá uma entrada correspondente para eles.

Uma *infração na chave do índice* ocorre nas seguintes situações:
+ Há uma inconsistência de tipo de dados entre um valor de atributo e o tipo de dados do esquema de chaves de índice. Por exemplo, suponha que um dos itens na tabela `GameScores` tivesse um valor `TopScore` do tipo `String`. Se você adicionasse um `TopScore` com uma chave de partição de do tipo `Number`, o item da tabela violaria a chave de índice.
+ Um valor de atributo da tabela excede o comprimento máximo para um atributo de chave de índice. O comprimento máximo de uma chave de partição é 2048 bytes, enquanto o comprimento máximo de uma chave de classificação é 1024 bytes. Se qualquer um dos valores de atributo correspondente na tabela exceder esses limites, o item da tabela violará a chave de índice.

**nota**  
Se um valor de atributo binário ou de string for definido para um atributo usado como uma chave de índice, o valor do atributo deverá ter um tamanho maior que zero. Caso contrário, o item da tabela violaria a chave de índice.  
Esta ferramenta não sinaliza esta infração na chave do índice neste momento.

Se uma infração na chave do índice ocorrer, a fase de preenchimento em segundo plano continuará sem interrupção. No entanto, os itens infratores não são incluídos no índice. Concluída a fase de aterramento, todas as gravações em itens que violam o esquema de chaves do novo índice serão rejeitadas.

Para identificar e corrigir os valores de atributos em uma tabela que violam uma chave de índice, use a ferramenta Violation Detector. Para executar o Violation Detector, crie um arquivo de configuração que especifique o nome de uma tabela a ser verificada, os nomes e os tipos de dados da chave de partição do índice secundário global e a chave de classificação, bem como quais ações deverão ser realizadas se violações de chave de índice forem encontradas. O Violation Detector pode ser executado em um destes dois diferentes modos:
+ **Modo de detecção**: detecta violações de chave de índice. Use o modo de detecção para informar os itens na tabela que causariam violações de chaves em um índice secundário global. (Você tem a opção de solicitar que esses itens de tabela infratores sejam excluídos imediatamente quando forem encontrados.) A saída do modo de detecção é gravada em um arquivo, que você pode usar para análise posterior.
+ **Modo de correção**: corrige violações de chaves de índice. No modo de correção, o Violation Detector lê um arquivo de entrada com o mesmo formato que o arquivo de saída do modo de detecção. O modo de correção lê os registros do arquivo de entrada e, para cada registro, ele exclui ou atualiza os itens correspondentes na tabela. (Observe que, se você optar por atualizar os itens, deverá editar o arquivo de entrada e definir os valores apropriados para essas atualizações.)

## Baixar e executar o Violation Detector
<a name="GSI.OnlineOps.ViolationDetection.Running"></a>

O Violation Detector está disponível como um arquivo Java executável (arquivo `.jar`) e pode ser executado em computadores Windows, Mac ou Linux. O Violation Detector requer o Java 1.7 (ou posterior) e o Apache Maven.
+ [Baixar o Violation Detector do GitHub](https://github.com/awslabs/dynamodb-online-index-violation-detector)

Siga as instruções no arquivo `README.md` para fazer download e instalar o Violation Detector usando o Maven.

Para iniciar o Violation Detector, acesse o diretório no qual você compilou o arquivo `ViolationDetector.java` e insira o seguinte comando:

```
java -jar ViolationDetector.jar [options]
```

A linha de comando do Violation Detector aceita as seguintes opções:
+ `-h | --help`: imprime um resumo de uso e opções do Violation Detector.
+ `-p | --configFilePath` `value`: o nome totalmente qualificado de um arquivo de configuração do Violation Detector. Para obter mais informações, consulte [O arquivo de configuração do Violation Detector](#GSI.OnlineOps.ViolationDetection.ConfigFile).
+ `-t | --detect` `value`: detecta violações de chave de índice na tabela e as grava no arquivo de saída do Violation Detector. Se o valor desse parâmetro for definido como `keep`, os itens com violações de chave não serão modificados. Se o valor for definido como `delete`, os itens com violações de chave serão excluídos da tabela.
+ `-c | --correct` `value`: lê violações de chave de índice de um arquivo de entrada e toma ações corretivas nos itens da tabela. Se o valor desse parâmetro for definido como `update`, os itens com violações de chave serão atualizados com valores novos não infratores. Se o valor for definido como `delete`, os itens com violações de chave serão excluídos da tabela.

## O arquivo de configuração do Violation Detector
<a name="GSI.OnlineOps.ViolationDetection.ConfigFile"></a>

Em tempo de execução, a ferramenta Violation Detector requer um arquivo de configuração Os parâmetros nesse arquivo determinam quais recursos do DynamoDB o Violation Detector pode acessar e quanto throughput provisionado ele pode consumir. A tabela a seguir descreve esses parâmetros.


****  

| Nome do parâmetro | Descrição | Obrigatório? | 
| --- | --- | --- | 
| `awsCredentialsFile` | O nome totalmente qualificado de um arquivo que contém suas credenciais da AWS. O arquivo de credenciais deve estar no seguinte formato:<pre>accessKey = {{access_key_id_goes_here}}<br />secretKey = {{secret_key_goes_here}} </pre> | Sim | 
| `dynamoDBRegion` | A região da AWS na qual a tabela reside. Por exemplo: `us-west-2`. | Sim | 
| `tableName` | O nome da tabela do DynamoDB a ser verificada. | Sim | 
| `gsiHashKeyName` | O nome da chave de partição do índice. | Sim | 
| `gsiHashKeyType` | O tipo de dados da chave de partição do índice: `String`, `Number` ou `Binary`<br />`S \| N \| B` | Sim | 
| `gsiRangeKeyName` | O nome da chave de classificação do índice. Não especifique esse parâmetro se o índice tiver apenas uma chave primária simples (chave de partição). | Não | 
| `gsiRangeKeyType` | O tipo de dados da chave de classificação do índice: `String`, `Number` ou `Binary`<br />`S \| N \| B`<br /> Não especifique esse parâmetro se o índice tiver apenas uma chave primária simples (chave de partição). | Não | 
| `recordDetails` | Se você deseja gravar os detalhes completos das violações de chaves de índice no arquivo de saída. Se a opção for definida como `true` (o padrão), todas as informações sobre os itens infratores serão relatadas. Se definido como `false`, apenas o número de violações será relatado. | Não | 
| `recordGsiValueInViolationRecord` | Se você deseja gravar os valores das chaves de índice infratoras no arquivo de saída. Se a opção for definida como `true` (padrão), os valores das chaves serão relatados. Se definido como `false`, os valores das chave não serão relatados. | Não | 
| `detectionOutputPath` | O caminho completo do arquivo de saída do Violation Detector. Esse parâmetro oferece suporte à gravação em um diretório local ou no Amazon Simple Storage Service (Amazon S3). Veja os exemplos a seguir:<br />`detectionOutputPath = ``//{{local/path/filename.csv}}`<br />`detectionOutputPath = ``s3://{{bucket}}/{{filename.csv}}`<br />As informações no arquivo de saída são mostradas no formato CSV (valores separados por vírgula). Se você não definir `detectionOutputPath`, o arquivo de saída se chamará `violation_detection.csv` e será gravado no seu diretório de trabalho atual. | Não | 
| `numOfSegments` | O número de segmentos de verificação paralela a serem usados quando o Violation Detector verificar a tabela. O valor padrão é 1, o que significa que a tabela é verificada de maneira sequencial. Se o valor for 2 ou superior, o Violation Detector dividirá a tabela no número correspondente de segmentos lógicos e em um número igual de threads de verificação. <br />A configuração máxima para `numOfSegments` é 4096.<br />Para tabelas maiores, uma verificação paralela é geralmente mais rápida do que uma verificação sequencial. Além disso, se a tabela for grande o suficiente para abranger várias partições, uma verificação paralela distribui sua atividade de leitura uniformemente entre essas várias partições.Para obter mais informações sobre verificações paralelas no DynamoDB, consulte [Verificar em paralelo](Scan.md#Scan.ParallelScan). | Não | 
| `numOfViolations` | O limite superior de violações de chaves de índice a serem gravadas no arquivo de saída. Se definido como `-1` (o padrão), a tabela inteira é verificada. Se definido como um número inteiro positivo, o Violation Detector será interrompido quando encontrar esse número de violações. | Não | 
| `numOfRecords` | O número de itens na tabela a ser verificada. Se definido como -1 (o padrão), a tabela inteira é verificada. Se definido como um número inteiro positivo, o Violation Detector será interrompido após verificar o mesmo número de itens na tabela. | Não | 
| `readWriteIOPSPercent` | Regula a porcentagem de unidades de capacidade de leitura provisionada que são consumidas durante a verificação de tabela. Os valores válidos variam de `1` até `100`. O valor padrão (`25`) significa que o Violation Detector não consumirá mais de 25% do throughput provisionado da tabela. | Não | 
| `correctionInputPath` | O caminho completo do arquivo de entrada de correção do Violation Detector. Se você executar o Violation Detector no modo de correção, o conteúdo desse arquivo será usado para modificar ou excluir os itens de dados na tabela que violam o índice secundário global.<br />O formato do arquivo `correctionInputPath` é o mesmo que o do arquivo `detectionOutputPath`. Isso permite que você processe a saída do modo de detecção como uma entrada no modo de correção. | Não | 
| `correctionOutputPath` | O caminho completo do arquivo de saída de correção do Violation Detector. Esse arquivo será criado somente se houver erros de atualização.<br />Esse parâmetro oferece suporte à gravação em um diretório local ou no Amazon S3. Veja os exemplos a seguir:<br />`correctionOutputPath = ``//{{local/path/filename.csv}}`<br />`correctionOutputPath = ``s3://{{bucket}}/{{filename.csv}}`<br />As informações no arquivo de saída são mostradas no formato CSV. Se você não definir `correctionOutputPath`, o arquivo de saída se chamará `violation_update_errors.csv` e será gravado no seu diretório de trabalho atual. | Não | 

## Detecção
<a name="GSI.OnlineOps.ViolationDetection.Detection"></a>

Para detectar violações de chave de índice, use o Violation Detector com a opção de linha de comando `--detect`. Para mostrar como essa opção funciona, considere a tabela `ProductCatalog`. Veja a seguir uma lista de itens na tabela. Apenas a chave primária (`Id`) e o atributo `Price` são mostrados.


****  

| ID (chave primária) | Preço | 
| --- | --- | 
| 101 |  5  | 
| 102 |  20  | 
| 103 | 200  | 
| 201 |  100  | 
| 202 |  200  | 
| 203 |  300  | 
| 204 |  400  | 
| 205 |  500  | 

Todos os valores para `Price` são do tipo `Number`. No entanto, como o DynamoDB não tem esquema, é possível adicionar um item com um não numérico `Price`. Por exemplo, suponha que adicionemos outro item à tabela `ProductCatalog`:


****  

| ID (chave primária) | Preço | 
| --- | --- | 
| 999 | "Hello" | 

Agora, a tabela tem um total de nove itens.

Agora você adiciona um novo índice secundário global à tabela: `PriceIndex`. A chave primária desse índice é uma chave de partição, `Price`, do tipo `Number`. Depois que o índice tiver sido construído, ele conterá oito itens, mas a tabela `ProductCatalog` tem nove itens. O motivo dessa discrepância é que o valor `"Hello"` é do tipo `String`, mas `PriceIndex` tem uma chave primária do tipo `Number`. O valor de `String` viola a chave do índice secundário global e, por isso, não está presente no índice.

Para usar o Violation Detector nesse cenário, você primeiro deve criar um arquivo de configuração como este.

```
# Properties file for violation detection tool configuration.
# Parameters that are not specified will use default values.

awsCredentialsFile = /home/alice/credentials.txt
dynamoDBRegion = us-west-2
tableName = ProductCatalog
gsiHashKeyName = Price
gsiHashKeyType = N
recordDetails = true
recordGsiValueInViolationRecord = true
detectionOutputPath = ./gsi_violation_check.csv
correctionInputPath = ./gsi_violation_check.csv
numOfSegments = 1
readWriteIOPSPercent = 40
```

Em seguida, execute o Violation Detector como no exemplo a seguir.

```
$  java -jar ViolationDetector.jar --configFilePath config.txt --detect keep

Violation detection started: sequential scan, Table name: ProductCatalog, GSI name: PriceIndex
Progress: Items scanned in total: 9,    Items scanned by this thread: 9,    Violations found by this thread: 1, Violations deleted by this thread: 0
Violation detection finished: Records scanned: 9, Violations found: 1, Violations deleted: 0, see results at: ./gsi_violation_check.csv
```

Se o parâmetro de configuração `recordDetails` for definido como `true`, o Violation Detector gravará os detalhes de cada infração no arquivo de saída, como no exemplo a seguir.

```
Table Hash Key,GSI Hash Key Value,GSI Hash Key Violation Type,GSI Hash Key Violation Description,GSI Hash Key Update Value(FOR USER),Delete Blank Attributes When Updating?(Y/N) 

999,"{""S"":""Hello""}",Type Violation,Expected: N Found: S,,
```

O arquivo de saída está no formato CSV. A primeira linha do arquivo é um cabeçalho, seguida de um registro por item que viola a chave de índice. Os campos desses registros infratores são os seguintes:
+ **Table Hash Key** (Chave de hash da tabela): o valor da chave de partição do item na tabela.
+ **Table Range Key** (Chave de classificação da tabela): o valor da chave de classificação do item na tabela.
+ **GSI Hash Key Value** (Valor da chave de hash do GSI): o valor da chave de partição do índice secundário global.
+ **GSI Hash Key Violation Type** (Tipo de violação da chave de hash do GSI): `Type Violation` ou `Size Violation`.
+ **GSI Hash Key Violation Description** (Descrição da violação da chave de hash do GSI): a causa da infração.
+ **GSI Hash Key Update Value(FORUSER)** (Valor da atualização da chave de hash do GSI [PARA USUÁRIO]): no modo de correção, um novo valor fornecido pelo usuário para o atributo.
+ **GSI Hash Key Value** (Valor da chave de hash do GSI): o valor da chave de classificação do índice secundário global.
+ **GSI Range Key Violation Type** (Tipo de violação da chave de intervalo do GSI: `Type Violation` ou `Size Violation`.
+ **GSI Range Key Violation Description** (Descrição da violação da chave de intervalo do GSI): a causa da infração.
+ **GSI Range Key Update Value(FOR USER)** (Valor da atualização da chave de intervalo do GSI [PARA USUÁRIO]: no modo de correção, um novo valor fornecido pelo usuário para o atributo.
+ **Delete Blank Attribute When Updating(Y/N)** (Excluir atributo em branco ao atualizar[S/N]): no modo de correção, determina se o item infrator deve ser excluído (Y) ou mantido (N) na tabela, mas apenas se algum dos seguintes campos estiver em branco:
  + `GSI Hash Key Update Value(FOR USER)`
  + `GSI Range Key Update Value(FOR USER)`

  Se qualquer um desses campos não estiver em branco, `Delete Blank Attribute When Updating(Y/N)` não terá efeito.

**nota**  
O formato de saída pode variar dependendo do arquivo de configuração e das opções da linha de comando. Por exemplo, se a tabela tiver uma chave primária simples (sem uma chave de classificação), nenhum campo de chave de classificação estará presente na saída.  
Os registros de infração no arquivo podem não estar na ordem classificada.

## Correção
<a name="GSI.OnlineOps.ViolationDetection.Correction"></a>

Para corrigir violações de chave de índice, use o Violation Detector com a opção de linha de comando `--correct`. No modo de correção, o Violation Detector lê o arquivo de entrada especificado pelo parâmetro `correctionInputPath`. Esse arquivo tem o mesmo formato que o arquivo `detectionOutputPath` e, portanto, você pode usar a saída da detecção como a entrada para a correção.

O Violation Detector fornece duas maneiras diferentes para corrigir violações de chave de índice:
+ **Excluir violações**: exclua os itens da tabela que possuem valores de atributo infratores.
+ **Atualizar violações**: atualize os itens da tabela substituindo os atributos infratores por valores não infratores.

Em ambos os casos, você pode usar o arquivo de saída do modo de detecção como uma entrada para o modo de correção.

Continuando com o exemplo de `ProductCatalog`, suponha que queiramos excluir o item infrator da tabela. Para fazer isso, use a seguinte linha de comando:

```
$  java -jar ViolationDetector.jar --configFilePath config.txt --correct delete
```

Neste ponto, você será solicitado a confirmar se deseja excluir os itens infratores.

```
Are you sure to delete all violations on the table?y/n
y
Confirmed, will delete violations on the table...
Violation correction from file started: Reading records from file: ./gsi_violation_check.csv, will delete these records from table.
Violation correction from file finished: Violations delete: 1, Violations Update: 0
```

Agora, tanto `ProductCatalog` quanto `PriceIndex` têm o mesmo número de itens.