DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Building an Enterprise CDC Solution
  • Change Data Captures CDC from MySQL Database to Kafka with Kafka Connect and Debezium
  • Harnessing the Power of AWS Aurora for Scalable and Reliable Databases
  • Enhancing Performance: Optimizing Complex MySQL Queries for Large Datasets

Trending

  • A Modern Stack for Building Scalable Systems
  • How to Configure and Customize the Go SDK for Azure Cosmos DB
  • Building Enterprise-Ready Landing Zones: Beyond the Initial Setup
  • From Zero to Production: Best Practices for Scaling LLMs in the Enterprise
  1. DZone
  2. Data Engineering
  3. Databases
  4. MySQL Database Table Data Purge/Removal Using MySQL Event Scheduler

MySQL Database Table Data Purge/Removal Using MySQL Event Scheduler

In this post, the author will be sharing his experience of how we can create a recurring event in MySQL to purge/remove the table data.

By 
Kapil Khandelwal user avatar
Kapil Khandelwal
·
Jul. 16, 19 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
13.8K Views

Join the DZone community and get the full member experience.

Join For Free

In this article, let's look at

  1. Deleting table data in batches/chunks
  2. Logging each iteration
  3. Handling and logging errors
  4. Creating a recurring event to cleanup/purge table data regularly

Recently, I was working on creating a utility to purge the table data of MySQL Database. In this post, I will be sharing my experience of how we can create a recurring event in MySQL to purge/remove the table data.

Step 1:

Basic Setup (Sample Database/Tables)

orders is the table for which we need to create purge job/utility.

CREATE TABLE `orders` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `OrderNumber` varchar(45) NOT NULL,
  `Total` double DEFAULT NULL,
  `Tax` double DEFAULT NULL,
  `Status` int(11) NOT NULL,
  `OrderDateUtc` datetime NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=112377 DEFAULT CHARSET=utf8;

*Note: Insert data in the orders table

log table to store the purge job/utility logs

