Quantcast
Channel: Andrew's Oracle Blog
Viewing all 330 articles
Browse latest View live

How Many Profiles Can an Oracle Database Have?

$
0
0
When you create a database, Oracle gives you one profile, called DEFAULT. You can then create more profiles if you need them. I wondered if there might be a limit to the number of profiles you could create.  I wrote some SQL to create 100,000 profiles and ran it in an Oracle 11.2.0.4 database.

SQL> conn system/manager
Connected.
SQL> select distinct profile from dba_profiles
  2  /

PROFILE
------------------------------
DEFAULT

SQL> declare
  2   sql_statement varchar2(100);
  3  begin
  4   for i in 1..100000 loop
  5    sql_statement := 'create profile profile'||i||
  6    ' limit idle_time 10';
  7    execute immediate sql_statement;
  8   end loop;
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL> select count(distinct profile)
  2  from dba_profiles
  3  /

COUNT(DISTINCTPROFILE)
----------------------
                100001

SQL>
 


This should be enough for most applications. If you have some strange database with over 100,000 users, each one needing a different profile, your applications probably need a redesign.

PASSWORD_REUSE_MAX and PASSWORD_REUSE_TIME

$
0
0
I tested this on Oracle 11.2. I created a profile called FOR_ANDREW with PASSWORD_REUSE_MAX set to 1. This meant that I could not reuse a password until I had used one other password first:
 
SQL> conn / as sysdba
Connected.
 
SQL> create profile for_andrew
  2  limit password_reuse_max 1
  3  /
 
Profile created.
 
SQL>
 
I created a user called ANDREW and gave him the FOR_ANDREW profile:
 
SQL> create user andrew
  2  identified by old_password
  3  profile for_andrew
  4  /
 
User created.
 
SQL> grant create session to andrew
  2  /
 
Grant succeeded.
 
SQL>
 
I connected to the database as user ANDREW:
 
SQL> conn andrew/old_password
Connected.
SQL>
 
I tried to reuse the existing password but this failed as I had expected it would:
 
SQL> alter user andrew
  2  identified by old_password
  3  /
alter user andrew
*
ERROR at line 1:
ORA-28007: the password cannot be reused
 
SQL>
 
I used a different password before trying to reuse the original one. This failed with the same error, which I had not expected:
 
SQL> alter user andrew
  2  identified by new_password
  3  /
 
User altered.
 
SQL> alter user andrew
  2  identified by old_password
  3  /
alter user andrew
*
ERROR at line 1:
ORA-28007: the password cannot be reused
 
SQL>
 
I did some research and saw that the PASSWORD_REUSE_TIME was set to DEFAULT. This meant that it had the same value as the DEFAULT profile where it was set to UNLIMITED:
 
SQL> conn / as sysdba
Connected.
SQL> select limit from dba_profiles
  2  where profile = 'FOR_ANDREW'
  3  and resource_name = 'PASSWORD_REUSE_TIME'
  4  /
 
LIMIT
----------------------------------------
DEFAULT
 
SQL> select limit from dba_profiles
  2  where profile = 'DEFAULT'
  3  and resource_name = 'PASSWORD_REUSE_TIME'
  4  /
 
LIMIT
----------------------------------------
UNLIMITED
 
SQL>
 
According to the Oracle 11.1 documentation:
 
These two parameters must be set in conjunction with each other. PASSWORD_REUSE_TIME specifies the number of days before which a password cannot be reused. PASSWORD_REUSE_MAX specifies the number of password changes required before the current password can be reused.
 
It then went on to say:

For these parameter to have any effect, you must specify an integer for both of them. 

... which I found a bit misleading. However, it clarified this a few lines later as follows: 

If you specify an integer for either of these parameters and specify UNLIMITED for the other, then the user can never reuse a password. 

I set PASSWORD_REUSE_TIME to 1 minute and checked that I still could not reinstate the original password:

SQL> alter profile for_andrew
  2  limit password_reuse_time 1/1440
  3  /
 
Profile altered.
 
SQL> conn andrew/new_password
Connected.
SQL> alter user andrew
  2  identified by old_password
  3  /
alter user andrew
*
ERROR at line 1:
ORA-28007: the password cannot be reused
 
SQL>
 
However, I waited for a minute and found that I could:
 
SQL> exec sys.dbms_lock.sleep(60);
 
PL/SQL procedure successfully completed.
 
SQL> alter user andrew
  2  identified by old_password
  3  /
 
User altered.
 
SQL>
 
I do not know which Oracle process controls this functionality but it seemed a bit hit and miss. When I repeated the test, I sometimes found I had to wait more than a minute before I could change the password back to its original value. 

SQL Developer Stops Running in Oracle 9

$
0
0
I created the following simple SQL script:

spool test_output
prompt Creating proc1:
create or replace procedure proc1 is
begin
null;
end;
/
prompt Creating proc2:
create or replace procedure proc2 is
begin
null;
end;
/
spool off

I started a SQL Developer session (version 4.2.0.17.089) and ran the script in an Oracle 10 database (as usual, click on the image to enlarge it/bring it into focus):

 
It worked as expected and the output you can see on the screen appeared in the SPOOL file as shown below:

Creating proc1:
 
Procedure PROC1 compiled
 
Creating proc2:
 
Procedure PROC2 compiled 

I then ran the script in an Oracle 9 database:

 
No further output was displayed after the first create procedure statement and the SPOOL file looked like this:

Creating proc1:
 
Procedure PROC1 compiled

The second procedure was not created either:

SQL> l
  1  select object_name from user_objects
  2  where object_name in ('PROC1', 'PROC2')
  3  and object_type = 'PROCEDURE'
  4* order by 1
SQL> /
 
OBJECT_NAME
------------------------------
PROC1
 
SQL> 

LOCKED and LOCKED(TIMED)

