I'd like to ask a question.
What happen If I create an index without specifying the tablespace in the process of creation.
For example :
CREATE INDEX indx_cd on distributors(dist_cd)
In what tablespace does the index created? And will the index still works as it should even if I put it that way?
The index will be created in the default tablespace of the schema.
As system user you can determine what tablespace that is:
select username,default_tablespace from dba_users
Related
There is a schema called Docker, in which there are tables named TABLE2, TABLE3.
Example
SELECT * FROM all_all_tables WHERE TABLE_name= 'TABLE3';
Also, the Docker schema belongs to the DEFAULT TABLESPACE SYSTEM tablespace.
select
username
, default_tablespace from dba_users WHERE USERNAME = 'DOCKER';
The following syntax is used to change the default tablespace of the schema. (TS3 tablespace already exists)
ALTER USER docker DEFAULT tablespace TS3;
Then, when I searched again, I found that the DEFAULT TABLESPACE was changed.
select
username
, default_tablespace from dba_users WHERE USERNAME = 'DOCKER';
And, of course, I thought that the tablespace in which TABLE2 and TABLE3 were designated would also have been changed to TS3, and the following statement was executed.
However, the tablespace of the table was SYSTEM, not TS3. I am curious about why it hasn't changed, and I want to know how.
SELECT * FROM all_all_tables WHERE TABLE_name= 'TABLE3';
The default tablespace is just that-- a default for when you create a segment (normally a table or an index but a segment could be a partition of a table, a materialized view, or anything else that requires space) and don't specify the tablespace. Once you create a segment and it is assigned to a particular tablespace, it will remain in that tablespace unless you move it.
Assuming you are on 12.2 or later so that online moves are an option (in other versions you'd need to remove the online keyword)
alter table table3
move online tablespace ts3;
You'd need to do that for each table. If there are also indexes in the system tablespace, you'd want to move those as well
alter index index_name
rebuild online tablespace ts3;
Depending on the number of tables and indexes involved, you may want to write a bit of dynamic SQL to generate the various alter table and alter index statements for you.
While creating tables or indexes, I always get the recommendation to add tablespace clause in the queries. Is there any major impact later on our table if we don't use the tablespace clause while creating them ?
This is what I am doing for a very long time.
CREATE TABLE XT_PMB_NOTIFY_UNSUB(
TXNID NUMBER(15),
APP_SEQNO NUMBER(15),
PRIMARY_KEYVAL VARCHAR2(4000) NOT NULL,
OP_CODE VARCHAR2(15),
TXN_STATUS VARCHAR2(1),
CREATE_DT DATE,
PRIMARY KEY (TXNID) );
Recommendation from DBA.
CREATE TABLE XT_PMB_NOTIFY_UNSUB(
TXNID NUMBER(15),
APP_SEQNO NUMBER(15),
PRIMARY_KEYVAL VARCHAR2(4000) NOT NULL,
OP_CODE VARCHAR2(15),
TXN_STATUS VARCHAR2(1),
CREATE_DT DATE,
PRIMARY KEY (TXNID) )
TABLESPACE DATA_ENC_TS;
The answer is it depends on how your company has defined its tablespace rules.
Oracle users (or schemas) can have one "default tablespace" which you can see by querying the database:
select username, default_tablespace from dba_users;
or if you do not have permission for that and you want to know what it is for the current user only:
select username, default_tablespace from user_users;
Or perhaps this one to see all users that are visible to your current connected user:
select username, default_tablespace from user_users;
According to Oracle documentation (https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_8003.htm) this is what it means:
Specify the default tablespace for objects that the user creates. If
you omit this clause, then the user's objects are stored in the
database default tablespace. If no default tablespace has been
specified for the database, then the user's objects are stored in the
SYSTEM tablespace.
So for your intents and purposes, when you create a table without explicitly using a tablespace at the end it will go to the user's default tablespace in general. If your DBAs tend to not define a default tablespace then it starts to have more serious impacts, because the table will be stored in a global default tablespace or (heaven forbid) it will go to SYSTEM tablespace. That last option would be extremely detrimental to the database health.
Some companies have the habit of assigning different tablespaces for tables and for indexes for instance. In that case, the users can only have one default tablespace, and if you omit the tablespace clause in the create index (or create table) statement, objects will go to the incorrect tablespace.
Now to the consequences of having a table or index in an incorrect tablespace. A tablespace is a collection of one or more physical operating system files (Oracle refers to them as data files). Whenever you create a table or index in a tablespace oracle allocates space in that datafile, which Oracle calls segments. Segments are logical units inside a data file. Keep in mind Oracle further breaks down segments into smaller logical units called extents and blocks, but that is a bit beyond the topic here. If you are interested there is more to read here: https://docs.oracle.com/cd/B19306_01/server.102/b14220/logical.htm
Let's go back to segments. Segments exist inside datafiles that belong to tablespaces. When you put your object in a tablespace and you want to move it out to a different tablespace, Oracle needs to physically write to files on the OS. And that can be simple if the table is empty, or can be a fair amount of work if it concerns a massive table spanning multiple datafiles or containing gigabytes or terabytes of data. It may mean an application outage is required to fix it.
Oracle provides certain methods to avoid application outages in those scenarios, like for example Online Redefinition (package DBMS_REDEFINITION). But I would hope we can agree that their use can be better leveraged for application migrations and things of the sort.
Using default tablespace settings is fine in many cases, by all means, but if you will allow me perhaps, the rule of thumb for many things Oracle is if you can write code to do something explicitly instead of relying on default values, do yourself and your DBA the favor. In general, the flexibility of relying on it is trumped by even a couple times of facing yourself with a surprise and then being responsible for cleaning it up later.
If you don't specify a tablespace, Oracle will use the default tablespaces assigned to the schema. You can find your default tablespace with the query below. Unless you have a very small development database w/o many schemas, that may be OK, but otherwise it is good practice to explicitly define them.
select *
from database_properties
where property_name like 'DEFAULT%TABLESPACE';
PROPERTY_NAME PROPERTY_VALUE DESCRIPTION
------------------------------ -------------------- ----------------------------------------
DEFAULT_TEMP_TABLESPACE TEMP Name of default temporary tablespace
DEFAULT_PERMANENT_TABLESPACE USERS Name of default permanent tablespace
I am using oracle 12c and I'm having a little trouble trying to attribute tablespace to a user.
Here is the error I got when processing the current DDL statement in pluggable database ORAPDB1:
the tablespace 'INTERVENTION_TBS' does no exist
Note that the tablespace was created successfully. So could someone suggest a solution please?
For more details I used this syntax query
CREATE USER c##DBAINTERVENTION
Identified by interventiondb
Default Tablespace INTERVENTION_TBS
Temporary Tablespace INTERVENTION_TempTBS;
run the following statements:
alter session set "_ORACLE_SCRIPT"=TRUE;
ALTER USER [username] IDENTIFIED BY [password];
You are trying to create a common user which will have access to all the PDBs in a CDB. As the user has access to all PDBs it can also create an object on those PDBs hence we need tablespace to create the objects. This is the reason why you need to have the tablespace specified in the CREATE USER command on all PDBs.
Please verify that you the INTERVENTION_TBS tablespace exists on all PDBs using the following query.
select cp.pdb_name
from cdb_pdbs cp join v$tablespace tb on(cp.con_id=tb.con_id)
where tb.name='INTERVENTION_TBS';
This query list all the PDBs which has the tablespace. If this tablespace doesn't exist on one of your PDBs then create one.
When I deploy my asp.net application,I have to create some tablesapces/users,I use the pqsql,however I want to know is there any way I can create them with batch processing?
For example,I can execute this ddl:
create tablespace TSA.....
Then I can execute:
create user a ... default tablespace TSA...
But when I execute them at the same time:
create tablespace TSA.....
create user a ... default tablespace TSA...
I will get an error.
ANy way?
update
Error is something like this:
ORA-02180: invalid CREATE TABLESPACE words
BTW,I run the sql batches in the sql window of the pl/sql developer.
Now,I just want to know if there is any way I can run a whole ddl sql file?
Suppose this is the content of the init.sql:
create smallfile tablespace "DEV" datafile 'f:\app\administrator\oradata\orcl\dev01.dbf' size 100m autoextend on next 10m maxsize unlimited logging extent management local segment space management auto default nocompress
-- Create the user
create user dev_sa
identified by "000000"
default tablespace DEV
temporary tablespace TEMP;
-- Grant/Revoke role privileges
grant connect to dev_sa;
grant dba to dev_sa;
--create another tablespace
--.....
How to execute it in the batch process model?
If you have the two statements in a file you're running from SQL*Plus, you need to separate the statements with the / character, which also causes each to be executed
create tablespace TSA ...
/
create user a ... default tablespace TSA
/
(That's quite a big 'if', of course as per #APC's comment; but is something that's come up before. As has different ways of running things in SQL Developer, among other things. But really no more than a guess from the minimal info given...)
You have a semi-colon ; missing off the end of your first CREATE TABLE
My question regards the situation were tablespace used for primary key index differs from tablespace used for the table itself. Will Oracle use this index or it becomes unusable?
Because when i tried to import the schema to Oracle that contains that table. Oracle complained with warning saying that index for this primary key is unusable. I've fixed the schema by change tablespace for primary key index, exported it again and it imported into database without warnings.
Does this means that primary key index tablespace must be always the same as the tablespace of the table itself? Or is it true for any kind of index (column index for example)?
Does this rule apply also for DB2?
Storing indexes and data in different tablespaces is perfectly acceptable. What happens when you do a:
alter index index_name rebuild;
Is the index still unusable after that? If not, check your import parameters on the table. For example, SQL*Loader can invalidate indexes with direct path loads (this is just a guess, you don't mention how you loaded the data).
If the index is still unusable, check for data anomalies, especially duplicate keys. Hope you fix it!
What Martin said is fine. However, there is no real need to separate the tablespaces. What you can do, to avoid tablespace errors on import (assuming you're using export/import and not datapump) is to create the user with a default tablespace that exists. Then import just the database and then add the indexes and constraints.