I am stuck at somewhere and I need some help from you.
I have two databases i.e., test_db1
and test_db2
and have users
I found a hack via DECLARE CONTINUE HANDLER
and GET DIAGNOSTICS CONDITION
, so just thought, I must share it here.
Here's my complete final script which keeps backup (sync) for both databases users
table what it means is that any update on test_db1
(which we may call it as a productionDB) will occur on test_db2
(which we may call it to as stagingDB):
/*
Create two databases:
1. `test_db1`
2. `test_db2`
and execute below create *Table script* on both databases.
after that execute *Triggers Script* on `test_db1` only..
*/
/*
TABLE STRUCTURE FOR `users`
*/
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) AUTO_INCREMENT NOT NULL,
`name` varchar(30) NOT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
/*
TABLE STRUCTURE FOR `errors`
*/
DROP TABLE IF EXISTS `errors`;
CREATE TABLE IF NOT EXISTS `errors` (
`id` int(11) AUTO_INCREMENT NOT NULL,
`code` varchar(30) NOT NULL,
`message` TEXT NOT NULL,
`query_type` varchar(50) NOT NULL,
`record_id` int(11) NOT NULL,
`on_db` varchar(50) NOT NULL,
`on_table` varchar(50) NOT NULL,
`emailed` TINYINT DEFAULT 0,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
/*
TRIGGERS SCRIPTS FOR INSERT, UPDATE AND DELETE OPERATIONS
*/
DELIMITER //
-- TRIGGER FOR INSERT
DROP TRIGGER IF EXISTS `test_db1_users_ai`;
CREATE TRIGGER `test_db1_users_ai` AFTER INSERT ON `users` FOR EACH ROW
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE errorCode CHAR(5) DEFAULT '00000';
DECLARE errorMessage TEXT DEFAULT '';
-- Declare exception handler for failed insert
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;
END;
-- Perform the insert
INSERT INTO `test_db2`.`users` (id, name, age) VALUES (NEW.id, NEW.name, NEW.age);
-- Check whether the insert was successful
IF errorCode != '00000' THEN
INSERT INTO `errors` (code, message, query_type, record_id, on_db, on_table) VALUES (errorCode, errorMessage, 'insert', NEW.id, 'test_db2', 'users');
END IF;
END; //
-- TRIGGER FOR UPDATE
DROP TRIGGER IF EXISTS `test_db1_users_au`;
CREATE TRIGGER `test_db1_users_au` AFTER UPDATE ON `users` FOR EACH ROW
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE errorCode CHAR(5) DEFAULT '00000';
DECLARE errorMessage TEXT DEFAULT '';
-- Declare exception handler for failed insert
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;
END;
-- Perform the update
UPDATE `test_db2`.`users`
SET name = NEW.name,
age = NEW.age
WHERE id = NEW.id;
-- Check whether the update was successful
IF errorCode != '00000' THEN
INSERT INTO `errors` (code, message, query_type, record_id, on_db, on_table) VALUES (errorCode, errorMessage, 'update', NEW.id, 'test_db2', 'users');
END IF;
END; //
-- TRIGGER FOR DELETE
DROP TRIGGER IF EXISTS `test_db1_users_ad`;
CREATE TRIGGER `test_db1_users_ad` AFTER DELETE ON `users` FOR EACH ROW
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE errorCode CHAR(5) DEFAULT '00000';
DECLARE errorMessage TEXT DEFAULT '';
-- Declare exception handler for failed insert
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;
END;
-- Perform the delete
DELETE FROM `test_db2`.`users`
WHERE id = OLD.id;
-- Check whether the insert was successful
IF errorCode != '00000' THEN
INSERT INTO `errors` (code, message, query_type, record_id, on_db, on_table) VALUES (errorCode, errorMessage, 'delete', OLD.id, 'test_db2', 'users');
END IF;
END; //
-- DELIMITER;
Hope this will help others when they come over here.
Cheers,
Check out the syntax for DECLARE HANDLER
http://dev.mysql.com/doc/refman/5.1/en/declare-handler.html
Also, if you're trying to debug a SP, this might be helpful for you:
http://www.bluegecko.net/mysql/debugging-stored-procedures/
Upon trigger you can use something like below :
CREATE TRIGGER `my_table_AINS` AFTER INSERT ON `my_table` FOR EACH ROW
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
RESIGNAL;
DECLARE EXIT HANDLER FOR SQLWARNING
RESIGNAL;
DECLARE EXIT HANDLER FOR NOT FOUND
RESIGNAL;
-- Do the work of the trigger.
END
Hope this may help you.
This looks like Master and Slave server/DB scenario. You can look into Binary Logging. So, any manipulation in Master server will be recorded as an event and same gets applied to slave server. Checkout MySQL official reference