$
0
0
This example, which was tested on Oracle 11.2, shows the difference between a user with an ACCOUNT_STATUS of LOCKED and one with an ACCOUNT_STATUS of LOCKED(TIMED). First I created a profile with a PASSWORD_LOCK_TIME of 0.0007 days i.e roughly 1 minute and a FAILED_LOGIN_ATTEMPTS limit of 1:

SQL> create profile for_andrew
  2  limit failed_login_attempts 1
  3  password_lock_time 0.0007
  4  /
 
Profile created.
 
SQL>

Then I created a user and gave it this profile:

SQL> create user andrew
  2  identified by reid
  3  profile for_andrew
  4  /
 
User created.
 
SQL> grant create session to andrew
  2  /
 
Grant succeeded.
 
SQL>

I checked that the user had an ACCOUNT_STATUS of OPEN:

SQL> select account_status
  2  from dba_users
  3  where username = 'ANDREW'
  4  /
 
ACCOUNT_STATUS
--------------------------------
OPEN
 
SQL>

Then I locked the user. This is how you get an ACCOUNT_STATUS of LOCKED:

SQL> alter user andrew account lock
  2  /
 
User altered.
 
SQL> select account_status
  2  from dba_users
  3  where username = 'ANDREW'
  4  /
 
ACCOUNT_STATUS
--------------------------------
LOCKED
 
SQL>

If you try to log in to a LOCKED user, you get an ORA-28000: 

SQL> conn andrew/reid
ERROR:
ORA-28000: the account is locked
 
Warning: You are no longer connected to ORACLE.
SQL>

Then I unlocked the user to give it an ACCOUNT_STATUS of OPEN again: 

SQL> alter user andrew account unlock
  2  /
 
User altered.
 
SQL> select account_status
  2  from dba_users
  3  where username = 'ANDREW'
  4  /
 
ACCOUNT_STATUS
--------------------------------
OPEN
 
SQL>

Next, I tried to login with an incorrect password:

SQL> conn andrew/blah
ERROR:
ORA-01017: invalid username/password; logon denied
 
Warning: You are no longer connected to ORACLE.
SQL>

This changed the ACCOUNT_STATUS to LOCKED(TIMED) as the user's profile only allows one 1 FAILED_LOGIN_ATTEMPT

SQL> conn / as sysdba
Connected.
SQL> select account_status
  2  from dba_users
  3  where username = 'ANDREW'
  4  /
 
ACCOUNT_STATUS
--------------------------------
LOCKED(TIMED)
 
SQL>

... so even when I tried to login with the correct password, I got an ORA-28000 again:

SQL> conn andrew/reid
ERROR:
ORA-28000: the account is locked
 
Warning: You are no longer connected to ORACLE.
SQL>

Once the user has an ACCOUNT_STATUS of LOCKED(TIMED), he cannot connect to the database for PASSWORD_LOCK_TIME days (around one minute in this case). I checked the current time:

SQL> conn / as sysdba
Connected.
SQL> select to_char(sysdate,'hh24:mi:ss') time_now
  2  from dual
  3  /
 
TIME_NOW
--------
19:02:02
 
SQL>

... then I waited until the user's ACCOUNT_STATUS was OPEN again:

SQL> declare
  2    andrews_account_status
  3      dba_users.account_status%type := 'BLAH';
  4  begin
  5    while andrews_account_status != 'OPEN' loop
  6      dbms_lock.sleep(10);
  7      select account_status into andrews_account_status
  8        from dba_users
  9        where username = 'ANDREW';
10    end loop;
11  end;
12  /
 
PL/SQL procedure successfully completed.
 
SQL>

I checked the time again to see how long it had taken. This time can vary quite a bit. You seem to be able to speed up the change of the user’s ACCOUNT_STATUS by trying to login with the correct password from another server session:

SQL> select to_char(sysdate,'hh24:mi:ss') time_now
  2  from dual
  3  /
 
TIME_NOW
--------
19:03:03
 
SQL>

I verified that the user's ACCOUNT_STATUS was OPEN:

SQL> select account_status
  2  from dba_users
  3  where username = 'ANDREW'
  4  /
 
ACCOUNT_STATUS
--------------------------------
OPEN
 
SQL>

... and checked that he could login again:

SQL> conn andrew/reid
Connected.
SQL> show user
USER is "ANDREW"
SQL>

ALTER USER Hangs on row cache lock

$
0
0
I created the following UNIX shell script called loop1.ksh:

Oracle 11.1 > cat loop1.ksh
#!/bin/bash
export ORACLE_SID=PQEDPT1
export ORAENV_ASK=NO
. oraenv
sqlplus / as sysdba << eof
grant create session to andrew
identified by reid1
/
exit
eof
echo "User created"
./loop2.ksh > loop2.log1 &
./loop2.ksh > loop2.log2 &
./loop2.ksh > loop2.log3 &
./loop2.ksh > loop2.log4 &
./loop2.ksh > loop2.log5 &
./loop2.ksh > loop2.log6 &
./loop2.ksh > loop2.log7 &
./loop2.ksh > loop2.log8 &
./loop2.ksh > loop2.log9 &
./loop2.ksh > loop2.log10 &
Oracle 11.1 >

I ran it against an Oracle 11.1 database. It created a user called andrew with a password of reid1. It then ran another shell script called loop2.ksh 10 times. The ampersand at the end of each line made these 10 jobs run simultaneously in the background. Each run wrote its output to a different log file i.e. loop2.log1, loop2.log2 etc.

Here is the shell script loop2.ksh:

Oracle 11.1 > cat loop2.ksh
#!/bin/bash
export ORACLE_SID=PQEDPT1
export ORAENV_ASK=NO
. oraenv
for (( i=1; i <=100; i++ ))
do
echo 'i = '$i
sqlplus andrew/reid1 << eof
exit
eof
done
Oracle 11.1 >

It connected to and disconnected from the same database 100 times as user andrew. So I had 10 background jobs, each connecting to and disconnecting from the same database 100 times. Here is part of one of the output files:

