首先把mysql的dms_data_gzdy表导出来,是一个标准sql文件dms_data_gzdy.sql

1. 预处理MySQL dump文件

需要处理MySQL特定的语法,让它兼容PostgreSQL:

# 备份原文件
cp dms_data_gzdy.sql dms_data_gzdy_original.sql

# 转换处理
sed -i 's/`//g' dms_data_gzdy.sql                           # 移除反引号
sed -i 's/AUTO_INCREMENT=[0-9]*//g' dms_data_gzdy.sql       # 移除AUTO_INCREMENT设置
sed -i '/^SET /d' dms_data_gzdy.sql                         # 移除MySQL SET语句
sed -i '/^\/\*![0-9]* /d' dms_data_gzdy.sql                # 移除MySQL版本特定注释
sed -i '/^LOCK TABLES/d' dms_data_gzdy.sql                  # 移除LOCK TABLES
sed -i '/^UNLOCK TABLES/d' dms_data_gzdy.sql               # 移除UNLOCK TABLES
sed -i 's/\\0/\\\\0/g' dms_data_gzdy.sql                   # 转义NULL字符
sed -i "s/\\\\'/'/g" dms_data_gzdy.sql                     # 处理转义单引号
sed -i 's/\\\n/\n/g' dms_data_gzdy.sql                     # 处理转义换行符

2. 进一步处理兼容性问题

创建一个Python脚本来处理更复杂的转换:

#!/usr/bin/env python3
# convert_mysql_to_pg.py

import re
import sys

def convert_mysql_dump(input_file, output_file):
    with open(input_file, 'r', encoding='utf-8') as infile, \
         open(output_file, 'w', encoding='utf-8') as outfile:
        
        skip_table_creation = False
        in_insert_block = False
        
        for line in infile:
            # 跳过DROP TABLE和CREATE TABLE语句(已经在TimescaleDB中创建)
            if line.strip().startswith('DROP TABLE'):
                continue
            if line.strip().startswith('CREATE TABLE'):
                skip_table_creation = True
                continue
            if skip_table_creation and line.strip().endswith(';'):
                skip_table_creation = False
                continue
            if skip_table_creation:
                continue
            
            # 处理INSERT语句
            if line.strip().startswith('INSERT INTO'):
                # 移除MySQL特定语法
                line = re.sub(r'INSERT INTO `?(\w+)`?', r'INSERT INTO \1', line)
                # 将datetime格式转换为PostgreSQL兼容格式
                line = re.sub(r"'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})'", r"'\1'", line)
                in_insert_block = True
            
            # 跳过其他非INSERT语句
            if not in_insert_block and not line.strip().startswith('INSERT'):
                continue
                
            # 检测INSERT块结束
            if in_insert_block and line.strip().endswith(';'):
                in_insert_block = False
            
            outfile.write(line)

if __name__ == "__main__":
    convert_mysql_dump('dms_data_gzdy.sql', 'dms_data_gzdy_pg.sql')
    print("转换完成: dms_data_gzdy_pg.sql")

运行转换脚本:

python3 convert_mysql_dump.py

3. 导入到TimescaleDB

直接导入(推荐用于较小数据量)

# 连接到TimescaleDB并导入
psql -h your_timescaledb_host -U your_username -d your_database -f dms_data_gzdy_pg.sql

4. 优化导入性能

在导入前可以临时调整一些设置以提高性能:

-- 连接到TimescaleDB
-- 临时调整设置
SET maintenance_work_mem = '2GB';
SET checkpoint_completion_target = 0.9;
SET wal_buffers = '16MB';
SET checkpoint_segments = 32;

-- 如果可能,临时禁用自动vacuum
ALTER TABLE dms_data_gzdy SET (autovacuum_enabled = false);

-- 导入完成后恢复设置
ALTER TABLE dms_data_gzdy SET (autovacuum_enabled = true);

5. 验证导入结果

-- 检查记录数
SELECT COUNT(*) FROM dms_data_gzdy;

-- 检查时间范围
SELECT MIN(record_time), MAX(record_time) FROM dms_data_gzdy;

-- 检查样本数据
SELECT * FROM dms_data_gzdy LIMIT 5;