A Python script that performs one-way incremental database mirroring from a source MySQL database to a target MySQL database. It is designed to run as a GitHub Actions job at regular intervals, with detailed logging and summary display in the workflow.
- One-way mirroring: Syncs data from source to target database only.
- Incremental data load: Only new, updated, or deleted rows are applied; avoids full table reloads.
- Idempotent operations: Safe to run multiple times without data duplication.
- Change tracking: Target database includes
operation_typecolumn (inserted,updated,deleted). - Soft deletes: Deleted source records are marked as
deletedin target, not physically removed. - Timezone-aware timestamps:
last_updatedcolumn in target table is stored in IST. - SSL connections: Connects securely to both source and target databases using
ssl_mode=REQUIRED. - Batch processing: Handles large tables efficiently.
- Error handling: Graceful handling of connection issues, data integrity problems, and foreign key constraints.
- Comprehensive logging: Detailed logs for monitoring and troubleshooting.
- GitHub Actions summary: Logs are parsed and displayed in a clean, table-formatted summary in the Actions UI.
- Automated execution: Can be scheduled or manually triggered via GitHub Actions.
- MySQL databases (source and target)
- GitHub repository with Actions enabled
- Python 3.11+ (handled by GitHub Actions)
- GitHub Secrets configured with database credentials
- Clone or create a repository with this code.
- Ensure the following files exist in your repository:
db_mirror.py- Main scriptrequirements.txt- Python dependencies.github/workflows/db-mirror.yml- GitHub Actions workflow
- Table must have a primary key.
- Grant SELECT permissions to the database user.
- Script automatically creates the target table if it doesn't exist.
- Grant CREATE, SELECT, INSERT, UPDATE permissions to the database user.
- Target table includes additional columns:
operation_typeVARCHAR(10) – Tracksinserted,updated, ordeleted.last_updatedTIMESTAMP – Tracks the last modification time in IST.
Navigate to your repository → Settings → Secrets and variables → Actions, and add:
SOURCE_DB_HOST– Hostname/IPSOURCE_DB_PORT– PortSOURCE_DB_USER– UsernameSOURCE_DB_PASSWORD– PasswordSOURCE_DB_NAME– Database name
TARGET_DB_HOST– Hostname/IPTARGET_DB_PORT– PortTARGET_DB_USER– UsernameTARGET_DB_PASSWORD– PasswordTARGET_DB_NAME– Database name
TABLE_NAME– Name of the table to mirror
The GitHub Actions workflow will:
- Run automatically (schedule configurable in
.yml). - Can be manually triggered from the Actions tab.
- Display logs in a clean, tabular summary in the workflow summary.
- Optionally upload raw logs as artifacts.
Runs automatically via GitHub Actions on schedule or manual trigger.
- Go to repository Actions tab.
- Select "Database Mirror" workflow.
- Click "Run workflow".
# Set environment variables
export SOURCE_DB_HOST="your-source-host"
export SOURCE_DB_USER="your-source-user"
# ...set all required variables
# Install dependencies
pip install -r requirements.txt
# Run the script
python db_mirror.py- Connection: Establishes SSL connections to source and target databases.
- Table Setup: Creates target table with
operation_typeandlast_updatedcolumns if missing. - Data Fetch: Retrieves all source rows and existing target rows.
- Comparison: Compares rows using primary key(s) to detect new, updated, or deleted rows.
- Synchronization:
- New rows: Inserted with
operation_type='inserted'. - Changed rows: Updated with
operation_type='updated'andlast_updatedin IST. - Deleted rows: Marked
operation_type='deleted'(soft delete).
- New rows: Inserted with
- Logging: Writes detailed logs (
db_mirror.log) and displays a formatted summary in GitHub Actions.
Example output:
## Database Mirror Summary
**Source DB:** Connected
**Target DB:** Connected
**Target Table:** Already exists, skipped creation
| Operation | Count |
|-----------|-------|
| Inserted | 1 |
| Updated | 0 |
| Deleted | 0 |
**Status:** Database mirroring completed successfully
- View logs in Actions run details.
- Local execution creates
db_mirror.log.
- Credentials stored securely as GitHub Secrets.
- Connections use SSL (
ssl_mode=REQUIRED). - Only necessary privileges granted (read-only for source recommended).
-
Connection Failures
- Verify credentials and port.
- Check network/firewall access from GitHub runners.
-
Permission Errors
- Source DB: SELECT required.
- Target DB: CREATE, SELECT, INSERT, UPDATE required.
-
Primary Key Issues
- Source table must have primary key.
- Composite keys are supported.
-
Foreign Key Constraints
- Script handles FK constraints gracefully.
- If soft delete conflicts occur, check referenced tables.
-
Large Dataset Performance
- Script is optimized for incremental loads.
- Batch processing reduces memory usage.
- Consider indexing large tables.