MySQL Triggers, deleting a row after inactivity? - mysql

I've done some googling but can't really get much relevant information. I'm trying to set a date/time for certain rows to be deleted depending on activity. If active, the time would be bumped to a later time unless activated once again.. Otherwise it will be deleted. I've managed to sort the rows when activated (inserted/updated) in activity.
Thanks in advance.

Firstly do not put this update/delete in a trigger if you have millions of rows that needs to be deleted you are going to see a huge performance hit on inserts/updates. It is not the best place for it. You can create either a cron job as Filype suggested. Or if you want to keep it all in MySQL use the MySQL Event scheduler.
Go to this page to read more about scheduling events in MySQL:
http://dev.mysql.com/doc/refman/5.1/en/events.html
MySQL Event allows you to schedule things on MySQL on a regular basis.
The code would look something like
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
DELETE FROM MyTable Where Expired< NOW();

Here is a suggestion, I haven't tried yet, you might think to update the row with deleted=1 instead of actually deleting the record.
CREATE TRIGGER deleteInactiveRecords AFTER UPDATE,INSERT ON myTable
FOR EACH ROW BEGIN
DELETE FROM myTable WHERE updated < (updated-((60)*60*24))
END;

Related

MySQL Insert with value from previous row / MySQL triggers fire multiple times, how to limit them

I've created a log trigger that runs every time my other table is being updated, it creates a row with log informations. Unfortunately the system I am working on performs one operation as multiple queries so my trigger is fired much more times than I need. This is an output from one operation.
During parameter update the system firstly perform separate DELETE query for each row with matched parameter and product_id and then perform INSERT statement for every parameter that match product_id. Because of that the trigger is fired for every query with parameter (7 times per INSERT in this product, but there are cases with 100+ parameters per product)
So, I want to reduce it to one row per operation, the last row. In the future parameters will be updated by Webservice API so I am looking for a simpler solution than making events with JS and PHP. I thought about subtracting NOW() with the date from previous row (with the same product_id) and if the result is slightly different or the same I delete the previous row. I saw posts and articles with lag() but it seems that it's not working with INSERT INTO queries. If you have any suggestion, please, help
https://dev.mysql.com/doc/refman/8.0/en/faqs-triggers.html#faq-mysql-have-trigger-levels says:
Does MySQL 8.0 have statement-level or row-level triggers?
In MySQL 8.0, all triggers are FOR EACH ROW; that is, the trigger is
activated for each row that is inserted, updated, or deleted. MySQL
8.0 does not support triggers using FOR EACH STATEMENT.
It doesn't seem like a trigger of the type MySQL supports can work easily for your case. I recommend you simply execute your inserts, then execute the deletions you want to do from your application, not from triggers.

Does insertion in mysql happen parallely or sequentially?

I'm using mysql with InnoDB engine, and I have created one trigger for BEFORE INSERT.
I want to be sure that if two insert queries are fired at the same time then will both trigger work in parallel or sequentially?
I have added sleep in trigger and fired two insert queries, and from the execution time it looks like second trigger is waiting for first one to finish.
For InnoDB in MySql, insertions happen in parallel, in my trigger I was using the update for a different table and when the same row was getting updated then in that case insertion was happening in sequential, and when different rows were getting updated then insertion was happening parallelly.
Read this post for more details: https://stackoverflow.com/a/32382959/9599500

How to delete MySQL record automatically after a specified time if not updated?

I would like to be able to have a MySQL record automatically deleted after 60 minutes if one of its columns hasn't been updated to a certain value within that period. I can set up cron jobs in my hosting, but I'd prefer to have more granular or exact (time-specific) control over the timing. I can't think of what would constitute the trigger (other than a cron job). Is it actually possible?
You could design your application/cron-job to schedule deletion of rows when they become close to expiry, so that they delete at that specific time. You would need to double check the row is still eligible for deletion at that time just before deleting it, in case it has been updated since.

Use time interval to update and delete rows based on now()

I am working on some game logic and I need a way to update a level when time runs out. Basically, there is a research table with columns as such:
research_time_id
research_started
research_end
active
level
I need the level to be set to level+1 when research_ended is sooner then NOW().
I know how to write the UPDATE statement. My question is should I run this through mysql eventscheduler? should I run it every second? Is that too often? What is optimum in a scalable environment? This table could have many rows in it.

SQL Server 2008 - How to implement a "Watch Dog Service" which woofs when too many insert statements on a table

Like my title describes: how can I implement something like a watchdog service in SQL Server 2008 with following tasks: Alerting or making an action when too many inserts are committed on that table.
For instance: Error table gets in normal situation 10 error messages in one second. If more than 100 error messages (100 inserts) in one second then: ALERT!
Would appreciate it if you could help me.
P.S.: No. SQL Jobs are not an option because the watchdog should be live and woof on the fly :-)
Integration Services? Are there easier ways to implement such a service?
Kind regards,
Sani
I don't understand your problem exactly, so I'm not entirely sure whether my answer actually solves anything or just makes an underlying problem worse. Especially if you are facing performance or concurrency problems, this may not work.
If you can update the original table, just add a datetime2 field like
InsertDate datetime2 NOT NULL DEFAULT GETDATE()
Preferrably, make an index on the table and then with whatever interval that fits, poll the table by seeing how many rows have an InsertDate > GetDate - X.
For this particular case, you might benefit from making the polling process read uncommitted (or use WITH NOLOCK), although one has to be careful when doing so.
If you can't modify the table itself and you can't or won't make another process or job monitor the relevant variables, I'd suggest the following:
Make a 'counter' table that just has one Datetime2 column.
On the original table, create an AFTER INSERT trigger that:
Deletes all rows where the datetime-field is older than X seconds.
Inserts one row with current time.
Counts to see if too many rows are now present in the counter-table.
Acts if necessary - ie. by executing a procedure that will signal sender/throw exception/send mail/whatever.
If you can modify the original table, add the datetime column to that table instead and make the trigger count all rows that aren't yet X seconds old, and act if necessary.
I would also look into getting another process (ie. an SQL Jobs or a homemade service or similar) to do all the housekeeping, ie. deleting old rows, counting rows and acting on it. Keeping this as the work of the trigger is not a good design and will probably cause problems in the long run.
If possible, you should consider having some other process doing the housekeeping.
Update: A better solution will probably be to make the trigger insert notifications (ie. datetimes) into a queue - if you then have something listening against that queue, you can write logic to determine whether your threshold has been exceeded. However, that will require you to move some of your logic to another process, which I initially understood was not an option.