【问题标题】:How to set journal-mode of Sqlite3 in ruby-on-rails如何在 ruby​​-on-rails 中设置 Sqlite3 的日志模式
【发布时间】:2019-05-24 05:13:39
【问题描述】:

我尝试在我的 Ruby-on-Rails 项目中设置 Sqlite3 的日志模式。

似乎 ruby​​-on-rails 使用 sqlite 的默认日志模式,即“删除”,因为我在更新数据库时在文件夹“db”中看到了一个日志文件,并且在更新完成时它被删除了。我希望将 jouranl-mode 设置为“WAL”或“memory”。 我试过 Sqlite 命令行

PRAGMA main.journal_mode=WAL

但它不影响在 ruby​​-on-rails 中的应用。

最后我通过更改 sqlite3_adapter.rb 的源代码实现了它

我更改了文件中的一个函数:activerecord-5.1.4/lib/active_record/connection_adapter/sqlite3_adapter.rb

def configure_connection  
    # here are original codes
    execute("PRAGMA journal_mode = WAL", "SCHEMA")  
end

因为 configure_connection 是由 SQLite3Adapter 的初始化调用的

虽然可行,但听起来不是很好的解决方案。 有没有更好的方法在 Ruby-on-Rails(版本为 5.1.4)中设置 Sqlite3 的日志模式?例如配置选项

【问题讨论】:

    标签: sqlite ruby-on-rails-5


    【解决方案1】:

    自从我不得不这样做已经有一段时间了,但是您应该能够使用初始化程序,因此您不需要修补源代码。

    把这样的东西放在config/initializers/configure_sqlite_journal.rb

    if c = ::ActiveRecord::Base.connection
        c.execute 'PRAGMA journal_mode = WAL'
    end
    

    应该做你想做的事

    【讨论】:

    • 它运行良好且优雅。非常感谢!
    【解决方案2】:

    我在这里找到了更好的答案:Speed up your Rails sqlite database for large dataset,更高的性能和配置:

    代码(我把它放到 config/initializers/speedup_sqlite3.rb 中):

    if ::ActiveRecord::Base.connection_config[:adapter] == 'sqlite3'
        if c = ::ActiveRecord::Base.connection
        # see http://www.sqlite.org/pragma.html for details
    
        # Page size of the database. The page size must be a power of two between 512 and 65536 inclusive
        c.execute 'PRAGMA main.page_size=4096;'
    
        # Suggested maximum number of database disk pages that SQLite will hold in memory at once per open database file
        c.execute 'PRAGMA main.cache_size=10000;'
    
        # Database connection locking-mode. The locking-mode is either NORMAL or EXCLUSIVE
        c.execute 'PRAGMA main.locking_mode=EXCLUSIVE;'
    
        # Setting of the "synchronous" flag, "NORMAL" means sync less often but still more than none
        c.execute 'PRAGMA main.synchronous=NORMAL;'
    
        # Journal mode for database, WAL=write-ahead log
        c.execute 'PRAGMA main.journal_mode=WAL;'
    
        # Storage location for temporary tables, indices, views, triggers
        c.execute 'PRAGMA main.temp_store = MEMORY;'
      end
    end
    

    【讨论】: