Yii框架无法恢复数据,能否恢复取决于数据库配置:MySQL需开启ROW格式binlog,SQL Server需FULL恢复模式及日志备份,PostgreSQL需logical wal_level与归档;软删除非容灾方案,紧急时应直接操作数据库日志恢复。

Yii 框架本身不提供数据恢复能力,恢复动作必须落在数据库层;框架只负责执行 SQL 或调用 ActiveRecord 方法,误删后能否救,取决于你有没有开启 binlog(MySQL)或完整恢复模式(SQL Server),以及是否保留了备份。
确认数据库是否支持按时间点恢复
Yii 是应用层框架,它不管理日志、不保存历史快照。真正决定“能不能救”的,是底层数据库配置:
- MySQL:必须
binlog_format = ROW且log_bin = ON,否则mysqlbinlog解析不出具体行变更 - SQL Server:数据库恢复模式必须是
FULL,且你有完整备份 + 后续日志备份文件 - PostgreSQL:需开启
wal_level = logical并配合归档(archive_mode)
没满足上述任一条件,Yii 层面再怎么写 rollback 逻辑也没用——数据物理上已不可追溯。
别在 Yii 中写“软删除”来替代备份
很多人在 ActiveRecord 里加 is_deleted 字段,以为这就叫“可恢复”。但这是典型混淆概念:
- 软删除只是逻辑标记,不能防 schema 变更(比如
DROP TABLE) - 没做定期清理的话,
WHERE is_deleted = 0会拖慢所有查询,索引失效风险高 - 一旦误执行
DELETE FROM xxx WHERE is_deleted = 1,连软删记录都丢了
软删除只适合业务侧可控的“用户主动删除”,不是 DBA 级别的容灾方案。
紧急恢复时,绕过 Yii 直接操作数据库
出事第一反应不是改 PHP 代码,而是立刻停止应用写入(比如临时注释掉 yii\db\Connection 配置里的 enableSchemaCache 并重启 PHP-FPM),然后:
- 查 MySQL 当前 binlog 位置:
SHOW MASTER STATUS; - 定位误操作时间点附近的 binlog 文件,用
mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000012找到对应DELETE或UPDATE事件 - 把事件反向生成
INSERT或旧值UPDATE,手工执行回库(注意主键冲突、外键约束) - 若用 SQL Server,直接走
RESTORE LOG ... WITH STOPAT还原到临时库,再用SELECT INTO抽数据
不要试图在 Yii 的 beforeDelete() 里塞日志表记录——那条记录本身可能还没写入就崩了;恢复必须从数据库原始日志出发,越早脱离应用层越安全。
最容易被忽略的一点:Yii 迁移文件不是备份
migration 只记录结构变更,不存数据快照。哪怕你每天跑 yii migrate/create backup_user_table,里面写的 INSERT 也只是当时静态快照,无法覆盖后续增删改。真要靠迁移做恢复,得配合 mysqldump --tab 导出 CSV + 定时 commit 到 Git,但这早已超出 Yii 能力范围——它只是个 PHP 框架,不是数据库运维工具。











