Best practices for allowing rollback of individual customers on a shared database
Mimic the transaction system of PostgreSQL:

Every affected table has a column visible_from and visible_to, type timestamp with time zone.

When you update or delete a table, set visible_to on the old version of the row to the current timestamp rather than actually updating or deleting it.

When you update or insert a table, add a new row with visible_from set to the current timestamp.


This way you can determine the state of the table at any given point in time. Rolling back is now a matter of deleting some rows and clearing visible_to on others.
Periodically a job removes data with visible_to older than a certain grace period.