Este documento descreve estratégias para migrar chaves primárias do seu banco de dados no Spanner para evitar problemas de ponto de acesso. Um ponto de acesso é concentração de operações em um único nó, o que diminui a capacidade de gravação à capacidade do nó, em vez de aproveitar o balanceamento de carga de todas as gravações entre os nós do Spanner. O uso de aumento ou colunas decrescentes como a primeira parte da chave primária (exemplos incluem sequências regulares ou carimbos de data/hora) é a causa mais comum de pontos de acesso.
Estratégias gerais
No Spanner, cada tabela que precisa armazenar mais de uma linha precisa ter uma chave primária que consiste em uma ou mais colunas da tabela. da sua tabela; a chave primária identifica exclusivamente cada linha em uma tabela, e o Spanner usa a chave primária para classificar as linhas da tabela. Como o Spanner é são altamente distribuídas, é possível usar as técnicas a seguir para gerar chaves-valor primárias e reduzir o risco de pontos de acesso:
- Usar um recurso de chave gerado automaticamente à prova de ponto de acesso que o Spanner
têm suporte. Confira mais detalhes na seção Migrar
chaves):
- Use a função
GENERATE_UUID()
(GoogleSQL, PostgreSQL) para gerar valores de identificador universalmente exclusivo (UUID versão 4) com o tipo de dadosSTRING(36)
. RFC 4122 (em inglês) define o formato UUID versão 4. - Use uma sequência positiva bit inversa (GoogleSQL, PostgreSQL). Essa sequência gera valores positivos com bits de ordem superior já para que sejam distribuídos uniformemente pelo espaço numérico.
- Use a função
- Trocar a ordem das chaves para que a coluna que contém os valores crescentes ou decrescentes monotonicamente não é a primeira parte da chave.
- Gere um hash da chave exclusiva e espalhe as gravações em fragmentos lógicos criando uma coluna que contenha o hash da chave exclusiva e em seguida, usando a coluna hash (ou a coluna hash e as colunas de chave única juntas) como a chave primária. Essa abordagem ajuda a evitar a ocorrência de pontos de acesso porque novas linhas são distribuídas de maneira mais uniforme pelo keyspace.
Depois de designar a chave primária para a tabela, não será possível alterá-la posteriormente sem excluir e recriar a tabela. Para mais informações sobre como designar sua chave primária, consulte Esquema e modelo de dados – chaves primárias.
Confira a seguir um exemplo de instrução DDL que cria uma tabela para um banco de dados de músicas faixas:
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) );
Migrar chaves geradas automaticamente
Esta seção descreve estratégias e exemplos para os seguintes cenários em que a tabela de origem já usa um recurso de chave gerado automaticamente:
- Migrar de uma tabela de origem que usa uma chave primária UUID.
- Como migrar de uma tabela de origem que usa um número inteiro sequencial gerado automaticamente
de dados. Os exemplos incluem, sem limitação, sequências (que várias
bancos de dados compatíveis), colunas
IDENTITY
(compatíveis com vários bancos de dados), Tipos de dadosSERIAL
do PostgreSQL e a colunaAUTO_INCREMENT
do MySQL . - Migração de uma tabela de origem que usa uma chave bit inversa. Talvez a fonte banco de dados é o Spanner, em que você cria chaves-valor usando o guia faça reversão em bits dos valores sequenciais.
É importante observar que, em todas as estratégias, o Spanner e alterar os dados migrados de um banco de dados de origem. Você só está mudando o método para gerar novos dados.
Migrar colunas de chave UUID
Se a tabela de origem usa uma coluna UUID, você pode converter a coluna em
STRING, insira os valores em minúsculas conforme
especificação RFC 4122 e use a
A função GENERATE_UUID()
(GoogleSQL,
PostgreSQL) como o valor padrão da coluna. Exemplo:
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) );
Migrar colunas de chave sequenciais
Se o sistema de banco de dados de origem gerar valores sequenciais para uma coluna de chave, é possível usar uma sequência positiva bit inversa (GoogleSQL, PostgreSQL) no esquema do Spanner para gerar valores distribuídos de maneira uniforme o espaço do número inteiro positivo de 64 bits. Para evitar que o Spanner para gerar um valor que se sobrepõe a um valor migrado, será possível definir um intervalo ignorado. Por exemplo, é possível ignorar varia de 1 a 4.294.967.296 (2^32) para as duas se souber que o banco de dados de origem só gera números inteiros 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;
Migrar colunas de chave com reversão de bit
Se você já tiver revertido seus valores de chave para evitar problemas de ponto de acesso banco de dados de origem, também é possível usar um valor positivo de bit invertido (GoogleSQL, PostgreSQL) para continuar gerando esses valores. Para evitar a geração de valores duplicados, pode configurar a sequência para iniciar seu contador a partir de um número personalizado.
Por exemplo, se você inverteu os números de 1 a 1.000 para gerar uma chave primária valores, a sequência do Spanner pode iniciar o contador de qualquer número maior que 10.000. É possível escolher um número alto deixam um buffer para novas gravações que ocorrem no banco de dados de origem após os dados migração. No exemplo a seguir, os contadores começam em 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;