롤백
롤백 계획은 선택한 병합 작업을 적용한 후 되돌리는 방법을 설명합니다. 쓰기 직전의 정확한 라이브 행을 사용해 적용 전에 만듭니다.
기준 스냅샷만으로 롤백을 생성하지 마세요. 기준은 공통 조상이며, 덮어쓰려는 라이브 상태와 반드시 같지는 않습니다.
롤백 계획 만들기
PHP
use Merql\Plan\ChangeGroupSelection;
use Merql\Rollback\RollbackPlanBuilder;
use Merql\Snapshot\SnapshotStore;
$selection = ChangeGroupSelection::fromIds([$plan->changeGroups[0]->id]);
$operationSelection = $selection->toOperationSelection($plan);
$expectedLive = SnapshotStore::load($plan->theirsSnapshot);
$liveBeforeRows = [];
foreach ($plan->operations as $operation) {
if (!$operationSelection->contains($operation->id)) {
continue;
}
$liveBeforeRows[$operation->id] = $expectedLive
->getTable($operation->table)
?->getRow($operation->rowKey);
}
$rollback = (new RollbackPlanBuilder())->build(
'rollback-1',
$plan,
$operationSelection,
$liveBeforeRows,
metadata: ['promotion_id' => 'promotion-1'],
);
계획에는 다음이 저장됩니다:
- 병합 계획 ID,
- 선택한 작업 ID,
- 영향을 받은 테이블,
- 역작업,
- 이전 행,
- 예상 이후 행,
- 메타데이터,
- 롤백 해시,
- 스키마 버전.
변경 확인
롤백을 적용하기 전에 현재 라이브 행을 롤백 계획의 예상 이후 행과 비교합니다. 승격 후 행이 하나라도 변경되었다면 기본적으로 중단합니다.
PHP
use Merql\Rollback\RollbackDrift;
$currentRows = [
$operationId => $currentLiveRow,
];
$drifted = (new RollbackDrift())->driftedOperationIds($rollback, $currentRows);
if ($drifted !== []) {
throw new RuntimeException('Rollback drifted: ' . implode(', ', $drifted));
}
변경 확인은 행 지문을 비교하므로 열 순서는 중요하지 않습니다.
롤백 적용
변경이 없다면 역작업을 적용합니다.
PHP
use Merql\Rollback\RollbackPlanApplier;
$applied = (new RollbackPlanApplier($connection))->apply($rollback);
if ($applied->hasErrors()) {
foreach ($applied->errors() as $error) {
echo $error . "\n";
}
}
롤백은 역작업에서 만든 일반 MergeResult을 적용합니다. 일반 병합 적용과 동일한 트랜잭션 적용 경로로 실행됩니다.
직렬화
정방향 병합을 적용하기 전에 롤백 계획을 저장하세요. 이 산출물은 나중에 롤백할 때 지속적으로 사용할 기반입니다.
PHP
use Merql\Rollback\RollbackPlanSerializer;
$json = RollbackPlanSerializer::toJson($rollback);
$restored = RollbackPlanSerializer::fromJson($json);
애플리케이션은 라이브 쓰기를 수행한 작업과 함께 직렬화된 계획 및 호스트별 감사 메타데이터를 저장해야 합니다.