mysql 修复函数表_MYSQL数据库一个BUG的修复

MYSQL数据库一个BUG的修复

环境

MYSQL 5.6

MAINTABLE 有唯一键BARCODE

PARTDEVICE

DATATABLE

MAINTABLE_HIS 有唯一键BARCODE

PARTDEVICE

DATATABLE

每天将5天前的数据从以上三个表中拷贝到历史数据表MAINTABLE_HIS/PARTDEVICE_HIS/DATATABLE_HIS中,以供查询,提高生产的效率

问题

生产节拍变慢

PARTDEVICE_HIS / DATATABLE_HIS 数据达到1亿多条

查找问题原因

PARTDEVICE_HIS / DATATABLE_HIS 中有大量重复数据

MAINTABLE / PARTDEVICE / DATATABLE中存在几个月前的数据

每天转存到历史数据表中的事件有问题

函数内容如下:

BEGIN

INSERT INTO datatablehis (

Barcode,

DeviceID,

DatiumName,

DatiumType,

DatiumValue,

DatiumTopLimit,

DatiumBottomLimit,

PartDeviceID

)SELECT

Barcode,

DeviceID,

DatiumName,

DatiumType,

DatiumValue,

DatiumTopLimit,

DatiumBottomLimit,

PartDeviceID

FROM

datatable

WHERE

Barcode in (

SELECT

Barcode

FROM

maintable

WHERE

Mfgtime

CURRENT_DATE (),

INTERVAL 5 DAY

)

);

INSERT INTO partdevicehis (

Barcode,

DeviceID,

OperatorID,

StartTime,

EndTime,

Result,

DefectID

)SELECT

Barcode,

DeviceID,

OperatorID,

StartTime,

EndTime,

Result,

DefectID

Import

FROM

partdevice

WHERE

StartTime <

DATE_SUB(

CURRENT_DATE (),

INTERVAL 5 DAY

);

INSERT INTO maintablehis (

Barcode,

PartID,

ChuteBarcode,

SkinBarcode,

CustomerBarcode,

ProcessID,

CurrentProcess,

CncID,

MfgStatusID,

MfgResultID,

DeviceFailureReasonID,

MfgTime,

Import

)SELECT

Barcode,

PartID,

ChuteBarcode,

SkinBarcode,

CustomerBarcode,

ProcessID,

CurrentProcess,

CncID,

MfgStatusID,

MfgResultID,

DeviceFailureReasonID,

MfgTime,

Import

FROM

maintable

WHERE

MfgTime <

DATE_SUB(

CURRENT_DATE (),

INTERVAL 5 DAY

);

DELETE

FROM

datatable

WHERE

Barcode in (

SELECT

Barcode

FROM

maintable

WHERE

Mfgtime

CURRENT_DATE (),

INTERVAL 5 DAY

)

);

DELETE

FROM

partdevice

WHERE

Barcode in (

SELECT

Barcode

FROM

maintable

WHERE

Mfgtime

CURRENT_DATE (),

INTERVAL 5 DAY

)

);

DELETE

FROM

maintable

WHERE

Mfgtime

CURRENT_DATE (),

INTERVAL 5 DAY

);

END

修改事件,增加日志功能:

BEGIN

DECLARE v_starttime DATETIME DEFAULT NOW();

DECLARE v_randno INTEGER DEFAULT FLOOR(RAND()*100001);

DECLARE r_code CHAR(5) DEFAULT ‘00000’;

DECLARE r_msg TEXT;

DECLARE v_error INTEGER;

INSERT INTO t_event_history (starttime,issuccess,randno) VALUES(v_starttime,0,v_randno);

BEGIN

#异常处理段

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION

BEGIN

SET v_error = 1;

GET DIAGNOSTICS CONDITION 1 r_code = RETURNED_SQLSTATE , r_msg = MESSAGE_TEXT;

END;

#此处为实际调用的用户程序过程

CALL CopyDelete();

END;

UPDATE t_event_history SET endtime=NOW(),issuccess=1,duration=TIMESTAMPDIFF(SECOND,starttime,NOW()),

errormessage=CONCAT(‘error=’,r_code,’, message=’,r_msg),randno=NULL WHERE starttime=v_starttime AND randno=v_randno;

END

发现错误日志,在插入MAINTABLE_HIS时有重复记录,无法插入,因此,后面的删除也没有执行。使用的是当前时间,所以在删除的时候有滞后,导致在MAINTABLE表中有记录没有删除。

DEBUG

首先删除MAINTABLE_HIS中与MAINTABLE中重复的记录

DELETE FROM maintablehis

WHERE BARCODE IN

(SELECT BARCODE FROM maintable)

删除PARTDEVICE_HIS / DATATABLE_HIS中重复的记录,只保留一条记录

首先在PARTDEVICE_HIS / DATATABLE_HIS 上建立一个新的索引,提高速度

ALTER TABLE partdevicehis ADD INDEX BARCODE_DEVICEID (BARCODE(50),DEVICEID(20))

用时883秒

