Using curl
curl -v telnet://host:port
Using netcat
nc -z -v host port
curl --write-out '%{time_total}' -X POST --data-binary "@5M.csv" -H "Content-Type:text/csv" --user <user>:<password> "https://....adb.us-ashburn-1.oraclecloudapps.com/ords/<user>/huge_csv/batchload?batchRows=5000&errorsMax=20"
Taken from here
For old versions as pointed in the note Troubleshooting Connectivity Issues From a Remote Client to a Database (Doc ID 271852.1)
For 9.2 and below, if the Operating System is Microsoft Windows NT,
and you are using the dedicated server connection, a spawned Oracle
thread communicates with the client through a randomly allocated port
(called a REDIRECT). To force the oracle process to communicate only
through the port in which Listener is listening, set the key,
USE_SHARED_SOCKET = TRUE, in the Windows Registry
NOTE:
This is no longer the case with 10g and up as a REDIRECT does not take place for DEDICATED connections.
Или, если верить ноте 124140.1, начиная с версии 10.2
This technique only involves the version 8.1 to 10.1 Oracle Database versions. From 10.2 onward the default changed to allow port sharing.
Причина этого
Microsoft WINSOCK V1.1 API did not allow one process to pass a TCP socket to another process and as a result did not allow port sharing like on UNIX systems
Знание уже абсолютно бесполезное, ибо:
Advice, I’ve met couple of times:
Oracle performance tip: JSON is always UTF8 -Use ‘al32utf8’ character set if possible
Use BLOB instead of CLOB CLOB stores data as UCS2/UTF16
Use lob data api to insert/fetch data - getBytes/setBytes instead of - getBlob/setBlob!
A lot has been written, that login.sql is no more executed from current folder, but if SQLPATH variable has been set in registry or in env variable and login.sql is not executed (but other scripts do) - patch from 2274608.1 have to be installed.
This is applicable to at least Oracle 12.2 clients
Comparing performance for simple json generation in Oracle 12.2
SQL’s json_object performs 1.5 times faster.
Result
SQL json_object: 41
PL/SQL JSON_OBJECT_T: 64
Test case
DECLARE
l_result CLOB;
l_cnt NUMBER := 10000;
l_start_time NUMBER;
l_key VARCHAR2(100) := 'testkey';
l_val VARCHAR2(32767) := lpad('x', 5000, 'x');
FUNCTION simple_json(p_name IN VARCHAR2, p_value IN CLOB) RETURN CLOB IS
l_result JSON_OBJECT_T := JSON_OBJECT_T;
BEGIN
l_result.put(p_name, p_value);
RETURN l_result.to_clob;
END;
BEGIN
l_start_time := dbms_utility.get_time;
FOR i IN 1 .. l_cnt LOOP
l_val := lpad('x', 5000, 'x') || systimestamp;
SELECT json_object(key l_key VALUE l_val RETURNING CLOB) json INTO l_result FROM dual;
--dbms_output.put_line(l_result);
END LOOP;
dbms_output.put_line('SQL json_object: ' || (dbms_utility.get_time - l_start_time));
l_start_time := dbms_utility.get_time;
FOR i IN 1 .. l_cnt LOOP
l_val := lpad('x', 5000, 'x') || systimestamp;
l_result := simple_json(l_key, l_val);
--dbms_output.put_line(l_result);
END LOOP;
dbms_output.put_line('PL/SQL JSON_OBJECT_T: ' || (dbms_utility.get_time - l_start_time));
END;
Right after Oracle 12c installation and database creation I was able to connect to the database with username and password
sqlplus sys/pass as sysdba
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
but unable to connect with / as sysdba
sqlplus / as sysdba
ERROR:
ORA-01017: invalid username/password; logon denied
Connection from local administrator account worked perfectly without user name and password, so I’ve checked ORA_DBA group with lusrmgr.msc console and found that I have to add currently connected domain user to ORA_DBA group.
But Add user dialog doesn’t allow search and add domain users. Solution for this is command line under Local Administrator account
net localgroup ORA_DBA /add domain\USERNAME
CREATE USER app_user_unknown_passwd IDENTIFIED BY unknown_password;
GRANT CREATE SESSION TO app_user_unknown_passwd;
CREATE USER connect_user_known_password IDENTIFIED BY known_password;
GRANT CREATE SESSION TO connect_user_known_password;
ALTER USER app_user_unknown_passwd GRANT CONNECT THROUGH connect_user_known_password;
Check through proxy_users view
SELECT * FROM proxy_users;
PROXY CLIENT AUTHENTICATION FLAGS
CONNECT_USER_KNOWN_PASSWORD APP_USER_UNKNOWN_PASSWD NO PROXY MAY ACTIVATE ALL CLIENT ROLES
Try to connect from SQL*Plus and check some context parameters
sqlplus connect_user_known_password[app_user_unknown_passwd]/known_password@db122
SQL> select USER,
sys_context('USERENV','PROXY_USER'),
sys_context('USERENV','CURRENT_SCHEMA')
from dual;
USER
--------------------------------------------------------------------------------
SYS_CONTEXT('USERENV','PROXY_USER')
--------------------------------------------------------------------------------
SYS_CONTEXT('USERENV','CURRENT_SCHEMA')
--------------------------------------------------------------------------------
APP_USER_UNKNOWN_PASSWD
CONNECT_USER_KNOWN_PASSWORD
APP_USER_UNKNOWN_PASSWD
Given:
When:
Trying to connect from 32-bit PL/SQL Developer get an error ORA-28040: No matching authentication protocol
Connection from 64-bit PL/SQL Developer is OK
Solution:
Add
SQLNET.ALLOWED_LOGON_VERSION_SERVER=12
to server sqlnet.ora file (not client or TNS_ADMIN file)
If you UNDO is not big enough or you want to split transaction here is the simple script for batched update
-- Execute batched update
-- UPDATE table_name SET set_parameter;
--
-- USAGE
-- 1. Set l_batch_size
-- 2. Set select WHERE clause
-- 3. Set update's SET clause
-- 4. invoke process_table(table_name) for which this update statement should be executed
DECLARE
TYPE tpt_rowid IS TABLE OF ROWID;
--1.Batch size
g_bacth_size NUMBER := 100000;
--2. SELECT rowid FROM table_name t WHERE ...value of variable below...
l_select_where_clause VARCHAR2(32000) := q'[column_a = 111]';
--3. UPDATE table_name SET ...value of variable below... WHERE rowid=rid
l_update_set_clause VARCHAR2(32000) := q'[column_a = 333]';
PROCEDURE process_table(p_table_name VARCHAR2) IS
l_rids tpt_rowid;
cur SYS_REFCURSOR;
BEGIN
OPEN cur FOR 'SELECT /*+ PARALLEL(8)*/rowid FROM ' || p_table_name || ' t WHERE ' || l_select_where_clause;
LOOP
FETCH cur BULK COLLECT INTO l_rids LIMIT g_bacth_size;
dbms_output.put_line('Fetched: ' || l_rids.count);
EXIT WHEN l_rids.count = 0;
FORALL i IN l_rids.FIRST .. l_rids.LAST
EXECUTE IMMEDIATE
'UPDATE ' || p_table_name || ' t' ||
' SET ' || l_update_set_clause ||
' WHERE rowid = :1'
USING l_rids(i);
dbms_output.put_line('Updated: ' || SQL%ROWCOUNT);
COMMIT;
END LOOP;
END;
BEGIN
--4. Invoke for all tables
process_table('BB');
END;
/
Simple app to count number of words in the file
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
class Scratch {
public static void main(String[] args) throws IOException {
Map<String, Long> words =
Files.lines(Paths.get("American Beauty-English.srt"))
.filter(str -> !str.trim().isBlank())
.filter(str -> !str.matches("^\\d+.*"))
.map(str -> str.split("[^\\w']"))
.flatMap(x -> Arrays.stream(x))
.filter(str -> !str.trim().isBlank())
.collect(Collectors.groupingBy(
s -> s.toLowerCase(),
Collectors.counting()));
System.out.println("Words count: " + words.keySet().size());
System.out.println("20 most popular words: ");
PriorityQueue<Word> sortedWords = new PriorityQueue<>(Collections.reverseOrder());
words.forEach(
(k, v) -> sortedWords.add(new Word(v, k))
);
sortedWords.stream()
.limit(20)
.forEach(System.out::println);
}
static class Word implements Comparable<Word> {
public Word(long cnt, String word) {
this.cnt = cnt;
this.word = word;
}
public long getCnt() {
return cnt;
}
public String getWord() {
return word;
}
private long cnt;
private String word;
@Override
public int compareTo(Word word) {
return Comparator.comparing(Word::getCnt).thenComparing(Word::getWord).compare(this, word);
}
@Override
public String toString() {
return String.format("'%s' used %d times", word, cnt);
}
}
}
Task
Source database has multiply PDBs. User wants to restore in specific point in time only one of them
Here is the Franck’s answer and script
There is no way other than point-in-time duplicate to an auxiliary CDB and unplug to put wherever you want. You can skip pluggable databases so that you restore only CDBROOTandyourPDB.ThisprocessisautomatedbyRMANwhenrestoringin−place(atemporaryauxiliarydatabaseiscreatedforCDBROOT) but not for your case.
Here is a script I used to demo it once on a lab:
---# create an init.ora
cat > /tmp/CDB_TEMP.ora <<'CAT'
db_name=CDB_TEMP
# I set a temporary domain to avoid any conflict
db_domain=[temp.dbi-services.com](http://temp.dbi-services.com/)
enable_pluggable_database=true
compatible=19.0.0.0
db_block_size=8192
db_files=200
sga_target=1024M
processes=150
db_create_file_dest=/u02/oradata
db_recovery_file_dest=/u90/fast_recovery_area
db_recovery_file_dest_size=1G
#_clone_one_pdb_recovery=true # this is used by automated in-place PDBPITR so it may be cool ;)
#_system_trig_enabled=false
CAT
---# Start the instance
ORACLE_SID=CDB_TEMP sqlplus / as sysdba <<<"startup force nomount pfile='/tmp/CDB_TEMP.ora';"
---## RMAN duplicate
---# RMAN connect to target and auxiliary
ORACLE_SID=CDB_TEMP rman
set echo on
connect target sys/manager@//localhost:1521/[CDB1.it.dbi-services.com](http://cdb1.it.dbi-services.com/)
alter system archive log current
/
connect auxiliary /
---# list PDBs to exclude (remove the one you want to keep!)
select listagg(pdb_name,',')within group(order by pdb_name) from dba_pdbs
/
---# duplicate skip PDBs(use no-open just to show funny name)
duplicate database CDB1_SITE1 to CDB_TEMP skip pluggable database CDB1PDB02,CDB1PDB03 until restore point 'DEMO_OOP_PDB_PITR' noopen;
quit;
---# Open it (because we did a noopen duplicate)
ORACLE_SID=CDB_TEMP sqlcl / as sysdba
show pdbs
alter database open resetlogs
/
show pdbs
Cleanup:
---# remove the temporary CDB
ORACLE_SID=CDB_TEMP rman target /
startup dba mount force;
drop database noprompt;
quit;
rm -rf /u??/?*/CDB_TEMP $ORACLE_BASE/diag/rdbms/cdb_temp $ORACLE_HOME/rdbms/log/cdb_temp* $ORACLE_HOME/rdbms/audit/CDB_TEMP* $ORACLE_HOME/dbs/?*CDB_TEMP* $ORACLE_BASE/admin/CDB_TEMP
I doubt there will ever be another solution because you need a CDB$ROOT at same point-in-time in order to open the PDB and unplug it.
Note that, as an alternative, if you have a standby you may stop apply, flashback the pdb, convert to snapshot standby, clone the pdb, and get all back to physical standby.
Для версии 12 (по крайней мере 2) как написано тут DOP downgrade reason можно посмотреть в SQL Monitor в Other column for PX coordinator shows the downgrade reason, а сами причины расшифровать запросом
select qksxareasons, indx
from x$qksxa_reason
where qksxareasons like '%DOP downgrade%';
DOP downgrade due to adaptive DOP 351
DOP downgrade due to resource managermax DOP 352
DOP downgrade due to insufficient number of processes 353
DOP downgrade because slaves failed to join 354
В 11.2 такой таблички я не нашел, поэтому там придется пользоваться старым добрым
alter session set "_px_trace"=high,all;
который прекрасно описан тут
One can use os_command package to create and execute script from database server as sysdba user. Oracle white paper about this package
Steps to implement:
create or replace directory &tmpdir as '&tmppath';
grant read, write, execute on directory &tmpdir to &username;
begin
dbms_java.grant_permission
(upper('&username'),
'java.io.FilePermission',
'<<ALL FILES>>',
'read,write,execute');
dbms_java.grant_permission
(upper('&username'),
'java.lang.RuntimePermission',
'*',
'writeFileDescriptor');
end;
/
--run sqlplus script
begin
lob_writer_plsql.write_clob(
'&tmpdir', '&scriptname',
q'[#!/bin/bash
ORACLE_SID=&dbname
ORACLE_HOME=/data/oracle/product/&dbver.&subver
PATH=/bin:/sbin:/usr/bin:${PATH}
export ORACLE_SID ORACLE_HOME
$ORACLE_HOME/bin/sqlplus -l -s / as sysdba <<!!!
--WRITE HERE WHAT TO DO
--example
SELECT * FROM sys.metaview\$;
--example (notice how to wrap handle "/" char)
BEGIN
NULL;
END;
]'||q'[/
exit
!!!
exit 0
]'
);
end;
/
&dbver and &subver can be extracted by query
column dbver new_value dbver
select regexp_substr(banner, 'Release (\d+.\d+.\d+.\d+).\d+', 1, 1, '', 1) dbver
from v$version
where banner like 'Oracle Database%';
declare
c clob;
begin
c := os_command.exec_CLOB('chmod 755 &tmppath/&scriptname');
c := os_command.exec_CLOB('&tmppath/&scriptname');
dbms_output.put_line(c);
c := os_command.exec_CLOB('rm &tmppath/&scriptname');
end;
/
As “log file sync” is not directly an I/O wait event (IO happens indirectly under the hood), but “wait for LGWR to ACK/increment redo persisting position” then there may be multiple reasons for delays. I’m repeating some of what others have said here too:
You’ll need to measure what LGWR itself was doing during the problem time
@snapper ash,stats,trace 10 999999 lgwr syntax includes LGWR slaves tooPaste the full Snapper output (of one time snapshot from the problem time) here if you can - we’ll be able to see what the slaves were doing
Regarding the ASH wait chains error on 19c - I’m aware of this but forgot to look into it
Were LGWR/LG* processes mostly idle during the problem time?
Why windows exit from sleep or hibernate mode? I’ve spent a lot of time trying to find answer on this question in internet. And finally found solution. Run from cmd with Administrator privileges
C:\Windows\system32>powercfg -sleepstudy
Sleep Study report saved to file path C:\Windows\system32\sleepstudy-report.html.
and see the report. This’ll show the reason why system enters/exits sleep/hibernate mode.
From habr:
С конвертацией коллекций в массивы у Java была непростая история. С момента появления
Collectionв Java 1.2 было два способа создания массива на основе коллекции:
[Collection.toArray()](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/Collection.html#toArray()), который возвращает Object[].Collection.toArray(Object[]), который принимает уже созданный массив и заполняет его. Если переданный массив недостаточной длины, то создаётся новый массив нужной длины того же типа и возвращается. С появлением дженериков в Java 1.5 метод логичным образом поменял свою сигнатуру на [Collection.toArray(T[])](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/Collection.html#toArray(T%5B%5D)).Загвоздка в том, что если нужен массив конкретного типа (допустим String[]), второй метод можно использовать двумя способами:
collection.toArray(new String[0]). Тем самым, мы сознательно почти всегда отбрасываем массив, а передаём его туда, чтобы метод узнал тип массива.collection.toArray(new String[collection.size()]). В этом случае массив передаётся нужной длины, а значит ничего зря не отбрасывается, и код по идее работает быстрее. К тому же здесь не нужен рефлективный вызов.Таким образом, второй вариант долгое время считался основным, и в IntelliJ IDEA даже была инспекция, которая подсвечивала первый вариант и предлагала конвертировать его во второй, более эффективный.
Однако в 2016 году вышла статья Алексея Шипилёва, где он решил досконально разобраться в этом вопросе и пришёл к выводу, что не-а: первый вариант всё-таки быстрее (по крайней мере в версиях JDK 6+). Эта статья получила большой резонанс, и в IDEA решили изменить инспекцию, сделав у неё три опции: предпочитать пустой массив (default), предпочитать преаллоцированный массив или предпочитать то или иное в зависимости от версии Java.
tags:
Quote from habr
Принцип единственной ответственности возник как попытка объединения двух важных понятий структурного анализа и проектирования: coupling (сопряжение, зацепление, связанность) и cohesion (сплочённость, связность, прочность модуля).
Как это было
Модуль A связан с модулем B, или что тоже самое, модуль B связан с модулем А, только тогда когда существует передача информации между ними.
Модуль A зависит от модуля B, а модуль B не зависит от A, если изменения в спецификации А никогда не приведут к изменениям кода в B, а изменения в спецификации B могут приводить к изменениям кода в A.
Существует также альтернативная формулировка:
Модуль A зависит от модуля B, а модуль B не зависит от A, если удаление модуля B приводит к нарушениям в работе A.
All solutions are well-known:
-- 1. The most elegant
WHERE ('fake', val) IN (
('fake', val1),
('fake', val2),
('fake', val3),
...
);
-- 2. The most obvious
val IN (
SELECT val1 FROM dual UNION ALL
SELECT val2 FROM dual UNION ALL
SELECT val3 FROM dual UNION ALL
...
)
-- 3. XMLTable magic
val IN (SELECT trim(COLUMN_VALUE) FROM XMLTABLE('"val1","val2","val3",...'))
I just want to mention one thing about XMLTable solution: string parameter for this function can exceed 4000 symbols (checked in Oracle 11.2.0.4)
It’s not a well-known phenomenon, but Oracle uses a completely
different strategy for deleting through an index range/full scan from
the strategy it uses when deleting through a tablescan or index fast
full scan. For the tablescan/index fast full scan Oracle deletes a row
from the table then updates each index in turn before moving on to
delete the next row. For the index range scan / full scan Oracle
deletes a table row but records the rowid and the key values for each
of the indexes that will need to be updated – then carries on to the
next row without updating any indexes. When the table delete is
complete Oracle sorts all the data that it has accumulated by index,
by key, and uses bulk updates to do delayed maintenance on the
indexes. Since bulk updates result in one undo record and one redo
change vector per block updated (rather than one per row updated) the
number of redo entries can drop dramatically with a corresponding drop
in the redo and undo size.