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

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, 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 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 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.


# 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, invokes the export logic.

./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.

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 processes this request.

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.

#!/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 – Defines the MysqlToData command structure and argument parsing for the CLI exporter.

  • 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 – 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 – Implements TransferImportManager and TransferReader to parse the file and dispatch Raft commands.

  • src/console/transfer_api.rs – Handles the HTTP POST /v2/transfer/import endpoint via import_transfer_file().

  • 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 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 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. 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →