Skip to content

Database Sync Architecture

Phony's Database Sync engine enables secure, scalable synchronization of production databases to non-production environments with automatic PII anonymization.

Architecture Overview

┌─────────────────────────────────────────────────────────────────────────┐
│                    DATABASE SYNC ARCHITECTURE                            │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  CUSTOMER ENVIRONMENT                    PHONY CLOUD                    │
│  ════════════════════                    ═══════════                    │
│                                                                          │
│  ┌─────────────────┐                    ┌─────────────────────────────┐ │
│  │  Production DB  │                    │      SYNC ENGINE (Go)       │ │
│  │  (MySQL/PG)     │◄── Secure ────────►│                             │ │
│  │                 │    Tunnel          │  ┌─────────────────────────┐│ │
│  │  100GB / PII    │                    │  │    Connection Pool      ││ │
│  └─────────────────┘                    │  │    (pgx / go-mysql)     ││ │
│                                          │  └───────────┬─────────────┘│ │
│                                          │              │              │ │
│                                          │  ┌───────────▼─────────────┐│ │
│                                          │  │    Schema Analyzer      ││ │
│                                          │  │    • FK Detection       ││ │
│                                          │  │    • PII Detection      ││ │
│                                          │  │    • Type Mapping       ││ │
│                                          │  └───────────┬─────────────┘│ │
│                                          │              │              │ │
│                                          │  ┌───────────▼─────────────┐│ │
│                                          │  │   Transform Pipeline    ││ │
│                                          │  │    • Streaming Read     ││ │
│                                          │  │    • Batch Transform    ││ │
│                                          │  │    • Parallel Write     ││ │
│                                          │  └───────────┬─────────────┘│ │
│                                          │              │              │ │
│                                          │  ┌───────────▼─────────────┐│ │
│  ┌─────────────────┐                    │  │    Rust Core (FFI)      ││ │
│  │  Staging DB     │◄── Secure ────────►│  │    • N-gram Generate    ││ │
│  │  (MySQL/PG)     │    Tunnel          │  │    • 5M records/sec     ││ │
│  │                 │                    │  └─────────────────────────┘│ │
│  │  100GB / No PII │                    └─────────────────────────────┘ │
│  └─────────────────┘                                                    │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Connection Management

Secure Tunnels

Customer databases are never exposed to the public internet. Phony uses secure tunnels:

┌─────────────────────────────────────────────────────────────────────────┐
│                    CONNECTION OPTIONS                                    │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  OPTION 1: SSH Tunnel (Recommended)                                     │
│  ═══════════════════════════════════                                    │
│                                                                          │
│  Customer VPC          │         Phony Cloud                            │
│  ┌──────────────┐      │      ┌──────────────┐                          │
│  │   Bastion    │◄─────┼──────│  Sync Engine │                          │
│  │   (SSH Key)  │  SSH │      │              │                          │
│  └──────┬───────┘      │      └──────────────┘                          │
│         │              │                                                 │
│  ┌──────▼───────┐      │                                                │
│  │   Database   │      │                                                │
│  │  (Private)   │      │                                                │
│  └──────────────┘      │                                                │
│                                                                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  OPTION 2: VPC Peering (Enterprise)                                     │
│  ═══════════════════════════════════                                    │
│                                                                          │
│  Customer VPC          │         Phony VPC                              │
│  ┌──────────────┐      │      ┌──────────────┐                          │
│  │   Database   │◄─────┼──────│  Sync Engine │                          │
│  │              │ VPC  │      │              │                          │
│  │              │Peering      │              │                          │
│  └──────────────┘      │      └──────────────┘                          │
│                                                                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  OPTION 3: Direct Connect (On-premise)                                  │
│  ═════════════════════════════════════                                  │
│                                                                          │
│  On-Premise DC         │         Phony Cloud                            │
│  ┌──────────────┐      │      ┌──────────────┐                          │
│  │   Database   │◄─────┼──────│  Sync Engine │                          │
│  │              │ IPSec│      │              │                          │
│  │              │  VPN │      │              │                          │
│  └──────────────┘      │      └──────────────┘                          │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Connection Configuration

json
{
  "source": {
    "type": "postgresql",
    "host": "db.internal.company.com",
    "port": 5432,
    "database": "production",
    "credentials": {
      "type": "ssh_tunnel",
      "bastion_host": "bastion.company.com",
      "bastion_user": "phony-sync",
      "private_key_ref": "vault://secrets/company/ssh-key"
    },
    "ssl": {
      "mode": "verify-full",
      "ca_cert_ref": "vault://secrets/company/ca-cert"
    }
  }
}

Schema Analysis

Automatic PII Detection

The Schema Analyzer uses multiple strategies to detect PII columns:

