Como migrar do PostgreSQL para a Cloud Spanner

Nesta página, você encontra orientação sobre como migrar um banco de dados PostgreSQL para o Cloud Spanner. Nela, descrevemos vários aspectos de uma migração do PostgreSQL para o Cloud Spanner:

  • Como mapear um esquema do PostgreSQL para um esquema do Cloud Spanner
  • Como criar uma instância, um banco de dados e um esquema Cloud Spanner
  • Como refatorar o aplicativo para funcionar com o banco de dados Cloud Spanner
  • Como migrar os dados
  • Como verificar o novo sistema e movê-lo para o status de produção

Nesta página, também apresentamos alguns esquemas de exemplo usando tabelas do banco de dados PostgreSQL do MusicBrainz.

Como mapear o esquema do PostgreSQL para o Cloud Spanner

A primeira etapa para mover um banco de dados PostgreSQL para o Cloud Spanner é determinar quais alterações de esquema você precisa fazer. Use pg_dump para criar instruções DDL (Data Definition Language, na sigla em inglês) que definem os objetos no banco de dados PostgreSQL e, em seguida, modifique as instruções conforme descrito nas seções a seguir. Depois de atualizar as instruções DLL, use-as para criar o banco de dados em uma instância do Cloud Spanner.

Tipos de dados

Na tabela a seguir, descrevemos como os tipos de dados do PostgreSQL são mapeados para os tipos de dados do Cloud Spanner. Atualize os tipos de dados nas instruções DDL dos tipos de dados do PostgreSQL para os tipos de dados do Cloud Spanner.

PostgreSQL Cloud Spanner
Bigint

int8

INT64
Bigserial

serial8

INT64
bit [ (n) ] ARRAY<BOOL>
bit varying [ (n) ]

varbit [ (n) ]

ARRAY<BOOL>
Boolean

bool

BOOL
box ARRAY<FLOAT64>
bytea BYTES
character [ (n) ]

char [ (n) ]

STRING
character varying [ (n) ]

varchar [ (n) ]

STRING
cidr STRING, usando a notação padrão CIDR.
circle ARRAY<FLOAT64>
date DATE
double precision

float8

FLOAT64
inet STRING
Integer

int

int4

INT64
interval[ fields ] [ (p) ] INT64 se armazenar o valor em milissegundos, ou STRING se armazenar o valor em um formato de intervalo definido pelo aplicativo.
json STRING
jsonb BYTES
line ARRAY<FLOAT64>
lseg ARRAY<FLOAT64>
macaddr STRING, usando a notação de endereço MAC padrão.
money INT64 ou STRING para números de precisão arbitrária.
numeric [ (p, s) ]

decimal [ (p, s) ]

INT64 ou STRING para números de precisão arbitrária.
path ARRAY<FLOAT64>
pg_lsn Esse tipo de dados é específico do PostgreSQL, portanto, não há um equivalente do Cloud Spanner.
point ARRAY<FLOAT64>
polygon ARRAY<FLOAT64>
Real

float4

FLOAT64
Smallint

int2

INT64
Smallserial

serial2

INT64
Serial

serial4

INT64
text STRING
time [ (p) ] sem fuso horário STRING, usando a notação HH:MM:SS.sss.
time [ (p) ] com fuso horário

timetz

STRING, usando a notação HH:MM:SS.sss+ZZZZ.
timestamp [ (p) ] sem fuso horário      TIMESTAMP
timestamp [ (p) ] com fuso horário

timestamptz

STRING, usando um formato padrão, como ISO 8601. Como alternativa, é possível armazenar a hora em uma coluna TIMESTAMP e, em seguida, armazenar o fuso horário em uma coluna separada.
tsquery Não há equivalente. Em vez disso, defina um mecanismo de armazenamento no aplicativo.
tsvector Não há equivalente. Em vez disso, defina um mecanismo de armazenamento no aplicativo.
txid_snapshot Não há equivalente. Em vez disso, defina um mecanismo de armazenamento no aplicativo.
uuid STRING ou BYTES
xml STRING

Chaves primárias