DUM11.2 /export/home/oracle/andrew/hanging > cat loop2.log2|more
The Oracle base for ORACLE_HOME=/oracle/app/oracle/product/11.1.0 is /oracle/app/oracle/product
i = 1

SQL*Plus: Release 11.1.0.6.0 - Production on Tue Oct 13 18:26:40 2015

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
i = 2

SQL*Plus: Release 11.1.0.6.0 - Production on Tue Oct 13 18:26:41 2015

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
i = 3

SQL*Plus: Release 11.1.0.6.0 - Production on Tue Oct 13 18:26:41 2015

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
i = 4

SQL*Plus: Release 11.1.0.6.0 - Production on Tue Oct 13 18:26:41 2015

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
i = 5

SQL*Plus: Release 11.1.0.6.0 - Production on Tue Oct 13 18:26:42 2015

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

While this was going on, I tried to change the password for user andrew in a separate SQL*Plus session. This took a long time. When it had finished, I checked the wait events and saw that it had been waiting on a row cache lock:

SQL> conn / as sysdba
Connected.
SQL> set timing on
SQL> alter user andrew identified by reid2
  2  /

User altered.

Elapsed: 00:00:24.94
SQL> set timing off
SQL> select event, time_waited/100
  2  from v$session_event
  3  where sid = (select distinct sid from v$mystat)
  4  and wait_class != 'Idle'
  5  /

EVENT                               TIME_WAITED/100
----------------------------------- ---------------
log file sync                                     0
row cache lock                                24.34
SQL*Net message to client                         0

SQL>

So if your ALTER USER statement hangs in this way, it could be due to other sessions trying to connect to the database again and again.

Password Expire

$
0
0
If a user forgets his password, he may ask you to reset it for him. You will then know his new password, which you may see as a security issue. By including the password expire clause in the alter user command, you can force the user to change his password the next time he logs in. After this, you will no longer know his password. The examples which follow show a DBA changing a password in red and a user logging in afterwards in green.
 
The first example shows a DBA using an Oracle 11 version of SQL*Plus to change a password in an Oracle 11 database:

TEST11 > sqlplus / as sysdba
 
SQL*Plus: Release 11.1.0.6.0 - Production on Wed Aug 26 11:03:51 2015
 
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> alter user a identified by b
  2  password expire
  3  /
 
User altered.
 
SQL>

The user then logs in with the same Oracle 11 version of SQL*Plus and is prompted to change his password. After doing this, he reconnects to the database. This is not necessary, it is just to show that the password change has taken effect:

TEST11 > sqlplus a/b
 
SQL*Plus: Release 11.1.0.6.0 - Production on Wed Aug 26 11:11:51 2015
 
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
 
ERROR:
ORA-28001: the password has expired
 
Changing password for a
New password:
Retype new password:
Password changed
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> conn a/c
Connected.
SQL>

The DBA then resets and expires the password again using the same Oracle 11 version of SQL*Plus:

TEST11 > sqlplus / as sysdba
 
SQL*Plus: Release 11.1.0.6.0 - Production on Wed Aug 26 11:56:10 2015
 
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> alter user a identified by b
  2  password expire
  3  /
 
User altered.
 
SQL>

The user logs in using an Oracle 10 version of SQL*Plus this time. He is prompted to change his password but is unable to do so:

TEST10 > sqlplus a/b@test11
 
SQL*Plus: Release 10.2.0.3.0 - Production on Wed Aug 26 11:59:46 2015
 
Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.
 
ERROR:
ORA-28001: the password has expired
 
Changing password for a
New password:
Retype new password:
ERROR:
ORA-01017: invalid username/password; logon denied
 
Password unchanged
Enter user-name: 

So, if you want to expire a password in an Oracle 11 database, you need to check that the person who will be logging in to that user afterwards is using an Oracle 11 version of SQL*Plus, not an Oracle 10 one.

ORA-28405

$
0
0
This post is an update to an earlier one, which I have now deleted. I tested the first part of it in an Oracle 11.1.0.6 database. First I created a role which was identified by a password:
 
SQL> conn / as sysdba
Connected.
SQL> create role low identified by secret_password
  2  /
 
Role created.
 
SQL>
 
I granted the role to a user and made sure it had no default roles:
 
SQL> grant create session, low
  2  to andrew identified by reid
  3  /
 
Grant succeeded.
 
SQL> alter user andrew default role none
  2  /
 
User altered.
 
SQL>
 
I connected as the user and tried to activate the role but this failed with an ORA-01979  as I had not supplied the password:
 
SQL> conn andrew/reid
Connected.
SQL> set role low
  2  /
set role low
*
ERROR at line 1:
ORA-01979: missing or invalid password for role 'LOW'
 
SQL> select role from session_roles
  2  /
 
no rows selected
 
SQL>
 
When I supplied the password, I was able to activate the role successfully:
 
SQL> set role low identified by secret_password
  2  /
 
Role set.
 
SQL> select role from session_roles
  2  /
 
ROLE
------------------------------
LOW
 
SQL>
 
I created another role without a password:
 
SQL> conn / as sysdba
Connected.
SQL> create role high
  2  /
 
Role created.
 
SQL>
 
… granted the first role to it:
 
SQL> grant low to high
  2  /
 
Grant succeeded.
 
SQL>
 
… and granted the 2nd role to the user:
 
SQL> grant high to andrew
  2  /
 
Grant succeeded.
 
SQL>
 
I then connected as the user and activated the 2nd role. This had the effect of also activating the 1st role without needing to supply the password. This has always seemed wrong to me:
 
SQL> conn andrew/reid
Connected.
SQL> select role from session_roles
  2  /
 
no rows selected
 
SQL> set role high
  2  /
 
Role set.
 
SQL> select role from session_roles
  2  /
 
ROLE
------------------------------
HIGH
LOW
 
SQL>
 
I went to a presentation given by Simon Pane from Pythian when I was at the UKOUG conference last week. He said that this behaviour changed in Oracle 11.2.0.4 so I decided to repeat the test in a database on this version:
 
SQL> conn / as sysdba
Connected.
SQL> create role low identified by secret_password
  2  /
 
Role created.
 
SQL> grant create session, low
  2  to andrew identified by reid
  3  /
 
Grant succeeded.
 
SQL> alter user andrew default role none
  2  /
 
User altered.
 
SQL> conn andrew/reid
Connected.
SQL> set role low
  2  /
set role low
*
ERROR at line 1:
ORA-01979: missing or invalid password for role 'LOW'
 
SQL> select role from session_roles
  2  /
 
no rows selected
 
SQL> set role low identified by secret_password
  2  /
 
Role set.
 
SQL> select role from session_roles
  2  /
 
ROLE
------------------------------
LOW
 
SQL> conn / as sysdba
Connected.
SQL> create role high
  2  /
 
Role created.
 
SQL>
 
It all worked as before until I tried to grant the 1st role to the 2nd role where this failed with an ORA-28405, which seems much more sensible to me:
 
SQL> grant low to high
  2  /
grant low to high
*
ERROR at line 1:
ORA-28405: cannot grant secure role to a role
 
SQL>
 
So when I granted the 2nd role to the user:
 
SQL> grant high to andrew
  2  /
 
Grant succeeded.
 
SQL> conn andrew/reid
Connected.
SQL> select role from session_roles
  2  /
 
no rows selected
 
SQL>
 
… he was able to activate the 2nd role but the 1st one, which had the password, was not activated:
 
SQL> set role high
  2  /
 
Role set.
 
SQL> select role from session_roles
  2  /
 
ROLE
------------------------------
HIGH
 
SQL>

Password Last Change Time

$
0
0
I read that the PTIME column in the SYS.USER$ table shows when a user’s password was last changed so I decided to try it out in an Oracle 10 database:

SQL> SELECT VERSION FROM PRODUCT_COMPONENT_VERSION
  2  WHERE PRODUCT LIKE 'Oracle Database%'
  3  /

VERSION
--------------------
10.2.0.3.0

SQL>


I noted the time and created a user:

SQL> SELECT TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS')
  2  DATE_AND_TIME1 FROM DUAL
  3  /

DATE_AND_TIME1
--------------------
06-JAN-2011 12:06:37

SQL> CREATE USER ANDREW IDENTIFIED BY REID
  2  /

SQL>

User created.

SQL>


I waited a few seconds:

SQL> EXEC DBMS_LOCK.SLEEP(5);

PL/SQL procedure successfully completed.

SQL>


I checked when the user was created and confirmed that this matched DATE_AND_TIME1:

SQL> SELECT TO_CHAR(CREATED,'DD-MON-YYYY HH24:MI:SS')
  2  USER_CREATION_TIME
  3  FROM DBA_USERS WHERE USERNAME = 'ANDREW'
  4  /

USER_CREATION_TIME
--------------------
06-JAN-2011 12:06:37

SQL>


I checked the password last change time and confirmed that this agreed with the time when the user was created:

SQL> SELECT TO_CHAR(PTIME,'DD-MON-YYYY HH24:MI:SS') PLCT
  2  FROM SYS.USER$ WHERE NAME = 'ANDREW'
  3  /

PLCT
--------------------
06-JAN-2011 12:06:37

SQL>


I noted the new time and changed the user’s password:

SQL> SELECT TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS')
  2  DATE_AND_TIME2 FROM DUAL
  3  /

DATE_AND_TIME2
--------------------
06-JAN-2011 12:06:42

SQL> ALTER USER ANDREW IDENTIFIED BY NEW_PASSWORD
  2  /

User altered.

SQL>


I waited a few more seconds and noted the new time:

SQL> EXEC DBMS_LOCK.SLEEP(5);

PL/SQL procedure successfully completed.

SQL> SELECT TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS')
  2  DATE_AND_TIME3 FROM DUAL
  3  /

DATE_AND_TIME3
--------------------
06-JAN-2011 12:06:47

SQL>


I checked the password last change time again and confirmed that it matched the time when the password was changed (i.e. DATE_AND_TIME2):

SQL> SELECT TO_CHAR(PTIME,'DD-MON-YYYY HH24:MI:SS') PLCT
  2  FROM SYS.USER$ WHERE NAME = 'ANDREW'
  3  /

PLCT
--------------------
06-JAN-2011 12:06:42

SQL>


6th January 2011: Date of first publication.
5th July 2017: Moved to June 2017 to have several security related posts together.

ORA-28010

$
0
0
I wondered what would happen if you tried to do a password expire on an externally identified user so I tried it out on an Oracle 11.2 database. As you might expect, it failed:
 
SQL> alter user system identified externally
  2  /
 
User altered.
 
SQL> alter user system password expire
  2  /
alter user system password expire
*
ERROR at line 1:
ORA-28010: cannot expire external or global accounts
 
SQL>
 
I guess this is because if an externally identified user had to change his password, he would not be externally identified any longer. Also, a user cannot change itself to or from external identification unless it has the ALTER USER privilege.

A Different Cause for enq: TM - contention

$
0
0
Doc ID 1905174.1 on My Oracle Support looks at how to resolve this wait event.

It says:

If contention is occurring, then the most common reason is missing Foreign Key (FK) index on the FK constraint columns in the Child tables.

In my experience until very recently, this has always been true. However, I have now found another possible cause, which I have recreated below in an Oracle 11.2.0.4 database:

First I created a couple of users called ANDREW and FRED:


SQL> create user andrew
  2  identified by reid
  3  default tablespace users
  4  quota unlimited on users
  5  /

User created.

SQL> grant create session, create table to andrew
  2  /

Grant succeeded.

SQL> create user fred identified by bloggs
  2  /

User created.

SQL> grant create session to fred
  2  /

Grant succeeded.

SQL>


I logged in as ANDREW, created a table, allowed FRED to update it and did an update on it myself. This created a lock as I did not commit the update. Note that the table had no foreign key constraints:

