

# Detección y corrección de infracciones de la clave del índice en DynamoDB
<a name="GSI.OnlineOps.ViolationDetection"></a>

Durante la fase de reposición de la creación de un índice secundario global, Amazon DynamoDB examina cada elemento de la tabla para determinar si es apto para incluirlo en el índice. Algunos elementos podrían no ser aptos por la posibilidad de que causen infracciones de claves de índice. En estos casos, el elemento en cuestión permanecen en la tabla, pero el índice no incluye la entrada correspondiente a dicho elemento.

Un registro *infracción de clave de índice* se produce en las siguientes situaciones:
+ Los tipos de datos del valor de un atributo y del esquema de claves del índice no coinciden. Por ejemplo, supongamos que uno de los elementos de la tabla `GameScores` tiene un atributo `TopScore` cuyo valor es de tipo `String`. Si agrega un índice secundario global con una clave de partición de `TopScore` de tipo `Number`, el elemento de la tabla infringiría la clave de índice.
+ El valor de atributo de la tabla supera la longitud máxima de un atributo de clave del índice. La longitud máxima de una clave de partición es de 2048 bytes y la longitud máxima de una clave de ordenación es de 1024 bytes. Si cualquiera de los valores de atributos correspondientes de la tabla supera estos límites, el elemento de la tabla infringiría la clave de índice.

**nota**  
Si se establece un valor binario o de cadena en un atributo que se utiliza como clave de índice, este valor debe tener una longitud mayor que cero; de lo contrario, el elemento de la tabla podría infringir la clave del índice.  
En la actualidad, esta herramienta no indica esta infracción de clave de índice de ninguna forma.

Si se produce una infracción de índice, la fase de reposición continúa sin interrupción. Sin embargo, los elementos infractores no se incluyen en el índice. Una vez que haya finalizado la fase de reposición, se rechazarán todas las escrituras en elementos que infringen el esquema de claves del nuevo índice.

Para identificar y corregir los valores de los atributos de una tabla que infringen una clave de índice, se utiliza la herramienta Violation Detector. Para ejecutar Violation Detector, debe crear un archivo de configuración que especifique el nombre de la tabla que se va a examinar, los nombres y los tipos de datos de las claves de partición y de ordenación del índice secundario global y qué medidas deben adoptarse si se detecta cualquier infracción de clave de índice. Violation Detector puede ejecutarse en dos modos diferentes:
+ **Modo de detección**: detecta las infracciones de claves de índice. El modo de detección se utiliza para registrar los elementos de la tabla que causarían infracciones de claves en un índice secundario global. (Si lo desea, puede solicitar que estos elementos infractores de la tabla se eliminen de inmediato en cuanto se encuentren). El resultado del modo de detección se escribe en un archivo, que se puede utilizar para analizar los datos posteriormente.
+ **Modo de corrección**: corrige las infracciones de claves de índice. En el modo de corrección, Violation Detector lee un archivo de información de entrada con el mismo formato que el archivo de resultados del modo de detección. En el modo de corrección se leen los registros del archivo de información de entrada y, para cada registro, se elimina o actualiza el elemento correspondiente de la tabla. Tenga en cuenta que si decide actualizar los elementos, deberá editar el archivo de información de entrada y establecer valores adecuados para estas actualizaciones.

## Descargar y ejecutar Violation Detector
<a name="GSI.OnlineOps.ViolationDetection.Running"></a>