Para tabelas no banco de dados Cloud Spanner que você anexa com frequência, evite usar chaves primárias que aumentem ou diminuam constantemente, porque essa abordagem cria pontos de acesso durante as gravações. Em vez disso, modifique as instruções CREATE TABLE DDL para que elas usem estratégias de chave primária compatíveis. A criação cuidadosa do esquema é importante, porque não é possível adicionar ou remover uma coluna de chave primária depois de criar uma tabela.

Durante a migração, talvez seja necessário manter algumas chaves inteiras atuais que aumentem constantemente. Se precisar manter esses tipos de chaves em uma tabela que é sempre atualizada com muitas operações nessas chaves, evite a criação de pontos de acesso prefixando a chave atual com um número pseudoaleatório. Essa técnica faz com que o Cloud Spanner redistribua as linhas. Consulte O que os DBAs precisam saber sobre o Cloud Spanner, parte 1: chaves e índices para mais informações sobre o uso dessa abordagem.

Chaves estrangeiras e integridade referencial

O Cloud Spanner não tem restrições ou acionadores de chave estrangeira. Se você confia nesses recursos, precisa mover essa funcionalidade para o aplicativo.

Quando há um relacionamento pai-filho entre tabelas e você quer que os registros nessas tabelas sejam co-localizados para acesso mais rápido, crie tabelas intercaladas. Ao usar uma tabela intercalada, é possível aplicar integridade referencial para excluir linhas da tabela filho quando a linha relacionada na tabela pai é excluída. Não será possível excluir a linha pai se houver linhas filho e se a cláusula ON DELETE NO ACTION for usada. Também não será possível adicionar uma linha filho se a linha pai não existir.

Para encontrar as chaves estrangeiras nas tabelas do PostgreSQL, consulte a visualização information_schema.table_constraints usando uma cláusula WHERE constraint_type = 'FOREIGN KEY'.

Atualize as instruções CREATE TABLE para que elas criem tabelas intercaladas conforme apropriado.

Índices

Os índices de árvore B do PostgreSQL são semelhantes aos índices secundários no Cloud Spanner. Em um banco de dados Cloud Spanner, você usa índices secundários para indexar colunas comumente pesquisadas para ter melhor desempenho e para substituir qualquer restrição exclusiva especificada nas tabelas. Por exemplo, se a DDL do PostgreSQL tiver esta instrução:

 CREATE TABLE customer (
    id CHAR (5) PRIMARY KEY,
    first_name VARCHAR (50),
    last_name VARCHAR (50),
    email VARCHAR (50) UNIQUE
 );

Você usará esta instrução na DDL do Cloud Spanner:

CREATE TABLE customer (
   id STRING(5),
   first_name STRING(50),
   last_name STRING(50),
   email STRING(50)
   ) PRIMARY KEY (id);

CREATE UNIQUE INDEX customer_emails ON customer(email);

É possível encontrar os índices para qualquer uma das tabelas do PostgreSQL executando o comando meta \di no psql.

Depois de determinar os índices necessários, adicione instruções CREATE INDEX para criá-los. Siga as orientações em Como criar índices.

O Cloud Spanner implementa índices como tabelas. Portanto, a indexação de colunas que crescem constantemente (como aquelas que contêm dados TIMESTAMP) pode criar um ponto de acesso. Consulte O que os DBAs precisam saber sobre o Cloud Spanner, parte 1: chaves e índices para mais informações sobre os métodos que evitam esses pontos de acesso.

Outros objetos de banco de dados

É preciso criar a funcionalidade dos seguintes objetos na lógica do aplicativo:

  • Visualizações
  • Acionadores
  • Procedimentos armazenados
  • Funções definidas pelo usuário (UDFs, na sigla em inglês)
  • Colunas que usam tipos de dados serial como geradores de sequência

Tenha as seguintes dicas em mente ao migrar essa funcionalidade para a lógica do aplicativo:

Como criar a instância do Cloud Spanner

Depois de atualizar as instruções DDL para atender aos requisitos de esquema do Cloud Spanner, use-as para criar o banco de dados no Cloud Spanner.

  1. Crie uma instância do Cloud Spanner. Siga as orientações em Instâncias para determinar a configuração regional correta e o número de nós para oferecer suporte às metas de desempenho.

  2. Crie o banco de dados usando o Console do Google Cloud Platform ou a ferramenta de linha de comando gcloud:

