Backup and Migration
System > Backup and Migration (/admin/backup Take four categories of work: complete backup export and download, whole library import restore, light site configuration export / import, and Qdrant vector library inspection and reconstruction. Complete backup is engine-neutral logic archive, the same zip can be imported between SQLite and PostgreSQL deployments, cross-computer migration, cross-engine migration, disaster recovery all go this path, without the need to touch pg_dump or database documents.
Completely backed up.
What is in the archive?
The output product is a single zip, internal structure:
aivory-docker-backup-20260711-153000-xxxxxxxxxx.zip
├── manifest.json # 格式版本、源引擎方言、各表行数、是否含文件
├── db/
│ ├── users.jsonl # 每表一个 JSONL,每行一个 JSON 对象
│ ├── conversations.jsonl # 按外键安全顺序排列,引擎中立
│ ├── messages.jsonl
│ └── ... # 全部数据表
├── files/ # 可选:勾选「包含上传文件与生成产物」时才有
│ ├── uploads/... # 用户上传的文件
│ └── artifacts/... # 模型生成的产物(图片、文档等)
└── qdrant/ # 可选:部署配置了 QDRANT_URL 时自动包含
└── collections/
└── aivory_c1536.jsonl # 逐 collection 的向量点位导出
Data rows are logical JSONL rather than database transfer: Binary column Base64 encoding, big integer guaranteed accuracy, which is why it can cross SQLite/PostgreSQL. aivory_c<维度> Name (e.g. 1536 Dimensional model corresponds to aivory_c1536)。
Exporting Options
| Optionally | admittedly | Explained |
|---|---|---|
| Includes uploaded documents and generated products | 开 | Packing uploads and artifacts directories together, the archive is significantly larger; if not, only the database rows |
| The Qdrant vector | Automated | Deployment is arranged. QDRANT_URL That is to say, there is no need to select; unconfigured Qdrant deployments do not naturally have this paragraph. |
Asynchronous tasks and archive lists
Go to “Export backup” on the page. ** Asymmetric tasks ** After clicking the task is generated in the background, the page shows progress (prepared, read the database, write to the archive), during which time you can leave the page.
- At the same time, only one output task is running; the output and the underlying vector maintenance task intersect, and the other side refuses to start when one side is running.
- Export is based on read-only transactions, consistent time snapshots, which are not affected by the normal use of users during the period.
- When the archive is completed, it appears in the "generated archive" list, with the "download" point saved to the local. archive file itself is stored on the server
BACKUP_DIRDirectory – Confirmed./data/backupsCompose deployment is mapped in the data volume), and the list is inverted by the generated time.
There is another synchronous stream endpoint for scripted periodic backups: GET /api/admin/backup/export Question of Parameters files=1 and documents, qdrant=0 Vector can be excluded), the response is directly zip stream. The small library uses it step-by-step, and the big library suggests going asynchronous tasks on the page to avoid downloading the connection for a long time hanging.
Asynchronous exports generated archives will remain on the server. BACKUP_DIR In this case, the system does not automatically rotate. Each full archive may be quite large (especially when it includes files and vectors), and after downloading offline storage, remember to periodically remove the old archive from the directory to avoid data volumes being filled with backup.
Simultaneous distinction: ordinary user in the "Settings > Privacy" also has a "export all data", that is, the individual user's own GDPR JSON export, with the entire site administrator backup is two things, see Sharing and data management。
Replacement of the whole box)
Operational steps
- In the Import and Restore section, select a zip archive exported above.
- Enter a confirmation word in the confirmation window.
REPLACE(It must be completely consistent.) - Click “Import and Replace Data” and wait for it to be completed.
- Successfully imported, the current session immediately disappears and automatically logs out. ** The account code in the backup. ** Registered again .
Replacement of language
Introduction is ** Replacing the whole box. ** Not a merger:
- Empty all tables in a database transaction, then reload from JSONL to table by table in the security order of the external key; columns that exist in the archive and do not exist in the current version are skipped (progressive compatibility). ** Meanwhile, no failed step will be submitted, and the database will remain in the state before import. **。
- File Recovery: The storage path prefix recorded in the archive will be rewritten as the native upload/product directory, and the machine change path does not require manual processing.
- Vector Recovery: Recovery points are reconstructed by collection when the archive contains Qdrant sections; vector recovery alerts do not interrupt imports, and can then be supplemented with vector maintenance.
- The PostgreSQL target library automatically resets the self-augmenting sequence; the SQLite target library temporarily shuts off the external key check during the recovery. ** Enter the engine into the box. ** SQLite backups can be imported into Postgres deployments and vice versa.
- After the import is completed, the setup cache immediately disappears, and the site configuration in the backup comes into effect immediately.
After the introduction is completed, ** In addition to "Execute the Administrator Mailbox Imported" this time, all the admin accounts brought with backup are automatically downgraded to ordinary users. ** This is an anti-retreat design: otherwise anyone who gets a structured backup can plug themselves into an administrator account.
The actual impact: ** The administrator mailbox created when the new instance was first launched should be the same as the administrator mailbox of the old instance. ** If it is not consistent, the administrators who imported the old instances will all become ordinary users, and the account that is imported (the mailbox may only exist in the backup of ordinary users or not) may not be able to log in to the admin console, and the database needs to be manually repaired.
Upper Size Limits with Cloudflare
Import the uploaded hard upper limit by the environmental variable MAX_BACKUP_BYTES Control, 20 GiB by default (see Core environmental variables If the site hangs behind Cloudflare, note that Cloudflare has a package ceiling of another 100 MB level for the request entity, and the large archive must bypass the proxy direct source station import, see Configuration of Cloudflare The reverse proxy layer (such as Nginx) client_max_body_size Also, it is necessary to install the backup, see The reverse proxy。
Introduction of common errors.
| phenomenon | Causes and Treatment |
|---|---|
| 400, the confirmation word does not match | REPLACE Must be consistent with characters (all large, no spaces) |
| 413 is too much. | More than archived MAX_BACKUP_BYTES, or blocked by the Cloudflare/Anti-Generation request body upper limit; enlarged the upper limit or go straight to the channel |
| The manifest failed. | Uploaded backup zip not exported by the system, or cut during download/transfer; re-export and verify file size |
| restore failed (no changes committed) | Restore the error, the transaction has been rolled back as a whole, the database is still the state before importation; see the service-side log positioning of the specific table and the back of the row. |
| Imported successfully but the knowledge base failed to retrieve content | Backup does not contain vector segments (the old instance does not include Qdrant) or a vector recovery warning; run to "Vector Check" to reconstruct once |
Configuration of export/import (light path)
There is a lighter path under the full backup: just move. ** Location of place. ** It is suitable for copying a set of configurations of the developer machine into production, unified configuration across deployments, or disaster preparation.
| The direction | behavior |
|---|---|
| Configuration of ZIP | Package site settings, channel, model, skills, OAuth provider, image style, user group, model quota, and icon and skill asset files |
| Introduction to archive. | by ID ** The UPSERT merger ** Configuration bar with ID is covered, more local configuration is retained; never touch users, conversations, messages, upload files, sessions and logs. also compatible with older pure JSON profiles |
Configuration Import Non-Destructive, Session Safe: No Loss Needed REPLACE There is no need to re-log in after import, a single confirmation box can be executed.
Installed in ZIP. ** clearly ** The channel API Key, OAuth Client Secret, SMTP password, object storage and search API key (otherwise it cannot work directly after importation).
Cross-engine migration: SQLite to PostgreSQL
Take the most common example of "single-machine SQLite start and grow to Postgres" as an example:
- ** Old Examples **: Go to Backup & Migration and select "includes uploaded files and generated products" to export the full backup and download (the word vector with Qdrant is configured automatically in the package).
- ** New Examples ** according to Deployment of Docker Compose Pull up a full suite of services for the Postgres mode and complete access to the site
/setupThe first run setup. ** The first administrator mailbox must be the same as the old administrator instance. ** (The password can be set as desired, after importing the password in the backup). - Log in with this administrator, go to System > Backup & Migration, select archive, enter
REPLACESequences, outer keys, path rewriting are all processed automatically. - Automatically log out and re-log in with the account password of the old instance.
- Verification: Number of user lists, scan several conversations and upload files, knowledge base retrieval fails. If the backup does not contain a vector (the old instance does not support Qdrant) or retrieves abnormalities, rebuild with vector maintenance.
The reverse (Postgres migration to SQLite) steps are exactly the same, see The SQLite model。
List of cross-border migrations
When switching servers (engine unchanged), check in the following order:
- The old computer exports the full backup (including files, vectors) and downloads it locally.
- New machine deployment ** The same or updated version ** The mirror image (the old version is not guaranteed to be imported into the new backup).
- New aircraft first.
/setup** Create an email address from an old instance administrator. ** (Rule of degradation, see the red warning above). - Files larger than 100 MB and new computers with Cloudflare: ready for direct connection channels (native computers)
127.0.0.1:8787or grey-cloud (DNS only) subdomain, see Configuration of Cloudflare。 - Import, re-log in, and verify (whether the user / conversation / file / knowledge base retrieval / channel API key works).
- DNS cuts to the new machine; the old machine data is retained until the verification is fully completed.
Vector maintenance
The vector check zone manages the consistency of the Qdrant vector library with the database, commonly used scenarios: a ** Not containing vector. ** Backups, migrations from older brand archives, lost Qdrant data volumes or replaced Qdrant instances.
| Operated | behavior | Costs of |
|---|---|---|
| Check the vector. | Check one by one for document cuts in the database for non-empty vectors in Qdrant, produce an audit report: should be / normal / missing / empty vector / jump, and list examples of problems. | Free, only read than right, no call to embedded interface |
| Recovery of missing vector | Cut for lack and empty vector. ** Cut text stored in the database ** Recall the embedding model and write the vector. aivory_c<维度> collection; package by embedding model, report reconstruction / failure number after completion | ** Incorporated API calls ** A great knowledge base once reconstructed will generate real embedding costs, pay attention to the embedded channel billing before implementation. |
The point:
- reconstructed ** No original documents needed. ** The cut text was originally in the database, so "backup without a vector" does not lose any data, only needs to spend an embedded fee to recover.
- Both tasks are asynchronous background tasks, page query progress; only run one at the same time, and interfere with backup export.
- Assuming that the Qdrant vector backend is configured for deployment; the unconfigured button directly reports that the vector backend is not configured.
Upgrading and daily backup habits
Upgrade to Update:
cd /opt/aivory # 你的 compose 目录
docker compose pull
docker compose up -d
Database structure when the new version is first launched ** Automated Migration ** (Additional Columns, Table Buildings), no need to manually execute SQL. Even so, develop two habits:
- ** Export a full backup before upgrading. ** Automatic migration is forward-looking, rolling back to the old version is not guaranteed; with archives at hand, any upgrade incident can be imported once before upgrading.
- ** Regularly exported and stored. **。
BACKUP_DIRThe archives and databases are lost on the same machine, and disk failures are lost together; it is a real disaster to place the downloaded archives in the object storage or on another machine.Configuration ZIP is also recommended to leave a copy after each major change of configuration.
Small teams are deployed once a week in full (with files) + each upgrade before, enough to control the worst losses within a few days.The archive is a regular zip, and can be rotated directly with the life cycle strategy stored by any object.