MYSQL replay dumpfile all or nothing in a transaction

﹥>﹥吖頭↗ 提交于 2019-12-11 10:52:03

问题


MYSQL re dump from a log.sql all or nothing

mysql -h "$databaseHost" -u "$username" --password="$password" "$databaseName" <                      /path/to/project/log.sql

if this log.sql file contains an error in middle then transaction before error are done and after error are not done..

BUT i want that either whole of the sql file show be re dump OR nothing from the file should be re-dumped i am using MySQL database and Debian(6.0.1) O.S

log.sql

  start transaction;
  insert into demo_table values('abc');
  insert just for to create an error;
  insert into demo_table values('xyz');
  commit;

shell script for it:

rollBack () {
      if [ $mysql_error -eq 1 ]; then    
      mysql -h "$databaseHost" -u "$username" --password="$password" "$databaseName" -e "rollback;";
      exit 0;
      fi  

 }

 mysql -h "$databaseHost" -u "$username" --password="$password" "$databaseName" < /path/to/project/log.sql|| if [ "$?" -ne 0 ]; then mysql_error=1; rollBack; fi

i tried this code its not working any help or suggestions please friends


回答1:


Note: Following is only tested roughly, there might be more things to consider when dumping, depending on your database.

That's only possible under certain circumstances.

First failure is, that a transaction is bound to a session. Since you connect again to issue the rollback, the rollback has no use since there's no transaction to rollback. That was in the other session.

Second failure is, that usually a mysqldump has several statements which cast an implicit commit and therefore end the transaction. This includes all DDL statements (data definition language, this includes drop, alter, create and so on) as well as (un)lock tables.
So, to execute your dumpfile in one single transaction, the dump should have been created something like this:

mysqldump -uuser -ppw database --no-create-info --skip-add-locks --skip-disable-keys --skip-triggers >dumpfiles

--no-create-info lets mysqldump skip all drop table ...; create table ...; statements.

--skip-add-locks lets mysqldump skip all lock table ...; unlock table ...; statements.

--skip-disable-keys lets mysqldump skip all alter table ... disable keys; alter table ...enable keys; statements.

--skip-triggers lets mysqldump skip all create trigger ...; statements.

There's also a --single-transaction option, but this option would only be applied to single tables.

Third (possible) failure is, that a transaction only can be rollbacked completely, if all tables involved are capable of transactions, like InnoDB or BDB. If you have i.e. MyISAM tables in there, the insert statements will not get rolled back.

The following fails, cause the source command is not allowed in a stored procedure, it's rather part of the mysql client.

If all that has been considered, you can do it like this:

First create a procedure like this:

DELIMITER $$
CREATE PROCEDURE sp_exec_dumpfile()
BEGIN

DECLARE EXIT HANDLER FOR SQLEXCEPTION 
BEGIN 
  ROLLBACK;
END ;

START TRANSACTION;

SOURCE '/path/to/dumpfile.sql';

COMMIT;
END $$
DELIMITER ;

Then execute it like this in your script:

mysql -uuser -ppw -hhost databasename -e "CALL sp_exec_dump()"

Or of course you parameterize the procedure with the dumpfile name.



来源:https://stackoverflow.com/questions/22909215/mysql-replay-dumpfile-all-or-nothing-in-a-transaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!