The Register Home Page

back to article Junior developer's code worked in tests, destroyed data in production

Alas, the weekend is over, but The Register tries to make your entry to the working week a little more enjoyable by bringing you a fresh installment of Who, Me? – the column in which you explain your worst slip-ups. This week, we have two readers for you to meet! The first asked to be Regomized as "Reggie" because he thought …

  1. Korev Silver badge
    Trollface

    I like how "Sam" becomes "mike" in the second story

    1. ArguablyShrugs

      Sam's name got deleted from the database halfway through the article, I guess

      1. Korev Silver badge
        Coat

        Presumably using the MyISAM engine

        1. C R Mudgeon Silver badge

          Involuntary SQL Access Muckup?

      2. wolfetone Silver badge

        DELETE FROM regomized

        WHERE regomize = Sam;

    2. Sparkypatrick

      Shirley the second contributor should have been Ronnie?

      1. logicalextreme

        I was half-expecting Perrin.

  2. Korev Silver badge
    Coat

    Was the second story a SQL?

    1. that one in the corner Silver badge

      Squirrel?!

      1. Anonymous Custard Silver badge
        Trollface

        That would be nuts...

        1. David 132 Silver badge

          Thats acorny pun.

          1. Zarno

            A deciduously fun one too.

  3. DavCrav2

    I was building a meeting scheduler for my department using Microsoft Power Automate (I know) and when someone cancels a meeting, you would like to blank the attendee field and open up the slot again. For some reason, although you can manually set a Person field to null, you cannot using Power Automate, because reasons. So when I tried to set the field to null, what happened was the system searched the database looking for the closest person to null, and now someone with the surname Nulli started getting dozens of meeting emails and calendar invites.

    Top job MS. Top job me for not testing it properly.

    1. Tanaka

      There *is* a workaround to that...

      https://www.shanebart.com/power-automate-reset-sp-person-field/

      1. Anonymous Coward Silver badge
        Linux

        Of course there's a better workaround -->

        1. Sp1z

          Workaround - exactly.

          Not solution.

    2. ForthIsNotDead

      Just create a dummy user in the system called "Room Available", and assign it when the meetings are cancelled?

      1. Richard 12 Silver badge

        Then it still shows as booked, and nobody can use it.

  4. Anonymous Anti-ANC South African Coward

    INFORMIX and informix is not the same. DBA showed me.

    Yet mangler and underlings don't see it that way.

    We'll have some fun coming up.

    1. TimMaher Silver badge
      Windows

      Informix

      See… mixed case.

      Anyway, is it still in use?

      Anybody remember INFORMIX 4GL?

  5. af108
    Pint

    Pro tip for DELETE queries

    If you're ever running something like this

    DELETE FROM bigtable WHERE secretfield = 1;

    in production the way I always do this is to type out the query without the table name ("bigtable") or the condition ("1").

    That means if you accidentally hit Enter at an inopportune moment e.g. after just DELETE FROM bigtable (which would delete all rows!) the query will fail because it's syntactically invalid.

    I then go back and add in the table name with a sanity check of "is this the table I really mean?" followed by the same with the conditions. Pause. Then press Enter.

    Takes about 5 seconds longer and I've never once deleted something inadvertently in production. Oh, and never copy/paste queries for exactly this reason - unless you modify them to remove the same params first.

    You're welcome.

    1. Prst. V.Jeltz Silver badge

      Re: Pro tip for DELETE queries

      or you could just start with SELECT * , and see if the results correspond with what you wanted to delete

      then bring the DELETE in once you're happy the filters/ table/ db are all correct

      or at the minimum type the WHERE field = 1 first to avoid accidentally hitting enter and doing a wholesale delete with no filter

      1. 42656e4d203239
        Coat

        Re: Pro tip for DELETE queries

        yeh this - SELECT the things you think you want to delete and see if they are the things then swap SELECT for DELETE when you are super sure you are right!

        I guess thats why having a "hidden" column called "reallyDelete" is handy... so you can practice the where with update <wherever>.reallyDelete=$true where .... and check with select * from <wherever> where <wherever>.reallyDelete=$true before you "delete from <wherever> where <wherever>.reallyDelete=$true"

        Yeh - what could possibly go wrong there? I definitely haven't ever had to restore tables/databases for DBAs who got it wrong even with a reallyDelete column

        /mines the one with a backup tape in the pocket

      2. af108
        Thumb Up

        Re: Pro tip for DELETE queries

        > or you could just start with SELECT * , and see if the results correspond with what you wanted to delete

        Yeah I should have clarified that I meant once you've actually verified what you're going to delete.

        There comes a point where you actually have to run the DELETE command.

        I've come across numerous people where they've accidentally hit Enter, or even copied/pasted a full query with a line break at the end which in some clients is enough to execute it. The point being that if you supply 95% of the query initially and then fill in the blanks it's a simple way to avoid this specific problem.

      3. Doctor Syntax Silver badge

        Re: Pro tip for DELETE queries

        Yes, do that - even just a COUNT to check if the number looks right. Then do the delete in a transaction and only COMMit if it still looks right because up to that pint you can still roll it back.

      4. Prst. V.Jeltz Silver badge
        Coat

        Re: Pro tip for DELETE queries

        .. and while were on the subject , a bit of sqletiquette .

        please put your commas at the start of the fields and dont skip writing AS before an alias!

        and if you want to go really crazy do some indenting as well

        1. logicalextreme

          Re: Pro tip for DELETE queries

          I'm a fiend for indentation, am generally coming around on AS (though I prefer lowercase SQL) but can't stand commas at the start of columns/expressions. Code should be written rarely and read often.

          1. Prst. V.Jeltz Silver badge
            Alien

            Re: Pro tip for DELETE queries

            well know , sombody , back in the day , probly the 60s , declared that all SQL keywords are in caps.

            It dont make any difference , but you just feel obliged, to avoid angering the gods

      5. DS999 Silver badge

        Re: Pro tip for DELETE queries

        Yep I have (thankfully) minimal SQL knowledge/experience but even I was thinking to myself while reading "why not run that query first as a select"? It costs nothing to verify it produces the expected level of output, then you can edit the select command to perform the deletion.

        I could understand if that extra step would add an unacceptable amount of load to the database (i.e. doing a highly complex query twice) but that's not true here. Even if the query took a few minutes to execute that wouldn't be a problem, because it isn't like you have to wait on its completion. You could catch up on email while you wait, then return to that window to issue the delete when the select completes with the expected output.

      6. Elongated Muskrat Silver badge

        Re: Pro tip for DELETE queries

        First do the SELECT * FROM bigtable WHERE <condition> bit, then when you have verified that, do a SELECT * INTO bigtable_backup_todaysdate FROM bigtable (without the WHERE clause) before changing it to a DELETE statement. If the database has active transactions going on, you might also want to make sure that either everyone else is out of the database, or you might want to consider using a query locking hint, such as WITH READUNCOMMITTED.

        You can always do a DROP TABLE bigtable_backup_todaysdate later, once you've established you didn't screw up.

        This does, of course, assume you have enough space in your database for a copy of "bigtable", but to be honest, if you don't have that much headroom (or log space) in your database, you're likely to run into bigger problems.

        This assumes SQL Server too, other DB engines are available.

        1. Prst. V.Jeltz Silver badge
          Windows

          Re: Pro tip for DELETE queries

          Heres a little snippet I always have handy for such temp backups , I usually only use the top one , which is the same as suggested above

          SELECT * INTO mytable_backup --newtable

          FROM mytable

          ----------------

          INSERT INTO mytable_backup --existing table

          SELECT * FROM mytable

          ----------------

          INSERT INTO dbo.mytable_backup (col1,col2) --existing table named cols

          SELECT col1,col2 FROM dbo.mytable

        2. logicalextreme

          Re: Pro tip for DELETE queries

          Plot twist: bigtable_backup_todaysdate never got dropped. See also _copy, _temp, _deleteme

    2. Anonymous Coward
      Anonymous Coward

      Re: "and I've never once deleted something inadvertently in production"

      As that's usually quite the dangerous statement to make ... we are now all looking forward to your upcoming contributions to this column ... :-)

      1. Anonymous Coward
        Anonymous Coward

        Re: "and I've never once deleted something inadvertently in production"

        I have found DROP is far more effective and efficient.

        If you must "double down" on your screw ups, do it in style. :)

        Dropping the "wrong" index while not normally catastrophic can be "interesting" (as in times, not hobbies.)

    3. neilo

      Re: Pro tip for DELETE queries

      How's this for a pro tip: always Always ALWAYS surround your PROD statements with begin transaction / rollback transaction FIRST?

      begin transaction

      delete from bigtable where secretfield=1

      rollback transaction

      See how many records are impacted. If it's more than you think, carefully query the data and understand why.

      Finally, when you are done, replace "rollback" with "commit":

      begin transaction

      delete from bigtable where secretfield=1

      commit transaction

      But even before you do this, do a SELECT with the same criteria as the DELETE and actually read some records.

    4. Claptrap314 Silver badge

      Re: Pro tip for DELETE queries

      I can appreciate your imagination, but there are just too many steps where things can completely go wrong.

      The only solution that works is to wrap things in a transaction. That's what they are there for, after all.

      Certainly, checking the number of rows delete is an important sanity check. But not the only thing that might be checked.

    5. This post has been deleted by its author

    6. Already?

      Re: Pro tip for DELETE queries

      Always always do the Select Count first, then run at least three queries - select count, delete, select count and select any other useful where to prove the delete or the surviving records - all wrapped in a transaction to give yourself chance to check that you’re getting what you expect. Then go for a coffee, come back and check it again before swapping rollback for commit.

      Once had an interesting chat with a co-worker who couldn’t trace why his select count where sanity check gave a different number to the delete where where where was the same in both queries. Never did find out why; I was busy, he sussed it and went home.

    7. phuzz Silver badge

      Re: Pro tip for DELETE queries

      In a similar vein, if I'm typing a complicated command in Linux that might break things if I accidentally hit enter, I won't put the sudo at the front until I'm ready to run.

    8. This post has been deleted by its author

  6. Mishak Silver badge

    Don't delete your shameful story

    Darn, that's just what I did...

  7. Just Enough

    Confusing

    ""All of the records were flagged with a test number – 1 – in an unused field,"

    I wouldn't have touched this job until it is was clarified exactly what was meant by " – 1 –". I'd sound like an annoying pedant, but I'd be sure what was required before doing something disastrous.

    And then I would have executed a SELECT before doing the DELETE.

    1. KarMann Silver badge
      Headmaster

      Re: Confusing

      To be fair, I'm pretty sure the en dashes are purely The Register's phrasing, to point out what that number was, and were not literally part of the brief however long ago.

      1. Paul Kinsler

        Re: I'm pretty sure the en dashes are purely ...

        I did think that they also rather nicely illustrated the oncoming confusion.

        1. chuckrman

          Re: I'm pretty sure the en dashes are purely ...

          So many times I have seen data in databases that were probably sane at the the time there were initially input but completely insane by the time I looked at it. The data type and boundaries were not well defined/if defined because they were built on different input applications that changed over time and scope of the input changed. Lazy, lets make it work, attitudes meant data built on data became increasingly undefined but nobody wanted to change the old values. This instinctively causes me to do changes in a separate table where I can. Basically I keep and old table and new table. Start using the new data to validate that changes are desired.

  8. Doctor Syntax Silver badge

    I suppose that sub-record thing is a hangover from a COBOL origianl. I've seen that in an accountig system as well. Why did they not realise that disk and especially RDBMS is not like tape to tape processing.

    1. An_Old_Dog Silver badge
      Windows

      Variant Records -- Woohoo!

      I'm wondering whether Pascal, C, PickOS, or Revelation underlay all this.

  9. RMclan

    I once did the the same as Sam/Mike. We had a table with about 97,000 records in it controlling the products on a live trade portal website. I wanted to remove about 800 that had a flag field delflag='Yes'.

    To test I had the right records I first ran

    select count(unique_field) from table ;

    then

    select count(unique_field) from table where delflag='Yes'

    then

    select count(unique_field) from table where delflag<>'Yes'

    Finally after I was happy these results all added up to what I was expecting I edited the open select query to make my delete query and ran

    delete from table where delflag<>'Yes' - of course that should have been where delflag='Yes'

    Luckily this particular table was updated very rarely so I was able to go back to the previous night's backup and just rebuild the table from there. Total downtime on the website was about 45 minutes, and as the mistake was made around 3pm on a Friday afternoon, no-one really noticed.

    I did learn not to edit the current query in pgAdmin when going from a select to a delete and actually start the delete from scratch.

    1. breakfast Silver badge

      The worst part of this kind of situation in my experience is the stomach drop when you realise what has just happened...

      1. Ken Shabby Silver badge
        Pint

        I once actually vomited, long long time ago, two terminals, one on prod, one on dev. Dropped a table, oh no it’s prod, had to run off to chunder, got back and it was dev. So felt better, had few of these that night, well I was thirsty.

        1. TSM

          Not so long ago we were doing a production database migration and the testing process involved creating a bunch of temporary tables corresponding to the proper database tables (but with a much smaller number of records).

          Testing was eventually declared successful. Time to drop all those temporary tables... except for one I accidentally dropped the main database table instead. This was Oracle, on which any DDL operation auto-commits.

          A quick panicked email to the DBA who was on-hand for the testing process and within 10 minutes the table was back. (Fortunately - since it was a migration - he just needed to re-import that table. The application was down during the migration process, so no intervening changes to worry about.)

      2. Anonymous Coward
        Anonymous Coward

        > DROP STOMACH

  10. David Harper 1

    It's not only junior developers that commit this type of SNAFU

    There's nothing more dangerous than an over-confident senior developer who has write access to the production daatabase.

  11. Antron Argaiv Silver badge
    Pint

    There are only two type of Unix sysops: those who have inadvertently deleted the root partition, and those who will.

    Here's one for all of them ---->

    1. Anonymous Coward
      Anonymous Coward

      We need more swap - nothing is using /dev/sd0a

      Not deleted; just "repurposed."

      Actually was more often /usr especially when the standard (BSD) disk partition conventions were flouted.

      I suspect "dd" aka disk destroyer, was responsible for more root deletions. dd from root partition to a new altroot partition after replacing a disk was favourite if you got your of= and if= arse about.

    2. An_Old_Dog Silver badge
      Windows

      Two Types of Unix Sysops

      I have never inadvertantly deleted the root partition on a Unix system.

      I have, however, inadvertantly deleted all the files in /.

      (The error was due to me, working as root, issuing a rm * when I thought the cwd was "/tmp/", rather than "/". Recovery was effected via tar and the previous night's backup tape.)

    3. FirstTangoInParis Silver badge

      A sub type being one that inadvertently tried restoring the /usr partition on to the / partition until it ran out of disk space and panicked. And then I panicked too.

    4. David Hicklin Silver badge

      And of course we have all done rm -rf * on a system being decommissioned to see how long it would keep going before it finally fell over

  12. Will Godfrey Silver badge
    Facepalm

    Mine was far more primitive

    Working from a terminal I was supposed to backup the current data but reversed the order of the locations, so I overwrote it with old stuff - this did not make me popular!

    That was back in the late 1980s. So far, I've not made the same mistake.

    1. Phil O'Sophical Silver badge

      Re: Mine was far more primitive

      I remember a sysadmin who ran a standalone backup (remember those?) and managed to copy the blank disk over the live one.

      There was a reason those older systems had drive write-protect switches, and it's a shame that they are not common nowadays.

  13. Chris Gray 1
    Headmaster

    Types!

    The programming language geek in me says that if the SQL query language was strongly typed, that bad command would be invalid. The WHERE clause should be Boolean. "value - 1" is not Boolean.

    1. Claptrap314 Silver badge
      Boffin

      Re: Types!

      SQL is too old for that, unfortunately.

  14. stiine Silver badge
    Facepalm

    Minus Sam, did you ever woth with with GOSUB Keith? So named because his program would not run to completion except under the debugger...

  15. AustinTX
    Facepalm

    Back in the DOS days, I had the bad habit of using the root directory of my second partition as a temp folder. It would ordinarilly never have files in it, so clean-up was as simple as deleting any non-folders.

    Well, one day Microsoft outsmarted me. Their installer finished adding the program, and then it just blanket deleted everything in that folder including itself, existing folders and the new program it had just installed.

    In my defense, the installer shouldn't have assumed it was being run from a directory with nothing valuable in it, and if it was going to clean up files, it should have only deleted ones belonging to it.

    I haven't even looked in root in years, so I obviously don't use it as a temp directory any more, but i'm sure I probably continued to do so after this adventure.

    1. Claptrap314 Silver badge

      Never EVER trust m$ to follow even its own standards.

      I learned that when I decided I wanted $PROGRAMFILES on my D: drive.

    2. Anonymous Coward
      Anonymous Coward

      Had that happen with, I think, a Valve game. (Possibly the original Half-Life.) The uninstaller assumed that it was running in, say, C:\Valve\Halflife, and deleted the parent directory. Except I had installed in C:\games\Halflife...

  16. Boris the Cockroach Silver badge
    Facepalm

    Down in robot land

    Theres a very nasty snafu waiting for the inattentive,

    We uploaded a new program to the robot cell, proved it all out, given this was a CAM generated monster(50 000+ lines), but it didnt return to a safe position at the end, so rather than CAM it all again, then have to reload it, and prove it, we thought "Lets just jump to the end and hand edit it"

    The control has a handy search function, type in the text you want and press the down arrow on the keyboard... however... if you press 'delete' it deletes everything upto that search text.

    We all know where this is going....

    All I can say is praise the god of backups ... I wonder what his name is....

  17. PRR Silver badge

    > praise the god of backups ... I wonder what his name is....

    "His" s/b "his/her".

    AI tells us:

    AI Overview: In mythology, the Greek daemon (spirit) of safety and deliverance is Soter, who can be considered a figure representing "the god of backups" in a broader sense of preservation and recovery. His female counterpart is Soteria, the goddess or personified spirit of safety, deliverance, and preservation from harm.

    Obviously some retcon here.

    1. Anonymous Coward
      Anonymous Coward

      His female counterpart is Soteria

      eSoteria for the info age ?

      Backups are frequently a deep and existential mystery to organisations in urgent need of the blessings of Esoteria's handmaiden, Restoria.

      The tutelary deity of tape drives would have to be Loki if not old Nick himself.

  18. AlgernonFlowers4

    Real DBAs Don't Delete

    Real DBAs Don't Delete they Archive!

  19. Joe 59

    Let him who is without sin ...

    who hasn't done something careless and dangerous like this?

    A young dev of mine recently built an API in GoLang for a project and the API mapped GET methods to POST methods so if you ordered /table/field=foo you actually set all entries' field field to foo. It also returned all fields where field=foo. So running GET /table/field=foo returned 200 OK and a shit-ton of JSON. Like all the JSON. Since they were now all foo.

    Worked fine when tested, it returned 200 OK and JSON data...

  20. GrahamRJ

    Make sure you can remove evidence

    Back in the day when I was a uni student working a summer job at GEC, I once accidentally deleted C:\Windows on my work PC. I realised my mistake, but the files were gone. I had access to a second PC, so I copied files over the network to reconstitute the basic file structure, but of course the Windows registry was toast so nothing worked. You could get to a DOS prompt, but no Windows.

    Solution? Lie through my teeth. I went to our IT guy and basically said "My PC isn't booting Windows", and gave a short account of what happened when you dropped into DOS and then tried running Windows. This being the days of Windows 95, hard disks not always being reliable, and me being generally regarded as someone who knew what they were doing, the IT manager just swore a bit about Windows 95, about the batch of hard drives he'd just got (apparently a couple had genuinely failed), and then replaced the (probably OK) hard drive and re-imaged the PC. Job done, bullet dodged.

  21. RAMChYLD

    Happens to the best of us

    Accidentally did just that at my second job when I was still a greenhorn. didn't notice which database I was on and assumed I was on the test database (my first mistake), and executed a mass purge of grades of the university exam database.

    Thankfully we had backups, but yeah, my contract was not renewed at the end of the term. It was for the best tho, since my relationship with one of the deans soured after he made me stay back and do unpaid overtime on a weekend when I already had plans a few months later.

  22. LarsB

    I’ve seen loads of experienced developers make these kind of mistakes. Myself included. One of the reasons I’ve acquired a defensive programming style, with lots of sanity checks sprinkled throughout my code to guard against mistakes.

  23. Stuart Castle

    Years ago, I had a job in Freight Forwarding. It was my job to help prepare the documentation for my various clients exports to various middle east countries. Sometimes, I had to deliver the documentation personally to the relevant country's embassy in London (this was the one aspect of the job I liked, because I love exploring and I got paid to go to all sorts of areas I wouldn't normally visit).

    To ensure that customs were notified of the shipments, we had to use a special computer system to enter the details, and print any relevant documentation. For this, we had an IBM AT, connected to both a dot matrix and daisywheel printer, a modem (it used this to upload details of our shipments to an HMRC computer) and a serial terminal. I can't remember the OS, but it was either Concurrant DOS or Multi User DOS.

    We had strict rules on how long we needed to keep documentation on shipments (5 years, IIRC), but due to the time required to upload, we were asked by customs to keep the online records to the last year or two, which meant one of my boss's jobs was, on a friday afternoon, deleting any out of date shipment records. For Audit purposes, we still had the paperwork.

    The system asked the user to enter the record number to delete. This is terrible UI design, and asking for trouble already. It did allow you to enter a range, which made things slightly easier. My boss had been happily deleting ranges of records for years, and was comfortable doing so. But he made a mistake. He entered the range backward. The software did not check for this, and couldn't cope with it. It happily started deleting everything. When the deletion (which normaly took a few seconds) was still going over 20 minutes later, he looked and realised what was happening. He immediately turned the computer off (there was no option to stop it or quit).

    When we got it back up and running, he tasked me with replacing the missing records. They didn't have a backup, and he didn't want to request access to our records from HMRC, because doing so would have meant admitting to an error.

    So, I spent the next 3 months knee deep in shipping paperwork, re-entering the details of all relavant shipments on the computer. The company didn't survive much longer, and ultimately I was rewarded with redundancy a few months later.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon

Other stories you might like