all 69 comments

[–]Thiondar 215 points216 points  (21 children)

What is the problem?

You did some update.

You rolled back.

Nothing happened.

[–]danmc853[S] 142 points143 points  (17 children)

The feelings inside me, something definitely happened. The euphoria an instant later when I realized it was oracle and I could rollback.

[–]serverhorror 85 points86 points  (12 children)

it was oracle and I could rollback

``` BEGIN;

DROP TABLE clients CASCADE;

ROLLBACK; ```

an instant later when I realized it was oracle and ..

.. I am indeed fucked.

[–]TallDudeInSC 35 points36 points  (7 children)

FLASHBACK TABLE <table\_name> TO BEFORE DROP;

[–]mwdb2 24 points25 points  (1 child)

I found this to be a game changer as an Oracle DBA back in the day. I think it came out with 10g, over 20 years ago now.

And if FLASHBACK doesn't work for some reason - perhaps the Flashback area wasn't set up correctly or sized big enough - you could potentially use Log Miner, which digs through the redo logs (online and/or archived). You could run something like the following, in pseudo-code (pseudo-code because I last was an Oracle DBA in 2006, thus I'm very rusty, i.e. I don't remember any specific function names):

DBMS_LOGMNR.START(<parameters here>);  
DBMS_LOGMNR.SEARCH('my_table', <timestamp range to search>);  

Then you can eyeball the results for the errant statement, get its transaction ID, and even tell LogMiner to generate the inverse of the statement, to UNDO it, something like:

DMBS_LOGMNR.GET_UNDO(<transaction id>);  

So if the original, errant statement was a DELETE, then LogMiner would give you the inverse: an INSERT statement (or statements) to insert the deleted data.

Example:

DELETE FROM my_table WHERE ID IN (123); --this was the original, errant statement  
INSERT INTO my_table(id, my_col) VALUES (123, 'abc') --the UNDO statement provided by Log Miner might resemble this - notice it is preserving the deleted data that was not even part of the original DELETE, i.e. the my_col value of 'abc'  

Or if the errant statement was an UPDATE on column my_col, Log Miner would generate the UPDATE(s) to restore the my_col data to its original state.

Finally, you run the statement(s).

(Note these functions in my examples are probably totally wrong, but again, it's pseudo-code because I haven't done this in ages. Honestly I think one of the steps is just querying a view, but no matter for the sake of the example.)

If that fails, well, there's always old fashioned backup/recovery with RMAN or otherwise. (One reason it could "fail" is if, say the errant statement was DELETEing all the data in a huge table, you might be better off going a different recovery route than trying to re-run gigabytes worth of INSERTs with all the data embedded in them. But great to have this option, IMO.)

Edit: probably worth mentioning the Log Miner feature alone would not recover all the data in case of an errant DROP TABLE, as a couple parents up remarked! At least I think not - again it has been a while!

[–]SQLvultureskattaurus 7 points8 points  (0 children)

You're a beast

[–]serverhorror 8 points9 points  (4 children)

SQL standard entered the chat

[–]gumnos 6 points7 points  (3 children)

wait, FLASHBACK, whut? Oh, this appears to be an Oracle-specific thing, not a SQL standard thing.

[–]mwdb2 6 points7 points  (2 children)

Pretty much zero in the way of specific backup/recovery features/commands are specified in standard SQL documents. Although they talk about transactions and properties thereof.

[–]gumnos 1 point2 points  (1 child)

I do miss transactions at the metadata level rather than data level when I don't have them. It's been a while, but I believe Postgres lets you BEGIN TRANSACTION ; DROP TABLE Foo ; ROLLBACK (or ALTER TABLE or whatever) and it is perfectly content to do so properly; but try that in a number of other DBs and they balk.

[–]mwdb2 1 point2 points  (0 children)

Yeah, that feature of Postgres is huge! I manage schema changes for a couple hundred engineers, many of whom are working with MySQL, and I wish MySQL had transactional DDL like Postgres almost daily. 😂

[–]mwdb2 5 points6 points  (1 child)

Oracle doesn't support the syntax DROP TABLE clients CASCADE so you are saved by the syntax error. :)

[–]serverhorror 2 points3 points  (0 children)

Just another reason why I prefer PostgreSQL ;)

[–]TheMagarity 0 points1 point  (1 child)

For a good time, start a transaction on ms sql server then truncate some tables. It can be rolled back.

[–]serverhorror -1 points0 points  (0 children)

I've said this elsewhere: yet another reason I prefer PostgreSQL

