In my project having 23 million records and around 6 fields has been indexed of that table.
Earlier I tested to add delta column for Thinking Sphinx search but it turns in holding the whole database lock for an hour. Afterwards when the file is added and I try to rebuild indexes this is the query that holds the database lock for around 4 hours:
"update user_messages set delta = false where delta = true"
Well for making the server up I created a new database from db dump and promote it as database so server can be turned live.
Now what I am looking is that adding delta column in my table with out table lock is it possible? And once the column delta is added then why is the above query executed when I run the index rebuild command and why does it block the server for so long?
PS.: I am on Heroku and using Postgres with ika db model.
Postgres 11 or later
Since Postgres 11, only volatile default values still require a table rewrite. The manual:
Bold emphasis mine.
falseis immutable. So just add the column withDEFAULT false. Super fast, job done:Postgres 10 or older, or for volatile
DEFAULTAdding a new column without
DEFAULTorDEFAULT NULLwill not normally force a table rewrite and is very cheap. Only writing actual values to it creates new rows. But, quoting the manual:UPDATEin PostgreSQL writes a new version of the row. Your question does not provide all the information, but that probably means writing millions of new rows.While doing the
UPDATEin place, if a major portion of the table is affected and you are free to lock the table exclusively, remove all indexes before doing the massUPDATEand recreate them afterwards. It’s faster this way. Related advice in the manual.If your data model and available disk space allow for it,
CREATEa new table in the background and then, in one transaction:DROPthe old table, andRENAMEthe new one. Related:While creating the new table in the background: Apply all changes to the same row at once. Repeated updates create new row versions and leave dead tuples behind.
If you cannot remove the original table because of constraints, another fast way is to build a temporary table,
TRUNCATEthe original one and massINSERTthe new rows – sorted, if that helps performance. All in one transaction. Something like this: