19/09/2019
1
The Best Database Feature Ever
Connor McDonald
Database Advocate
Copyright © 2019 Oracle and/or its affiliates.
2
Connor McDonald
1
2
19/09/2019
2
3 3
4 4
3
4
19/09/2019
3
5
6
Stuff
youtube bit.ly/youtube-connor
blog bit.ly/blog-connor
twitter bit.ly/twitter-connor
400+ posts mainly on database & development
250 technical videos, new uploads every week
rants and raves on tech and the world :-)
5
6
19/09/2019
4
7
etc...
facebook bit.ly/facebook-connor
linkedin bit.ly/linkedin-connor
instagram bit.ly/instagram-connor
slideshare bit.ly/slideshare-connor
9
the #1 thing
7
9
19/09/2019
5
10
"Readers don't block writers"
"Writers don't block readers"
11
Maximum concurrency…
… very few locking worries
10
11
19/09/2019
6
12
lack of understanding
13
12
13
19/09/2019
7
14
some revision / fundamentals
15
SQL> update EMP
2 set SAL = SAL * 1.10
3 /
14 rows updated.
SQL> rollback;
Rollback complete.
how ?
15
14
15
19/09/2019
8
16
we remember stuff
17
SQL> update EMP
2 set SAL = SAL * 1.10
3 where ename = 'SMITH'
undo header
smith $1,0001
block 2754
jones $9002
brown $1,5003
wells $2,0004
wilson $1,0005
block 2754, row 1,
sal $1000
uba 5 5
$1,100
uba 5.1
16
17
19/09/2019
9
18
SQL> rollback;
18
19
SQL> rollback;
undo header
smith $1,0001
block 2754
jones $9002
brown $1,5003
wells $2,0004
wilson $1,0005
block 2754, row 1,
sal $1000
uba 5
5
$1,100
uba 5.1
18
19
19/09/2019
10
20
we can use this stuff for queries!
(Oracle version 4)
20
21
read consistency
21
20
21
19/09/2019
11
22
select * from emp
where hiredate > '01/01/2004'
update emp set ename = 'SUE'
where ename = 'JOHN';
Block 3217
"I need block 3217…
… as it was at 9:00"
9:00
9:03
9:05
session 1 session 2
so what do we do now ?
23
22
23
19/09/2019
12
we apply undo
25
Session 1
Request
Block 3217,
SCN 4567192
Block 3217,
9:03am
"SUE"
Block 3217,
change 9:03 to 8:45
change SUE => JOHN
undo segment block(s)
No good..too new
take a copy of the block
Locate
apply undo
Block 3217,
9:03am
" SUE"
Block 3217,
9:03am
" SUE"
Block 3217,
8:45am
" JOHN"
Block 3217,
8:45am
"JOHN"
Session 2
update emp
set ename = 'SUE'
where ename = 'JOHN'
commit;
Done !
24
25
19/09/2019
13
26
in reality: system change number
stress: vast simplification
26
27
19/09/2019
14
results are time consistent
29
“I’m a developer…
I just write SQL ...
…who cares about all that?”
28
29
19/09/2019
15
30
So many ways…
TROUBLE
30
31
19/09/2019
16
32
example: copying data
“every hour,
populate data warehouse,
copy of OLTP data”
EMP DWEMP
readcon1/readcon2
32
33
19/09/2019
17
DIY data integrity
... true story
34
Manufacturer
Product
alter table add primary key
alter table add foreign key
“ensure that every
product corresponds to
a valid manufacturer”
34
35
19/09/2019
18
create or replace
trigger PROD_MAN_CHECK
before insert or update on PRODUCT
for each row
declare
l_man_id number;
begin
select man_id
into l_man_id
from manufacturer
where man_id = :new.man_id;
exception
when no_data_found then
raise_application_error(-20000,
'Manufacturer is not valid');
end;
create or replace
trigger MAN_PROD_CHECK
before delete on MANUFACTURERS
for each row
declare
l_prd_cnt number;
begin
select count(*)
into l_prd_cnt
from product
where prd_id = :old.prd_id;
if l_prd_cnt > 0 then
raise_application_error(-20001,
'Manufacturer in use by product records');
end if;
end;
36
37
19/09/2019
19
38
testing "works"
38
39
SQL> insert into PRODUCT (...,MAN_ID,...)
2 values (...,100, ...);
1 row created.
SQL> insert into PRODUCT (...,MAN_ID,...)
2 values (...,101,...);
ERROR at line 1:
ORA-20000: Manufacturer is not valid
SQL> delete from MANUFACTURER
2 where man_id = 5768;
ERROR at line 1:
ORA-20001: Manufacturer in use by product records
38
39
19/09/2019
20
40
one month later…
41
An unexpected error has
occurred. Manufacturer
record not found
40
41
19/09/2019
21
42
SQL> select count(*)
2 from
3 ( select man_id from PRODUCT
4 minus
5 select man_id from MANUFACTURER )
6 /
COUNT(*)
----------
86
42
43
data integrity in code = no data integrity
42
43
19/09/2019
22
44
create PRD with MAN=7
Trigger fires
- does MAN=7 exist?
- "Yes"
- OK
delete MAN=7
Trigger fires
- any PRD with MAN=7
- "No" (not yet)
- OK
commit
commit
45
data validity seems simple…
"look up X before allowing Y"
45
44
45
19/09/2019
23
46
referential integrity is complex
read consistency,
blocking / locking
47
beware the module specification
"When creating a product...
validate registration date – ensure not in the future,
validate …
validate …
validate manufacturer ID – must exist in Manufacturer table"
46
47
19/09/2019
24
48
concurrency testing vital
48
51
what about updates ?
48
51
19/09/2019
25
52
SQL> update EMP
2> set SAL = 1000
3> where ENAME = 'SMITH'
change block in current mode
locate blocks in consistent mode
ENAME = ‘SMITH’
SAL = 500
ENAME = ‘JONES’
SAL = 500
demo4a/b
53
so what happened ?
52
53
19/09/2019
26
54
Session 1
changed 4999 rows
got stuck...
Session 2
updated
row 5000
then
committed.. tried to
resume but
the data has
changed
rollback the
transaction
start again, this
time select-for-update
to avoid needing to
rollback again
updated
row 10000 got stuck at row 10000
then
committed.. OK locked all rows
go ahead and update
55
beware autonomous transactions
54
55
19/09/2019
27
56
beware doing external things in triggers
57
summary
56
57
19/09/2019
28
58
Oracle consistency model is …
59
very very cool… and
58
59
19/09/2019
29
60
very very complex !
60
61
(DIY) inter-table checking is hard to do right
60
61
19/09/2019
30
62
(DIY) intra-table checking is hard to do right
62
63
let the database do it
63
62
63
19/09/2019
31
64
Thanks for attending !!!
youtube tinyurl.com/connortube
blog connor-mcdonald.com
twitter @connor_mc_d
64

OOW19 - Read consistency