← Professional Data Engineer: pipelines e decisões de dados
16 / 21 · 135 MIN

Operar retenção e conjuntos de recuperação

Relaciona retenção, versões e dependências com um conjunto recuperável; distingue metadata, estimativas e prova de recuperação do serviço.

1. Definir o estado que precisa de regressar

Num exemplo fictício APS, um erro altera movimentos usados no fecho e a equipa procura o backup mais recente. Contudo, o cálculo também depende de preços de referência e de regras de classificação. Recuperar apenas os movimentos pode produzir um resultado incoerente. Começa pelos ativos necessários ao serviço, pelas relações entre eles e pelo ponto de negócio a recuperar. Estes exemplos não representam procedimentos BNP Paribas. Distingue disponibilidade, retenção e recuperação. Uma réplica pode manter o serviço disponível e reproduzir uma alteração errada. Uma cópia pode existir e estar inacessível por falta de chave ou permissão. Um restauro pode terminar antes de o consumidor conseguir usar os dados. Define o RPO, relativo à perda de dados tolerada, e o RTO, relativo ao tempo de recuperação, com critérios observáveis de aceitação. Regista o instante do incidente, o intervalo em que a corrupção pode ter começado e a evidência que sustenta essa fronteira. Um timestamp escrito num inventário não prova consistência transacional. Precisas de relacionar o ponto escolhido com a execução da aplicação e com reconciliação. Quando houver incerteza, conserva-a na decisão e identifica a verificação que falta antes de usar a cópia.

2. Operar versões e backups Bigtable

A política de garbage collection identifica células elegíveis para remoção, mas a limpeza ocorre em segundo plano. Se o consumidor não deve ler versões expiradas, aplica filtros coerentes com a política. Não concluas que a configuração falhou apenas porque uma célula elegível ainda aparece. Para combinar critérios, lê a regra como uma condição de remoção: intersection exige todos; union exige pelo menos um. Por exemplo, para remover uma versão apenas quando tem mais de 30 dias e existe uma mais recente, combina idade e máximo de uma versão por interseção. Uma regra só de idade pode eliminar a única versão antiga; uma regra só de versões pode eliminar histórico recente. Prevê ambos os contraexemplos antes de alterar a política e considera os dados já existentes. Num restauro de backup, prepara a tabela nova e as respetivas políticas: garbage collection não é herdada. Confirma a versão CMEK associada ao backup, porque a rotação da chave não altera essa associação. A versão antiga precisa de estar ativada para decifrar. Em instâncias replicadas, a hora da cópia não prova inclusão de todas as escritas de outro cluster. Valida o ponto capturado e o comportamento dos consumidores depois da recuperação.

3. Recuperar o warehouse com o âmbito correto

Em BigQuery, uma tabela eliminada usa a janela de time travel em vigor no momento da eliminação. Aumentar depois a janela de dois para sete dias não prolonga retroativamente essa recuperação. Trata a configuração atual e o histórico de eliminação como evidências distintas. Fora de time travel, fail-safe não é uma extensão diretamente consultável por SQL; a recuperação de emergência requer Cloud Customer Care. Não prometas um prazo autónomo sem suporte para esse compromisso. Um snapshot também tem um âmbito concreto. Os dados no streaming buffer não estão incluídos. Confirma o conjunto capturado antes de eliminar ou alterar a origem. Time travel recupera dados, mas não restaura metadata da tabela; compara configuração e proteção separadamente. Um total monetário correto não comprova que a tabela recuperada está pronta para todos os consumidores. Ao reduzir a expiração de partições, considera as existentes: as que já ultrapassam a nova janela expiram imediatamente. Expiração e eliminação física assíncrona são coisas diferentes. Um consumidor mensal pode depender de partições ignoradas pelo benchmark diário. Antes da alteração, liga a poupança pretendida ao uso histórico, à aceitação dos responsáveis e ao caminho de recuperação efetivamente ensaiado.

4. Restaurar objetos sem repetir efeitos

Soft delete conserva recursos eliminados durante a janela aplicável, mas não os mantém como objetos live para leitura normal. Uma alteração de sete para 30 dias afeta eliminações posteriores à entrada em vigor; as versões já eliminadas mantêm a duração original. Não uses a política atual como prova de que qualquer objeto antigo continua recuperável. Identifica a versão e a sua condição concreta. A interface de restauro também importa. Restaurar um bucket pela CLI ou JSON API repõe o bucket vazio; os objetos precisam de recuperação separada. Restaurar um objeto cria uma nova versão live e pode acionar consumidores de OBJECT_FINALIZE. Um pipeline que envia notificações ou inicia processamento precisa de controlar esses efeitos. O mesmo nome não prova que a operação de negócio já foi reconhecida como repetida. Para operações concorrentes, usa precondições apropriadas. Se leste a geração G1 e outro escritor criou G2, uma eliminação apenas pelo nome pode atingir a versão errada. A precondição generation-match liga o pedido à versão observada. Trata a falha de precondição como informação nova para reavaliar a operação; repetir cegamente sem a condição retira a proteção que procuravas.

5. Executar a seleção local de cópias

O exercício Python abaixo recebe metadata fictícia; não lê backups nem executa restaurações. Todos os tempos são inteiros numa escala comum de minutos. O envelope define asOf, incidentAt, targetRpo, targetRto, validationMinutes, requiredAssets e copies. Existem uma a 20 identidades de ativos e uma a 100 cópias. Cada cópia tem id único, asset, checkpoint, expiresAt, restoreMinutes, readable e keyAvailable. O modelo exige checkpoint estritamente anterior ao incidente e idade incidentAt menos checkpoint dentro do RPO inclusivo. A origem deve expirar estritamente depois de asOf mais restoreMinutes. readable e keyAvailable aceitam true, false ou null; só true torna a dependência elegível. False e desconhecido aparecem como razões diferentes, sem serem convertidos em sucesso. O programa agrupa por checkpoint e exige todos os ativos nesse mesmo ponto declarado. Para cada ativo escolhe a cópia elegível mais rápida, usando id como desempate determinístico. Assume cópias paralelas sem contenção, seguidas de validação: duração total igual ao tempo já decorrido desde o incidente mais o máximo dos tempos de cópia mais validationMinutes. O alvo de RTO é inclusivo. Entre conjuntos que cumprem estas regras, seleciona o checkpoint mais recente. Estes limites são didáticos e não representam contratos dos serviços cloud.

6. Prever resultados e contrariar o modelo

Executa python3 content/labs/pde-restore-set/run.py < content/labs/pde-restore-set/case.json na raiz do projeto. No fixture, asOf=120 e incidentAt=100. Os ativos são ledger e prices. Há ledger95, mas não prices95. O par 90 inclui uma chave de prices desconhecida. O par80 tem evidência true, tempos de cópia 6 e 7, e validação 5. Com RPO30 e RTO35, o modelo seleciona L80 e P80 e estima 32 minutos desde o incidente, dos quais 12 ainda faltam. Altera a chave de P90 para true e confirma que o par 90 passa a ser escolhido, com estimativa total de 34 minutos. Depois reduz o RTO para 32: o conjunto 80 volta a ser a alternativa que cabe no modelo. Testa a fronteira de expiração: P80 com expiresAt=127 não passa, porque 120+7 coincide com a expiração; 128 passa. Compara esta fronteira estrita com a aceitação de RPO e RTO exatamente no limite. O checkpoint comum não prova consistência dos bytes. Os tempos são premissas fornecidas, sem medição de rede, contenção ou arranque. rtoProven, consistencyProven, cloudRestorePerformed e productionApproval permanecem falsos. Explica que ensaio e reconciliação seriam necessários para substituir cada incerteza por evidência. Não mudes uma flag para fabricar essa prova.

7. Interpretar qualidade e governação após recuperação

Uma plataforma recuperada precisa de mais do que tabelas legíveis. Confirma referências de catálogo, responsáveis, acesso dos consumidores e políticas que sustentam o uso. O guia de exame usa nomenclatura Dataplex; a documentação atual consultada apresenta auto data quality em Knowledge Catalog. Mantém essa correspondência explícita sem inventar uma nova versão do exame a partir de uma mudança de nome do produto. Um scan só avalia as regras e a população configuradas. Filtros incrementais e amostragem podem excluir o histórico restaurado. Um resultado verde sobre dados recentes não prova preservação de seis meses de reporting. Regista os filtros, a data da execução, as regras, os thresholds e a população efetivamente considerada. Essa descrição permite que o responsável pelo dado decida se a evidência é adequada ao consumo. Um threshold de 95% permite que uma regra passe com 970 de 1000 linhas válidas; continuam a existir 30 exceções. Não confundas passagem agregada com correção de todas as linhas. Investiga a relevância das exceções e confirma que nenhuma regra crítica foi omitida. Para relações entre ativos, acrescenta reconciliação de chaves, granularidade e valores, em vez de depender apenas do número de linhas.

8. Entregar um procedimento de recuperação verificável

Prepara um procedimento que outra equipa consiga executar e avaliar. Indica ativos, versões de cópias, ponto de recuperação, dependências de chave e acesso, destino isolado, critérios de reconciliação e decisão de retorno ao serviço. Separa o fim da cópia da aceitação funcional. Mede a duração de cada etapa no ensaio e identifica o que depende de autorização ou suporte externo. Inclui condições para parar: cópia expirada, chave desconhecida, checkpoint sem um ativo obrigatório, dados de referência incompatíveis ou consumidor mensal fora do âmbito dos testes. Uma cópia mais antiga pode ser utilizável dentro dos objetivos, mas essa decisão precisa de perda conhecida e aceitação. Uma cópia mais recente não compensa a ausência de um ativo essencial. Como exercício final, entrega uma nota para os dois conjuntos 80 e 90: explica a seleção inicial, a evidência que permitiria mudar de escolha e as verificações após restauro. Acrescenta uma alteração de retenção e avalia o impacto sobre consumidores e recuperação. O resumo é: identificar um conjunto completo, confirmar dependências, recuperar num âmbito controlado, reconciliar e obter aceitação do serviço. Relaciona estas etapas com ingestão, contratos e capacidade das aulas anteriores.

"""Original parallel-copy planning model; metadata is supplied, never measured."""
import json
import re
import sys


def identifier(value):
    return isinstance(value, str) and re.fullmatch(r'[A-Za-z0-9_-]{1,64}', value, re.ASCII) is not None


def integer(value):
    return type(value) is int and 0 <= value <= 10**9


