There are actually two questions in one here:
- who should be responsible for changes in Production data?
- how best to perform those changes?
Let me address them separately.
Who should be responsible for changes in Production data?
No single person.
What the way you are performing the change; a change in Production (or any sensitive system) should be reviewed by at least another (knowledgeable) person, and approved by some manager.
This is teamwork and obeying the chain of responsibility. Then at this point, it does not matter if you do an error:
- It will only be applied if someone else has reviewed it (and failed to notice the issue)
- It will only be applied if some manager approved it (and took responsibility for it)
If no manager is willing to take responsibility for the change, do not perform it.
If people argue about the time-sensitivity of the change, tell them that one should never mistake being fast for rushing. I would actually argue for extra care in case of urgency (another reviewer, for example), specifically because pressure increases the chance of errors. It is much faster to be right the first time, than messing things up, cleaning the mess, and finally performing the change.
How best to perform those changes?
- a back-up is available and there is a restore procedure
- the change is performed through a script, which is accompanied by a vetted (*) fallback script
Now, unfortunately, conditions are not always ideal.
Back-ups are good, but in a live environment where data change every second it is just not possible to keep the back-ups exactly up-to-date; back-ups can only be used in case of massive error and by accepting that the latest changes will be lost. This is why I cannot insist enough on scripting the changes, and checking that the fallback script is working as intended.
Some changes cannot be fallen back. For example, when removing a column, the data in this column cannot be restored in case of issue. Those changes should be done in two-steps:
- in a first step, disable the access to the piece of data that will be deleted, without actually deleting it; in the case of column, rename it for example. This step can be fallen back.
- then, when it has been assessed that the change was valid (several days or weeks have gone by without issues), perform the non-fallbackable change in a single-purpose script
(*) To vet a fallback script, you have to run your script against a copy of the real database, then apply the fallback script and check that the data is back to normal.
(*) I have seen the suggestion of doing the change in a transaction; this is insufficient (what if you realize your mistake after the commit?), contention-prone (you are blocking all modified rows until you commit) and not always possible (too large change-set/risks of deadlocks). Still, if possible, use transactions within your script as half-done changes are harder to fallback.