生产环境Laravel将session驱动从file改为database时已有会话是否保留?
直接切换session驱动的影响
- 对在线用户的影响:直接切换后所有正在访问站点的用户会被强制退出登录,已存储在session中的临时数据(比如未提交的表单草稿、购物车内容、筛选查询状态等)全部丢失,会产生明显的用户体验问题。
- 旧会话保留情况:默认不会保留,Laravel切换驱动后只会从新的存储介质(数据库)中读取session数据,不会再读取原有file驱动存储的session文件。
无感知迁移方案(不丢失旧会话数据)
可以通过先预导数据再切换配置的方式实现无缝迁移,全程不会影响线上用户使用,具体步骤如下:
- 生成session数据库表
执行Laravel自带的命令生成表迁移文件:
执行迁移创建表:php artisan session:table
这一步可以在线上直接执行,不会对现有业务产生任何影响。php artisan migrate - 编写session迁移脚本
你可以创建一个自定义Artisan命令用于迁移旧的file session到数据库,核心逻辑参考如下:<?php use Illuminate\Console\Command; use Illuminate\Support\Facades\File; use App\Models\Session; class MigrateFileSessionToDatabase extends Command { protected $signature = 'session:migrate-file-to-db'; protected $description = 'Migrate existing file session to database driver'; public function handle() { $sessionPath = storage_path('framework/sessions'); $sessionLifetime = config('session.lifetime') * 60; $expireThreshold = now()->timestamp - $sessionLifetime; $sessionFiles = File::files($sessionPath); $this->info(sprintf('Found %d session files to process', count($sessionFiles))); $processed = 0; foreach ($sessionFiles as $file) { $sessionId = $file->getFilename(); // 跳过系统隐藏文件 if (str_starts_with($sessionId, '.')) { continue; } // 跳过已过期的session if ($file->getMTime() < $expireThreshold) { continue; } $sessionContent = $file->getContents(); $payload = @unserialize($sessionContent); $userId = $payload['user_id'] ?? null; Session::updateOrCreate( ['id' => $sessionId], [ 'user_id' => $userId, 'payload' => base64_encode($sessionContent), 'last_activity' => $file->getMTime(), ] ); $processed++; } $this->info(sprintf('Successfully migrated %d valid sessions', $processed)); return Command::SUCCESS; } } - 预迁移数据
在线上低峰期执行迁移命令:
可以重复执行多次,确保最后切换前的session数据尽可能完整,这一步也不会影响现有业务运行。php artisan session:migrate-file-to-db - 切换驱动配置
修改.env文件中的配置项:
然后刷新配置缓存:SESSION_DRIVER=database
这一步操作秒级完成,切换后所有请求都会使用数据库中的session数据,之前导入的旧会话可以正常读取,用户完全无感知。php artisan config:cache - 后续处理
切换后观察1-2天确认业务运行正常,再删除storage/framework/sessions目录下的旧session文件即可。
迁移注意事项
- 如果你的Laravel项目开启了session加密,不需要调整迁移逻辑,文件中存储的本身就是加密后的合法内容,导入数据库后Laravel可以正常解析。
- 如果迁移后出现异常,可以立刻将
SESSION_DRIVER改回file并刷新配置,即可快速回滚到原有状态,不会产生数据损失。 - 高并发站点可以在最后切换前1分钟再执行一次迁移命令,减少两次执行之间新增的session差异。
内容的提问来源于stack exchange,提问作者Jessica Shamoon
相关产品推荐
相关产品推荐

