-- 全量複製
INSERT INTO `db1`.`table_a` SELECT * FROM `db2`.`table_a`;
-- 去重複製(假設有主鍵/唯一鍵)
INSERT IGNORE INTO `db1`.`table_a` SELECT * FROM `db2`.`table_a`;
-- 限制筆數
INSERT INTO `db1`.`table_a` SELECT * FROM `db2`.`table_a` LIMIT 1000;
-- 顯式指定欄位對應
INSERT INTO `db1`.`table_a` (`id`, `name`, `email`, `created_at`)
SELECT `user_id`, `username`, `mail`, `reg_time` FROM `db2`.`users`;
-- 一次性建表+複製(結構含索引/主鍵/預設值,不含外鍵/觸發器/分區)
CREATE TABLE `db1`.`new_table` LIKE `db2`.`source_table`;
INSERT INTO `db1`.`new_table` SELECT * FROM `db2`.`source_table`;
CREATE TABLE `db1`.`empty_table` LIKE `db2`.`source_table`;
# 1. 導出單表(含結構+資料)
mysqldump -h src_host -u user -p --single-transaction --quick \
--databases src_db --tables source_table > /tmp/table.sql
# 2. 導入目標庫
mysql -h dst_host -u user -p dst_db < /tmp/table.sql
# 3. 一條管道命令完成(無中間檔,跨機房建議壓縮)
mysqldump -h src_host -u user -p --single-transaction --quick \
src_db source_table | gzip -c | ssh dst_host "gunzip -c | mysql -u user -p dst_db"
-- 1. 目標庫建立映射表
CREATE TABLE `federated_table` (
`id` INT NOT NULL,
`name` VARCHAR(50) NOT NULL
) ENGINE=FEDERATED
CONNECTION='mysql://user:pass@src_host:3306/src_db/source_table';
-- 2. 直接查詢/複製
INSERT INTO `local_table` SELECT * FROM `federated_table` WHERE ...;
限制:源表需有索引、不支援事務、DDL 需手動同步、大表效能差。僅適合臨時小表探查。
-- 範例:每批 5000 行,按主鍵範圍分批
-- 適用於單表 > 100 萬行或主從環境
DELIMITER //
CREATE PROCEDURE batch_copy()
BEGIN
DECLARE v_min_id BIGINT DEFAULT 0;
DECLARE v_max_id BIGINT DEFAULT 0;
DECLARE v_batch_size INT DEFAULT 5000;
DECLARE v_sleep_ms INT DEFAULT 100;
SELECT MIN(id), MAX(id) INTO v_min_id, v_max_id FROM src_db.source_table;
WHILE v_min_id <= v_max_id DO
INSERT IGNORE INTO dst_db.target_table
SELECT * FROM src_db.source_table
WHERE id >= v_min_id AND id < v_min_id + v_batch_size;
SET v_min_id = v_min_id + v_batch_size;
DO SLEEP(v_sleep_ms / 1000); -- 釋放鎖、緩解主從延遲
END WHILE;
END//
DELIMITER ;
CALL batch_copy();
# 僅導出 id > 1000000 的資料
mysqldump -u root -p src_db source_table \
--where="id > 1000000" > /tmp/partial.sql
# 多條件
mysqldump -u root -p src_db source_table \
--where="status=1 AND created_at > '2023-01-01'" > /tmp/active.sql
-- 1. 導出為 CSV(需 FILE 權限、secure_file_priv 目錄)
SELECT `id`, `name`, `email`
INTO OUTFILE '/var/lib/mysql-files/export.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM `source_table`;
-- 2. 目標庫高速導入
LOAD DATA INFILE '/var/lib/mysql-files/export.csv'
INTO TABLE `target_table`
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES; -- 若含標題行
速度比 INSERT 快 10~20 倍,適合 TB 級大表遷移。需注意 `secure_file_priv` 限制目錄、字符集一致、外鍵/觸發器暫時關閉。
| 錯誤 | 原因 | 修正 |
|---|---|---|
| INSERT ... SELECT 卡住/極慢 | 無索引關聯、大事務鎖表、主從延遲 | 加索引、分批、關閉 binlog (`SET sql_log_bin=0`)、暫停從庫 |
| CREATE TABLE ... LIKE 不複製外鍵/觸發器/分區 | 官方行為定義 | 手動補充 `SHOW CREATE TABLE` 獲取完整 DDL |
| mysqldump 導出報 "Access denied ... FILE privilege" | 用戶無 FILE 權限或 secure_file_priv 限制 | 授權 `GRANT FILE ON *.* TO user` 或改用管道導入 |
| FEDERATED 表查詢報 "Can't connect to MySQL server" | 連線字串錯誤、防火牆、源表無索引 | 檢查 CONNECTION 字串、源表加索引、網路連通 |
| LOAD DATA 導入資料截斷/亂碼 | 字符集不匹配、欄位長度不足、分隔符衝突 | 統一 `utf8mb4`、檢查欄位定義、用不衝突分隔符 |
資料量 < 10萬行、同實例
→ INSERT ... SELECT / CREATE TABLE LIKE + INSERT
資料量 10萬~1000萬、同實例/同機房
→ 分批存儲過程 / mysqldump 管道 / SELECT INTO OUTFILE + LOAD DATA
資料量 > 1000萬、跨機房/異構/需增量同步
→ DataX / Canal / DTS / pt-archiver
臨時探查、小表、不想導出檔案
→ FEDERATED 引擎(謹慎使用)
MySQL 跨庫/跨表複製看似簡單,實則暗藏「鎖表、主從延遲、字符集、索引缺失、權限、外鍵」等陷阱。核心原則:**小表直推、大表分批、生產用工具、導入前驗證**。建立組織內部「資料遷移 SOP」,納入變更管理流程,方能穩健演進。