Dropping and creating tables in read only tablespaces?!
2015-12-14 22:03
323 查看
You probably already know that it’s possible to drop tables in Oracle read only tablespaces… (You did know that already, right? ;-) Here’s a little example:
I just dropped a table from a read only tablespace! Well, perhaps it’s because that instead of dropping the table was put into recyclebin instead (which is a data dictionary update)? Let’s check which segments remain in the RONLY tablespace:
Indeed, it seems that the table segment wasn’t actually dropped. Well, let’s purge the recycle bin to try to actually drop the table segment:
Wow, Oracle has converted the table segment into a temporary segment instead (see segment_type)! Bur our tablespace is read only, how can it do that?! The answer is that neither the regular DROP nor DROP PURGE need to write anything into the tablespace where
the segment resides! The initial DROP operation just updated data dictionary, like renaming the table to BIN$… in OBJ$ and so on. The second DROP PURGE operation just ran a bunch of deletes against data dictionary to indicate that the table object is gone.
But why is the TEMPORARY segment left behind? This has to do with locally managed tablespaces. Before LMT days, when you dropped a segment, then the segment space was released and acquired back to tablespace through inserts/updates to UET$/FET$ (used/free
extents) base tables, which resided in system tablespace like all other data dictionary base tables. But with LMTs, the free space information is kept in bitmaps in the tablespace files themselves! Thus, if you drop a table in a read only LMT tablespace, the
table will be gone, but the space will not be physically released (as you can’t update the LMT bitmaps in read only tablespace files). However, Oracle doesn’t want to lose that space should someone make the tablespace read write later on, so the table segment
is updated to be a TEMPORARY segment instead of completely deleting it from data dictionary. That’s how the SMON can clean it up later on should that tablespace become read-write again. The 9.130 in SEGMENT_NAME column means relative file# 9 and starting block#
130, that’s a segment’s unique identifier in a tablespace. Let’s move on. This example is executed on Oracle 11.2, while logged on to a non-SYS/SYSTEM user:
The tablespace is still in read only status. Let’s try to CREATE a table into that tablespace:
What? I can also CREATE a table into a read only tablespace?! Well, this is the behavior you get starting from 11gR2 onwards, it’s called deferred segment creation, Oracle doesn’t need to create any segments for a table until you actually insert rows into it!
So, Oracle creates all needed metadata about the new table in data dictionary, but doesn’t actually allocate any space from the tablespace. This applies to other segment types like index and table/index partitions as well. There’s new syntax which controls
the deferred segment creation:
In the above case I disabled the deferred segment creation and got an error immediately as Oracle tried to allocate space from the read only tablespace. Let’s try the other way:
Now, with deferred segment creation enabled, Oracle didn’t try to allocate space from the read only tablespace. Let’s look into the segments in that tablespace again:
We still have that old segment from an earlier DROP TABLE operation waiting to be cleaned up (when the tablespace goes into read-write mode again), but no segment for our latest test table created. Let’s make the tablespace read write and check again:
Apparently SMON has kicked in already and cleaned up the table segment which had been marked temporary earlier when I dropped the table in a read only tablespace.
Note that tables in SYS and SYSTEM schema can not use deferred segment creation:
SQL> create table sys.test (a int) segment creation deferred;
create table sys.test (a int) segment creation deferred
*
ERROR at line 1:
ORA-14223: Deferred segment creation is not supported for this table
SQL> create table system.test (a int) segment creation deferred;
create table system.test (a int) segment creation deferred
*
ERROR at line 1:
ORA-14223: Deferred segment creation is not supported for this table
SQL> create table tanel.test (a int) segment creation deferred;
Table created.
There’s also a parameter, deferred_segment_creation which controls the default behavior:
NB! Dates updated: After a 1.5 year break, this year’s only Advanced Oracle Troubleshooting training class (updated with Oracle 12c content) takes place
on 14-18 December 2015 and 11-15 January 2016 (I had to reschedule the start from November to December). So sign up now if you want to learn new cool stuff!
SQL> create tablespace ronly datafile '/u03/oradata/LIN112/ronly.01.dbf' size 10m; Tablespace created. SQL> create table test tablespace ronly as select * from all_users; Table created. SQL> alter tablespace ronly READ ONLY; Tablespace altered. SQL> drop table test; Table dropped.
I just dropped a table from a read only tablespace! Well, perhaps it’s because that instead of dropping the table was put into recyclebin instead (which is a data dictionary update)? Let’s check which segments remain in the RONLY tablespace:
SQL> select owner,segment_name,segment_type from dba_segments where tablespace_name = 'RONLY'; OWNER SEGMENT_NAME SEGMENT_TYPE ------- ------------------------------- ------------------ TANEL BIN$ix7rAUXZfB3gQKjAgS4LXg==$0 TABLE
Indeed, it seems that the table segment wasn’t actually dropped. Well, let’s purge the recycle bin to try to actually drop the table segment:
SQL> purge recyclebin; Recyclebin purged. SQL> select owner,segment_name,segment_type from dba_segments where tablespace_name = 'RONLY'; OWNER SEGMENT_NAME SEGMENT_TYPE -------- ------------------------------ ------------------ TANEL 9.130 TEMPORARY
Wow, Oracle has converted the table segment into a temporary segment instead (see segment_type)! Bur our tablespace is read only, how can it do that?! The answer is that neither the regular DROP nor DROP PURGE need to write anything into the tablespace where
the segment resides! The initial DROP operation just updated data dictionary, like renaming the table to BIN$… in OBJ$ and so on. The second DROP PURGE operation just ran a bunch of deletes against data dictionary to indicate that the table object is gone.
But why is the TEMPORARY segment left behind? This has to do with locally managed tablespaces. Before LMT days, when you dropped a segment, then the segment space was released and acquired back to tablespace through inserts/updates to UET$/FET$ (used/free
extents) base tables, which resided in system tablespace like all other data dictionary base tables. But with LMTs, the free space information is kept in bitmaps in the tablespace files themselves! Thus, if you drop a table in a read only LMT tablespace, the
table will be gone, but the space will not be physically released (as you can’t update the LMT bitmaps in read only tablespace files). However, Oracle doesn’t want to lose that space should someone make the tablespace read write later on, so the table segment
is updated to be a TEMPORARY segment instead of completely deleting it from data dictionary. That’s how the SMON can clean it up later on should that tablespace become read-write again. The 9.130 in SEGMENT_NAME column means relative file# 9 and starting block#
130, that’s a segment’s unique identifier in a tablespace. Let’s move on. This example is executed on Oracle 11.2, while logged on to a non-SYS/SYSTEM user:
SQL> select status from dba_tablespaces where tablespace_name = 'RONLY'; STATUS --------- READ ONLY
The tablespace is still in read only status. Let’s try to CREATE a table into that tablespace:
SQL> create table test(a int) tablespace ronly; Table created.
What? I can also CREATE a table into a read only tablespace?! Well, this is the behavior you get starting from 11gR2 onwards, it’s called deferred segment creation, Oracle doesn’t need to create any segments for a table until you actually insert rows into it!
So, Oracle creates all needed metadata about the new table in data dictionary, but doesn’t actually allocate any space from the tablespace. This applies to other segment types like index and table/index partitions as well. There’s new syntax which controls
the deferred segment creation:
SQL> drop table test purge; Table dropped. SQL> create table test (a int) segment creation IMMEDIATE tablespace ronly; create table test (a int) segment creation IMMEDIATE tablespace ronly * ERROR at line 1: ORA-01647: tablespace 'RONLY' is read-only, cannot allocate space in it
In the above case I disabled the deferred segment creation and got an error immediately as Oracle tried to allocate space from the read only tablespace. Let’s try the other way:
SQL> create table test (a int) segment creation DEFERRED tablespace ronly; Table created.
Now, with deferred segment creation enabled, Oracle didn’t try to allocate space from the read only tablespace. Let’s look into the segments in that tablespace again:
SQL> select owner,segment_name,segment_type from dba_segments where tablespace_name = 'RONLY'; OWNER SEGMENT_NAME SEGMENT_TYPE ------------ --------------- --------------- TANEL 9.130 TEMPORARY
We still have that old segment from an earlier DROP TABLE operation waiting to be cleaned up (when the tablespace goes into read-write mode again), but no segment for our latest test table created. Let’s make the tablespace read write and check again:
SQL> alter tablespace ronly read write; Tablespace altered. SQL> select owner,segment_name,segment_type from dba_segments where tablespace_name = 'RONLY'; no rows selected
Apparently SMON has kicked in already and cleaned up the table segment which had been marked temporary earlier when I dropped the table in a read only tablespace.
Note that tables in SYS and SYSTEM schema can not use deferred segment creation:
SQL> create table sys.test (a int) segment creation deferred;
create table sys.test (a int) segment creation deferred
*
ERROR at line 1:
ORA-14223: Deferred segment creation is not supported for this table
SQL> create table system.test (a int) segment creation deferred;
create table system.test (a int) segment creation deferred
*
ERROR at line 1:
ORA-14223: Deferred segment creation is not supported for this table
SQL> create table tanel.test (a int) segment creation deferred;
Table created.
There’s also a parameter, deferred_segment_creation which controls the default behavior:
SQL> show parameter deferred NAME_COL_PLUS_SHOW_PARAM TYPE VALUE ---------------------------- ----------- -------- deferred_segment_creation boolean TRUE SQL>
NB! Dates updated: After a 1.5 year break, this year’s only Advanced Oracle Troubleshooting training class (updated with Oracle 12c content) takes place
on 14-18 December 2015 and 11-15 January 2016 (I had to reschedule the start from November to December). So sign up now if you want to learn new cool stuff!
相关文章推荐
- URL之Linux相关资源整理
- Mac下配置PHP+Apache+phpMyAdmin+MySql远程链接
- linux处理邮件编码
- centos 6.5源码编译安装subversion 1.8.10
- Linux-CentOS XAMPP Apache 支持mp4与flv拖动播放的功能模块
- linux-结构化成行成列-小文件循环合并成大文件--方便上传到hadoop
- linux应用编程笔记(16)多线程编程函数全解析
- CVE-2014-0050: Exploit with Boundaries, Loops without Boundaries、Apache Commons FileUpload and Apache Tomcat DoS
- nginx变量
- linux处理邮件编码
- hadoop2.6安装
- linux字符设备驱动解析
- linux监控程序-程序自动重启方法
- Asp.net docker
- Linux VI常用命令
- Linux下高并发socket最大连接数所受的限制问题
- centos6.5 FTP服务器的搭建
- Linux centOS下安装配置openfire
- Apache Commons 工具集
- Nginx基本命令