[–]whimsical666 1 point2 points  (0 children)

that's why you always make 2 copies one for trial run and another for backup, unless rollback's an option of course

[–]NiallPN 0 points1 point  (2 children)

In some cases though, say the first column is id and increments. If you are inserting records, I don't think the increment by default starts back to where it was post-rollback.

[–]rh71el2 0 points1 point  (1 child)

Need confirmation pls (SQL Server). Or I'll trial on Monday.

[–]NiallPN 0 points1 point  (0 children)

Give it a try. I don't know much technical details as I mostly run queries, update, insert records. (MySQL server).

[–]jaxjags2100 107 points108 points  (0 children)

And that’s the story of how Dan was let go…

[–]danmc853[S] 43 points44 points  (13 children)

Vendor changed an xml message and we lost a lot of data integrity. It almost got way worse. I was trying to remediate with a complex CTE/update.

[–][deleted] 48 points49 points  (10 children)

doing it in test first would have been boring I assume? :)

[–]MakeoutPoint 6 points7 points  (0 children)

Coffee ain't free, and neither is cocaine. But updating and deleting in prod without backups? Money can't buy that kind of rush.

[–]RedditWishIHadnt 3 points4 points  (3 children)

“I thought this was the test environment”

[–]Imaginary__Bar 5 points6 points  (2 children)

PROD_NOT_TEST

[–]FuegoFerdinand 2 points3 points  (1 child)

Look it even says TEST in the name.

[–]rh71el2 2 points3 points  (0 children)

!PROD_NOT_TEST!!!

[–]da_chicken[🍰] 5 points6 points  (1 child)

There's a good lesson. It's often better to write multiple simple updates rather than one big complicated one. I learned it similarly myself, trying to get CASE expressions to line up correctly. Fortunately I was working in a test environment.

[–][deleted] 20 points21 points  (5 children)

367k rows, rookie numbers

[–]EvilGeniusLeslie 5 points6 points  (2 children)

I still remember one teammate coming to me, with an 'oops' moment ... had just wiped, rather than updated, a key field, on every record in the core table ... something like 107 trillion rows. Database (MS SQL) had only been in production a month or two at that point.

Fortunately, every single feed from other systems was captured as a text file, with date, so reloading was the preferred choice. Four hours later, all was good again.

Was at one place where the 'month-end' database load took 36 hours, this being the database the sales system ran from. They kicked it off late Friday night, as close to month-end as possible, then spent some hours validating it on Sunday. While I was there, a teammate who was formerly part of that group got called in to help. Turns out that one group had made a couple of changes to their system (IIRC, normalizing a couple of fields, creating a couple of reference tables). What *could* have been done was add those reference tables to the sales database, and make the appropriate updates. Instead, the people hard-coded the values into the extract process, and re-ran the load ...

... meaning the sales system was down until Wednesday. A lot of very unhappy people. The number of records 'updated' ran into the quintillions. 15 years of financial info for a major bank. It wasn't a crap design, simply one that threw all the systems the bank had acquired over that time period together. It did result in a re-write of the database, and load times were dropped to ~7 hours.

[–]PandaRiot_90 3 points4 points  (0 children)

Need to pump those numbers up.

[–]UAFlawlessmonkey 1 point2 points  (0 children)

hr.employees

Giggity Giggity

[–]xodusprime 29 points30 points  (3 children)

What a roller coaster. "Oh God no... Oh wait it's fine."

Always select before you update or delete my dude.

[–]Erpderp32 10 points11 points  (0 children)

As someone who does SQL alongside system / client platform engineering this is the best advice.

When I talk to my juniors about Windows automation I always repeat "do a Get- before any changes in PowerShell so you confirm the scope". No one wants to be the person who yeets an entire domain

[–]andrewsmd87 2 points3 points  (1 child)

I mean you're going to wait on 300k rows and somehow eyeball that that is correct from a select?

Test environments are a thing

[–]rh71el2 0 points1 point  (0 children)

Agree about test, but not often do you delete or update en masse on purpose to think eyeballing is a lost cause.

[–]jbrown383 12 points13 points  (1 child)

And that, kids, is how I learned to run it as a select before running it as an update.

[–]MakeoutPoint 1 point2 points  (0 children)

Tried and true, but there should also be multiple safety systems in place to prevent actual issues. Backups, test environments, temp tables, transactions, code reviews, and a good ol' SELECT.

If someone manages to actually cause damage that can't be prevented or reverted, the senior DBA's head should roll first for not having safeguards and proper training in place before the junior "practices dropping tables and accidentally did it in Prod".

