The day I reached the 1600 columns limit in PostgreSQL
rosenfeld.herokuapp.com
rosenfeld.herokuapp.com
The reason why I had this problem in the first place is that I wasn't aware that dropped columns would still count towards the columns limit in PostgreSQL. It's not a complaint, it's just ignorance. There's a difference between being ignorant and not understanding the problem after it happens. I never claimed to be an expert on PostgreSQL.
FWIW, I hope we (the PG devs) will fix that some day.
Fixed or not, PG is awesome anyway. Thanks for helping to make it the best database I've worked with so far :-)
The other part was to enable new columns to be added to that table in case we need in the future. For that part, I locked a few tables for writing, recreated them with a separate name and replaced the old with the new one in order to avoid any downtime or dealing with master-slave set-ups to be able to dump and restore without downtimes. Full vacuum freeze wouldn't reclaim that space back.
If you're curious why I didn't simply create that column permanently in the first place, the reason is that this was supposed to be a one-off script (it would run multiple times but just during the transition to the new template until all deals would have been ported) and I didn't want to pollute the table or have to remember to drop that column in a future time. There are also other reasons why I don't think it would be a good idea. The script was greatly simplified with the assumption that all rows having a value in the previous_id column would be related to that deal being ported. If I want to keep the same simple logic I'd have to make sure the script would delete any values from that column in the beginning of the transaction and I figured that could increase the chance of conflicts in case of concurrent attempts of porting deals and I didn't want to have to bother about concurrency issues so I didn't want to even think about that. With a temporary column I knew I wouldn't have to worry about that.
I don't actually regret my approach. It allowed me to deliver the first version for testing earlier and I was able to fix the script later in less than an hour once the problem happened. Maybe other parts of the script were not ideal either, but the migration was successful and this is what really matter to me. It would be a completely different situation if I was writing a permanent code. In those cases I write the code way more carefully and give it quite a lot of thoughts on the future implications.