SQL> conn andrew/reid
Connected.
SQL> create table tab1 as select 1 col1 from dual
  2  /


Table created.

SQL> grant update on tab1 to fred
  2  /

Grant succeeded.

SQL> update tab1 set col1 = 2
  2  /

1 row updated.

SQL>


I then logged in as user FRED in a second SQL*Plus session and tried to lock the table but this did not work:

SQL> conn fred/bloggs

Connected.

SQL> lock table andrew.tab1 in exclusive mode
  2  /


I waited a few minutes before logging in as SYS in a third SQL*Plus session and found that FRED was waiting on the enq: TM – contention event:

SQL> conn / as sysdba

Connected.

SQL> select event, time_waited/100
  2  from v$session_event
  3  where sid =
  4  (select sid from v$session
  5   where username = 'FRED')
  6  and wait_class != 'Idle'
  7  /

EVENT                          TIME_WAITED/100
------------------------------ ---------------
enq: TM - contention                    351.05
SQL*Net message to client                    0

SQL>

Correct Password Gives ORA-01017

$
0
0
This post replicates a real-life situation where Oracle returned an ORA-01017 when the correct password was used. First I created a user in an Oracle 11 database and checked that I could connect to it:

Oracle 11: sqlplus /

SQL*Plus: Release 11.1.0.6.0 - Production on Wed Jan 23 10:55:39 2019

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create user blah identified by secret_password
  2  /

User created.

SQL> grant create session to blah
  2  /

Grant succeeded.

SQL> conn blah/secret_password
Connected.
SQL>

Then I connected to that user from a server which only had Oracle 9 software installed:

Oracle 9: sqlplus blah/secret_password@flwdpt1

SQL*Plus: Release 9.2.0.7.0 - Production on Wed Jan 23 11:02:32 2019

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

The user had a hashed password created using the pre Oracle 11 routine:

Oracle 11: sqlplus /

SQL*Plus: Release 11.1.0.6.0 - Production on Wed Jan 23 11:05:08 2019

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> select password from sys.user$ where name = 'BLAH'
  2  /

PASSWORD
------------------------------
92D633C444E0CD1A

SQL>

It also had a hashed password created using the Oracle 11 routine:

SQL> select spare4 from sys.user$ where name = 'BLAH'
  2  /

SPARE4
--------------------------------------------------------------------------------
S:A19249C8E39996F37B62E3DD40A49EC9ADF171BD5B4036462304E353E384

SQL>

In the real-life situation, the user's password expired because the PASSWORD_LIFE_TIME was set to 180 in the DEFAULT profile. For the purposes of this test I expired it manually:

SQL> alter user blah password expire
  2  /

User altered.

SQL> select account_status from dba_users
  2  where username = 'BLAH'
  3  /

ACCOUNT_STATUS
--------------------------------
EXPIRED

SQL>

In the real-life situation I did not know the user's password so I reinstated the Oracle 11 hash to preserve the password's case sensitivity:

SQL> alter user blah identified by values
  2  'S:A19249C8E39996F37B62E3DD40A49EC9ADF171BD5B4036462304E353E384'
  3  /

User altered.

SQL>

This set the ACCOUNT_STATUS to OPEN:

SQL> select account_status from dba_users
  2  where username = 'BLAH'
  3  /

ACCOUNT_STATUS
--------------------------------
OPEN

SQL>

It did not occur to me at the time but this also removed the Oracle 10 hash presumably because Oracle had no way of knowing if it was still correct:

SQL> select nvl(password,'NULL') from sys.user$
  2  where name = 'BLAH'
  3  /

NVL(PASSWORD,'NULL')
------------------------------
NULL

SQL>

I spoke to the developer concerned. He confirmed that he knew the user's password so I told him he could login again. A couple of hours later he told me that he could login to the user using SQL*Plus:

C:\>sqlplus blah/secret_password@flwdpt1

SQL*Plus: Release 11.2.0.3.0 Production on Wed Jan 23 11:42:58 2019

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

...but he could not connect using JDBC. I am not in a position to replicate that now but I can show the same problem by trying to login from the server with the Oracle 9 software:

Oracle 9: sqlplus blah/secret_password@flwdpt1

SQL*Plus: Release 9.2.0.7.0 - Production on Wed Jan 23 11:45:18 2019

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

ERROR:
ORA-01017: invalid username/password; logon denied

Enter user-name:

I guess this was sending a hash of the password created using the pre Oracle 11 routine.
The Oracle 11 database had nothing to compare this with so it returned an ORA-01017. The developer told me the password and I reset it. This reinstated the pre Oracle 11 hash of the password:

Oracle 11: sqlplus /

SQL*Plus: Release 11.1.0.6.0 - Production on Wed Jan 23 11:49:12 2019

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> alter user blah identified by secret_password
  2  /

User altered.

SQL> select password from sys.user$ where name = 'BLAH'
  2  /

PASSWORD
------------------------------
92D633C444E0CD1A

SQL> select spare4 from sys.user$ where name = 'BLAH'
  2  /

SPARE4
--------------------------------------------------------------------------------
S:784AAC15DBA436AA97653EE6C3868F7B87B434793F2BD69DCEDF55C2EDDB

SQL>

This allowed me to login again from the server with the Oracle 9 software:

Oracle 9: sqlplus blah/secret_password@flwdpt1

SQL*Plus: Release 9.2.0.7.0 - Production on Wed Jan 23 11:54:01 2019

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

...and the developer was able to set up his JDBC connection.

Oracle DBA Interview Question

$
0
0
This Oracle DBA interview question is based on some work I did recently. I will leave you to decide whether it is too easy, too difficult or just right for your candidate.

Question:

I created two Oracle 11.2.0.4 test databases on a UNIX server some time ago. I called them GBASRDB1 and GBASRDB2. Each database has a user called ANDREW. I can connect to GBASRDB1 from my Micrososft Windows PC like this:


C:\Users\J0294094>sqlplus andrew/reid@gbasrdb1

SQL*Plus: Release 11.2.0.3.0 Production on Fri Mar 8 11:29:59 2019

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>


I can also logon to the UNIX server and connect to GBASRDB1 as follows:

GBASRDB1: sqlplus andrew/reid

SQL*Plus: Release 11.2.0.4.0 Production on Fri Mar 8 11:18:50 2019

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>


I can connect to GBASRDB2 from my Microsoft Windows PC like this:
 

C:\Users\J0294094>sqlplus andrew/reid@gbasrdb2

SQL*Plus: Release 11.2.0.3.0 Production on Fri Mar 8 11:31:42 2019

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

 

...but when I logon to the UNIX server and try to connect to GBASRDB2 as follows, I see this message:
 
GBASRDB2: sqlplus andrew/reid

SQL*Plus: Release 11.2.0.4.0 Production on Fri Mar 8 11:23:23 2019

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

ERROR:
ORA-00604: error occurred at recursive SQL level 1
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4

Enter user-name:
 


What could cause this to happen?

Answer:

Looking at the two sessions in GBASRDB1, you can see that the V$SESSION PROGRAM column in the first SQL*Plus session is 11 characters long. However, the PROGRAM column from the second session includes the name of the UNIX server and is 35 characters long:


SQL> select name from v$database
  2  /

NAME
---------
GBASRDB1

SQL> select program, length(program)
  2  from v$session
  3  where username = 'ANDREW'
  4  order by logon_time
  5  /

PROGRAM                             LENGTH(PROGRAM)
----------------------------------- ---------------
sqlplus.exe                                      11
sqlplus@sge-mktred-lab2 (TNS V1-V3)              35

SQL>

 
GBASRDB2 has a database level logon trigger which was created as shown below. The original trigger was much longer so I have only left enough of the code to illustrate the problem:
 

SQL> conn / as sysdba
Connected.
SQL> select name from v$database
  2  /

NAME
---------
GBASRDB2

SQL> grant select on v_$session to public
  2  /

Grant succeeded.

SQL> conn /
Connected.
SQL> show user
USER is "OPS$ORACLE"
SQL> create or replace trigger trigger1
  2  after logon on database
  3  declare
  4   current_program varchar2(30);
  5  begin
  6   select program into current_program
  7    from v$session
  8    where audsid = userenv('sessionid');
  9  end;
 10  /

Trigger created.

SQL> show errors
No errors.
SQL>


This assumes that the PROGRAM column from V$SESSION is never longer than 30 characters. It can actually be up to 48 characters long:
  
SQL> desc v$session
 Name                       Null?    Type
 -------------------------- -------- ------------------
 etc
 etc
 PROGRAM                             VARCHAR2(48)
 etc
 etc
SQL>

 

So when a user tries to connect with a PROGRAM which is greater than 30 characters long, the logon trigger fails and displays the error shown.

Shared on LinkedIn on 9th March 2019.

RMAN-04022

$
0
0
I created an RMAN script to copy an Oracle 11.2.0.1 target database called BUSPROD into an auxiliary database called BUSSOUT2. I left it running overnight but when I looked at the log the following day, I noticed it had failed with RMAN-04022:

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-00601: fatal error in recovery manager
RMAN-03004: fatal error during execution of command
RMAN-04022: target database mount id 1608114561 does not match channel's mount id 1608162051
ORA-03114: not connected to ORACLE
RMAN-03002: failure of Duplicate Db command at 03/25/2019 20:00:45
RMAN-03015: error occurred in stored script Memory Script
ORA-03114: not connected to ORACLE
ORA-01109: database not open


Apparently this happens if the target database is closed during the recovery operation. I checked and saw that it had been bounced shortly before the failure took place:


SQL> conn system@busprod
Enter password:
Connected.
SQL> select to_char(startup_time,'dd-mon-yy hh24:mi:ss')
  2  from v$instance
  3  /

TO_CHAR(STARTUP_TI
------------------
25-mar-19 19:35:29

SQL>


Shared on LinkedIn on 26th March 2019.

How to Skip N Rows in an Oracle SELECT Statement

$
0
0
I saw this question on a SQL Server blog. Apparently it was asked at an interview. Here is the suggested answer:

SELECT *
FROM [AdventureWorks2014].[Person].[Address]
ORDER BY AddressID
OFFSET 100 ROWS;
 
I don’t have access to SQL Server right now so I wondered how I might do this in Oracle. This is what I came up with. I ran it in an Oracle 11.2.0.4 database:

SQL> l
  1   select username from dba_users
  2   minus
  3   (select username from
  4    (select username from dba_users order by username)
  5    where rownum <=10)
  6* order by username
SQL> /
 
USERNAME
------------------------------
FRED
MDDATA
MDSYS
MGMT_VIEW
OLAPSYS
ORACLE
ORACLE_OCM
ORDDATA
ORDPLUGINS
ORDSYS
OUTLN
OWBSYS
OWBSYS_AUDIT
SI_INFORMTN_SCHEMA
SPATIAL_CSW_ADMIN_USR
SPATIAL_WFS_ADMIN_USR
SYS
SYSMAN
SYSTEM
WMSYS
XDB
XS$NULL
 
22 rows selected.
 
SQL>
 
It skips the first 10 rows from DBA_USERS and returns the rest. Here are all the rows, in case you are interested:
 
SQL> select username from dba_users order by 1
  2  /
 
USERNAME
------------------------------
ABCD
ANONYMOUS
APEX_030200
APEX_PUBLIC_USER
APPQOSSYS
CTXSYS
DBSNMP
DIP
EXFSYS
FLOWS_FILES
FRED
MDDATA
MDSYS
MGMT_VIEW
OLAPSYS
ORACLE
ORACLE_OCM
ORDDATA
ORDPLUGINS
ORDSYS
OUTLN
OWBSYS
OWBSYS_AUDIT
SI_INFORMTN_SCHEMA
SPATIAL_CSW_ADMIN_USR
SPATIAL_WFS_ADMIN_USR
SYS
SYSMAN
SYSTEM
WMSYS
XDB
XS$NULL
 
32 rows selected.
 
SQL>

ORA-02391

$
0
0
I tested this on an Oracle 11.1 database.
 
Oracle profiles control how certain database resources are allocated to a user session. They also define some security rules. When you create a user, it is assigned a profile and, if you do not specify it explicitly, the DEFAULT profile will be used:
 
SQL> grant create session to andrew
  2  identified by reid
  3  /
 
Grant succeeded.
 
SQL> select profile from dba_users
  2  where username = 'ANDREW'
  3  /
 
PROFILE
------------------------------
DEFAULT
 
SQL>
 
You can look at the limits defined in a profile by querying DBA_PROFILES:
 
SQL> select profile, resource_name, limit
  2  from dba_profiles
  3  where profile = 'DEFAULT'
  4  and resource_name = 'SESSIONS_PER_USER'
  5  /
 
PROFILE    RESOURCE_NAME        LIMIT
---------- -------------------- ----------
DEFAULT    SESSIONS_PER_USER    UNLIMITED
 
SQL>
 
The SESSIONS_PER_USER resource is set to UNLIMITED so a user with the DEFAULT profile can have as many simultaneous sessions as he wishes. What can you do if you do not like this? You can create a new profile with a different SESSIONS_PER_USER limit and assign it to the user. I will demonstrate this in a future post. Alternatively you can alter the DEFAULT profile, as shown below:
 
SQL> alter profile default
  2  limit sessions_per_user 3
  3  /
 
Profile altered.
 
SQL> select profile, resource_name, limit
  2  from dba_profiles
  3  where profile = 'DEFAULT'
  4  and resource_name = 'SESSIONS_PER_USER'
  5  /
 
PROFILE    RESOURCE_NAME        LIMIT
---------- -------------------- ----------
DEFAULT    SESSIONS_PER_USER    3
 
SQL>
 
You also need to set RESOURCE_LIMIT to TRUE otherwise Oracle does not check limits in a user's profile at all:
 
SQL> alter system set resource_limit = true
  2  /
 
System altered.
 
SQL>
 
The screen print below shows how this works (as usual, click on the image to enlarge it and bring it into focus if necessary).Three simultaneous connections have been made to the database. A fourth connection is then attempted but fails with an ORA-02391:



TNS-01189

$
0
0
I saw a couple of messages like this in an Oracle listener log recently:

TNS-01189: The listener could not authenticate the user
 
I knew that somebody in another country was carrying out internal security scans and suspected this may have been the reason. To confirm, I tried to check the status of the listener from another server and was able to reproduce the error as follows:
 
UNIX: lsnrctl status 10.80.1.150:1529
 
LSNRCTL for Solaris: Version 11.2.0.1.0 - Production on 05-SEP-2019 10:22:57
 
Copyright (c) 1991, 2009, Oracle.  All rights reserved.
 
Connecting to (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=))(ADDRESS=(PROTOCOL=TCP)(HOST=10.80.1.150)(PORT=1529)))
TNS-01189: The listener could not authenticate the user
UNIX:

ORA-16005

$
0
0
I did a shutdown abort in an Oracle 19c database:

C:\Users\Admin>sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Sun Feb 9 20:52:49 2020
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

SQL> shutdown abort
ORACLE instance shut down.
SQL>

A shutdown abort blocks new connections and kills current sessions whether they are doing anything or not. It does not roll back terminated transactions either. As a result, Oracle has some recovery to do when the instance is restarted to make the database consistent again.

I tried to open the database in read only mode:

SQL> startup mount
ORACLE instance started.

Total System Global Area 7717518448 bytes
Fixed Size                  9284720 bytes
Variable Size            1258291200 bytes
Database Buffers         6442450944 bytes
Redo Buffers                7491584 bytes
Database mounted.
SQL> alter database open read only;
alter database open read only
*
ERROR at line 1:
ORA-16005: database requires recovery

SQL>

This would have prevented the recovery from taking place so Oracle returned an ORA-16005.

I recovered the database manually:

SQL> recover database
Media recovery complete.
SQL>

I thought this might allow me to open the database in read only mode but it didn't:

SQL> alter database open read only;
alter database open read only
*
ERROR at line 1:
ORA-16005: database requires recovery

SQL>

To open the database in read only mode, I had to open it normally, close it then reopen it as shown below:

SQL> alter database open;

Database altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area 7717518448 bytes
Fixed Size                  9284720 bytes
Variable Size            1258291200 bytes
Database Buffers         6442450944 bytes
Redo Buffers                7491584 bytes
Database mounted.
SQL> alter database open read only;

Database altered.

SQL>

How to Create a 3 by 3 Puzzle Using Oracle Database Express Edition

$
0
0
In 2012 I wrote a C program to create sudoku puzzles. I took a break from writing about Oracle to set up a blog for these puzzles. You can see it here. I also created a group on Facebook called Sudoku Puzzles. At the time of writing this post it has over 10,000 members.

I recently saw a new kind of puzzle in a UK newspaper. The UK agents for this puzzle are Puzzler and their offices are only a few hundred yards from my own place of work. I paid them a visit one lunchtime and they told me that the name used for these puzzles is copyright so I cannot use it here. However, they said that there is nothing to stop me creating my own puzzles as long as I call them something different. You can see the first one I made here. I used Oracle 18 Express Edition to create it. First I ran the PL/SQL below:

SQL> create table nine_digit_numbers
  2  (col1 varchar2(9))
  3  /

Table created.

SQL> declare
  2   valid_switch boolean;
  3  begin
  4  for a in 123456789..987654321 loop
  5   valid_switch := true;
  6   for b in 2..9 loop
  7    for c in 1..b-1 loop
  8     if substr(a,c,1) = substr(a,b,1) then
  9      valid_switch := false;
 10     end if;
 11    end loop;
 12   end loop;
 13   for d in 1..9 loop
 14    if substr(a,d,1) = 0 then
 15     valid_switch := false;
 16    end if;
 17   end loop;
 18   if valid_switch then
 19    insert into nine_digit_numbers(col1) values(a);
 20    commit;
 21   end if;
 22  end loop;
 23  end;
 24  /

