【问题标题】:Does CodeIgniter's ci_sessions need occasional emptying?CodeIgniter 的 ci_sessions 是否需要偶尔清空?
【发布时间】:2013-02-27 22:36:25
【问题描述】:

我正在使用 CI 的会话与数据库连接。所以我们所有的会话都在我们数据库的这个 ci_sessions 表中,并且考虑到 session_id 每 5 分钟不断变化,它可以获得很多行。

我们是否需要清空桌子,比如每月/每周一次?

【问题讨论】:

    标签: php codeigniter session


    【解决方案1】:

    虽然@Marc-Audet 说的是真的,但如果你看一下代码,你会发现这是清理会话的一种非常糟糕的方式。

    构造函数每次启动都会调用_sess_gc函数。因此,基本上每个请求都会自动加载到您的服务器上。

    然后,它会生成一个低于 100 的随机数,并查看它是否低于某个值(默认为 5)。如果满足此条件,则它将删除会话表中 last_activity 值小于当前时间减去会话到期时间的所有行。

    虽然这适用于大多数情况,但技术上可能(如果世界真的是随机的)随机数生成器不会长时间生成低于 5 的数字,在这种情况下,您的会话将不会被清理.

    此外,如果您将会话到期时间设置为较长时间(如果设置为 0,CI 会将其设置为 2 年),那么这些行无论如何都不会被删除。而且,如果您的网站足以吸引大量访问者,那么您的 DBA 很快就会指责会话表 :)

    它适用于大多数情况 - 但我不会称其为合适的解决方案。他们的会话 id 重新生成确实应该被构建以删除与以前的 id 有关的记录,并且垃圾收集确实不应该留给随机数 - 从理论上讲,可能不会像您希望的那样频繁生成所需的数字.

    在我们的例子中,我已经从会话库中删除了会话垃圾收集,并且我每天手动处理一次(使用 cron 作业......和合理的会话到期时间)。这减少了对数据库的不必要点击次数,也不会在数据库中留下大量表。它仍然是一张大桌子,但比以前小了很多。

    【讨论】:

    • 您富有洞察力的 cmets 具有指导性和帮助性,谢谢。 cron 作业技术非常有用。我使用类似的方法来清理作为报告系统的一部分生成的临时 PDF 文件的目录。
    • 非常感谢您提供有关 CI 会话的重要信息,非常感谢 @dakdad :)
    【解决方案2】:

    鉴于 OP 问题没有 CodeIgniter 2 标签,我将回答如何在 CodeIgniter 3 的数据库不断增长时处理会话清理。

    问题:
    当您设置(在 config.php 文件中)sess_expiration 键太高(假设 1 年)和sess_time_to_update 键低(假设 5 分钟)时,会话表将随着用户浏览您的网站而不断增长,直到会话行将过期并被垃圾回收(即 1 年)。

    解决方案:
    sess_regenerate_destroy 键设置为TRUE(默认设置为FALSE)将在旧会话使用新ID 重新生成时删除旧会话,从而自动清理您的表。

    【讨论】:

    • 这是 CodeIgniter 3 的正确答案。谢谢!
    【解决方案3】:

    不,CodeIgniter 会自行清理...

    注意
    根据CodeIgniter documentation

    Session 类具有内置的垃圾回收功能,可以清除过期的会话,因此您无需编写自己的例程即可。

    CodeIgniter 的会话类可能会检查会话表并清理过期条目。但是,文档没有说明何时进行清理。由于 CodeIgniter 没有 cron 作业,因此必须在调用 Session 类时进行清理。我想如果站点永远保持空闲状态,会话表将永远不会被清除。但是,这将是一个不寻常的情况。

    【讨论】:

    • 参见上面添加的注释。如果您的有效期较长,则表格需要很长时间才能清除。
    • 你能告诉我是哪个系统文件用于从 ci_session 表中删除行吗?
    • @NikoliusLau 查看我的回答了解详情:stackoverflow.com/a/39986478/1873197
    【解决方案4】:

    CodeIgniter 实现了SessionHandlerInterface(请参阅custom driver 的文档)。

    CodeIgniter 为每个驱动程序(数据库、文件、redis 等)定义了一个名为 gc() 的垃圾收集器方法,或者您可以为自定义驱动程序定义自定义 gc()。

    gc()方法通过session_set_save_handler()函数传递给PHP,因此垃圾收集器由PHP内部调用基于session.gc_divisor,@987654325 @设置。

    例如,使用以下设置:

    session.gc_probability = 1
    session.gc_divisor = 100
    

    垃圾收集器进程在每次请求时启动的几率为 1%。

    因此,如果设置正确,则无需清理会话表。

    【讨论】:

      【解决方案5】:

      当你打电话时:

      $this->session->sess_destroy();

      它会自行删除数据库中的信息。

      【讨论】:

      • 好吧,我从不在我的网站上使用 sess_destroy.. 所以我必须手动删除它?
      • sess_destroy 只删除用户当前 session_id 的记录。剩下的记录只会被_sess_gc清理干净
      【解决方案6】:

      清理桌子总是好的做法。否则,如果您查询会话数据以创建报告或其他内容,它将变得缓慢且不可靠。不过,鉴于mysql的性能,是的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-06
        • 1970-01-01
        • 1970-01-01
        • 2020-06-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多