Violation Detector está disponible como archivo Java ejecutable (`.jar`) y se ejecuta en ordenadores Windows, Mac o Linux. Violation Detector requiere Java 1.7 (o posterior) y Apache Maven.
+ [Descargar Violation Detector de GitHub](https://github.com/awslabs/dynamodb-online-index-violation-detector)

Siga las instrucciones del archivo `README.md` para descargar e instalar Violation Detector mediante Maven.

Para iniciar Violation Detector, vaya al directorio donde ha construido `ViolationDetector.java` e ingrese el siguiente comando.

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

La línea de comandos de Violation Detector acepta las siguientes opciones:
+ `-h | --help`: imprime un resumen de uso y las opciones posibles de Violation Detector.
+ `-p | --configFilePath` `value`: nombre completo de un archivo de configuración de Violation Detector. Para obtener más información, consulte [El archivo de configuración de Violation Detector](#GSI.OnlineOps.ViolationDetection.ConfigFile).
+ `-t | --detect` `value`: detecta las infracciones de claves de índice de la tabla y las escribe en el archivo de resultados de Violation Detector. Si el valor de este parámetro se establece en `keep`, los elementos con infracciones de claves no se modifican. Si el valor se establece en `delete`, los elementos con infracciones de claves se eliminan de la tabla.
+ `-c | --correct` `value`: lee las infracciones de claves de índice en un archivo de información de entrada y adopta medidas para corregir los elementos de la tabla. Si el valor de este parámetro se establece en `update`, los elementos con infracciones de claves se actualizan a otros valores sin infracciones. Si el valor se establece en `delete`, los elementos con infracciones de claves se eliminan de la tabla.

## El archivo de configuración de Violation Detector
<a name="GSI.OnlineOps.ViolationDetection.ConfigFile"></a>

En tiempo de ejecución, la herramienta Violation Detector requiere un archivo de configuración. Los parámetros de este archivo determinan a qué recursos de DynamoDB puede obtener acceso Violation Detector y cuánto rendimiento aprovisionado puede consumir. En la siguiente tabla se describen estos parámetros.


****  

| Nombre del parámetro | Descripción | ¿Obligatorio? | 
| --- | --- | --- | 
|  `awsCredentialsFile`  |  Nombre completo de un archivo que contiene las credenciales de AWS. El archivo de credenciales debe tener el siguiente formato: <pre>accessKey = access_key_id_goes_here<br />secretKey = secret_key_goes_here </pre>  |  Sí  | 
|  `dynamoDBRegion`  |  Región de AWS en la que la reside la tabla. Por ejemplo: `us-west-2`.  |  Sí  | 
|  `tableName`  | Nombre de la tabla de DynamoDB que se va a examinar. |  Sí  | 
|  `gsiHashKeyName`  |  Nombre de la clave de partición del índice.  |  Sí  | 
|  `gsiHashKeyType`  |  Tipo de datos de la clave de partición del índice: `String`, `Number` o `Binary`: `S \| N \| B`  |  Sí  | 
|  `gsiRangeKeyName`  |  Nombre de la clave de ordenación del índice. No especifique este parámetro si el índice solo tiene una clave principal simple (clave de partición).  |  No  | 
|  `gsiRangeKeyType`  |  Tipo de datos de la clave de ordenación del índice: `String`, `Number` o `Binary`: `S \| N \| B`  No especifique este parámetro si el índice solo tiene una clave principal simple (clave de partición).  |  No  | 
|  `recordDetails`  |  Indica si se deben escribir todos los detalles de las infracciones de claves de índice en el archivo de resultados. Si se establece en `true` (valor predeterminado), se registra toda la información sobre los elementos infractores. Si se establece en `false`, solo se registra el número de infracciones.  |  No  | 
|  `recordGsiValueInViolationRecord`  |  Indica si se deben escribir los valores de las claves de índice infractoras en el archivo de resultados. Si se establece en `true` (predeterminado), se registran los valores de las claves. Si se establece en `false`, los valores de las claves no se registran.  |  No  | 
|  `detectionOutputPath`  |  Ruta completa del archivo de resultados de Violation Detector;. Este parámetro es compatible con la escritura en un directorio local o en Amazon Simple Storage Service (Amazon S3). A continuación se muestran algunos ejemplos: `detectionOutputPath = ``//local/path/filename.csv` `detectionOutputPath = ``s3://bucket/filename.csv` La información del archivo de resultados aparece en formato CSV (valores separados por comas). Si no se establece `detectionOutputPath`, el archivo de resultados se denomina `violation_detection.csv` y se escribe en el directorio de trabajo actual.  |  No  | 
|  `numOfSegments`  | El número de segmentos de examen en paralelo que se utilizarán cuando Violation Detector analice la tabla. El valor predeterminado es 1, lo que significa que la tabla se examina de forma secuencial. Si el valor es 2 o superior, entonces Violation Detector dividirá la tabla en esa cantidad de segmentos lógicos y un número igual de subprocesos de examen. El ajuste máximo de `numOfSegments` es 4096.En el caso de las tablas de mayor tamaño, un examen en paralelo suele resultar más rápido que un examen secuencial. Además, si la tabla es lo bastante grande para abarcar varias particiones, un examen en paralelo distribuye su actividad de lectura de manera uniforme entre varias particiones.Para obtener más información sobre los análisis en paralelo en DynamoDB, consulte [Análisis paralelo](Scan.md#Scan.ParallelScan). |  No  | 
|  `numOfViolations`  |  Límite superior de infracciones de claves de índice que se escribirán en el archivo de resultados. Si se establece en `-1` (valor predeterminado), se examina toda la tabla. Si se establece en un número entero positivo, entonces Violation Detector se detendrá después de haber detectado esa cantidad de infracciones.  |  No  | 
|  `numOfRecords`  |  Número de elementos de la tabla que se va a examinar. Si se establece en -1 (valor predeterminado), se examinará toda la tabla. Si se establece en un número entero positivo, entonces Violation Detector se detendrá después de haber examinado esa cantidad de elementos en la tabla.  |  No  | 
|  `readWriteIOPSPercent`  |  Regula el porcentaje de unidades de capacidad de lectura provisionadas que se consumen durante un examen de la tabla. Los valores válidos van de `1` a `100`. El valor predeterminado (`25`) significa que Violation Detector consumirá no más del 25 % del rendimiento de lectura aprovisionado de la tabla.  |  No  | 
|  `correctionInputPath`  |  Ruta completa del archivo de información de entrada de corrección de Violation Detector. Si ejecuta Violation Detector en modo de corrección, el contenido de este archivo se usa para modificar o eliminar los elementos de datos de la tabla que infringen el índice secundario global. El formato del archivo `correctionInputPath` es el mismo que el del archivo `detectionOutputPath`. Esto permite procesar el resultado del modo de detección como información de entrada en el modo de corrección.  |  No  | 
|  `correctionOutputPath`  |  Ruta completa del archivo de resultados de corrección de Violation Detector. Este archivo se crea solo si existen errores de actualización. Este parámetro es compatible con la escritura en un directorio local o en Amazon S3. A continuación se muestran algunos ejemplos: `correctionOutputPath = ``//local/path/filename.csv` `correctionOutputPath = ``s3://bucket/filename.csv` La información del archivo de resultados aparece en formato CSV. Si no se establece `correctionOutputPath`, el archivo de resultados se denomina `violation_update_errors.csv` y se escribe en el directorio de trabajo actual.  |  No  | 

## Detección
<a name="GSI.OnlineOps.ViolationDetection.Detection"></a>

Para detectar infracciones de claves de índice, use Violation Detector con la opción de línea de comandos `--detect`. Para ver cómo funciona esta opción, tomemos la tabla `ProductCatalog`. A continuación se muestra una lista de elementos de la tabla. Solo se muestran la clave principal (`Id`) y el atributo `Price`.


****  

| Id (clave principal) | Precio | 
| --- | --- | 
| 101 |  5  | 
| 102 |  20  | 
| 103 | 200  | 
| 201 |  100  | 
| 202 |  200  | 
| 203 |  300  | 
| 204 |  400  | 
| 205 |  500  | 

Todos los valores de `Price` son de tipo `Number`. No obstante, dado que en DynamoDB no se usan esquemas, es posible agregar un elemento con un valor de no numérico `Price`. Por ejemplo, supongamos que agrega otro elemento a la tabla `ProductCatalog`.


****  

| Id (clave principal) | Precio | 
| --- | --- | 
| 999 | "Hello" | 

Ahora, la tabla contiene un total de nueve elementos.

Ahora agrega un nuevo índice secundario global a la tabla: `PriceIndex`. La clave principal de este índice es una clave de partición, `Price`, que es de tipo `Number`. Después de crearlo, el índice contendrá ocho elementos. Sin embargo, la tabla `ProductCatalog` tiene nueve elementos. El motivo de esta discrepancia es que, aunque el valor `"Hello"` es de tipo `String`, la clave principal de `PriceIndex` es de tipo `Number`. El valor `String` infringe la clave del índice secundario global, por lo que no está presente en el índice.

Para usar Violation Detector en esta situación, primero se crea un archivo de configuración, como el siguiente.

```
# 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
```

A continuación, se ejecuta el Violation Detector como en el siguiente ejemplo.

```
$  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
```

Si el parámetro de configuración `recordDetails` se establece en `true`, entonces Violation Detector escribe los detalles de cada infracción en el archivo de resultados, como en el siguiente ejemplo.

```
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,,
```

El archivo de salida está en formato CSV. La primera línea del archivo es un encabezado, seguido de un registro por cada elemento que infringe la clave del índice. Los campos de estos registros de infracción son los siguientes:
+ **Table hash key**: valor de la clave de partición del elemento de la tabla.
+ **Table range key**: valor de la clave de clasificación del elemento de la tabla.
+ **GSI hash key value**: valor de la clave de partición del índice secundario global.
+ **GSI hash key violation type**: puede ser `Type Violation` o `Size Violation`.
+ **GSI hash key violation description**: causa de la infracción.
+ **GSI hash key update value (FOR USER)**: en el modo de corrección, nuevo valor suministrado por el usuario para el atributo.
+ **GSI range key values**: el valor de la clave de clasificación del índice secundario global.
+ **GSI range key violation type**: puede ser `Type Violation` o `Size Violation`.
+ **GSI range key violation description**: causa de la infracción.
+ **GSI range key update value (FOR USER)**: en el modo de corrección, nuevo valor suministrado por el usuario para el atributo.
+ **Delete blank attribute when updating (Y/N)**: en el modo de corrección, determina si el elemento infractor se eliminará (Y) o se conservará (N) en la tabla, pero solamente si cualquiera de los campos siguientes está en blanco:
  + `GSI Hash Key Update Value(FOR USER)`
  + `GSI Range Key Update Value(FOR USER)`

  Si alguno de estos campos no está en blanco, entonces `Delete Blank Attribute When Updating(Y/N)` no surte ningún efecto.

**nota**  
El formato de los resultados puede variar, en función del archivo de configuración y de las opciones de la línea de comandos. Por ejemplo, si la tabla tiene una clave principal simple (sin clave de ordenación), no habrá ningún campo de clave de ordenación en el resultado.  
Los registros de infracción del archivo podrían no estar ordenados.

## Corrección
<a name="GSI.OnlineOps.ViolationDetection.Correction"></a>

Para corregir infracciones de claves de índice, use Violation Detector con la opción de línea de comandos `--correct`. En el modo de corrección, Violation Detector lee el archivo de información de entrada especificado por el parámetro `correctionInputPath`. Este archivo tiene el mismo formato que el archivo `detectionOutputPath`, lo que permite utilizar el resultado de la detección como información de entrada para la corrección.

Violation Detector ofrece dos maneras distintas de corregir las infracciones de claves de índice:
+ **Eliminar las infracciones**: se eliminan los elementos de la tabla cuyos valores de atributos infringen alguna clave.
+ **Actualizar las infracciones**: se actualizan los elementos de la tabla, para lo cual se sustituyen los atributos infractores por otros que no causan ninguna infracción.

En ambos casos, puede utilizar el archivo de resultados del modo de detección como información de entrada para el modo de corrección.

Si continuamos con el ejemplo anterior de `ProductCatalog`, supongamos que desea eliminar el elemento infractor de la tabla. Para ello, utilizamos la línea de comandos siguiente.

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

En este momento, le pedirá que confirme si desea eliminar los elementos infractores.

```
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
```

Ahora, tanto `ProductCatalog` como `PriceIndex` tienen el mismo número de elementos.