CREATE TABLE `log` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Message` varchar(150) COLLATE utf8_bin NOT NULL,
`CreatedDateUtc` datetime NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=81 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

Step 2:

Get the minimum and maximum value of 'ID' (auto-increment column in orders table) satisfying Date range condition (based on DaysToRetainParam).

Here, DaysToRetainParam is the input parameter and is used to specify the duration in days for which we want to retain the data in the orders table.

DECLARE minID INT;
DECLARE maxID INT;
DECLARE createdDateUtcForIteration DATETIME;
SET createdDateUtcForIteration = UTC_TIMESTAMP();

SELECT 
    MIN(id), MAX(id)
    INTO minID, maxID
FROM
    sample.orders AS orders
WHERE
    OrderDateUtc < DATE_SUB(createdDateUtcForIteration,
                INTERVAL DaysToRetainParam DAY);

Step 3:

Delete table data in batches/chunks (here, the chunk size is 1000) with a sleep of 1 second between batches.

DECLARE createdDateUtcForIteration DATETIME;
DECLARE rowsDeleted INT;
DECLARE rowCount INT;
DECLARE maxBatchID INT;
SET createdDateUtcForIteration = UTC_TIMESTAMP();
SET rowsDeleted = 0;


OrdersPurge: LOOP

  SET maxBatchID = 0;

  SELECT 
    id
    INTO maxBatchID
  FROM
    sample.orders AS orders
  WHERE
    id >= minID AND id <= maxID AND
    OrderDateUtc < DATE_SUB(createdDateUtcForIteration,
                INTERVAL DaysToRetainParam DAY)
  ORDER BY id
  LIMIT 1000, 1;

  IF maxID < minID OR minID is null OR maxBatchID = minID OR maxBatchID is null OR maxBatchID = 0 THEN
    -- SELECT minID, maxID, maxBatchID, 'exit';
         LEAVE OrdersPurge;  -- last chunk
  END IF;

  DELETE FROM sample.orders
  WHERE
    id >= minID AND id < maxBatchID
    AND OrderDateUtc < DATE_SUB(createdDateUtcForIteration,
            INTERVAL DaysToRetainParam DAY);

  SELECT ROW_COUNT() INTO rowCount;
    -- SELECT rowCount;
    SET rowsDeleted = rowsDeleted + rowCount;
  SET minID = maxBatchID;

    -- Log message
  INSERT INTO sample.log
  (Message,
  CreatedDateUtc)
  VALUES
  (concat('Iteration: ' , rowCount, ' rows deleted.'),
  UTC_TIMESTAMP());

  DO SLEEP(1);

END LOOP OrdersPurge;

Step 4:

Delete the last batch

IF minID is not null THEN
  DELETE FROM sample.orders
  WHERE
    id >= minID AND id <= maxID
    AND OrderDateUtc < DATE_SUB(createdDateUtcForIteration,
        INTERVAL DaysToRetainParam DAY);

Step 5:

Handle and log the error

DECLARE errorCode CHAR(5) DEFAULT '00000';
DECLARE errorMessage TEXT;

DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN

  GET DIAGNOSTICS CONDITION 1 errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;

  INSERT INTO sample.log
  (Message,
  CreatedDateUtc)
  VALUES
  (CONCAT('Error = ',errorCode,', message = ',errorMessage),
  UTC_TIMESTAMP());
END;

Step 6:

Full code of OrdersPurge stored procedure

CREATE DEFINER=`root`@`localhost` PROCEDURE `OrdersPurge`(
IN DaysToRetainParam int
)
BEGIN

DECLARE createdDateUtcForIteration DATETIME;
DECLARE rowsDeleted INT;
DECLARE rowCount INT;
DECLARE minID INT;
DECLARE maxID INT;
DECLARE maxBatchID INT;
DECLARE errorCode CHAR(5) DEFAULT '00000';
DECLARE errorMessage TEXT;

DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN

  GET DIAGNOSTICS CONDITION 1 errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;

  INSERT INTO sample.log
  (Message,
  CreatedDateUtc)
  VALUES
  (CONCAT('Error = ',errorCode,', message = ',errorMessage),
  UTC_TIMESTAMP());
END;


SET createdDateUtcForIteration = UTC_TIMESTAMP();

INSERT INTO sample.log
(Message,
CreatedDateUtc)
VALUES
('Started.',
UTC_TIMESTAMP());

SELECT 
    MIN(id), MAX(id)
    INTO minID, maxID
FROM
    sample.orders AS orders
WHERE
    OrderDateUtc < DATE_SUB(createdDateUtcForIteration,
                INTERVAL DaysToRetainParam DAY);

SET rowsDeleted = 0;

OrdersPurge: LOOP

  SET maxBatchID = 0;

  SELECT 
    id
    INTO maxBatchID
  FROM
    sample.orders AS orders
  WHERE
    id >= minID AND id <= maxID AND
    OrderDateUtc < DATE_SUB(createdDateUtcForIteration,
                INTERVAL DaysToRetainParam DAY)
  ORDER BY id
  LIMIT 1000, 1;

  IF maxID < minID OR minID is null OR maxBatchID = minID OR maxBatchID is null OR maxBatchID = 0 THEN
    -- SELECT minID, maxID, maxBatchID, 'exit';
         LEAVE OrdersPurge;  -- last chunk
  END IF;

  DELETE FROM sample.orders
  WHERE
    id >= minID AND id < maxBatchID
    AND OrderDateUtc < DATE_SUB(createdDateUtcForIteration,
            INTERVAL DaysToRetainParam DAY);

  SELECT ROW_COUNT() INTO rowCount;
    -- SELECT rowCount;
    SET rowsDeleted = rowsDeleted + rowCount;
  SET minID = maxBatchID;

    -- Log message
  INSERT INTO sample.log
  (Message,
  CreatedDateUtc)
  VALUES
  (concat('Iteration: ' , rowCount, ' rows deleted.'),
  UTC_TIMESTAMP());

  DO SLEEP(1);

END LOOP OrdersPurge;

IF minID is not null THEN
  DELETE FROM sample.orders
  WHERE
    id >= minID AND id <= maxID
    AND OrderDateUtc < DATE_SUB(createdDateUtcForIteration,
        INTERVAL DaysToRetainParam DAY);

    SELECT ROW_COUNT() INTO rowCount;
  -- SELECT rowCount;
  SET rowsDeleted = rowsDeleted + rowCount;
  -- SELECT rowsDeleted as TotalRowsDeleted;

    -- Log message
  INSERT INTO sample.log
  (Message,
  CreatedDateUtc)
  VALUES
  (concat('Iteration: ' , rowCount, ' rows deleted.'),
  UTC_TIMESTAMP());

END IF;

-- Log message
INSERT INTO sample.log
(Message,
CreatedDateUtc)
VALUES
(concat('Completed successfully. ', rowsDeleted, ' rows deleted.'),
UTC_TIMESTAMP());

END

Step 7:

Check and enable MySQL Event Scheduler.

Check whether the MySQL Event Scheduler is enabled:

SHOW PROCESSLIST;

If it is enabled, it will be listed in the output.

If it is not enabled, then enable it by updating the MySQL my.ini or my.cnf file as shown below:

[mysqld]

# Event Scheduler
# OFF: The Event Scheduler is stopped.
# ON: The Event Scheduler is started; the event scheduler thread runs and executes all scheduled events.
# DISABLED: This value renders the Event Scheduler nonoperational.
event_scheduler=ON

Or,

SET GLOBAL event_scheduler = ON;

Step 8:

Create a recurring event in MySQL.

OrdersPurgeEvent Event:

  1. Starts at '2019-06-15 11:42:00'
  2. Run everyday at 11:42:00
  3. Calls the OrdersPurge Stored Procedure.

Note: Do change Start DateTime to any future value at which you want the event to start.

DROP EVENT IF EXISTS OrdersPurgeEvent;
CREATE EVENT IF NOT EXISTS OrdersPurgeEvent
  ON SCHEDULE EVERY 1 DAY
  STARTS '2019-06-15 11:42:00'
  DO
    CALL sample.OrdersPurge(30);

Check Event:

SHOW EVENTS;

Step 9:

Table data purge job utility log of one the iteration

That's it!
Database Data (computing) Event MySQL job scheduling

Published at DZone with permission of Kapil Khandelwal, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Building an Enterprise CDC Solution
  • Change Data Captures CDC from MySQL Database to Kafka with Kafka Connect and Debezium
  • Harnessing the Power of AWS Aurora for Scalable and Reliable Databases
  • Enhancing Performance: Optimizing Complex MySQL Queries for Large Datasets

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!