def evaluate(data):
    keys = {'asOf', 'incidentAt', 'targetRpo', 'targetRto', 'validationMinutes', 'requiredAssets', 'copies'}
    if not isinstance(data, dict) or set(data) != keys:
        raise ValueError('invalid planning envelope')
    for key in keys - {'requiredAssets', 'copies'}:
        if not integer(data[key]):
            raise ValueError('invalid time or duration')
    if data['incidentAt'] > data['asOf']:
        raise ValueError('incident cannot be after assessment')
    assets = data['requiredAssets']
    if not isinstance(assets, list) or not 1 <= len(assets) <= 20 or not all(identifier(a) for a in assets) or len(set(assets)) != len(assets):
        raise ValueError('expected 1..20 unique assets')
    copies = data['copies']
    if not isinstance(copies, list) or not 1 <= len(copies) <= 100:
        raise ValueError('expected 1..100 copies')
    ids, assessed = set(), []
    copy_keys = {'id', 'asset', 'checkpoint', 'expiresAt', 'restoreMinutes', 'readable', 'keyAvailable'}
    for copy in copies:
        if not isinstance(copy, dict) or set(copy) != copy_keys:
            raise ValueError('invalid copy fields')
        if not identifier(copy['id']) or copy['id'] in ids or not identifier(copy['asset']) or copy['asset'] not in assets:
            raise ValueError('invalid copy identity or asset')
        ids.add(copy['id'])
        for key in ['checkpoint', 'expiresAt', 'restoreMinutes']:
            if not integer(copy[key]):
                raise ValueError('invalid copy time')
        if copy['checkpoint'] > data['asOf'] or copy['expiresAt'] < copy['checkpoint']:
            raise ValueError('invalid copy chronology')
        for key in ['readable', 'keyAvailable']:
            if copy[key] is not None and type(copy[key]) is not bool:
                raise ValueError('evidence must be true,false or null')
        reasons = []
        if copy['checkpoint'] >= data['incidentAt']:
            reasons.append('not-before-incident')
        if data['incidentAt'] - copy['checkpoint'] > data['targetRpo']:
            reasons.append('outside-rpo')
        if copy['expiresAt'] <= data['asOf'] + copy['restoreMinutes']:
            reasons.append('expires-before-copy-completes')
        for key in ['readable', 'keyAvailable']:
            if copy[key] is not True:
                reasons.append(key + ('-unknown' if copy[key] is None else '-false'))
        assessed.append({'id': copy['id'], 'asset': copy['asset'], 'checkpoint': copy['checkpoint'], 'eligible': not reasons, 'reasons': sorted(reasons)})
    assessment = {r['id']: r for r in assessed}
    plans = []
    for checkpoint in sorted({c['checkpoint'] for c in copies}, reverse=True):
        selected, missing = [], []
        for asset in sorted(assets):
            options = [c for c in copies if c['asset'] == asset and c['checkpoint'] == checkpoint and assessment[c['id']]['eligible']]
            options.sort(key=lambda c: (c['restoreMinutes'], c['id']))
            if options:
                selected.append(options[0])
            else:
                missing.append(asset)
        remaining = None if missing else max(c['restoreMinutes'] for c in selected) + data['validationMinutes']
        minutes = None if missing else data['asOf'] - data['incidentAt'] + remaining
        plans.append({'checkpoint': checkpoint, 'copyIds': [c['id'] for c in selected], 'missingEligibleAssets': missing, 'estimatedRemainingMinutes': remaining, 'estimatedMinutes': minutes, 'withinModel': not missing and minutes <= data['targetRto']})
    feasible = [p for p in plans if p['withinModel']]
    return {'selected': feasible[0] if feasible else None, 'plans': plans,
            'copies': sorted(assessed, key=lambda r: r['id']),
            'parallelCopyAssumption': True, 'rtoProven': False,
            'consistencyProven': False, 'cloudRestorePerformed': False,
            'productionApproval': False}


def unique_object(pairs):
    result = {}
    for key, value in pairs:
        if key in result:
            raise ValueError('duplicate JSON key')
        result[key] = value
    return result


if __name__ == '__main__':
    try:
        raw = sys.stdin.read(1000001)
        if len(raw) > 1000000:
            raise ValueError('input too large')
        print(json.dumps(evaluate(json.loads(raw, object_pairs_hook=unique_object)), sort_keys=True))
    except (ValueError, TypeError, RecursionError) as error:
        print('invalid input: ' + str(error), file=sys.stderr)
        sys.exit(2)
NA PRÁTICA

O par80 é selecionado quando prices90 tem chave desconhecida; a estimativa de 32 minutos não comprova RTO real.

Armadilhas comuns

Última cópia por ativo como conjunto coerente; TTL como exclusão imediata; política atual como retenção retroativa; scan parcial como validação integral.

Tópicos relacionados: Fidelidade e partições · Rejeições e replay · Capacidade e continuidade

Leva esta ideia contigo

Existir uma cópia não prova recuperação: confirma o conjunto, as dependências, os dados e o tempo medido.

Criar conta

Referência: Professional Data Engineer standard exam guide · Current linked standard guide (document title v4.2); edition date unconfirmed (2026-09-30 inspection)

Google Cloud é uma marca comercial de Google LLC. A dr.pt é uma plataforma de preparação independente e não está afiliada, associada, patrocinada, autorizada nem aprovada por Google. Os conteúdos e as perguntas são originais, não são perguntas oficiais de exame, e concluir os nossos testes não atribui nem garante qualquer certificação. Os nomes são usados apenas para identificar o tema. Todas as outras marcas pertencem aos respetivos titulares.