MySQL定时任务执行Insert语句失败,报Error 2013连接丢失
解决MySQL任务调度时查询超时丢失连接的问题
问题场景
手动执行SQL脚本可正常运行,但通过任务调度执行时频繁出现Error Code 2013: Lost Connection to MySQL during query错误,导致table_a仅创建表头,无数据插入。
解决方案
1. 优化查询性能,缩短执行时间
- 添加必要索引:针对关联字段和过滤条件创建索引,大幅提升查询速度:
-- 为主表labs_inventory添加索引 CREATE INDEX idx_labs_inv_lotid ON skynet_msa.labs_inventory(LOTID); CREATE INDEX idx_labs_inv_filter ON skynet_msa.labs_inventory(lot_location, module_lot); -- 为关联表lab_inv_prio添加索引 CREATE INDEX idx_lab_prio_lotid ON skynet_msa.lab_inv_prio(lot_id); - 移除不必要排序:原SQL末尾的
order by lot_location如果不是业务必需,直接删除——排序会额外消耗大量时间,尤其是数据量较大时。 - 简化字段计算:原SQL中
CONCAT(trim(PACKAGE_WIDTH)+0,'x',trim(PACKAGE_LENGTH)+0,'x',trim(PACKAGE_HEIGHT)+0)的+0转换若可省略(如字段本身为数值型),直接去掉;若频繁使用该计算字段,可考虑在源表中预计算存储。
2. 调整MySQL超时参数
修改MySQL配置文件(my.cnf或my.ini),延长超时时间,避免因查询耗时过长被断开连接:
wait_timeout = 3600 interactive_timeout = 3600 net_read_timeout = 300
修改后重启MySQL服务生效;若无法重启服务,可通过临时会话调整:
SET GLOBAL wait_timeout = 3600; SET GLOBAL interactive_timeout = 3600; SET GLOBAL net_read_timeout = 300;
同时检查任务调度工具的连接超时设置,确保其值大于MySQL的超时参数。
3. 拆分脚本为独立步骤
将原脚本的删除表、创建表、插入数据、修改表结构拆分为独立执行单元,避免单条语句执行时间过长:
-- 步骤1:删除旧表 DROP TABLE IF EXISTS table_a; -- 步骤2:创建表时直接包含所有字段,避免后续ALTER操作 CREATE TABLE table_a ( LOT_LOCATION VARCHAR(255), `Zone Attribute` VARCHAR(255), LOTID VARCHAR(255), DESIGN_ID VARCHAR(255), QA_WORK_REQUEST_NO VARCHAR(255), PRIORITY VARCHAR(255), QA_PROCESS_TYPE VARCHAR(255), QA_PROCESS_NAME VARCHAR(255), START_TIME DateTime, ENV_TEST_INTERVAL VARCHAR(255), EST_DURATION_TIME VARCHAR(255), days VARCHAR(255), elapsed VARCHAR(255), END_TIME DateTime, CURRENT_QTY VARCHAR(255), LOCATION VARCHAR(255), PACKAGE_TYPE VARCHAR(255), NUMBER_OF_DIE_IN_PKG VARCHAR(255), LEAD_COUNT VARCHAR(255), PACKAGE_SIZE VARCHAR(255), CONFIGURATION_WIDTH VARCHAR(255), RPM_WW VARCHAR(255), TC_WEIGHT VARCHAR(255), QA_BURN_EXPERIMENT VARCHAR(255), QA_CONTACT_NAME VARCHAR(255), row_created Timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ); -- 步骤3:插入数据(移除不必要的order by) INSERT INTO table_a SELECT LOT_LOCATION, '', -- Zone Attribute字段默认值 LOTID, DESIGN_ID, QA_WORK_REQUEST_NO, COALESCE(B.priority, A.PRIORITY, 4) AS PRIORITY, QA_PROCESS_TYPE, QA_PROCESS_NAME, LOCATION_DATE AS START_TIME, ENV_TEST_INTERVAL, ROUND(EST_DURATION_TIME), ROUND(EST_DURATION_TIME /24) AS days, HOUR(TIMEDIFF(NOW(), LOCATION_DATE)) AS elapsed, BINOUT_DUE_DATE AS END_TIME, CURRENT_QTY, A.LOCATION, PACKAGE_TYPE, NUMBER_OF_DIE_IN_PKG, LEAD_COUNT, CONCAT(trim(PACKAGE_WIDTH)+0,'x',trim(PACKAGE_LENGTH)+0,'x',trim(PACKAGE_HEIGHT)+0) AS PACKAGE_SIZE, CONFIGURATION_WIDTH, RPM_WW, TC_WEIGHT, QA_BURN_EXPERIMENT, QA_CONTACT AS QA_CONTACT_NAME FROM skynet_msa.labs_inventory A LEFT JOIN skynet_msa.lab_inv_prio B ON A.LOTID = B.lot_id WHERE (lot_location LIKE 'SGHAST%' OR lot_location LIKE 'SGTHS%' OR lot_location LIKE 'SGBAKE%' OR lot_location LIKE 'SGTC%' OR lot_location LIKE 'SGTHB%' OR lot_location LIKE 'SGTS%' OR lot_location LIKE 'SGREFLOW%') AND module_lot != 1;
4. 分批次插入数据
如果源表数据量极大,将插入操作按过滤条件拆分,分批次执行:
-- 分批次插入不同lot_location的数据 INSERT INTO table_a SELECT ... WHERE lot_location LIKE 'SGHAST%' AND module_lot !=1; INSERT INTO table_a SELECT ... WHERE lot_location LIKE 'SGTHS%' AND module_lot !=1; INSERT INTO table_a SELECT ... WHERE lot_location LIKE 'SGBAKE%' AND module_lot !=1; -- 依次处理剩余的lot_location条件
每次插入少量数据,降低单条语句的执行时间。
5. 排查调度环境问题
- 检查调度服务器与MySQL服务器之间的网络稳定性,避免因网络波动导致连接中断;
- 确认调度工具的资源限制(CPU、内存),防止因资源不足导致执行缓慢触发超时。
内容的提问来源于stack exchange,提问作者GQS
相关产品推荐
相关产品推荐