ALTER TABLE datatablehis ADD INDEX BARCODE_DEVICEID_DATIUMNAME (BARCODE(50),DEVICEID(20),DatiumName(20))

用时863秒

删除PARTDEVICE_HIS / DATATABLE_HIS中重复的数据

用时几个小时了

DELETE FROM partdevicehis

WHERE ID NOT IN

(SELECT DTC.MIN_ID FROM

(SELECT MIN(ID) AS MIN_ID FROM partdevicehis GROUP BY BARCODE,DeviceID) DTC )

DELETE FROM datatablehis

WHERE ID NOT IN

(SELECT DTC.MIN_ID FROM

(SELECT MIN(ID) AS MIN_ID FROM partdevicehis GROUP BY BARCODE,DeviceID,DatiumName) DTC )

修改函数

BEGIN

START TRANSACTION;

set @N := (now());

INSERT INTO datatablehis (

Barcode,

DeviceID,

DatiumName,

DatiumType,

DatiumValue,

DatiumTopLimit,

DatiumBottomLimit,

PartDeviceID

)SELECT

Barcode,

DeviceID,

DatiumName,

DatiumType,

DatiumValue,

DatiumTopLimit,

DatiumBottomLimit,

PartDeviceID

FROM

datatable

WHERE

Barcode in (

SELECT

Barcode

FROM

maintable

WHERE

Mfgtime

@N,

INTERVAL 30 DAY

)

);

DELETE FROM datatable

WHERE Barcode in (

SELECT Barcode FROM maintable

WHERE

Mfgtime

@N,

INTERVAL 30 DAY

)

);

INSERT INTO partdevicehis (

Barcode,

DeviceID,

OperatorID,

StartTime,

EndTime,

Result,

DefectID

)SELECT

Barcode,

DeviceID,

OperatorID,

StartTime,

EndTime,

Result,

DefectID

Import

FROM

partdevice

WHERE

StartTime <

DATE_SUB(

@N,

INTERVAL 30 DAY

);

DELETE

FROM

partdevice

WHERE

Barcode in (

SELECT

Barcode

FROM

maintable

WHERE

Mfgtime

@N,

INTERVAL 30 DAY

)

);

INSERT INTO maintablehis (

Barcode,

PartID,

ChuteBarcode,

SkinBarcode,

CustomerBarcode,

ProcessID,

CurrentProcess,

CncID,

MfgStatusID,

MfgResultID,

DeviceFailureReasonID,

MfgTime,

Import

)SELECT

Barcode,

PartID,

ChuteBarcode,

SkinBarcode,

CustomerBarcode,

ProcessID,

CurrentProcess,

CncID,

MfgStatusID,

MfgResultID,

DeviceFailureReasonID,

MfgTime,

Import

FROM

maintable

WHERE

MfgTime <

DATE_SUB(

@N,

INTERVAL 30 DAY

);

DELETE

FROM

maintable

WHERE

Mfgtime

@N,

INTERVAL 30 DAY

);

COMMIT;

END

建立监控表

CREATE TABLE t_event_history (

id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,

dbname VARCHAR(128) NOT NULL DEFAULT ‘cat’,

eventname VARCHAR(128) NOT NULL DEFAULT ‘BakupCat’,

starttime DATETIME NOT NULL DEFAULT ‘2000-01-01 00:00:00’,

endtime DATETIME DEFAULT NULL,

issuccess INT(11) DEFAULT NULL,

duration INT(11) DEFAULT NULL,

errormessage VARCHAR(512) DEFAULT NULL,

randno INT(11) DEFAULT NULL

) ENGINE=INNODB DEFAULT CHARSET=utf8;

修改事件

DELIMITER $$

create DEFINER=root@% EVENT job_move_to_history ON SCHEDULE EVERY 1 DAY STARTS ‘2016-09-07 01:00:00’ ON COMPLETION NOT PRESERVE ENABLE DO BEGIN

DECLARE v_starttime DATETIME DEFAULT NOW();

DECLARE v_randno INTEGER DEFAULT FLOOR(RAND()*100001);

DECLARE r_code CHAR(5) DEFAULT ‘00000’;

DECLARE r_msg TEXT;

DECLARE v_error INTEGER;

INSERT INTO t_event_history (starttime,issuccess,randno) VALUES(v_starttime,0,v_randno);

BEGIN

#异常处理段

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION

BEGIN

SET v_error = 1;

GET DIAGNOSTICS CONDITION 1 r_code = RETURNED_SQLSTATE , r_msg = MESSAGE_TEXT;

END;

#此处为实际调用的用户程序过程

CALL COPYDELETE();

END;

UPDATE t_event_history SET endtime=NOW(),issuccess=1,duration=TIMESTAMPDIFF(SECOND,starttime,NOW()),

errormessage=CONCAT(‘error=’,r_code,’, message=’,r_msg),randno=NULL WHERE starttime=v_starttime AND randno=v_randno;

END$$

DELIMITER ;

通过查询t_event_history表,我们就知道event何时执行,执行是否成功,执行时长,出错时的错误信息,为管理我们日常调度计划提供很大方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值