Console

  1. Acesse a página "Instâncias".
  2. Clique no nome da instância na qual você quer criar o banco de dados de exemplo para abrir a página Detalhes da instância.
  3. Clique em Criar banco de dados.
  4. Digite um nome para o banco de dados e clique em Continuar.
  5. Na seção Definir seu esquema de banco de dados, ative o controle Editar como texto.
  6. Copie e cole as instruções DDL no campo Instruções DDL.
  7. Clique em Criar.

gcloud

  1. Instale a ferramenta gcloud.
  2. Use o comando gcloud spanner databases create para criar o banco de dados:
    gcloud spanner databases create DATABASE_NAME --instance=INSTANCE_NAME
    --ddl='DDL1' --ddl='DDL2'
    
  • DATABASE_NAME é o nome do banco de dados.
  • INSTANCE_NAME é a instância do Cloud Spanner que você criou.
  • DDLn são as instruções DDL modificadas.

Depois de criar o banco de dados, siga as instruções em Como aplicar papéis do IAM para criar contas de usuário e conceder permissões à instância e ao banco de dados do Cloud Spanner.

Como refatorar os aplicativos e as camadas de acesso a dados

Além do código necessário para substituir os objetos de banco de dados anteriores, é preciso adicionar a lógica do aplicativo para processar a seguinte funcionalidade:

  • Geração de hash de chaves primárias para gravações, em tabelas com altas taxas de gravação para chaves sequenciais.
  • Validação de dados, para substituir restrições que você não pôde migrar do esquema do PostgreSQL.
  • Verificações de integridade referencial que ainda não são cobertas pela intercalação de tabelas ou lógica de aplicativo, incluindo a funcionalidade executada por acionadores no esquema do PostgreSQL.

Recomendamos usar o seguinte processo ao refatorar:

  1. Encontre todo o código do aplicativo que acessa o banco de dados e refatore-o em um único módulo ou biblioteca. Desse modo, você sabe exatamente que código acessa o banco de dados e, portanto, o código exato que precisa ser modificado.
  2. Escreva um código que realize leituras e gravações na instância do Cloud Spanner, oferecendo funcionalidade paralela ao código original que lê e grava no PostgreSQL. Durante as gravações, atualize a linha inteira, não apenas as colunas que foram alteradas, para garantir que os dados do Cloud Spanner sejam idênticos aos do PostgreSQL.
  3. Escreva um código que substitua a funcionalidade dos objetos e funções do banco de dados que não estão disponíveis no Cloud Spanner.

Como migrar dados

Depois de criar o banco de dados Cloud Spanner e refatorar o código do aplicativo, migre os dados para o Cloud Spanner.

  1. Use o comando COPY do PostgreSQL para descarregar os dados para arquivos .csv.
  2. Faça upload dos arquivos .csv para o Cloud Storage.

    1. Crie um intervalo do Cloud Storage.
    2. No console do Cloud Storage, clique no nome do intervalo para abrir o navegador dele.
    3. Clique em Enviar arquivos.
    4. Navegue até o diretório que contém os arquivos .csv e selecione-os.
    5. Clique em Abrir.
  3. Crie um aplicativo para importar dados para o Cloud Spanner. Este aplicativo pode usar o Cloud Dataflow ou as bibliotecas de cliente diretamente. Siga as orientações em Práticas recomendadas de carregamento de dados em massa para ter o melhor desempenho.

Teste

Teste todas as funções do aplicativo em relação à instância do Cloud Spanner para verificar se elas funcionam conforme o esperado. Execute cargas de trabalho no nível de produção para garantir que o desempenho atenda às suas necessidades. Atualize o número de nós conforme necessário para atender às suas metas de desempenho.

Como mover para o novo sistema

Depois de concluir o teste inicial do aplicativo, ative o novo sistema usando um dos seguintes processos. A migração off-line é o método mais simples. No entanto, essa abordagem torna o aplicativo indisponível por um período e não permite nenhum caminho de reversão se você encontrar problemas de dados posteriormente. Para executar uma migração off-line:

  1. Exclua todos os dados no banco de dados Cloud Spanner.
  2. Encerre o aplicativo que tem como destino o banco de dados PostgreSQL.
  3. Exporte todos os dados do banco de dados PostgreSQL e importe-os para o banco de dados Cloud Spanner, conforme descrito em Como migrar dados.
  4. Inicie o aplicativo que tem como destino o banco de dados Cloud Spanner.

    Fluxo de dados de migração off-line.

