# How to Migrate Data from Java Nacos MySQL to r-nacos: A Complete Guide

> Migrate Java Nacos MySQL data to r-nacos easily. Export MySQL data using rnacos mysql-to-data then import via the r-nacos import endpoint for a seamless transition.

- Repository: [Nacos Group/r-nacos](https://github.com/nacos-group/r-nacos)
- Tags: migration-guide
- Published: 2026-03-07

---

**Use the `rnacos mysql-to-data` CLI tool to export your Java Nacos MySQL database into a binary transfer file, then POST that file to the `/v2/transfer/import` endpoint of your r-nacos cluster to replay the data via Raft commands.**

The r-nacos project provides a high-performance Rust implementation of the Nacos service registry and configuration center. When transitioning from the original Java-based Nacos to r-nacos, you can migrate data from Java Nacos MySQL to r-nacos using the built-in data migration toolchain that ships with the repository.

## Understanding the r-nacos Migration Architecture

The migration toolchain consists of three integrated components that handle the end-to-end data transfer without requiring manual SQL manipulation.

### The Exporter Component

The **Exporter** reads your legacy MySQL schema and serializes records into an intermediate format. Implemented in [`src/transfer/mysql_to_data.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/transfer/mysql_to_data.rs), the `mysql_to_data()` function creates a `TransferWriterActor` to process rows from the `config_info`, `config_history`, `tenant`, and `user` tables. Each row transforms into a `TransferRecordDto` Protobuf message via helper functions like `build_config_record()` and `apply_tenant()`.

### The Transfer File Format

The **transfer file** acts as the binary bridge between systems. Defined in `proto/transfer.proto`, the format contains a file header, a table-name mapping section, and a stream of `TransferRecordDto` messages. This Protobuf-based structure ensures version compatibility and efficient serialization across different architectures.

### The Importer Component

The **Importer** replays the transfer file into your r-nacos cluster through Raft consensus. The `TransferImportManager` in [`src/transfer/reader.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/transfer/reader.rs) parses the file using `TransferReader`, maps each record to its appropriate table handler, and dispatches Raft commands to reconstruct configuration, tenant, user, and cache data. The HTTP API layer in [`src/console/transfer_api.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/console/transfer_api.rs) exposes this functionality via the `import_transfer_file()` handler.

## Step-by-Step Migration Process

Follow this sequence to migrate data from Java Nacos MySQL to r-nacos without service interruption.

### Step 1: Build the r-nacos Binary

Compile the migration tools from the source. The CLI tool ships with the main binary.

```bash

# Clone and build

git clone https://github.com/nacos-group/r-nacos.git
cd r-nacos
cargo build --release

# Binary location: target/release/rnacos

```

### Step 2: Export Data from MySQL

Use the `mysql-to-data` subcommand to generate the transfer file. This command, defined in [`src/cli.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/cli.rs), invokes the export logic.

```bash
./target/release/rnacos mysql-to-data \
    --uri "mysql://nacos:nacos@127.0.0.1:3306/nacos" \
    --out /tmp/nacos_export.data

```

The exporter serializes configurations, history, tenants, and users into `/tmp/nacos_export.data` using the `TransferWriterActor`.

### Step 3: Transfer the File to Target Cluster

Copy the binary file to any node in your r-nacos cluster using standard file transfer tools.

```bash
scp /tmp/nacos_export.data user@rnacos-node:/tmp/

```

### Step 4: Import via HTTP API

Import the data by posting the file to the `/v2/transfer/import` endpoint. The handler in [`src/console/transfer_api.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/console/transfer_api.rs) processes this request.

```bash
curl -X POST \
  -F "files=@/tmp/nacos_export.data" \
  -H "import-config: 1" \
  -H "import-user: 1" \
  -H "import-cache: 0" \
  http://rnacos-node:8848/v2/transfer/import

```

Header options control the import scope:

- `import-config: 1` – Import configuration and history data
- `import-user: 1` – Import tenant and user information
- `import-cache: 0` – Skip cache data (optional)

After the HTTP 200 response, the `TransferImportManager` logs the completion status:

```

transfer import finished,count:12345,ignore:0

```

## Complete End-to-End Example

This shell script demonstrates the full migration workflow from build to verification.

```bash
#!/bin/bash
set -e

# Configuration

MYSQL_URI="mysql://nacos:nacos@legacy-nacos:3306/nacos"
RNACOS_HOST="rnacos-new:8848"
EXPORT_FILE="/tmp/nacos_migration.data"

# 1. Build r-nacos

echo "Building r-nacos..."
cargo build --release

# 2. Export from MySQL

echo "Exporting data from Java Nacos MySQL..."
./target/release/rnacos mysql-to-data \
    --uri "$MYSQL_URI" \
    --out "$EXPORT_FILE"

# 3. Transfer file (example using local copy)

echo "Moving data to target cluster..."
cp "$EXPORT_FILE" /var/lib/rnacos/

# 4. Import to r-nacos

echo "Importing data into r-nacos..."
curl -X POST \
  -F "files=@/var/lib/rnacos/nacos_migration.data" \
  -H "import-config: 1" \
  -H "import-user: 1" \
  http://$RNACOS_HOST/v2/transfer/import

echo "Migration completed successfully!"

```

## Key Source Files and Implementation Details

Understanding the underlying code helps troubleshoot migration issues and customize the process.

- **[`src/cli.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/cli.rs)** – Defines the `MysqlToData` command structure and argument parsing for the CLI exporter.

- **[`src/transfer/mysql_to_data.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/transfer/mysql_to_data.rs)** – Contains the `mysql_to_data()` function that orchestrates the export process, creates the `TransferWriterActor`, and queries tables via the DAO layer.

- **[`src/transfer/mod.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/transfer/mod.rs)** – Provides `init_writer_actor()` to initialize the transfer writer and pre-populate the table-name mapping.

- **`proto/transfer.proto`** – Defines the Protobuf schema for `TransferRecordDto` and the transfer file structure.

- **[`src/transfer/reader.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/transfer/reader.rs)** – Implements `TransferImportManager` and `TransferReader` to parse the file and dispatch Raft commands.

- **[`src/console/transfer_api.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/console/transfer_api.rs)** – Handles the HTTP `POST /v2/transfer/import` endpoint via `import_transfer_file()`.

- **[`src/starter.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/starter.rs)** – Initializes the `TransferImportManager` actor at service startup.

## Summary

- **Export** your Java Nacos MySQL data using the built-in `rnacos mysql-to-data` CLI tool, which serializes records into a binary transfer file via `TransferWriterActor`.

- **Transfer** the resulting file to any node in your target r-nacos cluster using standard file copy methods.

- **Import** the data by posting the file to the `/v2/transfer/import` HTTP endpoint, which uses `TransferImportManager` to replay records through Raft commands.

- The migration toolchain handles configurations, history, tenants, and users automatically without requiring manual SQL conversion or application downtime.

## Frequently Asked Questions

### How does the transfer file format ensure data integrity during migration?

The transfer file uses a Protobuf-based binary format defined in `proto/transfer.proto`, which includes a file header, table-name mappings, and a stream of `TransferRecordDto` messages. This structure ensures version compatibility and preserves data types across different architectures. The `TransferReader` in [`src/transfer/reader.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/transfer/reader.rs) validates the header before processing records, ensuring the file is complete and uncorrupted before Raft commands are dispatched.

### Can I migrate data while the Java Nacos server is still running?

Yes, the export process operates in read-only mode against the MySQL database. The `mysql_to_data()` function in [`src/transfer/mysql_to_data.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/transfer/mysql_to_data.rs) queries tables such as `config_info`, `tenant`, and `user` through the DAO layer without modifying the source data. This allows you to export a consistent snapshot while the Java Nacos server continues serving traffic, minimizing downtime during the migration window.

### What data types are preserved during the migration?

The migration toolchain preserves configuration data (including content and metadata), configuration history, tenant information, and user credentials. The `build_config_record()` and `apply_tenant()` functions in the exporter ensure that all relational data transforms correctly into `TransferRecordDto` messages. When importing, the `TransferImportManager` dispatches specific Raft commands for each data type, recreating the exact same logical state in the r-nacos cluster without losing hierarchical relationships between tenants and configurations.

### How do I troubleshoot a failed import operation?

Check the r-nacos logs for messages from `TransferImportManager` in [`src/transfer/reader.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/transfer/reader.rs). A successful import logs `transfer import finished,count:X,ignore:Y`, where X indicates processed records. If the HTTP API returns an error, verify that the `import-config` and `import-user` headers are correctly set in your cURL command. Ensure the transfer file was copied completely (compare file sizes) and that the target r-nacos node has sufficient disk space and healthy Raft consensus before attempting the import again.