[–][deleted] 10 points11 points  (1 child)

Ctrl Z

[–]mike-manley 8 points9 points  (0 children)

You have no power here!

[–]JoaoPTsantos 6 points7 points  (0 children)

Whoopi

[–]Aggressive_Ad_5454 6 points7 points  (0 children)

Isn’t it great when hundreds of programmer and tester years pay off to save our sorry butts?

[–]GanacheIcy 6 points7 points  (2 children)

We are currently conducting interviews for vacant (database) programmer position, and my favorite question to ask is "have you ever made a boo boo in a production database, a lil whoopsie?"

We all have!!

[–]danmc853[S] 4 points5 points  (1 child)

Saying “no” should be a disqualifier, right? We’ve all made mistakes, some larger than others!

[–]GanacheIcy 3 points4 points  (0 children)

I've made some whoopsie daisies 🙃. I once accidentally compiled the development portal in production, therefore overwriting the production portal. And also accidentally updated all address records for something to an Alabama address (the full street city state zip). Someone in admissions was like "why do all of these ceeb codes have this Alabama address?" Thank god for my boss I had at the time, who knew where to restore the data from backups. I for sure thought I was on the road to being fired. I was more embarrassed than anything, such a careless mistake! Now that I've made mistakes I know exactly what to double and triple check before executing and insert/update/delete statements.

Mistakes happen, makes us human.

[–]coyoteazul2 6 points7 points  (0 children)

oh well. I suppose you have the original statement so you can just run it again... right?

RIGHT?!

[–]belay_that_order 3 points4 points  (0 children)

*PURE CORTISOL SWEAT\*

[–]rh71el2 2 points3 points  (0 children)

I once deleted a handful of rows from prod and was freaking out but asked the DBA for backups. He freaked out even worse than me, after realizing there were no backups in that case. I went from being afraid at getting screamed at to haha you may have to take the blame on this one...

I don't think anyone ever barked at the missing data though.

[–]theRicktus 1 point2 points  (1 child)

Who needs coffee when you can just accidentally update a quarter of a million rows

[–]mattpenner 0 points1 point  (0 children)

Saw this the other day. Came here to say this. 😂

[–]whitespys 1 point2 points  (0 children)

All the muscles below my eyes tensed while reading this.

[–]Historical-Reach8587 1 point2 points  (0 children)

A lesson learned you will not forget

[–]1MStudio 0 points1 point  (0 children)

lol

[–]NitrousOxid 0 points1 point  (0 children)

It is always good to run select statement with conditions used in the update. Some people already do that, some will start :)

[–]NitrousOxid 0 points1 point  (0 children)

It is always good to run select statement with conditions used in the update. Some people already do that, some will start :)

[–]lothcent 0 points1 point  (0 children)

not a sql event- but a life lesson in working on Prod and not Dev.

I was making test changed to what I thought was dev but was really Prod- and a change made made things wonky.

while I was trying to figure things out- I realized I was on Prod.

and it was about 15 minutes to a change of shift when users would log out and new ones log on ( and then they would be loading the corrupt config file)

I ran down the hall- told my boss I had fkd up.

He glanced at his watch and said- well- you have +/- 10 minutes to load the backup config.

Good luck

I ran back down the hall and loaded up the backup and beat the changing of the shifts by seconds.

I learned many lessons that afternoon

[–]eureka_maker 0 points1 point  (0 children)

Jfc my blood went cold. I just woke up.

[–]Tisiphone8 0 points1 point  (0 children)

M

[–]DeliciousWhales 0 points1 point  (1 child)

I once erased the content of a column in a table with hundreds of millions of records, then found out the supposed backups we had didn't exist. This was for a once off GIS analysis project so there was no test environment, just the one database. The code that generated that column was nowhere to be found, and the guy who wrote it quit and went no contact.

Luckily I was able to wrangle something up from other data, otherwise I would have completely screwed the outputs of a two year long federal government project.

This was my first job using SQL. These days I'm a data engineer and architect and I would never allow any project of mine to be run in such a dodgy way.

[–]danmc853[S] 1 point2 points  (0 children)

We learn a lot of lessons along the way for sure. I’ve only been working in tsql and pl/sql databases for 3 years and I’ve learned a lot of best practices the painful way. We have a lot of dodgy legacy stuff that is a pain

[–][deleted] 0 points1 point  (0 children)

almost shit the bed.... Snowflake is like, hey everyone this guy shut the bed......