A migração em tempo real é possível e requer extensas alterações no aplicativo para oferecer suporte à migração.

Exemplos de migração de esquema

Estes exemplos mostram as instruções CREATE TABLE para várias tabelas no esquema do banco de dados PostgreSQL do MusicBrainz. Cada exemplo inclui o esquema do PostgreSQL e o esquema do Cloud Spanner.

tabela artist_credit

Versão do PostgreSQL:

CREATE TABLE artist_credit (
  id SERIAL,
  name VARCHAR NOT NULL,
  artist_count SMALLINT NOT NULL,
  ref_count INTEGER DEFAULT 0,
  created TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

Versão do Cloud Spanner:

CREATE TABLE artist_credit (
  hashed_id STRING(4),
  id INT64,
  name STRING(MAX) NOT NULL,
  artist_count INT64 NOT NULL,
  ref_count INT64,
  created TIMESTAMP OPTIONS (
     allow_commit_timestamp = true
  ),
) PRIMARY KEY(hashed_id, id);

tabela recording

Versão do PostgreSQL:

CREATE TABLE recording (
  id SERIAL,
  gid UUID NOT NULL,
  name VARCHAR NOT NULL,
  artist_credit INTEGER NOT NULL, -- references artist_credit.id
  length INTEGER CHECK (length IS NULL OR length > 0),
  comment VARCHAR(255) NOT NULL DEFAULT '',
  edits_pending INTEGER NOT NULL DEFAULT 0 CHECK (edits_pending >= 0),
  last_updated TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  video BOOLEAN NOT NULL DEFAULT FALSE
);

Versão do Cloud Spanner:

CREATE TABLE recording (
  hashed_id STRING(36),
  id INT64,
  gid STRING(36) NOT NULL,
  name STRING(MAX) NOT NULL,
  artist_credit_hid STRING(36) NOT NULL,
  artist_credit_id INT64 NOT NULL,
  length INT64,
  comment STRING(255) NOT NULL,
  edits_pending INT64 NOT NULL,
  last_updated TIMESTAMP OPTIONS (
     allow_commit_timestamp = true
  ),
  video BOOL NOT NULL,
) PRIMARY KEY(hashed_id, id);

tabela recording-alias

Versão do PostgreSQL:

CREATE TABLE recording_alias (
  id SERIAL, --PK
  recording INTEGER NOT NULL, -- references recording.id
  name VARCHAR NOT NULL,
  locale TEXT,
  edits_pending INTEGER NOT NULL DEFAULT 0 CHECK (edits_pending >=0),
  last_updated TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  type INTEGER, -- references recording_alias_type.id
  sort_name VARCHAR NOT NULL,
  begin_date_year SMALLINT,
  begin_date_month SMALLINT,
  begin_date_day SMALLINT,
  end_date_year SMALLINT,
  end_date_month SMALLINT,
  end_date_day SMALLINT,
  primary_for_locale BOOLEAN NOT NULL DEFAULT false,
  ended BOOLEAN NOT NULL DEFAULT FALSE
  -- CHECK constraint skipped for brevity
);

Versão do Cloud Spanner:

CREATE TABLE recording_alias (
  hashed_id STRING(36)  NOT NULL,
  id INT64  NOT NULL,
  alias_id INT64,
  name STRING(MAX)  NOT NULL,
  locale STRING(MAX),
  edits_pending INT64  NOT NULL,
  last_updated TIMESTAMP NOT NULL OPTIONS (
     allow_commit_timestamp = true
  ),
  type INT64,
  sort_name STRING(MAX)  NOT NULL,
  begin_date_year INT64,
  begin_date_month INT64,
  begin_date_day INT64,
  end_date_year INT64,
  end_date_month INT64,
  end_date_day INT64,
  primary_for_locale BOOL NOT NULL,
  ended BOOL NOT NULL,
) PRIMARY KEY(hashed_id, id, alias_id),
 INTERLEAVE IN PARENT recording ON DELETE NO ACTION;
Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação do Cloud Spanner