Sometimes, I execute a query with wrong condition, and I must cancel changes that query made. I must restore the previous data.
No, you can't unless you have run that query in a transaction. Rollback would have saved you if you executed the query in transaction.
Or, check if there is scheduled backup. If so, There is a chance of rolling back to nearest data.
Related
In a single session, if I want to:
// make a query on Foo table to get one instance
// update this instance
// commit() or not?
// make the same query on Foo table
Will I get the same result in these two queries? That's to say, is it necessary to commit the update before query on the table within a single session?
Thanks!
It is not necessary to commit prior to making the query again. As a general principle, updates within a transaction (session) will be visible to subsequent queries in that same transaction, even prior to a commit.
Having said that, doing the same exact query twice within a transaction might be "code smell". It's worth considering, since the updated object is already memory, is it really necessary to query the object again?
Also, depending on the database isolation level, the second query is not guaranteed to return the same result set as the first one. This can happen if another transaction modifies the data prior to the second query.
It's not necessary to do both commits, as each transaction is visible to subsequent actions in the database (or queries).
You can just put the commit at the end, although I am not sure if multiple commits will affect runtime.
I've been running a delete query on one of our databases. The query has been running for about 7 hours and now I need to cancel it. If I cancel it will it cause a rollback? And of so, is there a way to cancel the query without causing a rollback?
Thanks
Yes, it will cause a rollback. You can expect the rollback to take even more time than the original delete (because a: rollbacks are always single-threaded and b: rollbacks are logged as well). Same if you restart the instance. SQL Server will always do it's best to return database to transactionally consistent state.
To add to my own answer :)
The best way to delete large amount of data from a table is to do it in smaller chunks, like 5000 rows at a time, each in it's own transaction. I know it's too late now, but for the next time.
Unless you're deleting all the rows from the table, then it's TRUNCATE TABLE the fastest method.
If I cancel it will it cause a rollback?
Yes, and it likely takes longer than it was running so far.
nd of so, is there a way to cancel the query without causing a rollback?
No. The data now is in an inconsistent state without rollback.
I happened to execute a query similar to this one:
update table1
set data=(select data from table1 where key1=val1 and key2=val2)
which was supposed to update only one row, but since I missed the second where clause, I guess it started to update every row in the database, which contains a few million rows.
The correct query would have taken about 0 seconds and would be:
update table1
set data=(select data from table1 where key1=val1 and key2=val2)
where key1=val1 and key2=val3
After a few seconds, I realized it took too long and stopped it.
The database is set to full recovery mode and running on sql server 2008 r2.
The question is, what was the effect of this query? My hope is that there would be no effect since the query was stopped before completion and SQL Server rolled back the changes automatically. Is that correct?
If not, how do I roll back the database to its state at a particular point in time (right before I did the unfortunate update)?
(I saw this question: If I stop a long running query, does it rollback? but it is different in that it performs several changes as opposed to just one.)
(And yes, I do have very recent backups, but given the size of the DB I would prefer not to have to restore from backup)
If your command to cancel came in time, it was rolled back in its entirety. DML statements are always all or nothing. You should probably check the data to make sure that your cancel did arrive in time. It might have arrived in the last millisecond or so after the transaction was already committed.
I have a table that has millions of rows.
Accidentally I wrote an update query over a table without where clause and clicked execute.
It started executing. After two seconds I realized the query is wrong and I clicked 'Stop' button in Sql Server Management Studio. The query execution was stopped, this all happened within 7 seconds.
Now I am curious to know if there are any rows affected. If any which are they?
How to find it?
A single update statement will not update some rows. It's all rows or none
This is the atomicity in the ACID properties which SQL server respects well.
Atomicity requires that each transaction is "all or nothing": if one part of the transaction fails, the entire transaction fails, and the database state is left unchanged. An atomic system must guarantee atomicity in each and every situation, including power failures, errors, and crashes.
Then the commit is at the end of the statement, so when you cancel there's no commit
I am running a bunch of database migration scripts. I find myself with a rather pressing problem, that business is waking up and expected to see their data, and their data has not finished migrating. I also took the applications offline and they really need to be started back up. In reality "the business" is a number of companies, and therefore I have a number of scripts running SPs in one query window like so:
EXEC [dbo].[MigrateCompanyById] 34
GO
EXEC [dbo].[MigrateCompanyById] 75
GO
EXEC [dbo].[MigrateCompanyById] 12
GO
EXEC [dbo].[MigrateCompanyById] 66
GO
Each SP calls a large number of other sub SPs to migrate all of the data required. I am considering cancelling the query, but I'm not sure at what point the execution will be cancelled. If it cancels nicely at the next GO then I'll be happy. If it cancels mid way through one of the company migrations, then I'm screwed.
If I cannot cancel, could I ALTER the MigrateCompanyById SP and comment all the sub SP calls out? Would that also prevent the next one from running, whilst completing the one that is currently running?
Any thoughts?
One way to acheive a controlled cancellation is to add a table containing a cancel flag. You can set this flag when you want to cancel exceution and your SP's can check this at regular intervals and stop executing if appropriate.
I was forced to cancel the script anyway.
When doing so, I noted that it cancels after the current executing statement, regardless of where it is in the SP execution chain.
Are you bracketing the code within each migration stored proc with transaction handling (BEGIN, COMMIT, etc.)? That would enable you to roll back the changes relatively easily depending on what you're doing within the procs.
One solution I've seen, you have a table with a single record having a bit value of 0 or 1, if that record is 0, your production application disallows access by the user population, enabling you to do whatever you need to and then set that flag to 1 after your task is complete to enable production to continue. This might not be practical given your environment, but can give you assurance that no users will be messing with your data through your app until you decide that it's ready to be messed with.
you can use this method to report execution progress of your script.
the way you have it now is every sproc is it's own transaction. so if you cancel the script you will get it update only partly up to the point of the last successfuly executed sproc.
you cna however put it all in a singel transaction if you need all or nothign update.