[Rails] 如何快速的對大資料量建立索引,避免 Downtime
source link: https://blog.niclin.tw/2018/06/15/rails-%E5%A6%82%E4%BD%95%E5%BF%AB%E9%80%9F%E7%9A%84%E5%B0%8D%E5%A4%A7%E8%B3%87%E6%96%99%E9%87%8F%E5%BB%BA%E7%AB%8B%E7%B4%A2%E5%BC%95%E9%81%BF%E5%85%8D-downtime/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Postgres 在建立索引時,會阻塞 DML 也就是 lock 整個 table 的寫入(讀取則不影響),所以當需要對大資料量的 Table 打 index 時,會造成有 Downtime 時間,這在 Production 這種高並發的環境下是不適合的。
並發計算建立 index
Postgres 在建立索引時有提供 CONCURRENTLY 的選項可以設定(並發計算),這樣一來就不會影響 table 的寫入行為(INSERT, UPDATE, DELETE)
可以同時處理一般的寫入行為,也可以打 index, 不過是生成時間會再慢一些,但至少沒有停機時間。
在 Rails 4 之後可以直接加入 algorithm: :concurrently 在你的 migration 檔案內
class AddIndexToUsers < ActiveRecord::Migration
disable_ddl_transaction!
def change
add_index :users, :alive, algorithm: :concurrently
end
end
不過這邊要注意的是, disable_ddl_transaction!
與 algorithm: :concurrently
是一組的,必須一起使用。
如果你有其他的 migrate 要做,建議分開。
為什麼要用 disable_ddl_transaction! ?
因為在 Rails 的 migration 中預設每個執行都會包一個 transaction ,如果有失敗的情況就會整個 Rollback,但如果要使用 Postgres 當中的 Concurrently 去建立 index 的話,必須要在 transaction 之外 (concurrent indexes must be created outside a transaction.)
一般 CREATE INDEX 情況下,只會掃一次表,但如果使用這個並發計算參數時,則會引發 Database 掃兩次表,並且等待所有潛在會讀到該索引的事務結束,這樣一來會增加 CPU + I/O 的負擔,不過拿這個負擔來換 Downtime 想必是划算的。
使用 concurrently 參數時,有可能遇到創建索引失敗的狀況,比方說建立 uniqu 索引結果發現數據重複了,此時 Table 上會存在索引,這是因為帶 concurrently 參數的指令發出後,會馬上在 Log 裡面插一個 index 記錄進去,又因為這個索引建立失敗了,會被標記一個 INVALID 的狀態
"idx" btree (col) INVALID
Recommend
-
4
我們公司許多開發測試用的資料庫都直接使用開在 Azure SQL Database 中,然而如果錯誤的授權可能會導致權限過大,甚至有可能刪除資料庫本身。本篇文章我打算分享幾個建立 SQL Server 登入與資料庫使用者的過程,幫助管理者更加正確的授權給開發人員與應用程式。...
-
7
Azure SQL Database 的 Elastic p...
-
4
快速產生 SQLite 資料的方式:一分鐘內產生十億筆資料 在「Towards Inserting One Billion Rows in SQLite Under A Minute」這邊看到作者想要在一分鐘內在 MBP 2019 上面寫 1B 筆...
-
4
架設一個測試網站,最常見的需求就是一個網站(Azure Web App)外加一個資料庫(Azure SQL Database),如果有檔案儲存需求,頂多就再加一個儲存體帳戶(Azure Storage Account)就可以搞定。這篇文章我將分享如...
-
2
建立索引式的学习方法建立索引式的学习方法原文地址:https://geekplux.com/2015/12/08/learning-by-index学习方法的重要性不必多言,相信每个人都...
-
4
低 Downtime 將 4TB 的 PostgreSQL 9.6 資料庫升級到 13 的故事 前幾天在 Hacker News 首頁上看到的文章,講怎麼把一個 4TB 的 Postgr...
-
3
EF Core 測試小技巧 - 快速建立資料表 2022-04-11 09:41 AM 1 523 截至目前,我的 EF Core 範例都是用 dotnet ef migrations create 產生建立(或升級)...
-
4
除了把關鍵字的 SEO 做好以外,也要注意被「禁止收錄」的部分,有時我們會有其他的環境,例如 staging, 用不同的域名或是 subdomain 下去做等等,在這些情況下,不要讓搜尋引擎收錄網頁其實是有好處的,如果一個網站被收錄了很多對搜尋結果沒有幫助的網頁,反而...
-
2
Discord使用ElasticSearch建立数十亿条消息的索引 -Sukhad 解道Jdon
-
2
Mysql中如果建立了索引,索引所占的空间随着数据量增长而变大,这样无论写入还是查询,性能都会有所下降,怎么处理? ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK