You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理Amazon DMS中MySQL/MariaDB TIME列的乱码问题

修复Amazon DMS复制MariaDB TIME列乱码问题

问题分析

你的问题根源是DMS对MariaDB启用mysql56_temporal_format后的TIME列二进制日志解析错误。MariaDB 10.1+开启该参数后,TIME列采用和MySQL 5.6一致的4字节存储格式(替代旧的3字节),但DMS的binlog读取逻辑未正确适配这种格式,导致数值被错误解析为异常时间字符串。

转换原理

正确的4字节TIME存储规则是将时间转换为秒数后,以小端字节序存储为32位有符号整数:

  • 标准TIME范围:-838:59:59到838:59:59,对应秒数范围-3020399到3020399
  • DMS错误解析时,相当于把4字节二进制数据按错误规则转成了时间字符串,我们需要反向操作:将错误时间转成总秒数,修正32位有符号整数溢出,再还原为标准TIME格式。

Python 转换实现

def fix_dms_time(wrong_time_str):
    # 处理负号标记
    is_negative = wrong_time_str.startswith('-')
    time_part = wrong_time_str[1:] if is_negative else wrong_time_str
    
    # 拆分时分秒,跳过无法解析的异常值
    try:
        h, m, s = map(int, time_part.split(':'))
    except ValueError:
        return None
    
    # 计算原始总秒数(保留符号)
    total_seconds = (h * 3600 + m * 60 + s) * (-1 if is_negative else 1)
    
    # 修正32位有符号整数溢出
    max_32bit = 2**31 - 1
    min_32bit = -2**31
    total_seconds = (total_seconds - min_32bit) % (max_32bit - min_32bit + 1) + min_32bit
    
    # 转换回标准TIME格式
    abs_seconds = abs(total_seconds)
    hours = abs_seconds // 3600
    remaining = abs_seconds % 3600
    minutes = remaining // 60
    seconds = remaining % 60
    
    sign = '-' if total_seconds < 0 else ''
    return f"{sign}{hours:02d}:{minutes:02d}:{seconds:02d}"

# 测试示例
print(fix_dms_time("112:16:02"))  # 输出: 13:22:31
print(fix_dms_time("-911:43:62")) # 输出: 13:23:59

JavaScript 转换实现

function fixDmsTime(wrongTimeStr) {
    const isNegative = wrongTimeStr.startsWith('-');
    const timePart = isNegative ? wrongTimeStr.slice(1) : wrongTimeStr;
    
    const parts = timePart.split(':');
    if (parts.length !== 3) return null;
    
    const [h, m, s] = parts.map(Number);
    if (isNaN(h) || isNaN(m) || isNaN(s)) return null;
    
    let totalSeconds = (h * 3600 + m * 60 + s) * (isNegative ? -1 : 1);
    
    // 修正32位有符号整数溢出
    const max32Bit = 2**31 - 1;
    const min32Bit = -2**31;
    totalSeconds = ((totalSeconds - min32Bit) % (max32Bit - min32Bit + 1)) + min32Bit;
    
    const absSeconds = Math.abs(totalSeconds);
    const hours = Math.floor(absSeconds / 3600);
    const remaining = absSeconds % 3600;
    const minutes = Math.floor(remaining / 60);
    const seconds = remaining % 60;
    
    const sign = totalSeconds < 0 ? '-' : '';
    return `${sign}${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}

// 测试示例
console.log(fixDmsTime("112:16:02"));  // 输出: "13:22:31"
console.log(fixDmsTime("-911:43:62")); // 输出: "13:23:59"

额外建议

  • 优先尝试升级AWS DMS Serverless版本,AWS后续版本大概率修复了该格式解析bug
  • 若无法升级,可在Kinesis消费端嵌入上述转换逻辑,对所有TIME字段批量修正
  • 验证时需对比源库与Kinesis中的TIME值,确保转换逻辑覆盖所有异常场景

内容的提问来源于stack exchange,提问作者Marco Roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 15:30:09