SQL Server → MySQL / MariaDB
Step-by-step procedure for migrating a SQL Server database to MySQL 8.0 or MariaDB 10.6+ using Endrias Bridge, including prerequisites, type mapping notes, and post-migration validation.
Overview & Scope
This SOP covers a one-time full copy (schema + data) of a SQL Server source database into an existing MySQL 8.0 or MariaDB 10.6+ target, using the Endrias Bridge Assessment and Migration tabs. Type conversions are applied automatically — see the Type Conversions reference at the bottom of this document for the complete mapping table.
Prerequisites — Source (SQL Server)
| Requirement | Notes |
|---|---|
| ODBC Driver 17 for SQL Server installed on migration host | Required |
SQL login with db_datareader + VIEW DATABASE STATE (minimum) | Minimum |
db_owner recommended for CDC stream mode | Recommended |
| TCP 1433 open from migration host to source server | Required |
-- Grant minimum permissions (run on source SQL Server)
USE EndriasBridge;
CREATE USER MigrationUser FOR LOGIN MigrationUser;
ALTER ROLE db_datareader ADD MEMBER MigrationUser;
GRANT VIEW DATABASE STATE TO MigrationUser;
Prerequisites — Target (MySQL / MariaDB)
Endrias Bridge does not create the target database — it must exist before you run Step 1. Run the following on the MySQL/MariaDB server before connecting:
-- 1. Create the target database with utf8mb4 charset (required for NVARCHAR mapping)
CREATE DATABASE EndriasBridgeTarget
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 2. Create migration user and grant access
CREATE USER 'MigrationUser'@'%' IDENTIFIED BY 'your-password';
GRANT ALL PRIVILEGES ON EndriasBridgeTarget.* TO 'MigrationUser'@'%';
FLUSH PRIVILEGES;
SET FOREIGN_KEY_CHECKS=0 is applied automatically by Endrias Bridge during the truncate pre-flight phase — you do not need to set this manually.| Requirement | Notes |
|---|---|
| MySQL 8.0+ or MariaDB 10.6+ running and accessible | Required |
Target database exists with utf8mb4 charset | Required |
MigrationUser granted ALL PRIVILEGES on target DB | Required |
| MySQL port 3306 open from migration host to target server | Required |
Configure Connections
Open Endrias Bridge and navigate to Step 5 — DB Migration. Fill in both connection blocks as shown below. Leave the Port field blank for SQL Server (uses default instance port).
SOURCE DATABASE
TARGET DATABASE
Run Assessment
In Endrias Bridge, switch to the Assessment tab and click Run Assessment. The tool connects to the source only at this stage and catalogs all objects and compatibility considerations.
SOURCE OBJECTS
Users 12,450 rows
Products 3,200 rows
Orders 890,000 rows
OrderItems 2,100,000 rows
… (43 more)
COMPATIBILITY ISSUES
• Products.Description: NVARCHAR → VARCHAR (utf8mb4)
• Orders.Amount: MONEY → DECIMAL(19,4)
• Users.RowGuid: UNIQUEIDENTIFIER → CHAR(36)
• Flags.IsActive: BIT → TINYINT(1)
• … (full list per scanned table)
TINYINT → TINYINT(1) and NVARCHAR → VARCHAR conversions will be listed in the Compatibility Issues panel. System-versioned temporal tables will also be flagged — plan to exclude or handle them in Step 3. The Assessment does not connect to the MySQL target.Select Tables
Switch to the Migration tab. Click Load Tables from Source to populate the table list, then review selections. System-versioned temporal tables will be flagged and should be excluded on the first run.
PERIOD FOR SYSTEM_TIME definition) are flagged with a warning icon. MySQL and MariaDB do not support SQL Server temporal tables natively. Exclude these tables on first run — migrate the current-row table only, then manually drop the SysStart/SysEnd period columns from the target after import.Start Migration & Monitor
Click Start Migration. Watch the Migration Log update live as type conversions are applied, schema is created, and rows are copied in batches of 1,000.
Verify & Export Report
- Click Verify Data Integrity — compares source vs. target row counts for every migrated table and logs any mismatches.
- Click Export Report (enabled once migration finishes) to save an HTML/text summary of what was created, copied, and any warnings (type changes, truncated strings, rounded decimals, etc.).
- Spot-check key tables directly on the MySQL target to confirm row counts and data values.
-- Run on MySQL target after migration to spot-check row counts
SELECT TABLE_NAME, TABLE_ROWS
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'EndriasBridgeTarget'
ORDER BY TABLE_NAME;
Post-Migration Indexes + Charset
After migration completes, perform the following post-migration validation and cleanup steps on the MySQL target.
1. Verify charset on target tables:
-- Confirm utf8mb4 charset was applied correctly
SHOW CREATE TABLE EndriasBridgeTarget.Users;
-- Expected output includes: DEFAULT CHARSET=utf8mb4
-- Check all tables in the target database
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'EndriasBridgeTarget'
ORDER BY TABLE_NAME;
2. Rebuild full-text indexes manually if needed:
-- Full-text indexes are not migrated automatically.
-- Recreate any required FULLTEXT indexes on the target:
ALTER TABLE EndriasBridgeTarget.Products
ADD FULLTEXT INDEX ft_description (Description);
3. Re-enable FK checks if disabled externally:
-- Endrias Bridge manages FK checks internally during migration.
-- If you manually disabled FK checks in your session, re-enable:
SET FOREIGN_KEY_CHECKS = 1;
Known Issues
Temporal tables (system-versioned): MySQL and MariaDB do not support SQL Server temporal tables. The history table and SysStart/SysEnd columns are not migrated — exclude these tables or migrate the current-row table only and drop the period columns from the target after import.
IDENTITY → AUTO_INCREMENT: Values are seeded from the max existing value + 1 automatically. No manual sequence reset is required.
MONEY → DECIMAL(19,4): There is no MONEY type in MySQL. Values are stored as DECIMAL with 4 decimal places — arithmetic precision is preserved but the type label changes.
XML columns: Stored as LONGTEXT on MySQL — no XQuery or XML schema validation is available on the target. If your application relies on XML querying against these columns, add application-level handling post-migration.
BIT(1) vs TINYINT(1): MySQL uses TINYINT(1) as the boolean equivalent. Endrias Bridge maps SQL Server BIT → TINYINT(1). Values 0 and 1 are preserved exactly.
Case sensitivity: MySQL on Linux is case-sensitive for table names by default (lower_case_table_names=0). If your source SQL Server uses mixed-case table names, set lower_case_table_names=1 on the MySQL target before migration to avoid name resolution issues at the application layer.
| Issue | Impact | Resolution |
|---|---|---|
| Temporal tables | History table / period columns not migrated | Exclude on first run; migrate current-row table only |
| IDENTITY → AUTO_INCREMENT | Seed set from max value + 1 | Automatic — no manual action needed |
| MONEY precision | Stored as DECIMAL(19,4) | No precision loss; type label differs |
| XML columns | Becomes LONGTEXT — no XQuery | Application-level handling if needed |
| Case sensitivity (Linux) | Table name mismatches on application queries | Set lower_case_table_names=1 on target |
Type Conversions Applied (SQL Server → MySQL)
| Source Type | Target Type | Note |
|---|---|---|
| INT IDENTITY | INT AUTO_INCREMENT | Seed set from max existing value |
| BIGINT IDENTITY | BIGINT AUTO_INCREMENT | |
| UNIQUEIDENTIFIER | CHAR(36) | No native UUID type in MySQL |
| MONEY | DECIMAL(19,4) | |
| SMALLMONEY | DECIMAL(10,4) | |
| DATETIMEOFFSET | DATETIME | Timezone offset lost — stored in UTC |
| DATETIME2 / DATETIME / SMALLDATETIME | DATETIME | |
| NVARCHAR(n) / NCHAR(n) | VARCHAR(n) / CHAR(n) | utf8mb4 charset |
| NTEXT / TEXT | LONGTEXT | |
| IMAGE / VARBINARY(MAX) | LONGBLOB | |
| VARBINARY(n) | VARBINARY(n) | |
| XML | LONGTEXT | No XML validation on target |
| BIT | TINYINT(1) | MySQL boolean convention |
| TINYINT | TINYINT | Same width |
| ROWVERSION / TIMESTAMP | BINARY(8) | No auto-update semantics on MySQL |
| hierarchyid / geography | TEXT | Read via .ToString() |
| SQL_VARIANT | TEXT | Serialized string representation |