diff --git a/db/routines/vn/functions/diagnoseProductionFailure_dbFreeze.sql b/db/routines/vn/functions/diagnoseProductionFailure_dbFreeze.sql new file mode 100644 index 0000000000..fd40a76949 --- /dev/null +++ b/db/routines/vn/functions/diagnoseProductionFailure_dbFreeze.sql @@ -0,0 +1,30 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`diagnoseProductionFailure_dbFreeze`() + RETURNS int(11) + DETERMINISTIC +BEGIN +/** + * Comprueba si la db está congelada. + * + * @table tmp.diagnoseProductionFailure(message, hasError) + */ + DECLARE vHasError BOOL; + DECLARE vMaxThreads INT; + DECLARE vMaxTime INT; + + SELECT dbFreezeMaxThreads, dbFreezeMaxTime + INTO vMaxThreads, vMaxTime + FROM diagnoseProductionFailureConfig; + + IF vMaxThreads IS NULL OR vMaxTime IS NULL THEN + CALL util.throw("Configuration variables not set"); + END IF; + + SELECT COUNT(ID) INTO vHasError + FROM information_schema.PROCESSLIST + WHERE COMMAND = 'Query' + AND `time` > vMaxTime; + + RETURN vHasError; +END$$ +DELIMITER ; diff --git a/db/routines/vn/functions/diagnoseProductionFailure_dbGetLock.sql b/db/routines/vn/functions/diagnoseProductionFailure_dbGetLock.sql new file mode 100644 index 0000000000..809341cdc2 --- /dev/null +++ b/db/routines/vn/functions/diagnoseProductionFailure_dbGetLock.sql @@ -0,0 +1,35 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`diagnoseProductionFailure_dbGetLock`() + RETURNS int(11) + DETERMINISTIC +BEGIN +/** + * Comprueba si la db está congelada. + * + * @table tmp.diagnoseProductionFailure(message, hasError) + */ + DECLARE vHasError BOOL; + DECLARE vMaxTime INT; + + SELECT dbGetLockMaxTime INTO vMaxTime + FROM diagnoseProductionFailureConfig; + + IF vMaxTime IS NULL THEN + CALL util.throw("Configuration variable not set"); + END IF; + + /* Bug: En local la tabla METADATA_LOCK_INFO no existe... + + SELECT COUNT(*) INTO vHasError + FROM information_schema.METADATA_LOCK_INFO mli + JOIN information_schema.PROCESSLIST pl ON pl.ID = mli.THREAD_ID + WHERE mli.LOCK_MODE = 'MDL_SHARED_NO_WRITE' + AND pl.`time` > vMaxTime; + + RETURN vHasError; + + */ + + RETURN TRUE; +END$$ +DELIMITER ; diff --git a/db/routines/vn/procedures/diagnoseProductionFailure.sql b/db/routines/vn/procedures/diagnoseProductionFailure.sql new file mode 100644 index 0000000000..f03525b195 --- /dev/null +++ b/db/routines/vn/procedures/diagnoseProductionFailure.sql @@ -0,0 +1,66 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`diagnoseProductionFailure`( + vWarehouseFk INT +) +BEGIN +/** + * Comprueba si hay fallos en producción. + */ + DECLARE vDynSql VARCHAR(125); + DECLARE vSchema VARCHAR(64); + DECLARE vFunction VARCHAR(64); + DECLARE vParams VARCHAR(255); + DECLARE vMessage TEXT; + DECLARE vResolution TEXT; + DECLARE vDone BOOL; + DECLARE cFunctions CURSOR FOR + SELECT `schema`, + `function`, + params, + `message`, + resolution + FROM diagnoseProductionFailureQueue + ORDER BY `order`; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + + CREATE OR REPLACE TEMPORARY TABLE tDiagnoseProductionFailure ( + `message` TEXT NOT NULL, + hasError TINYINT(1) NOT NULL, + `resolution` TEXT + ); + + OPEN cFunctions; + l: LOOP + SET vDone = FALSE; + FETCH cFunctions INTO + vSchema, + vFunction, + vParams, + vMessage, + vResolution; + + IF vDone THEN + LEAVE l; + END IF; + + SET vDynSql = CONCAT('SELECT ', vSchema, '.', vFunction, '() INTO @vHasError'); + PREPARE stmt FROM vDynSql; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + + INSERT INTO tDiagnoseProductionFailure + SELECT vMessage, + @vHasError, + IF (@vHasError, + vResolution, + NULL + ); + + END LOOP; + CLOSE cFunctions; + + SELECT * FROM tDiagnoseProductionFailure; + DROP TEMPORARY TABLE tDiagnoseProductionFailure; +END$$ +DELIMITER ; diff --git a/db/versions/11067-brownLaurel/00-firstScript.sql b/db/versions/11067-brownLaurel/00-firstScript.sql new file mode 100644 index 0000000000..44a044a052 --- /dev/null +++ b/db/versions/11067-brownLaurel/00-firstScript.sql @@ -0,0 +1,27 @@ +CREATE TABLE `vn`.`diagnoseProductionFailureQueue` ( + `schema` varchar(64) NOT NULL, + `function` varchar(64) NOT NULL, + `params` varchar(255) DEFAULT NULL, + `order` int(11) DEFAULT NULL, + `message` text NOT NULL, + `resolution` text DEFAULT NULL, + PRIMARY KEY (`schema`,`function`), + UNIQUE KEY `diagnoseProductionFailureQueue_unique` (`order`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +CREATE TABLE `vn`.`diagnoseProductionFailureConfig` ( + `id` int(11) NOT NULL, + `dbFreezeMaxThreads` int(11) NOT NULL, + `dbFreezeMaxTime` int(11) NOT NULL, + `dbGetLockMaxTime` int(11) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `diagnoseProductionFailureConfig_check` CHECK (`id` = 1) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +INSERT IGNORE INTO vn.diagnoseProductionFailureConfig (id,dbFreezeMaxThreads,dbFreezeMaxTime,dbGetLockMaxTime) + VALUES (1, 5, 60, 30); + +INSERT IGNORE INTO vn.diagnoseProductionFailureQueue (`schema`,`function`,`order`,message,resolution) VALUES + ('vn','diagnoseProductionFailure_dbFreeze',1,'Base de datos congelada','Esto es una prueba 1'), + ('vn','diagnoseProductionFailure_dbGetLock',2,'Get lock bloqueando para asignar colecciones','Esto es una prueba 2'); +