I have a systemEvents table.
Trigger will be running, so whenever a new row is added, it should fetch the details from the systemEvents table and send a details to the SNMP manager as a SNMP trap/inform.
For one of your own tables, you can add functions to MySQL through its user-defined function (UDF) interface. This SO answer shows how to invoke PHP scripts through MySQL triggers (though similar should be ok for any scripts eg net-snmp ones to send traps).
EDIT: However after seeing comments from #Joddy, I realise now that it is probably the built in systemEvents table you want, i.e. it is state of whole MySQL you want, so one of tools he mentions may be simpler than UDF approach.
Related
I need to send an email when a record is added to a table.
A bunch of googling has left me with the impression that the only choices are "bad" and "really bad" and was wondering if anybody had any clean, solid, reliable suggestions.
So far I've found:
Use a mysql plugin that sends the mail. I'd rather not do this because I have a perfectly good mail server and the database wasn't designed to send mail.
Poll the table periodically from an external program, look for changes and send the mail if appropriate. This is almost OK, but I'd rather skip the dead time between the record being added and the next poll.
I had considered using SELECT ... OUTFILE, however this is really limited because it won't overwrite the output file and the only way to change the filename is by building the query with dynamic SQL, which can't be used inside a trigger.
I could write a socket listener and have Mysql open the socket and tell the mail app there are records waiting, however there doesn't seem to be a way to open a socket from mysql.
It feels like I must be missing something here.
All I want is to run an external application when a record is added.
Has anybody run into a clean, low overhead way to do this?
Modify the code that is adding the record and have it do the notifications. If you put it in a try/catch block you will know for sure whether or not the record was added successfully.
Trigger on table(s) of interest to insert into other table (email queue).
Create a scheduled process to process the other table.
I am developing a Delphi XE7 application with data stored in an online Mysql database. For the database access I use FireDAC. Because the application can be used on more than one computer simultaneously I need to be notified when a table is changed, so I can update the displayed information on each computer. FireDAC has a component called TFDEventAlerted which sounded like exactly what I need for this. But this component gives an error when activating (calling Register): [FireDAC][Phys][MySQL]-303. Capability is not supported.
I am not sure what this means, but after reading more about the component it seems Mysql does not support this type of events? If so: can anyone tell me whether there is another solution to accomplish the same?
Any help would be appreciated as I cannot seem to find a good solution.
Native MySQL doesn't have the push-notification feature you're hoping to use. To make this work you'll need to poll (to regularly run a query) to look for changes.
There are some ways to overcome this limitation if the scale of your system makes polling infeasible. You could add a user-defined function to your MySQL server, like this one to send messages: https://github.com/mysqludf/lib_mysqludf_stomp#readme
This won't work if you don't own the MySQL server; most hosting services won't allow you to install UDFs.
Or, you could build a message publish/subscribe app. This is pretty easy to do with the Amazon simple queuing service or with rabbitmq. But it's a different kind of system design from what you are probably used to.
In my article series about Firebird Database Events I proposed a solution based on message-oriented middleware. The middle tier of your application then would notify all interested parties about certain database events. Middle tier code would be database independent, all you need is a message broker who is specialized in reliable message delivery. An imaginary example for a 'after post' event handler is shown below:
procedure TAppDataModule.PurchaseOrderAfterPost(DataSet: TDataSet);
var
Notification: INotification;
begin
Notification := NotificationService.CreateNotification(PURCHASE_ORDER_TABLE_UPDATED);
Notification.SetIntProperty(PURCHASE_ORDER_ID, PurchaseOrderID.AsInteger);
NotificationService.Send(Notification);
end;
Popular free/libre open source message brokers are for example Apache ActiveMQ and RabbitMQ.
TFDEventAlerted control is not for MySQL database. That database doesn't support event model. If you want update data in "real time" then you must add manual request for changed data
Here are steps:
Add new field to your database table like "last_updated";
Fill that field by now() value on update or insert actions (by trigger or sql);
Add timer to delphi app and add request by SELECT MAX(last_updated) AS last_updated FROM my_table for last updated time;
If that time is new then request updated data by SELECT * FROM my_table WHERE last_updated >= :need_last_updated.
I want to create an insert trigger on MySQL which will automatically insert the record into an Oracle database. I would like to know if there are people that have experience to share on this topic.
Cheers
Invoke a script as is done in this example that calls the Oracle code.
Note: you lose support for transactions (there will be no built-in rollback for the Oracle database) when you perform this type of cascading, and you also will take a likely very large performance hit in doing so. The script could turn around and simply call Java code or some other executable that invokes your some generic code to insert into Oracle, or it could be a raw query that gets passed arguments from the script.
This is almost certainly a bad idea because of the odd side-effect behavior, but it's one that can be implemented. I think that you would be much better off having the code to do this against two different DataSources (in Java/.NET speak) rather than have a hidden script in a MySQL trigger that screams unmaintainable, as well as hidden failure for future developers.
I have a BEFORE UPDATE trigger on one table. Now in that trigger, I want to identify whether the update query is sent from application (Java) or it is direct from database access, like a query from MySql command prompt.
Is it possible in MySql trigger ?
No. Triggers are fired independent of clients. They are not built for client specific concerns.
And hence you can't find which client's statement caused the trigger to fire.
I know what I'm looking for is probably a security hole, but since I managed to do it in Oracle and SQL Server, I'll give it a shot:
I'm looking for a way to execute a shell command from a SQL script on MySQL. It is possible to create and use a new stored procedure if necessary.
Notice: I'm not looking for the SYSTEM command which the mysql command line tool offers. Instead I'm looking for something like this:
BEGIN IF
COND1...
EXEC_OS cmd1; ELSE
EXEC_OS cmd2; END;
where EXEC_OS is the method to invocate my code.
This isn't so much an answer to the question as it is justification for this sort of functionality - hence negating those who would say "you should do something else" or "why would you want to".
I have a database which I am trying to keep strict rules on - I don't want orphans anywhere. Referential integrity checks help me with this on the table level, but I have to keep some of the data as files within the filesystem (this is a result from a direct order from my boss to not store any binary data in the database itself).
The obvious solution here is to have a trigger which fires on deletion of a record, which then automatically deletes the associated external file.
Now, I do realise that UDF's may provide a solution, but that seems like a lot of C/C++ work to simply delete a file. Surely the database permissions themselves would provide at least some security from would-be assailants.
Now, I do realise that I could write a shell script or some such which could delete the table record and then go and delete the related file, but again, that's outside the domain of the database itself. As an old instructor once told me "the rules of the business should be reflected in the rules of the database". As one can clearly see, I cannot enforce this using MySQL.
You might want to consider writing your scripts in a more featureful scripting language, like Perl, Python, PHP, or Ruby. All of these languages have libraries to run SQL queries.
There is no built-in method in the stored procedure language for running shell commands. This is considered a bad idea, not only because it's a security hole, but because any effects of shell commands do not obey transaction isolation or rollback, as do the effects of any SQL operations you do in the stored procedure:
START TRANSACTION;
CALL MyProcedure();
ROLLBACK;
If MyProcedure did anything like create or edit a file, or send an email, etc., those operations would not roll back.
I would recommend doing your SQL work in the stored procedure, and do other work in the application that calls the stored procedure.
see do_system() in http://www.databasesecurity.com/mysql/HackproofingMySQL.pdf
According to this post at the forums.mysql.com, the solution is to use the MySQL_Proxy.