Last updated
One way: SharePoint stays the system of record, and SPSync keeps a read-only copy of your lists current in MariaDB.
Status: Shipped · product: SPSync for Relational Databases
MariaDB often runs on servers its owners patch themselves, sometimes in place of an older MySQL installation. SPSync writes SharePoint lists into that same server, so the list data sits next to the systems that already use it and needs no extra service.
How SPSync talks to MariaDB
The destination is SPSync’s MySQL destination, with a mysql+pymysql:// connection
string held in an environment variable. MariaDB has its own run in SPSync’s integration
tests, against a MariaDB 11 server, because it differs from MySQL 8 in places such as
JSON functions. The SQL SPSync issues today avoids those differences.
Sign-in is a MariaDB username and password. The user needs rights to create tables in
the target database. If the server requires TLS, pass the CA certificate path as ssl_ca
in the connection string.
Allow the network path from wherever the sync runs: a firewall rule, a security group, a VPN or a host on the same network.
Tables you can query
A spare-parts list with a Machine lookup, a Storekeeper person column, a Bin
text column and a multi-choice Compatible models column becomes maint_parts, keyed on
the SharePoint item ID. The lookup gives machine_id and machine_value.
Each storekeeper is a storekeeper_user_id that matches a row in sp_users. The multi-choice column
becomes maint_parts__compatible_models, a row per part and model. Names longer than 64
characters are shortened to fit MariaDB’s limit.
New SharePoint columns appear on the next run. Removed columns stay in the table. A column
whose type changes keeps its history and gets a _v2 column alongside.
| Title | Client lookup | Tags multi-choice | Owner person | Due |
|---|---|---|---|---|
| Riverside | Acme Ltd | Design; Build | Ada Lovelace | 2026-11-30 |
| Harbour | Borealis plc | Build | Alan Turing | 2027-02-14 |
then sync
- id
- title
- client_id → clients.id
- owner_id → sp_users.id
- due
- is_deleted soft delete
- sp_modified
- id
- title
- …
- project_id
- tag
One row per value: Riverside has two.
- id
- display_name
One users table shared by every list.
Where it is used
An open-source BI stack. Metabase and Grafana read MariaDB directly; see Tableau, Looker, Metabase and Grafana on SharePoint data.
An application on MariaDB. The app queries replicated tables with the same driver it uses for its own schema; see a read replica for internal apps.
Reference data. Approved vendors or product codes kept in SharePoint join to other tables on the same server; see reference and master data from SharePoint.
Leaving SharePoint lists. A current copy gives the application something to cut over to; see migrating list data off SharePoint.
Steps
- Sign in with delegated access to try it, and switch to
Sites.Selectedapp permissions, approved by an admin, for scheduled runs. - Store the connection string in an environment variable and name it in the destination settings.
- Choose the lists, or a whole site so new lists are picked up.
- Run. The first run builds the schema and loads everything.
- Set a schedule, every few minutes up to hourly, with a reconcile, weekly by default.
The first full load of a large list moves far more data than any run after it, so start it at a time when the server is quiet.
Desktop, Azure or command line
All three editions run the same engine, write the same tables and use the same licence key, so the choice comes down to who looks after the sync.
Desktop app
For macOS and Windows. Sign in with Microsoft, tick the lists, choose a database and sync from your own machine on the schedule you set. Delegated sign-in needs no admin unless your tenant requires admin consent for apps.
In your Azure
SPSync in your Azure, a managed application for your own subscription, is deployed with you on a call while the Marketplace listing is prepared. Once deployed it is always on, so the sync keeps running with every laptop closed.
Command line
Every replication is a YAML file you can review and commit. Run it from a server, a container or a CI pipeline, and re-run it safely any time.
Frequently asked questions
Is MariaDB a separate destination from MySQL?
It uses the MySQL destination and the same connection settings, because MariaDB speaks the MySQL protocol. SPSync's own test suite runs against a MariaDB server separately, so a MariaDB-only difference cannot hide behind a passing MySQL run.
Does SPSync work with MariaDB on a managed host?
Yes. Anything that accepts MySQL-protocol connections works, whether it runs on your own Linux servers, in a container or as a managed MariaDB service.
Can I put a unique index on the replicated columns?
Yes, on IDs and shorter text columns, which are bounded VARCHAR(n). Longer text stays TEXT, which MariaDB will not index without extra work, so SPSync leaves those columns unindexed.
Can several SharePoint sites replicate into one MariaDB database?
Yes. Each site's tables get a prefix, so several sites share one database without name clashes.
Talk to us about MariaDB
SPSync is licensed per installation and per target family, with Standard Support included. Tell us which targets you need and how many machines, and we will size it with you. See how licensing works.
Set it up
Sign in to SharePoint with the SharePoint connection guide, then follow the MySQL and MariaDB setup guide to create the database user and open the connection for MariaDB. If the connection test fails, the troubleshooting guide lists the errors people hit and what fixes them.
Script it
Everything you can click, you can script. The CLI, YAML config and automation below reproduce this scenario exactly. See the CLI reference.
spsync auth login --client-id 00000000-0000-0000-0000-000000000000
spsync export-config --output replication.yaml --pipeline-name mariadb --prefix mariadb --destination-kind mysql --connection-string-env SPSYNC_DB_CONNECTION --dataset-name mariadb --client-id 00000000-0000-0000-0000-000000000000 --site-url https://contoso.sharepoint.com/sites/example --all-lists
spsync doctor replication.yaml
spsync run replication.yaml pipeline_name: mariadb
prefix: mariadb
auth:
mode: delegated
client_id: 00000000-0000-0000-0000-000000000000
tenant_id: common
destination:
kind: mysql
connection_string_env: SPSYNC_DB_CONNECTION
dataset_name: mariadb
scopes:
- site_url: https://contoso.sharepoint.com/sites/example
mode: entire_site
reconcile_interval_days: 7
create_reporting_views: false
Cron (MySQL nightly):
# every night at 02:00
0 2 * * * cd /opt/spsync && SPSYNC_DB_CONNECTION="$(cat /etc/spsync/db.env)" uv run spsync run replication.yaml >> /var/log/spsync/run.log 2>&1 GitHub Actions:
# .github/workflows/spsync-run.yml
name: SPSync
on:
schedule:
- cron: "0 2 * * *"
workflow_dispatch: {}
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv sync
- run: uv run spsync run replication.yaml
env:
SPSYNC_DB_CONNECTION: ${{ secrets.SPSYNC_DB_CONNECTION }}
SPSYNC_LICENCE_KEY: ${{ secrets.SPSYNC_LICENCE_KEY }} Azure DevOps:
# azure-pipelines.yml
schedules:
- cron: "0 2 * * *"
branches: { include: [main] }
always: true
steps:
- script: uv sync
- script: uv run spsync run replication.yaml
env:
SPSYNC_DB_CONNECTION: $(SPSYNC_DB_CONNECTION)
SPSYNC_LICENCE_KEY: $(SPSYNC_LICENCE_KEY) Windows (PowerShell + Task Scheduler):
# Windows Task Scheduler action (see /docs/cli/automation/)
$env:SPSYNC_DB_CONNECTION = (Get-Content C:\spsync\db.env)
uv run spsync run C:\spsync\replication.yaml
schtasks /Create /SC DAILY /ST 02:00 /TN "SPSync" /TR "powershell -File C:\spsync\run.ps1" macOS (launchd):
# ~/Library/LaunchAgents/io.spsync.run.plist, then: launchctl load ~/Library/LaunchAgents/io.spsync.run.plist Secrets (licence key, connection strings) come from the environment, so never write them into the YAML. See scheduling and secrets.