提问人:Code Magician 提问时间:11/7/2023 最后编辑:user1191247Code Magician 更新时间:11/8/2023 访问量:57
计划事件未正确执行
Scheduled Event not Executing Properly
问:
我有一个计划每晚运行的 mysql 事件,定义如下:
create definer = myuser@`%` event nightly on schedule
every '1' DAY
starts '2023-10-21 00:00:00'
enable
do
call mydb.nightly_script;
尽管当我查看将由 proc 修改的表时,更新没有发生。如果我从事件中复制该行并执行它,我会看到过程正确执行,但是该事件没有任何反应。call mydb.nightly_script;
我已经完成了基本的故障排除步骤。我已验证事件调度程序是ON
SELECT @@event_scheduler
返回
event_scheduler |
---|
上 |
而且,当我查看 information_schema 中的 EVENTS 表时,它显示该事件每晚都在运行。
SELECT *
FROM information_schema.EVENTS
WHERE EVENT_NAME = 'nightly';
EVENT_CATALOG | EVENT_SCHEMA | EVENT_NAME | 定义者 | TIME_ZONE | EVENT_BODY | EVENT_DEFINITION | EVENT_TYPE | EXECUTE_AT | INTERVAL_VALUE | INTERVAL_FIELD | SQL_MODE | 开始 | 结束 | 地位 | ON_COMPLETION | 创建 | LAST_ALTERED | LAST_EXECUTED | EVENT_COMMENT | 鼻祖 | CHARACTER_SET_CLIENT | COLLATION_CONNECTION | DATABASE_COLLATION |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
def | mydb的 | 夜间 | myuser@% | 系统 | SQL算法 | 致电mydb.nightly_script | 经常性 | 零 | 1 | 日 | STRICT_TRANS_TABLES | 2021-10-21 18:08:00 | 零 | 启用 | 不保存 | 2023-10-05 18:07:45 | 2023-11-05 00:00:45 | 2023-11-06 00:00:02 | 2866802262 | UTF8MB4的 | utf8mb4_general_ci | latin1_swedish_ci |
尽管一切都表明计划程序正在运行并且事件正在触发,但存储过程要么没有运行,要么以某种方式失败,我不确定如何进一步调查(它是 Azure DBaaS,我不确定如何找到相关日志,如果它们存在的话)。
我尝试了在事件正文中对命令进行一些变体,例如验证过程名称的大小写,使用点表示法完全限定过程,包括或排除过程末尾的parens(它不采用任何参数)等。call
过程和事件的定义者都是我的用户,例如
CREATE
definer = myuser@`%` procedure nightly()
BEGIN
...
我的用户具有以下 GRANTS:
SHOW GRANTS FOR myuser
myuser@% 的赠款 |
---|
授予选择、插入、更新、删除、创建、删除、重新加载、处理、引用、索引、更改、显示数据库、创建临时表、锁定表、执行、复制从属、复制客户端、创建视图、显示视图、创建例程、更改例程、创建用户、事件、触发器。到带有授权选项的 'MYUSER'@'%' |
存储过程本身的主体如下所示:
CREATE
definer = myuser@`%` procedure AutoTagAll()
BEGIN
/*Clean up any tables that shouldn't be there*/
drop table if exists jobuserlist;
drop table if exists pl;
drop table if exists listIds;
drop table if exists OldList;
/*Create staging tables */
CREATE TEMPORARY TABLE OldList(
listId CHAR(36),
contactId CHAR(36),
PRIMARY KEY(contactId, listID))
;
CREATE TEMPORARY TABLE jobUserList
(
user_id CHAR(36) PRIMARY KEY,
company_id CHAR(36)
);
CREATE INDEX IXN__jobUserList__company_id on jobUserList (company_id);
CREATE TEMPORARY TABLE pl
(
ListId CHAR(36),
contactId CHAR(36),
primary key (listId, contactId)
);
CREATE TEMPORARY TABLE listIds(
listID CHAR(36) PRIMARY KEY,
listName VARCHAR(200)
);
insert into jobUserList ( user_id, company_id)
...
/*clean up*/
drop table if exists jobuserlist;
drop table if exists pl;
drop table if exists listIds;
drop table if exists OldList;
END;
鉴于该事件无法正常运行,我目前在另一台正在连接并进行调用的机器上运行一个 bash 脚本:
...
#Prepare sql query
SQL_Query='call mydb.nightly'
#mysql command to connect to database
mysql -h$MASTER_DB_HOST -u$MASTER_DB_USER -p$MASTER_DB_PASSWD --ssl_mode=REQUIRED -D$MASTER_DB_NAME <<EOF
$SQL_Query
EOF
echo "script complete."
但是,我对这种解决方法的安全性和可靠性不满意,并且更愿意将此工作集成到 RDBMS 调度程序中。
在这一点上,我不确定如何将事件用于我想要的目的。我在活动中遗漏了什么吗?这是错误的方法吗?存储过程本身是否有冗长的内容(在 mydb 中创建临时表、执行插入、更新和删除)?
提前感谢 SO 社区!
答:
我不确定这是否适用于您的 Azure DB,但您可以尝试查询performance_schema:
SELECT * FROM performance_schema.error_log WHERE `DATA` LIKE '%scheduler%';
如果失败,您可以添加一个简单的日志表,并在您的进程中添加一些日志记录语句:
CREATE TABLE nightly_log (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
message VARCHAR(255) NOT NULL,
ts DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
);
CREATE
definer = myuser@`%` procedure AutoTagAll()
BEGIN
DECLARE _RowCount INT;
INSERT INTO nightly_log (message) VALUES ('Starting AutoTagAll');
/*Clean up any tables that shouldn't be there*/
drop table if exists jobuserlist;
drop table if exists pl;
drop table if exists listIds;
drop table if exists OldList;
INSERT INTO nightly_log (message) VALUES ('Populating jobUserList...');
insert into jobUserList ( user_id, company_id)
select ...
SET _RowCount = ROW_COUNT();
INSERT INTO nightly_log (message) VALUES (CONCAT(_RowCount, ' rows inserted into jobUserList'));
...
我在活动中遗漏了什么吗?这是错误的方法吗?
我使用示例存储过程检查了您的方案,它工作正常。您面临问题有两种可能的情况。
- 检查您在排序过程中使用的所有名称作为表名或您在 Event 中调用的存储过程名称。
在这里,我尝试了以下代码,每分钟都有示例存储过程:
--created sample Stored procedure to insert the rows
DELIMITER //
CREATE PROCEDURE Insertstudent()
BEGIN
--your code
insert into student (Id, Name) values (1,'Amy');
END //
DELIMITER ;
--created event to insert row on every minute by calling above stored procedure
create event minutelycity
on schedule every '1' minute
starts '2023-07-11 00:00:00'
enable
do
call mydb.Insertstudent();
您可以看到上面的过程名称在事件中创建和使用它时是相同的。
要验证是否为 On - 执行以下命令:event_scheduler
SHOW PROCESSLIST;
它将输出一个表/条目,您必须使用 User 和 Command 查找条目:event_scheduler
Daemon
每分钟为我插入行:
存储过程本身是否有冗长的内容(在 mydb 中创建临时表、执行插入、更新和删除)?
正如您所说,当您在事件外部调用它时,它工作正常,因此请检查您在事件中使用的 SP 的名称。
评论