┌─────────────────────────────────────────────────────────────────────────┐
│                    PII DETECTION PIPELINE                                │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  1. COLUMN NAME HEURISTICS (Fast)                                       │
│  ════════════════════════════════                                       │
│  Pattern matching on column names:                                      │
│  • email, mail, e_mail → EMAIL type                                     │
│  • phone, tel, mobile, gsm → PHONE type                                 │
│  • first_name, fname, ad → NAME type                                    │
│  • ssn, tc_kimlik, national_id → NATIONAL_ID type                      │
│  • address, adres, street → ADDRESS type                                │
│  • credit_card, cc_number → CREDIT_CARD type                           │
│                                                                          │
│  2. DATA SAMPLING (Accurate)                                            │
│  ════════════════════════════                                           │
│  Sample N rows and analyze content:                                     │
│  • Regex patterns (email format, phone format)                          │
│  • Statistical analysis (entropy, uniqueness)                           │
│  • Named entity recognition (names, addresses)                          │
│                                                                          │
│  3. ML CLASSIFICATION (Enterprise)                                      │
│  ══════════════════════════════════                                     │
│  Fine-tuned model for domain-specific PII:                              │
│  • Healthcare: MRN, diagnosis codes                                     │
│  • Finance: account numbers, transactions                               │
│  • Custom training on customer data patterns                            │
│                                                                          │
│  OUTPUT:                                                                │
│  ════════                                                               │
│  {                                                                      │
│    "users.email": { "pii_type": "EMAIL", "confidence": 0.98 },         │
│    "users.phone": { "pii_type": "PHONE", "confidence": 0.95 },         │
│    "users.bio": { "pii_type": "FREE_TEXT", "confidence": 0.72 }        │
│  }                                                                      │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Foreign Key Detection

Preserving referential integrity is critical:

sql
-- Automatic FK detection via:
-- 1. Database metadata (information_schema)
-- 2. Naming conventions (user_id, order_id)
-- 3. Data analysis (matching value distributions)

-- Result: Dependency graph
orders.user_idusers.id
order_items.order_idorders.id
payments.order_idorders.id

Transform Pipeline

Streaming Architecture

Large databases are processed in streams, never loaded fully into memory:

┌─────────────────────────────────────────────────────────────────────────┐
│                    STREAMING TRANSFORM PIPELINE                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  SOURCE DB              SYNC ENGINE                    TARGET DB        │
│  ═════════              ═══════════                    ═════════        │
│                                                                          │
│  ┌────────┐    ┌────────────────────────────────┐    ┌────────┐        │
│  │        │    │                                │    │        │        │
│  │ users  │───►│  ┌──────┐  ┌──────┐  ┌──────┐ │───►│ users  │        │
│  │ 10M    │    │  │ Read │  │Trans-│  │ Write│ │    │ 10M    │        │
│  │ rows   │    │  │Batch │─►│form  │─►│Batch │ │    │ rows   │        │
│  │        │    │  │ 10K  │  │      │  │ 10K  │ │    │        │        │
│  └────────┘    │  └──────┘  └──────┘  └──────┘ │    └────────┘        │
│                │       ▲                   │    │                       │
│                │       │    ┌──────────┐   │    │                       │
│                │       └────│  Buffer  │◄──┘    │                       │
│                │            │  Queue   │        │                       │
│                │            │ (memory) │        │                       │
│                │            └──────────┘        │                       │
│                │                                │                       │
│                │  Parallel workers: 4-16        │                       │
│                │  Batch size: 1K-100K           │                       │
│                │  Memory limit: 512MB-4GB       │                       │
│                │                                │                       │
│                └────────────────────────────────┘                       │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Transform Types

json
{
  "tables": {
    "users": {
      "columns": {
        "id": { "transform": "KEEP" },
        "email": {
          "transform": "ANONYMIZE",
          "generator": "template",
          "pattern": "{{uuid}}@example.com"
        },
        "first_name": {
          "transform": "ANONYMIZE",
          "generator": "model",
          "source": "tr_TR/first_names"
        },
        "phone": {
          "transform": "MASK",
          "pattern": "+90 5** *** **{last2}"
        },
        "password_hash": { "transform": "KEEP" },
        "created_at": { "transform": "KEEP" },
        "notes": { "transform": "NULL" }
      }
    }
  }
}

Sync Modes

Full Sync

Complete table copy with transformation:

┌─────────────────────────────────────────────────────────────────────────┐
│                    FULL SYNC PROCESS                                     │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  1. SCHEMA SYNC                                                         │
│     • Drop existing tables (if exists)                                  │
│     • Create tables with same schema                                    │
│     • Create indexes after data load                                    │
│                                                                          │
│  2. DATA SYNC (per table, ordered by FK dependencies)                   │
│     • Disable FK constraints                                            │
│     • Truncate target table                                             │
│     • Stream + Transform + Bulk insert                                  │
│     • Enable FK constraints                                             │
│                                                                          │
│  3. POST-SYNC                                                           │
│     • Rebuild indexes                                                   │
│     • Update statistics                                                 │
│     • Verify row counts                                                 │
│                                                                          │
│  Duration: ~1 hour per 100GB (depends on transforms)                    │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Incremental Sync

