An event is a stored program on a schedule: AT a timestamp, or EVERY an interval between optional STARTS and ENDS. The global event_scheduler thread, ON by default, runs it as its DEFINER; toggle that thread only on a test server of your own (Running MySQL in Docker). This event cancels orders left unpaid for two weeks, first firing two seconds after creation:
CREATE EVENT expire_pending
ON SCHEDULE EVERY 1 DAY STARTS CURRENT_TIMESTAMP + INTERVAL 2 SECOND
DO UPDATE orders SET status = 'cancelled'
WHERE status = 'pending' AND ordered_at < NOW() - INTERVAL 14 DAY;
DO SLEEP(3);
SELECT e.STATUS, e.LAST_EXECUTED, o.status AS order_8 FROM information_schema.EVENTS AS e
JOIN orders AS o ON o.id = 8 WHERE e.EVENT_NAME = 'expire_pending';+---------+---------------------+-----------+ | STATUS | LAST_EXECUTED | order_8 | +---------+---------------------+-----------+ | ENABLED | 2026-09-23 08:34:34 | cancelled | +---------+---------------------+-----------+
SET GLOBAL event_scheduler = OFF pauses all events; a one-off event that fell due meanwhile ran when the scheduler came back ON, then dropped itself (ON COMPLETION NOT PRESERVE is the default). DISABLED is startup-only (error 1231 at runtime). Event errors reach only the error log, and replicas receive events as REPLICA_SIDE_DISABLED (Administration), so a job runs once. Use cron and PHP (Cron, Logs and journalctl) for jobs that need files, mail or HTTP.