2012-03-08 27 views
9

Tôi muốn thêm chỉ mục vào cơ sở dữ liệu sản xuất. May mắn thay, chúng tôi đang chạy Postgres, cho phép lập chỉ mục đồng thời một cách độc đáo, vì vậy chúng tôi có thể thêm chỉ mục mà không có thời gian chết. Các chỉ mục đánh bắt - đồng thời không thể được thêm từ bên trong một giao dịch và việc di chuyển đường ray bao bọc mọi thứ bên trong một giao dịch.Làm thế nào để dừng Rails 3.1 di chuyển từ chạy trong một giao dịch?

May mắn thay, có điều gì đó trông giống như một giải pháp thực sự đơn giản: ghi đè phương thức riêng tư ActiveRecord :: Migration ddl_transaction, dưới dạng explained here.

class IndexUsersEmails < ActiveRecord::Migration 
    def ddl_transaction(&block) 
    block.call # do not start a transaction 
    end 

    def self.up 
    execute "CREATE INDEX CONCURRENTLY index_users_on_email ON users(email)" 
    end 
end 

Vấn đề là nó dường như không hoạt động trong Rails 3.1. Tôi làm chính xác những gì các mã trong Gist không, và đường ray dường như hoàn toàn bỏ qua nó. Bất kỳ ý tưởng về nơi để đi với điều này?

+0

Bạn đã thử thay đổi định nghĩa phương pháp sao cho đó là một phương pháp lớp? ví dụ. 'def self.ddl_transaction (& block) ...' –

Trả lời

11

Tôi chỉ nhận thấy rằng tôi chưa bao giờ chấp nhận câu trả lời ở đây, vì vậy tôi nên nói những gì tôi đã làm. Hóa ra bạn có thể thoát khỏi giao dịch như sau:

class AddFbPageIdIndexToTabs < ActiveRecord::Migration 
    def up 
    execute "END" 
    execute "CREATE INDEX CONCURRENTLY bob_lob_law_index ON bob_lob (law)" 
    execute "BEGIN" 
    end 

    def down 
    execute "END" 
    execute "DROP INDEX CONCURRENTLY bob_lob_law_index" 
    execute "BEGIN" 
    end 
end 

Chỉ cần chạy execute "END" trước khi bạn muốn chạy bên ngoài giao dịch. Thao tác này sẽ kết thúc giao dịch mà ActiveRecord :: Migration tự động thiết lập để di chuyển. Sau khi bạn đã hoàn thành mã mà bạn muốn chạy bên ngoài giao dịch, execute "BEGIN" sẽ mở một giao dịch mới để ActiveRecord :: Di chuyển có thể thực hiện quy trình dọn dẹp của nó và đóng giao dịch mà nó cho rằng nó đã mở.

(Tôi quên nơi trực tuyến tôi tìm thấy thủ thuật này và không thể tìm thấy nó ngay bây giờ. Chỉnh sửa chào mừng bạn đến nguồn này!)

1

Tôi không nói đây là "đúng cách" để làm điều đó, nhưng những gì làm việc cho tôi là để chạy chỉ một di cư trong sự cô lập.

rake db:migrate:up VERSION=20120801151807 

nơi 20120801151807 là dấu thời gian của quá trình di chuyển CREATE INDEX CONCURRENTLY.

Dường như, nó không sử dụng giao dịch khi bạn chạy một lần di chuyển.

Các vấn đề liên quan