在演示事务的read only mode 的时候,因为一个错误有了这个意外的收获。场景是这样的:
在session 1 中执行了如下的语句。
SQL> set transaction read only;
Transaction set.
SQL> select count(*) from employees;
COUNT(*)
----------
107
在session 2 中执行如下的语句。
SQL> insert into employees
2 (employee_id, last_name, email,
3 hire_date, job_id) values (210,
4 'Hintz', 'JHINTZ', SYSDATE,
5 'SH_CLERK');
insert into employees
*
ERROR at line 1:
ORA-01502: 索引 'HR.EMP_EMAIL_UK' 或这类索引的分区处于不可用状态
嗯,这是因为以前我把这个索引的状态alter 成unusable了,好吧,我们rebulid。
SQL> alter index emp_email_uk rebuild;
Index altered.
SQL> insert into employees
2 (employee_id, last_name, email,
3 hire_date, job_id) values (210,
4 'Hintz', 'JHINTZ', SYSDATE,
5 'SH_CLERK');
1 row created.
SQL> commit;
Commit complete.
现在貌似一切很正常,返回到session 1 中执行如下的语句。
SQL> select count(*) from employees;
select count(*) from employees
*
ERROR at line 1:
ORA-08176: 一致读取失败; 回退数据不可用
正常情况下,不应该啊,查看下undo 的保留时间,900s 足够了。也不可能
是undo tablespace 的空间不够,因为我的实验系统中每秒的事务量几乎为零。
就算空间不够也应该报“snapshot too old”的错。
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ---------------------- ---------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
不由的让人想到上面的alter index 的语句。我们试着重现错误。
在session 1 中执行如下的语句.
SQL> set transaction read only;
Transaction set.
SQL> select count(*) from employees;
COUNT(*)
----------
107
在session 2 中执行如下的语句。
SQL> alter index emp_email_uk unusable;
Index altered.
SQL> INSERT INTO employees
2 (employee_id, last_name, email,
3 hire_date, job_id) VALUES (210,
4 'Hintz', 'JHINTZ', SYSDATE,
5 'SH_CLERK');
INSERT INTO employees
*
ERROR at line 1:
ORA-01502: 索引 'HR.EMP_EMAIL_UK' 或这类索引的分区处于不可用状态
SQL> alter index emp_email_uk rebuild;
Index altered.
返回到session 1 中执行如下的语句。
SQL> select count(*) from employees;
select count(*) from employees
*
ERROR at line 1:
ORA-08176: 一致读取失败; 回退数据不可用
--至此错误重现了。
通过重现错误,我们已经知道症结所在的,所以以后我们需要避免这种情况的发生。对这个ORA-08176 错误也有了更多的认识。最后我们来看看这个错误代码的信息:
ORA-08176: cannot continue consistent read for the table/index - no undo
records
Cause: Oracle encountered an operation that does not generate undo records.
For example, the operation might have been an attempt to create an index by
performing a direct load or executing a discrete mode transaction.
records
Cause: Oracle encountered an operation that does not generate undo records.
For example, the operation might have been an attempt to create an index by
performing a direct load or executing a discrete mode transaction.
导致这个问题的根本原因是上面加黑的那句话。