Skip to content

Latest commit

Β 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

DbBackupTool

.NET 8 License: MIT Platform Zero NuGet dependencies PRs Welcome

Oracle SQL Server MySQL MariaDB PostgreSQL MongoDB SQLite

A free, open-source, cross-platform .NET 8 console app that automatically backs up the full schema and data of one or more databases on a schedule, keeping only the newest N backups. Point it at Oracle, SQL Server, MySQL, MariaDB, PostgreSQL, MongoDB, or SQLite β€” the engine is picked entirely by config, never by code.

Built for the "I just want a reliable weekly database backup with automatic rotation, and I don't want to hand-roll a PowerShell/bash script per database engine" problem. No paid product, no agent to install, no cloud dependency β€” it shells out to each database's own official, battle-tested backup tool (exp, sqlcmd, mysqldump, pg_dump, mongodump, sqlite3) and manages the scheduling glue and retention around them.

πŸ“¦ Features

  • Multiple database engines in one tool β€” Oracle, SQL Server, MySQL, MariaDB, PostgreSQL, MongoDB, SQLite. Add a job per database in one config file.
  • Multiple databases backed up simultaneously β€” every job in appsettings.json runs concurrently in the same execution. One failing job never blocks or is blocked by the others.
  • Automatic retention β€” keeps only the newest N backup runs per database (default 4), deleting older ones after every successful run. A failed run is never counted or kept.
  • Config-only setup, zero code changes β€” moving this to a new server or pointing it at a different database is editing appsettings.json, not recompiling anything.
  • Zero NuGet dependencies β€” every provider shells to that engine's own native CLI tool rather than reimplementing schema/data export in C#, so there's nothing fragile to keep in sync with database version changes.
  • Runs once and exits β€” designed to be triggered by Windows Task Scheduler or cron, not to run as a background service. Simpler, and a crashed scheduler can't silently kill an internal timer loop the way it could with a long-running daemon.
  • Passwords kept off the process command line where the underlying tool supports it (PostgreSQL's PGPASSWORD env var, temp credential files for MySQL/Oracle, deleted immediately after use) β€” see πŸ”’ Security notes.

πŸ—„οΈ Supported databases

Database Native tool used Notes
πŸ”΄ Oracle exp (classic Export) Deliberately not Data Pump (expdp) β€” see why
🟦 SQL Server sqlcmd (BACKUP DATABASE) Has an important remote-path caveat β€” read this
🐬 MySQL mysqldump
🟫 MariaDB mysqldump Wire-compatible with MySQL's dump format β€” use DbType: "MariaDb" or "MySql", same config shape
🐘 PostgreSQL pg_dump (custom format)
πŸƒ MongoDB mongodump
πŸ“„ SQLite sqlite3 (.backup command) Uses SQLite's official online backup API, safe against a live database

πŸš€ Quick start

  1. Install the .NET 8 SDK or Runtime and whichever native tool(s) your database(s) need (see table above) on the machine that will run this app.
  2. Clone this repo and copy the example config:
    git clone https://github.com/zawad-monsur/DbBackupTool.git
    cd DbBackupTool
    cp appsettings.example.json appsettings.json
  3. Edit appsettings.json β€” keep only the job(s) you need from the example, fill in your real connection details. See βš™οΈ Configuration reference below for every field.
  4. Build and run:
    dotnet build -c Release
    dotnet bin/Release/net8.0/DbBackupTool.dll
    Or publish a standalone build to deploy elsewhere:
    dotnet publish -c Release -r win-x64 --self-contained false -o ./publish
    # or -r linux-x64 for a Linux target
  5. Check {BackupFolder}\backup.log (or the console) to confirm it worked, then ⏰ schedule it to run automatically.

appsettings.json is gitignored on purpose β€” your real credentials never get committed even by accident. appsettings.example.json is the only config file this repo tracks.

βš™οΈ How it works

Each entry in appsettings.json's Jobs array is one independent backup job:

{
  "Jobs": [
    {
      "Label": "MyOracleDb",
      "DbType": "Oracle",
      "BackupFolder": "C:\\DB_Backup\\MyOracleDb",
      "RetentionCount": 4,
      "Oracle": { "...": "..." }
    }
  ]
}

On each run, every job:

  1. Creates a timestamped subfolder: {Label}_{yyyyMMdd_HHmmss}\.
  2. Shells out to that engine's native backup tool, writing its output into that subfolder.
  3. On success, deletes every subfolder for that Label beyond the newest RetentionCount. On failure, deletes just its own partial subfolder and leaves everything else untouched.

All jobs run concurrently (Task.WhenAll), so a single scheduled trigger can back up several databases β€” even different engines β€” at once. Every job logs to its own {BackupFolder}\backup.log, tagged with its Label, so concurrent output stays attributable. The process exits 0 only if every job succeeded, 1 if any failed β€” Task Scheduler/cron surface this directly in their own run history.

βš™οΈ Configuration reference

Every job needs Label, DbType, BackupFolder, and the settings block matching DbType. RetentionCount defaults to 4 if omitted.

πŸ”΄ Oracle
"Oracle": {
  "TnsConnectString": "host:1521/service_name",
  "Username": "myuser",
  "Password": "mypassword",
  "Schema": "MYSCHEMA",
  "ExpPath": "exp"
}

Requires exp (Oracle's classic Export client) installed and on PATH, or set ExpPath to its full location. Ships with an Oracle Instant Client "Tools" package or a full Oracle Client install.

🟦 SQL Server
"SqlServer": {
  "Server": "host\\INSTANCE",
  "Database": "MyDatabase",
  "UseWindowsAuth": true,
  "Username": "",
  "Password": "",
  "SqlcmdPath": "sqlcmd",
  "ServerSideBackupPath": "C:\\DB_Backup\\MyDatabase"
}

Requires sqlcmd on PATH. Read the caveat below before using this one.

🐬 MySQL / 🟫 MariaDB
"MySql": {
  "Host": "host",
  "Port": 3306,
  "Username": "myuser",
  "Password": "mypassword",
  "Database": "mydatabase",
  "MysqldumpPath": "mysqldump"
}

Requires mysqldump on PATH. Use DbType: "MariaDb" for a MariaDB target β€” same settings shape, same tool.

🐘 PostgreSQL
"PostgreSql": {
  "Host": "host",
  "Port": 5432,
  "Username": "myuser",
  "Password": "mypassword",
  "Database": "mydatabase",
  "PgDumpPath": "pg_dump"
}

Requires pg_dump on PATH. Produces a custom-format (-Fc) dump, restorable selectively via pg_restore.

πŸƒ MongoDB
"MongoDb": {
  "Host": "host",
  "Port": 27017,
  "Username": "myuser",
  "Password": "mypassword",
  "Database": "mydatabase",
  "AuthSource": "admin",
  "MongodumpPath": "mongodump"
}

Requires mongodump on PATH. Leave Username/Password empty for an unauthenticated instance.

πŸ“„ SQLite
"Sqlite": {
  "DatabasePath": "C:\\MyApp\\data\\app.db",
  "Sqlite3Path": "sqlite3"
}

Requires the sqlite3 CLI on PATH. No host/port/credentials β€” SQLite is just a file.

🧩 Why exp, not expdp, for Oracle

Oracle Data Pump (expdp) always writes its dump file on the database server's own disk, via a DIRECTORY object β€” getting that file onto a different machine needs a network share the DB server can write to, which is a separate, fragile thing to set up. The classic exp utility instead streams the dump through the client connection straight into a local file on whichever machine runs it. If this tool runs on a different box than the database (the common case β€” a dedicated backup/ops server, or the app server pulling a backup of its own remote DB) and needs the file to land in a local folder, exp is the right tool for that, even though it's the "older" one. If your Oracle Instant Client only ships expdp/impdp (some newer Instant Client "Tools" packages dropped classic exp/imp), you'll need an older Instant Client version that still includes it.

⚠️ SQL Server's remote-backup caveat

Read this before pointing the tool at a SQL Server database.

BACKUP DATABASE ... TO DISK is executed by the SQL Server engine itself β€” the path is resolved against its filesystem view, on whatever machine SQL Server runs on, not the machine running this tool. If SQL Server is remote from wherever you run this app:

  • SqlServer:ServerSideBackupPath must be a UNC path (\\thisToolsMachine\ShareName\...) that the SQL Server service account (not your own login) has write access to, or
  • run this tool on the SQL Server box itself, in which case a local C:\... path is fine.

Get this wrong and it doesn't fail obviously β€” you'll see "Cannot open backup device... Access is denied" from the engine's own service account's point of view, not yours. Oracle's exp, PostgreSQL's pg_dump, and MySQL's mysqldump don't have this problem β€” they stream the file back to the client (this tool), so their backup folders are always local from this app's perspective.

πŸ”’ Security notes

  • appsettings.json holds plaintext credentials. It's gitignored here for a reason β€” never commit your real one.
  • Where the underlying tool supports it, this app avoids putting the password on the process command line (visible to anything reading the process list while the backup runs):
    • PostgreSQL: password passed via the PGPASSWORD environment variable (Postgres's own documented mechanism).
    • MySQL/MariaDB: a temporary --defaults-extra-file is written just before the run and deleted immediately after, regardless of success or failure.
    • Oracle: a temporary exp parameter file (PARFILE) is used the same way.
    • SQL Server: prefer UseWindowsAuth: true (integrated auth via sqlcmd -E) over SQL auth wherever possible β€” avoids a plaintext credential in the config file entirely.
    • MongoDB: mongodump has no equally standard non-interactive credentials mechanism across its versions, so the password is passed as a plain argument here. If that matters for your setup, scope that MongoDB user's permissions narrowly and/or run this tool under an account other processes on the box can't inspect.
  • Whatever OS account runs the scheduled task needs write access to BackupFolder and (for SQL Server) the DB engine needs write access to ServerSideBackupPath β€” scope both as narrowly as your environment allows.

⏰ Scheduling

This app runs once and exits β€” it does not schedule itself.

Windows Task Scheduler:

schtasks /Create /TN "DB Backup" /TR "C:\Tools\DbBackupTool\DbBackupTool.exe" /SC WEEKLY /D SUN /ST 02:00 /RU SYSTEM /RL HIGHEST

Or via the GUI: Task Scheduler β†’ Create Task β†’ Trigger: Weekly β†’ Action: Start a program β†’ path to the .exe β†’ "Run whether user is logged on or not".

cron (Linux/macOS):

0 2 * * 0 dotnet /opt/dbbackuptool/DbBackupTool.dll >> /var/log/dbbackuptool-cron.log 2>&1

(Every Sunday at 2 AM. Adjust for your publish output β€” a self-contained publish doesn't need the dotnet prefix.)

Either way, the exit code (0/1) is your immediate success/failure signal β€” backup.log next to each job's backups has the detail when something fails.

βž• Adding another database engine

Every engine is one class implementing IBackupProvider (Task RunAsync(string backupDir, string fileBaseName, JobLog log, CancellationToken ct)), registered in one switch in Program.cs. If you add support for something not listed above (Redis, Cassandra, DB2, whatever), a PR is welcome.

🀝 Contributing

Issues and pull requests welcome β€” bug reports, a new database engine, a platform quirk this hasn't hit yet. Keep new providers consistent with the existing ones: shell out to the engine's own native tool, never hand-roll an export.

πŸ“„ License

MIT β€” use it, fork it, ship it internally, whatever you need.

About

Free, open-source .NET console app to automatically back up Oracle, SQL Server, MySQL, MariaDB, PostgreSQL, MongoDB, and SQLite databases on a schedule, with automatic backup retention.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages