How to get a MySQL Trigger to fire from multiple accounts - mysql

Here's my situation: I have a MySQL database in which I'd like to use triggers to automatically manage the updating of date creation and date modified fields in a few of my tables. Later, I'd like to expand them into logging data changes, but that's neither here nor there at the moment.
The triggers work fine and update the fields as intended. The problem is that the application account is now basically the only account that can affect these tables, actions from other MySQL user accounts (such as mine) fail because the definer is the application account.
I can't seem to find a way to have the trigger fire regardless of who executes a command on the tables and it's quite frustrating. Is there a way to either open up a trigger to fire regardless of user or allow multiple users to fire the trigger?
We're currently running MySQL 5.0.18 - changing this is very unlikely as the folks here in charge of infrastructure are rather resistant to fixing what (in their minds at least) isn't broken.

Related

Is there a way to watch any table changes in MySQL workbench and automatically take action upon?

I have a database shared by two completely separate server applications and those applications cannot communicate with one another at all. Let's say those two applications are called A and B. Whenever A updates table in the shared DB, B should quickly know that there was a change somehow (remember *A and B cannot communicate with each other). Also, I want to avoid using setInterval type of approach where I query every x seconds. Initially I thought there would be a way to 'watch' changes within MySQL itself but seems like there isn't. What would be the best approach to achieve this? I'm using Node.js, MySQL Workbench, and PHP.
TDLR:
I'm trying to find a best way to 'watch' any table changes and trigger action (maybe like http request) whenever change is detected. I'm using MySQL Workbench and Node.js. I really want to avoid using setInterval type of approach. Any recommendation?
What you want is a Change Data Capture (CDC) feature. In MySQL, the feature is the binary log.
Some tools like Debezium are designed to watch and filter the binary log, and transform it into events on a message queue (e.g. Kafka).
Some comments above suggest using triggers, but this is a problematic idea, because triggers fire during a data change, when the transaction for that change is not yet committed. If you try to invoke an http request or any other application action when a trigger fires, then you risk having the action execute even if the data change is subsequently rolled back. This will really confuse people.
Also there isn't a good way to run application actions from triggers. They are for making subordinate data changes, not actions that are outside transaction scope.
Using the binary log as a record of changes is safer, because changes are not written to the binary log until they are committed. Also the binary log contains all changes to all tables.
Whereas with a trigger solution you would have to create three triggers (INSERT, UPDATE, and DELETE) for each table. Also MySQL does not support triggers for DDL statements (CREATE, ALTER, DROP, TRUNCATE, etc.).

Why is MySQL Event Scheduler Stuck Opening Tables?

I'm using MySQL 8.0.21 From the MySQL Community Installer on Windows 10 updated to version2004 and for some reason if I create a event in the event scheduler, which calls a procedure once every second (regardless of what that SP actually does, I'll explain my test case) - my CPU maxes out and when I look at the active connections in MySQL Workbench, it stacks up a ton of worker threads which stall on the "Opening Tables" state. My PC freezes, I have to edit the event to be disabled, stop the MySQL process in Task Manager and Start the service again.
TEST CASE
During setup of a brand new server, I used all default settings, except I enabled the general log and I use the new 8.0+ mysql_sha2_password encryption (although I ALTER USER to mysql_native_password for phpmyadmin so that might revert it, I'm honestly not sure)
I create a new Schema called "Test"
I create one Table called
"TestTable" has only one column called "column1" INT
I then create a Stored Procedure "TestProc" which does "SELECT COUNT(*) FROM
TestTable;" Adjusts Priv.'s, DEFINER::Definer is root#localhost and
Reads SQL
And Finally I create an Event called "TestEvent" which does
"CALL TestProc()s" Reoccurring every 1/sec, preserve on Complete, and
definer is root#localhost
restart server before event is fired.
Also, if I enable the event, or create it, it'll run without issue, it's important to note that the issue begins when the event scheduler is left on, and the event is left enabled, then the server is restarted from the services in task manager. Immediately the CPU jacks up to max and active connections show threads stacking up without completing.
Any clues are appreciated, I find no actual errors nor do I have any idea where to begin debugging anymore. I've tried skipping grant tables (but obviously that's not optimal, and didn't work).
I did find a hint when reviewing the MySQL 8.0+ docs
"If a repeating event does not terminate within its scheduling interval, the result may be multiple instances of the event executing simultaneously. If this is undesirable, you should institute a mechanism to prevent simultaneous instances. For example, you could use the GET_LOCK() function, or row or table locking. " from
However, when analyzing there does not appear to be any locks, nor should I need to implement such manually just for this test case (or my actual program)
UPDATE
Up to this point, albeit a rather niche bug, I do believe that is exactly what this is, and I have posted it on MySQL bug forum. Reference post is here:
The answer actually has turned out to be a bug which is reproducible - Bug#: 100449

Triggers or Procedures

I am currently working on a web application using CakePhp as a framework and MySql as a RDMBS. The application will be used later on by tens (probably hundreds) of users at the same time and they might actually be updating the database several times a day, and I want to keep track of all the changes to the database for later analysis. Now, and in terms of optimizing my script/application, do you think that it would be better to use classic Triggers or Stored Procedures ,in order to keep track of any changes to the database after each "insert","update" or "delete" action done by the user.

Lock records when certain conditions are met

I'm creating a database that registers working hours.
People can introduce start working day, when and how long they take lunch break, and the end of the working day.
All works well, and I've created some tables that proplery catch the time.
BUT my manager wants to prevent that people can change their working hours the next day (unless of course the field is empty because the user forgot). The user should only change his working hours when the admin (manager) gives access via a password.
Note that I've created a separate database for each user (which is automatically created when the user registers) due to the need for password protection.
How would I handle this best? I don't know if locking records would work (?).
Locking controls doesn't have a purpose, because the user obviously has manual access to his own personalized password protected database.
I could provide code, but the code I would provide would be useless to this specific problem...
(I've got a hundreds of lines by now, all not really anything to do with this specific problem).
Thanks for your suggestions

Granular 'Up to the minute' data recoverability of mySQL database data

I operate a web-based online game with a mySQL backend. Every day many writes are performed against hundreds of related tables holding user data.
Frequently a user's account will become compromised. I would like the ability to restore the user's data to a certain point in time prior to the attack without affecting any other user data.
I'm aware of binary logging in mySQL, but as far as I know this is whole-database recovery up to a certain point in time. I would like a more granular solution, ie able to specify which tables, which rows etc.
What should I be looking into? What are the general best-practices?
If you create and use audit tables (populated through triggers) you can always get back to the data for one particular user in any table.
Be sure to write your general restore script before you need it though. Much easier to put in a userid into a script that you already have available than to sit there looking at the audit tables going, how do I do this again.
MySQL (or any other RDBMS that I'm aware of) is not able to do that by itself. Therefore you should implement that yourself in your application layer.
This is (without external modules) not possible.
As thejh in the comments suggested, revisions would be a good solution. When you only need to work with userdata, create a table that resembles the usertable with additional timestamp or similar and run a cron job once a week/day/.. that copies the userdata that has recently been modified (additional flags/dates in the actual user table) into this table.