MySQL 报错 ERROR 5270 解决
一、异常现象:闪回操作遭遇的 "对象不在回收站" 错误
在数据库管理过程中,当执行表闪回操作时,可能会遇到一个令人困惑的错误:
ERROR 5270 (HY000): object not in RECYCLE BIN。这种情况通常发生在通过show recyclebin命令确认表存在于回收站中,但执行flashback table命令时却提示对象不在回收站的场景中。以下是错误复现的具体过程:-- 创建测试表
MySQL [mysql]> create table test.a (i int);
Query OK, 0 rows affected (0.04 sec)
-- 开启回收站功能
MySQL [mysql]> set session recyclebin = 1;
Query OK, 0 rows affected (0.00 sec)
-- 删除表
MySQL [mysql]> drop table test.a;
Query OK, 0 rows affected (0.01 sec)
-- 查看回收站,确认表存在
MySQL [mysql]> show recyclebin;
+-----------------------------------------+---------------+-------+----------------------------+
| OBJECT_NAME | ORIGINAL_NAME | TYPE | CREATETIME |
+-----------------------------------------+---------------+-------+----------------------------+
| __recycle_$_1677212890_1680250599065600 | a | TABLE | 2023-03-31 16:16:39.065038 |
+-----------------------------------------+---------------+-------+----------------------------+
1 row in set (0.01 sec)
-- 尝试闪回表,报错对象不在回收站
MySQL [mysql]> flashback table a to before drop;
ERROR 5270 (HY000): object not in RECYCLE BIN
-- 使用回收站中的对象名闪回,仍然报错
MySQL [oceanbase]> flashback table __recycle_$_1677212890_1680250599065600 to before drop;
ERROR 5270 (HY000): object not in RECYCLE BIN
二、原因剖析:数据库上下文与对象定位机制
深入分析发现,该错误的根源在于闪回操作时的数据库上下文环境。当执行
flashback table命令时,系统默认使用当前数据库作为表的上级对象。如果被删除的表不属于当前数据库,就需要使用database.table的完整格式来指定表。具体来说:-
当在
test数据库中创建表a,然后切换到oceanbase数据库执行闪回操作时,直接使用flashback table a to before drop会默认在当前oceanbase数据库中查找表a,而不是在test数据库中查找,从而导致错误。 -
即使使用回收站中的对象名
__recycle_$_1677212890_1680250599065600执行闪回,如果不指定数据库,系统仍然会在当前数据库中查找该对象,而该对象实际存在于test数据库中,因此同样会报错。
三、关于回收站机制的深入思考与测试验证
1. 如何获取回收站中表的所属数据库?
通过查询系统表可以获取回收站中表的所属数据库信息。具体步骤如下:
-- 在test库中创建表a
MySQL [oceanbase]> create table test.a(i int);
Query OK, 0 rows affected (0.05 sec)
-- 开启回收站
MySQL [oceanbase]> set session recyclebin=1;
Query OK, 0 rows affected (0.00 sec)
-- 切换到oceanbase库并删除test.a表
MySQL [oceanbase]> use oceanbase;
Database changed
MySQL [oceanbase]> drop table test.a;
Query OK, 0 rows affected (0.01 sec)
-- 查看回收站
MySQL [oceanbase]> show recyclebin;
+-----------------------------------------+---------------+-------+----------------------------+
| OBJECT_NAME | ORIGINAL_NAME | TYPE | CREATETIME |
+-----------------------------------------+---------------+-------+----------------------------+
| __recycle_$_1677212890_1680257357905408 | a | TABLE | 2023-03-31 18:09:17.904933 |
+-----------------------------------------+---------------+-------+----------------------------+
1 row in set (0.00 sec)
-- 查询回收站中表对应的数据库名称
MySQL [oceanbase]> select rb.tenant_id, rb.database_id, db.database_name, rb.table_id,
-> rb.tablegroup_id, rb.original_name from __all_recyclebin rb
-> inner join __all_virtual_database db
-> on rb.database_id=db.database_id;
+-----------+---------------+---------------+---------------+---------------+---------------+
| tenant_id | database_id | database_name | table_id | tablegroup_id | original_name |
+-----------+---------------+---------------+---------------+---------------+---------------+
| 1 | 1099511628776 | test | 1099511677793 | -1 | a |
+-----------+---------------+---------------+---------------+---------------+---------------+
1 row in set (0.00 sec)
2. 回收站中能否保存多个同名表?闪回时如何处理?
测试表明,回收站可以保存多个同名表,且闪回操作会优先恢复最晚删除的表。具体过程如下:
-- 在test库中创建表a并开启回收站
MySQL [oceanbase]> create table test.a(i int);
MySQL [oceanbase]> set session recyclebin=1;
MySQL [oceanbase]> drop table test.a;
-- 再次创建并删除表a
MySQL [oceanbase]> create table test.a(i int);
MySQL [oceanbase]> insert into test.a values(1);
MySQL [oceanbase]> drop table test.a;
-- 查看回收站,发现两个同名表
MySQL [oceanbase]> show recyclebin;
+-----------------------------------------+---------------+-------+----------------------------+
| OBJECT_NAME | ORIGINAL_NAME | TYPE | CREATETIME |
+-----------------------------------------+---------------+-------+----------------------------+
| __recycle_$_1677212890_1680258454351360 | a | TABLE | 2023-03-31 18:27:34.351415 |
| __recycle_$_1677212890_1680258454423040 | a | TABLE | 2023-03-31 18:27:34.422931 |
+-----------------------------------------+---------------+-------+----------------------------+
2 rows in set (0.01 sec)
-- 闪回表a,恢复的是最晚删除的表
MySQL [oceanbase]> flashback table test.a to before drop;
Query OK, 0 rows affected (0.02 sec)
-- 确认闪回结果
MySQL [oceanbase]> select * from test.a;
+------+
| i |
+------+
| 1 |
+------+
1 row in set (0.01 sec)
3. 关闭回收站后能否查看和操作回收站中的对象?
测试发现,即使关闭回收站,仍然可以查看和操作回收站中的对象:
-- 创建表并开启回收站
MySQL [oceanbase]> create table test.a(i int);
MySQL [oceanbase]> set session recyclebin=1;
MySQL [oceanbase]> drop table test.a;
-- 关闭回收站
MySQL [oceanbase]> set session recyclebin=0;
-- 仍然可以查看回收站中的对象
MySQL [oceanbase]> show recyclebin;
+-----------------------------------------+---------------+-------+----------------------------+
| OBJECT_NAME | ORIGINAL_NAME | TYPE | CREATETIME |
+-----------------------------------------+---------------+-------+----------------------------+
| __recycle_$_1677212890_1680259040929280 | a | TABLE | 2023-03-31 18:37:20.928638 |
+-----------------------------------------+---------------+-------+----------------------------+
1 row in set (0.00 sec)
-- 关闭回收站后仍然可以闪回表
MySQL [oceanbase]> flashback table test.a to before drop;
Query OK, 0 rows affected (0.02 sec)
4. 回收站的可见性范围:全租户可见还是仅当前租户可见?
测试表明,回收站中的对象仅在当前租户内可见,其他租户无法查看:
-- 在租户t1中操作
[root@ob-70 ~]# mysql -h10.186.63.134 -uroot@t1#oceanb_test_zhn -P2883 -c -A -e "create table test.tb1(i int);set session recyclebin=1;drop table test.tb1;show recyclebin;purge recyclebin;"
+-----------------------------------------+---------------+-------+----------------------------+
| OBJECT_NAME | ORIGINAL_NAME | TYPE | CREATETIME |
+-----------------------------------------+---------------+-------+----------------------------+
| __recycle_$_1677212890_1680259840925720 | tb1 | TABLE | 2023-03-31 18:50:40.924748 |
+-----------------------------------------+---------------+-------+----------------------------+
-- 在sys租户中查看回收站,只能看到当前租户的对象
[root@ob-70 ~]# mysql -h10.186.63.134 -uroot@sys#'oceanb_test_zhn' -P2883 -c -p'aaAA__12' -A -e "show recyclebin;"
+-----------------------------------------+---------------+-------+----------------------------+
| OBJECT_NAME | ORIGINAL_NAME | TYPE | CREATETIME |
+-----------------------------------------+---------------+-------+----------------------------+
| __recycle_$_1677212890_1680259040929280 | a | TABLE | 2023-03-31 18:37:20.928638 |
+-----------------------------------------+---------------+-------+----------------------------+
5. 关闭回收站后能否闪回租户?
测试表明,关闭回收站后仍然可以闪回租户:
-- 开启回收站并删除租户t1
MySQL [oceanbase]> set session recyclebin=1;
MySQL [oceanbase]> drop tenant t1;
-- 查看回收站,确认租户t1存在
MySQL [oceanbase]> show recyclebin;
+-----------------------------------------+---------------+--------+----------------------------+
| OBJECT_NAME | ORIGINAL_NAME | TYPE | CREATETIME |
+-----------------------------------------+---------------+--------+----------------------------+
| __recycle_$_1677212890_1680256737738240 | t1 | TENANT | 2023-03-31 18:03:11.107511 |
+-----------------------------------------+---------------+--------+----------------------------+
1 row in set (0.00 sec)
-- 关闭回收站并闪回租户t1
MySQL [oceanbase]> set session recyclebin=0;
MySQL [oceanbase]> flashback tenant t1 to before drop;
Query OK, 0 rows affected (0.02 sec)
四、关键结论与实践建议
关键结论总结
-
对象定位机制:闪回表时需要使用
database.table的完整格式,否则系统会在当前数据库中查找对象。 -
同名表处理:回收站可以保存多个同名表,闪回时会恢复最晚删除的表,历史表仍保留在回收站中。
-
回收站可见性:回收站中的对象仅在当前租户内可见,关闭回收站后仍可查看和操作。
-
关闭后的操作:即使关闭回收站,仍然可以闪回表和租户。
实践建议
-
闪回操作规范:执行闪回表操作时,始终使用
database.table的完整格式,避免因当前数据库上下文导致的错误。 -
同名表管理:如果需要保留多个版本的同名表,建议通过备份或其他方式实现,避免依赖回收站的默认行为。
-
回收站配置:根据业务需求合理配置回收站功能,开启回收站可以为误删除操作提供恢复机会,但也会占用一定的存储空间。
-
租户级操作:在多租户环境中,注意回收站的租户隔离性,避免跨租户操作导致的问题。
-
定期清理:定期清理回收站中的无用对象,释放存储空间,同时避免因回收站中对象过多导致的管理困难。
通过深入理解回收站机制的工作原理和行为特点,可以更好地利用这一功能,提高数据库管理的效率和可靠性,同时避免因不熟悉机制而导致的操作失误。
浙公网安备 33010602011771号