Only sync changes since last sync:

┌─────────────────────────────────────────────────────────────────────────┐
│                    INCREMENTAL SYNC STRATEGIES                           │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  STRATEGY 1: Timestamp-based (Simple)                                   │
│  ══════════════════════════════════════                                 │
│  Requires: updated_at column on tables                                  │
│                                                                          │
│  SELECT * FROM users                                                    │
│  WHERE updated_at > '2024-01-15 10:00:00'                              │
│                                                                          │
│  Pros: Simple, works everywhere                                         │
│  Cons: Misses deletes, clock skew issues                               │
│                                                                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  STRATEGY 2: CDC (Change Data Capture) - Recommended                    │
│  ═════════════════════════════════════════════════════                  │
│  Uses database replication log:                                         │
│  • PostgreSQL: Logical replication slots                                │
│  • MySQL: Binary log (binlog)                                           │
│                                                                          │
│  Captures: INSERT, UPDATE, DELETE                                       │
│  Latency: Near real-time (seconds)                                      │
│                                                                          │
│  Pros: Complete, no missed changes                                      │
│  Cons: Requires DB config, more complex                                 │
│                                                                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  STRATEGY 3: Soft Delete Tracking                                       │
│  ═════════════════════════════════                                      │
│  Requires: deleted_at column + no hard deletes                         │
│                                                                          │
│  Combined with timestamp-based for complete picture                     │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Subset Sync

Sync a representative subset for development:

json
{
  "subset": {
    "strategy": "percentage",
    "percentage": 1,
    "preserve_integrity": true,
    "seed_tables": ["users"],
    "rules": {
      "users": {
        "sample": "1%",
        "filter": "created_at > '2024-01-01'"
      },
      "orders": {
        "sample": "follow_fk",
        "parent": "users"
      },
      "order_items": {
        "sample": "follow_fk",
        "parent": "orders"
      }
    }
  }
}

Consistency Guarantees

Referential Integrity

Foreign keys are preserved through deterministic ID mapping:

┌─────────────────────────────────────────────────────────────────────────┐
│                    FK CONSISTENCY                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  SOURCE:                           TARGET:                              │
│  ════════                          ═══════                              │
│                                                                          │
│  users                             users                                │
│  ┌─────┬───────────┐              ┌─────┬───────────┐                  │
│  │ id  │ email     │              │ id  │ email     │                  │
│  ├─────┼───────────┤   Transform  ├─────┼───────────┤                  │
│  │ 1   │ a@x.com   │ ──────────►  │ 1   │ xx@ex.com │                  │
│  │ 2   │ b@x.com   │              │ 2   │ yy@ex.com │                  │
│  └─────┴───────────┘              └─────┴───────────┘                  │
│                                                                          │
│  orders                            orders                               │
│  ┌─────┬─────────┐                ┌─────┬─────────┐                    │
│  │ id  │ user_id │                │ id  │ user_id │                    │
│  ├─────┼─────────┤   ID preserved ├─────┼─────────┤                    │
│  │ 101 │ 1       │ ──────────────►│ 101 │ 1       │  ✓ FK intact      │
│  │ 102 │ 2       │                │ 102 │ 2       │                    │
│  └─────┴─────────┘                └─────┴─────────┘                    │
│                                                                          │
│  KEY INSIGHT: IDs are NEVER transformed, only PII columns               │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Transaction Consistency

Sync jobs are atomic at the table level:

  • If a table sync fails, it's rolled back
  • Other tables remain consistent
  • Retry mechanism with exponential backoff
  • Dead letter queue for persistent failures

Performance

Database SizeFull SyncIncrementalSubset (1%)
1 GB~2 min~10 sec~5 sec
10 GB~15 min~30 sec~20 sec
100 GB~2 hours~2 min~2 min
1 TB~20 hours~10 min~10 min

Optimization levers:

  • Parallel workers (up to 16)
  • Batch size tuning
  • Index-free loading (rebuild after)
  • Connection pooling

Scheduling

json
{
  "schedule": {
    "type": "cron",
    "expression": "0 2 * * *",
    "timezone": "Europe/Istanbul",
    "mode": "incremental",
    "fallback_to_full": {
      "enabled": true,
      "after_days": 7
    }
  },
  "notifications": {
    "on_success": ["slack://channel"],
    "on_failure": ["email://team@company.com", "pagerduty://service"]
  }
}

Phony Cloud Platform Specification