Postgres中更好的資料庫遷移

2021-08-09 02:41:45 字數 983 閱讀 8560

譯者注:在postgres中進行資料庫遷移時會遇到哪些問題?如何解決它們?請見下文。

有兩種操作發生的很頻繁,每種操作都有一些簡單的方法可以減少停機時間。讓我們看看每乙個操作,它們是如何工作的,以及如何以更安全的方式來處理它們。

在postgres中新增乙個新列實際上代價是很低的。當你這樣做的時候,它會更新對於已有列時刻的跟蹤,它幾乎是瞬時的。當對某個列有一些約束時,這一部分就會變得很昂貴。乙個約束可以是乙個主鍵或者外來鍵,或者是一些唯一性約束。 postgres不得不掃瞄表中的所有記錄以確保沒有違反這些約束。新增諸如「非空」等一些約束時,可能會有一些違反,但這不是最常見的原因。

造成新增新列遲緩最常見的原因是大部分的框架中為新列設定預設值太過簡單。對於所有的新記錄這是一回事,但是對於已有的表來說,這意味著資料庫不得不要讀取所有的記錄並且向這些記錄中重寫新的預設值。對於只有幾百條記錄的表來說,這還不算太糟,但是對於上千萬條記錄的表來說,這時間就無法容忍了 。

簡而言之,在新增新列時,如果將其設為非空或者在建立是設定乙個預設值都會給你帶來麻煩。解決之道是不要這樣做。但是,如果你需要乙個預設值或者不想欄位為空時該怎麼辦。這有一些你可以採取的簡單步驟,將你的遷移工作從一步分為 四步: 

1. 新增新列,允許其為空 

2. 開始在所有新記錄和更新中寫入預設值 

3. 逐步回填預設值 

4. 應用你的約束 

是的,只是稍微多一點工作,對現有工作的影響很微小。

類似大部分的ddl操作,建立索引時會加鎖,這就意味著所有新的資料必須等待索引建立完成後才可以寫入。對於新建的或者小規模的表,等待的時間不是很明顯,但是對於大規模資料庫,等待的時間可能是以分鐘甚至小時計新增索引的本意是為了提高查詢速度,但是實際的效果卻是降低了速度,這真是有點諷刺。

postgres中對於這個問題的答案是 concurrent 建立索引。就是在後台逐步建立索引。你可以通過:create index concurrently語句併發建立索引。一旦建立了索引,只要你做想做的事情,postgres就會在查詢中使用它。

postgres資料庫中的資料轉換

postgres8.3以後,字段資料之間的預設轉換取消了。如果需要進行資料變換的話,在postgres資料庫中,我們可以用 來進行字段資料的型別轉換。實際上 是呼叫cast函式的。究竟哪些字段之間可以進行資料轉換呢?這個問題只要研究一下cast函式就能夠得到答案。cast函式的資訊在系統pg cas...

postgres資料庫中的資料轉換

postgres8.3以後,字段資料之間的預設轉換取消了。如果需要進行資料變換的話,在postgres資料庫中,我們可以用 來進行字段資料的型別轉換。實際上 是呼叫cast函式的。究竟哪些字段之間可以進行資料轉換呢?這個問題只要研究一下cast函式就能夠得到答案。cast函式的資訊在系統pg cas...

postgres模板資料庫

create database 實際上是通過拷貝乙個現有的資料庫進行工作的。預設時,它拷貝名為 template1 的標準系統資料庫。所以該資料庫是建立新資料庫的 模板 如果你給 template1 增加物件,這些物件將被拷貝到隨後建立的使用者資料庫中。這樣的行為允許節點對資料庫中的標準套件進行修改...