Migra estrategias de clave primaria

En este documento, se describen estrategias para migrar claves primarias de las tablas de tu base de datos a Cloud Spanner a fin de evitar problemas de generación de hotspots. Un hotspot es una concentración de operaciones en un solo nodo, lo que reduce la capacidad de procesamiento de escritura a la capacidad del nodo, en lugar de beneficiarse del balanceo de cargas de todas las escrituras entre los nodos de Spanner. El uso de columnas que aumentan o disminuyen monótonamente como la primera parte de la clave primaria (por ejemplo, secuencias regulares o marcas de tiempo) es la causa más común de los puntos problemáticos.

Estrategias generales

En Spanner, cada tabla que debe almacenar más de una fila debe tener una clave primaria compuesta por una o más columnas. La clave primaria de la tabla identifica de manera única cada fila de una tabla, y Spanner usa la clave primaria para ordenar las filas de la tabla. Debido a que Spanner está altamente distribuido, puedes usar las siguientes técnicas para generar valores de clave primaria únicos y reducir el riesgo de tener puntos problemáticos:

  • Usa una función de clave generada automáticamente y a prueba de hotspots compatible con Spanner (más detalles se describen en la sección Migra claves generadas de forma automática):
    • Usa la función GENERATE_UUID() (GoogleSQL, PostgreSQL) para generar valores de identificador único universal (UUID versión 4) con el tipo de datos STRING(36). RFC 4122 define el formato de la versión 4 del UUID.
    • Usar una secuencia positiva invertida de bits (GoogleSQL, PostgreSQL) Esta secuencia genera valores positivos con bits de orden superior ya invertidos, de modo que se distribuyen de manera uniforme en el espacio positivo de los números de 64 bits.
  • Cambia el orden de las claves para que la columna que contiene el valor monótonamente creciente o decreciente no sea la primera parte de la clave.
  • Genera un hash de la clave única y distribuye las escrituras entre fragmentos lógicos; para ello, crea una columna que contenga el hash de la clave única y, luego, usa la columna de hash (o la columna de hash más la columna de la clave única) como clave primaria. Este enfoque ayuda a evitar los puntos problemáticos porque las filas nuevas se distribuyen de manera más uniforme en el espacio de claves.

Una vez que designes tu clave primaria para la tabla, no podrás cambiarla sin borrar y volver a crear la tabla. Para obtener más información sobre cómo designar la clave primaria, consulta Esquema y modelo de datos: Claves primarias.

A continuación, se incluye un ejemplo de instrucción DDL que crea una tabla para una base de datos de pistas de música:

GoogleSQL

CREATE TABLE Singers (
  SingerId   INT64 NOT NULL,
  FirstName  STRING(1024),
  LastName   STRING(1024),
  SingerInfo BYTES(MAX),
  BirthDate  DATE,
) PRIMARY KEY(SingerId);

PostgreSQL

CREATE TABLE Singers (
  SingerId   bigint NOT NULL,
  FirstName  varchar(1024),
  LastName   varchar(1024),
  SingerInfo bytea,
  BirthDate  date,
  PRIMARY KEY(SingerId)
);

Migra claves generadas automáticamente

En esta sección, se describen las estrategias y los ejemplos para las siguientes situaciones en las que la tabla de origen ya usa una función de clave generada de forma automática:

  • Migra desde una tabla de origen que usa una clave primaria de UUID.
  • Migra desde una tabla de origen que usa una clave de número entero secuencial generada de forma automática. Los ejemplos incluyen, entre otros, secuencias (compatibles con varias bases de datos), columnas IDENTITY (que admiten varias bases de datos), tipos de datos SERIAL de PostgreSQL y el atributo de columna AUTO_INCREMENT de MySQL.
  • Migra desde una tabla de origen que usa una clave invertida de bits. Quizás la base de datos de origen sea Cloud Spanner, en la que creas valores clave mediante la guía revertir los bits de los valores secuenciales.

Es importante tener en cuenta que, en todas las estrategias, Spanner no modifica los datos que migra desde una base de datos de origen. Solo estás cambiando el método para generar datos nuevos.

Migra las columnas de claves de UUID

Si tu tabla de origen usa una columna de UUID, puedes convertir la columna al tipo STRING, escribir los valores en minúsculas según la especificación RFC 4122 y usar la función GENERATE_UUID() (GoogleSQL, PostgreSQL) como el valor predeterminado de la columna. Por ejemplo:

GoogleSQL


CREATE TABLE UserAccessLog (
UserId     STRING(36) DEFAULT (GENERATE_UUID()),
...
) PRIMARY KEY (UserId);

PostgreSQL


CREATE TABLE UserAccessLog (
UserId     varchar(36) DEFAULT SPANNER.GENERATE_UUID(),
...
PRIMARY KEY (UserId)
);

Migra las columnas de claves secuenciales

Si el sistema de base de datos de origen genera valores secuenciales para una columna de clave, puedes usar una secuencia positiva invertida de bits (GoogleSQL, PostgreSQL) en tu esquema de Cloud Spanner a fin de generar valores que se distribuyan de manera uniforme en el espacio de números enteros positivos de 64 bits. Para evitar que la secuencia de Cloud Spanner genere un valor que se superponga con un valor migrado, puedes definir un rango omitido para ella. Por ejemplo, puedes omitir el rango de 1 a 4,294,967,296 (2^32 TODO: format) para las siguientes dos secuencias, si sabes que la base de datos de origen solo genera números enteros de 32 bits:

GoogleSQL


CREATE SEQUENCE MyFirstSequence OPTIONS (
  sequence_kind = "bit_reversed_positive",
  skip_range_min = 1,
  skip_range_max = 4294967296
);

ALTER SEQUENCE MySecondSequence SET OPTIONS (
  skip_range_min = 1,
  skip_range_max = 4294967296
);

PostgreSQL


CREATE SEQUENCE MyFirstSequence BIT_REVERSED_POSITIVE
  SKIP RANGE 1 4294967296;

ALTER SEQUENCE MySecondSequence SKIP RANGE 1 4294967296;

Migra las columnas de claves con inversión de bits

Si ya invertiste bits de tus valores clave para evitar problemas de hotspots en tu base de datos de origen, también puedes usar una secuencia positiva invertida de bits de Cloud Spanner (GoogleSQL, PostgreSQL) para seguir generando esos valores. A fin de evitar generar valores duplicados, puedes configurar la secuencia para iniciar su contador desde un número personalizado.

Por ejemplo, si invertiste los números del 1 al 1,000 para generar valores de clave primaria, la secuencia de Cloud Spanner puede iniciar su contador desde cualquier número superior a 10,000. De manera opcional, puedes elegir un número alto para dejar un búfer para las nuevas operaciones de escritura que se produzcan en la base de datos de origen después de la migración de datos. En el siguiente ejemplo, los contadores comienzan en 11,000:

GoogleSQL


CREATE SEQUENCE MyFirstSequence OPTIONS (
  sequence_kind = "bit_reversed_positive",
  start_with_counter = 11000
);

ALTER SEQUENCE MySecondSequence SET OPTIONS (
  start_with_counter = 11000
);

PostgreSQL


CREATE SEQUENCE MyFirstSequence BIT_REVERSED_POSITIVE
  START COUNTER 11000;

ALTER SEQUENCE MySecondSequence RESTART COUNTER 11000;