PL/SQL procedure successfully completed.

SQL>

This produced a table of all possible numbers containing each of the digits 1 through 9 exactly once. There should be 9 factorial in all. I checked the first few values:

SQL> l
  1  select * from
  2  (select col1 from nine_digit_numbers
  3   order by 1 asc)
  4* where rownum <= 5
SQL> /

COL1
---------
123456789
123456798
123456879
123456897
123456978


SQL>

I checked the last few values:

SQL> l
  1  select * from
  2  (select col1 from nine_digit_numbers
  3   order by 1 desc)
  4* where rownum <= 5
SQL> /

COL1
---------
987654321
987654312
987654231
987654213
987654132


SQL>

...and I checked the number of rows:

SQL> l
  1* select count(*) from nine_digit_numbers
SQL> /

  COUNT(*)
----------
    362880


SQL>

I chose a solution at random (719368524) and decided by trial and error which extra number I would provide as a clue. Then I ran the following SQL to ensure the puzzle would only have one solution:

SQL> l
  1  select col1 from nine_digit_numbers
  2  where
  3  substr(col1,1,1) + substr(col1,2,1) +
  4  substr(col1,4,1) + substr(col1,5,1) = 17
  5  and
  6  substr(col1,2,1) + substr(col1,3,1) +
  7  substr(col1,5,1) + substr(col1,6,1) = 24
  8  and
  9  substr(col1,4,1) + substr(col1,5,1) +
 10  substr(col1,7,1) + substr(col1,8,1) = 16
 11  and
 12  substr(col1,5,1) + substr(col1,6,1) +
 13  substr(col1,8,1) + substr(col1,9,1) = 20
 14  and
 15* substr(col1,2,1) = 1
SQL> /

COL1
---------
719368524

SQL>

I put the puzzle away for a couple of days so that I would forget the answer then I solved it myself to ensure the solution could be reached using human logic.

Finally, I used Microsoft Paint to create the puzzle and the solution.

ORA-12954

$
0
0
I went to Techfest 2019 in Brighton. While I was there I saw a presentation by somebody from Pythian. He said that Oracle Database Express Edition is now very similar to Enterprise Edition, it just has certain resource limits applied. This makes it ideal for testing out new features. One of the resource limits is on database size, which is limited to 12 gigabytes. I wondered what would happen if I tried to exceed this. 

I checked the name of the datafile for the USERS tablespace:

SQL> l
  1  select file_name from dba_data_files
  2* where tablespace_name = 'USERS'
SQL> /

FILE_NAME
---------------------------------------------------
C:\APP\ADMIN\PRODUCT\18.0.0\ORADATA\XE\USERS01.DBF

SQL>

I checked its size:

SQL> select bytes from dba_data_files
  2  where tablespace_name = 'USERS'
  3  /

     BYTES
----------
   5242880

SQL>

...then I tried to resize it:

SQL> l
  1  alter database datafile
  2  'C:\APP\ADMIN\PRODUCT\18.0.0\ORADATA\XE\USERS01.DBF'
  3* resize 10g
SQL> /

Database altered.

SQL>

As soon as it looked like the total amount of data would exceed 12 gigabytes, Oracle returned an ORA-12954:

SQL> l
  1  alter database datafile
  2  'C:\APP\ADMIN\PRODUCT\18.0.0\ORADATA\XE\USERS01.DBF'
  3* resize 11g
SQL> /
alter database datafile
*
ERROR at line 1:
ORA-12954: The request exceeds the maximum allowed database size of 12 GB.

SQL>

It is not obvious how this calculation was done but I assume some allowance was made for data in the SYSAUX, UNDOTBS1 or TEMP tablespaces. 

ORA-00439

$
0
0
I created a tablespace in an Oracle 12 Enterprise Edition database.

I should have used ASM but I put its datafile in ordinary disk space by mistake:


SQL> col banner format a47
SQL> l
  1  select banner from v$version
  2* where banner like 'Oracle Database%'
SQL> /

BANNER
-----------------------------------------------
Oracle Database 12c Enterprise Edition Release
12.2.0.1.0 - 64bit Production

SQL> select file_name from dba_data_files
  2  where tablespace_name = 'ANDREW'
  3  /

FILE_NAME
--------------------------------------------------
/home/oracle/andrew/datafile1.dbf

SQL>

I moved the datafile to ASM as follows:

SQL> alter database move datafile
  2  '/home/oracle/andrew/datafile1.dbf'
  3  to '+DATA'
  4  /

Database altered.

SQL> select file_name from dba_data_files
  2  where tablespace_name = 'ANDREW'
  3  /

FILE_NAME
--------------------------------------------------
+DATA/NLPEST1_LHR1S2/7976D62027536974E0530600000A7
C7B/DATAFILE/andrew.301.1036667943

SQL>

I tried the same thing in an Oracle 12 Standard Edition database on a different server but Oracle returned an ORA-00439:

SQL> col banner format a45
SQL> l
  1  select banner from v$version
  2* where banner like 'Oracle Database%'
SQL> /

BANNER
---------------------------------------------
Oracle Database 12c Standard Edition Release
12.2.0.1.0 - 64bit Production

SQL> select file_name from dba_data_files
  2  where tablespace_name = 'ANDREWS_TABLESPACE'
  3  /

FILE_NAME
----------------------------------------------
/home/oracle/andrew/andrews_tablespace.dbf

SQL> alter database move datafile
  2  '/home/oracle/andrew/andrews_tablespace.dbf'
  3  to '+DATA'
  4  /
alter database move datafile
*
ERROR at line 1:
ORA-00439: feature not enabled: online move datafile

SQL>
Viewing all 330 articles
Browse latest View live