一、内存分配
Oracle数据库中,只需要通过参数memory_target来控制数据库占用的总体内存空间即可。
物理服务器内存分配:
1、操作系统:
主要是操作系统的进程占用内存空间。一般给2G内存即可。
操作系统进程一般就是服务器进程:日志服务、网络服务、磁盘管理服务、图形化进程、内核进程。
操作系统需要提供远程连接功能:每当有客户端连接,就会有ssh进程+bash进程+执行操作占用内存。
2、定时任务中会有自动执行的脚本:
这些脚本,尤其是备份脚本,运行期间会占用内存,所以也需要预留空间。至少2G给定时任中的脚本运行使用。
3、数据库占用的内存:
通过memory_target来控制Oracle的总内存量。
SQL> show parameter target;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
archive_lag_target integer 0
db_flashback_retention_target integer 1440
fast_start_io_target integer 0
fast_start_mttr_target integer 0
memory_max_target big integer 0
memory_target big integer 0 /自动控制pga和sga
parallel_servers_target integer 16
pga_aggregate_target big integer 97M /PGA占用的总内存空间
sga_target big integer 292M /SGA占用的总内存空间
备注:分别指定sga和pga来决定oracle占用的内存空间。
4、单个PGA的连接数(进程数):
注意:pga单个大小建议设置为10M---30M。则pga总大小=pga单个大小*process进程数
SQL> show parameter process;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
aq_tm_processes integer 1
cell_offload_processing boolean TRUE
db_writer_processes integer 1
gcs_server_processes integer 0
global_txn_processes integer 1
job_queue_processes integer 1000
log_archive_max_processes integer 4
processes integer 150 /(后台进程+服务器进程)
processor_group_name string
二、还原数据:
image.png还原数据:原始的、修改之前的数据副本。
历史数据:之前的数据就叫历史数据。如昨天有一条数据,到了此刻他就是历史数据。
特点1:
当我们执行DML操作,导致数据发生变化,而还原数据会保存在undo中,数据块的数据为当前新数据。
举例:updata 100 修改为300
当前数据 | 历史数据 |
---|---|
300(当前数据) | 100(还原数据) |
保存在undo中 |
特点2:还原数据至少保留到事务处理结束。
#######事务正常提交redo log落盘的工作流程:
备注:这里的redo log落盘是采用commit机制落盘。
redo log(对数据块修改的数据偏移量)--->redo log buffer(redo log会临时存放在内存中)--->redo log group(一旦事务提交就会把redo log buffer中的块落盘到redo log group)
#######事务不提交:
备注:这里的redo log落盘在不提交情况下会在非commit机制下落盘。
redo log(对数据块修改的数据偏移量)--->redo log buffer(redo log会临时存放在内存中)--->redo log group(一旦事务不提交就会在别的机制触发下,使redo log进行落盘)
redo log落盘机制:
1、每3秒提交一次;
2、内存空间不足三分之一提交;
3、大于1M数据;
4、commit;
5、手动切换日志也会发生落盘。
细节概念:
1、redo log buffer在使用过程中,只存在落盘操作,不会有覆盖。
2、落盘到redo log file就会出现循环覆盖。
redo log group覆盖的前提是什么?
1、redo log file中的redo log对应的事务已经提交并且脏块落盘。
2、归档结束。
详解落盘机制:
redo log buffer --->redo log落盘(通过LGWR进程)
redo log(对数据块修改的数据偏移量)--->redo log buffer
在数据块的操作期间,会产生redo log,会被记录到redo log buffer中。
DBWn进程:仅将buffer cache中的脏块落盘,由内存到硬盘。
脏块:就是客户进行DML操作,先将硬盘中的数据块加载到buffer cache中(注意:这个过程不由后台进程负责,是由前台进程负责),然后对数据块进行修改,DBWn进程再负责脏块落盘。
注意:客户端连接Oracle数据库服务器,会产生对应的服务器进程+PGA内存区域。加载数据的操作由每个连接对应的服务器进程完成,但是最终数据块被加载到SGA的buffer cache中(内存共享区域)。这么做的目的就是提高并发的处理性能。
数据块由服务器进程从硬盘加载到内存。######什么时候服务器进程会进行加载操作?
1、需要执行DQL、DML操作才会触发对数据操作。
2、去buffer cache中寻找是否存在需要操作的数据。如果没有,服务器进程才会真正的由磁盘加载数据到内存。
服务器进程修改数据块:
SQL> updata test set object_id=3000 where object_id=30;
现在30数据所在的数据块缓存在buffer cache中。
30修改为3000由谁完成?--->服务器进程。
此时3000数据所在的数据块--->脏块。它会直接落盘?
image.png
1、为了保证脏块中数据安全,会先把它记录到redo log,服务器进程会把redo log放在redo log buffer中。服务器进程在工作
2、为了保证事务rollback的特性,服务器进程会把之前的还原数据(也就是30)记录在undotbs中(undo表空间)。服务器进程在工作
思考问题:
既然服务器进程可以直接写入硬盘(如还原数据直接由服务器进程写入undo表空间文件),那为什么redo log和脏块还要交给lgwr进程和dbWn进程负责落盘?
还原数据至少保留到事务处理结束,如何理解?
服务器进程对数据块进行修改,产生还原数据,最终由服务器进程写入undotbs表空间中。
还原数据的作用:支持回滚。
细节回顾:
1、如果事务提交,则意味着undo就失去了作用。
2、如果脏块落盘并且归档结束,则意味着redo log失去作用。
3、redo log group空间有限,所以引入“循环覆盖”概念。
4、undotbs空间有限,所以引入“超时覆盖”概念(还原数据失效后当超过过期时间,则可以被覆盖)。为了充分利用undo表空间所以才要覆盖。如果不覆盖,当undo表空间耗尽,会导致所有DML操作无法进行,数据库hang死。
还原数据中针对DML语句的存放逻辑,最终达到支持回滚的目的:
undotbs中还原数据以SQL的形式存在,还原数据就是单纯的逻辑日志。
1、执行insert语句--->还原数据存放改写的delete语句;
2、执行update语句--->还原数据存放改写的update语句;
3、执行delete语句--->还原数据存放改写的insert语句;
备注:一旦事务提交,则对应的undo失效,当undo失效超过一段时间,就可以被覆盖。
还原数据作用:
1、支持事务回滚:执行rollback操作时,还原数据中记录的SQL会被应用在已经修改的数据块上。回到事务开始之前的数据状态。
2、读取一致性查询(事务隔离性):保证事务之间的隔离性,避免脏读发生。
例如:
事务A:当前执行:undate 30 300--->undotbs中记录:update 300 30
当前数据块是300,2.1、 事务A未提交:
事务B:进行查询操作,此时正常查询的是30,因为Oracle用的隔离级别是RC(解决脏读问题/一致性读),此时因为事务A未提交,所以查询到的数据实际上来自undo中。
注意:此时事务B先查询到数据块,然后对比数据块的SCN时间点,读取undo中的还原数据重构数据块,再读取之前的数据。
2.2、 事务A提交:
查询到的值是300,可能会出现不可重复读问题。
2.3、为了保证rollback和一致性读,查询时使用还原数据的高效性,进程在将还原数据写入undotbs中时会记录数据块地址。
备注:如果进程1将地址保存在进程1自己的pga中,显然进程2是不能获取到的。
进程1负责记录该地址,但是实际上进程1进行回滚需要该地址用来寻找还原数据,进程2一致性查询也需要该地址寻找undo。所以这个数据块地址保存在sga区中buffer cache中的数据块的块头中。
数据块头:数据块的块头中存在事务处理插槽(ITL interested transaction list),每个插槽的大小约为23字节,修改块中的行时会使用这些插槽。
一旦对数据块进行修改操作,就会产生对应的ITL,ITL有很多段构成,期中存在一个UBA区域(undo block address)。
一旦修改,还原数据保存在undotbs中的数据块中,undo数据块的地址保存在uba中。(注意:换言之,就是数据保存在了undotbs表空间数据块中,对应的数据块地址保存在了sga区域buffer cache中数据块头中的uba中)。
进程2要进行查询,实际上就是通过块头中的ITL中的UBA获取到undo数据块,加载undo还原数据到内存重构数据块。
image.png
模拟:
会话1:
事务A(update数据)--->服务器进程1--->修改数据(记录还原数据)--->undotbs中
会话2:
事务B(select查询)--->服务器进程2--->寻找还原数据--->undotbs
总结:回滚操作和一致性读查询都发生在事务提交前。
3、还原数据支持Oracle闪回查询、Oracle闪回事务处理和Oracle闪回表:
举例:
事务A(9:00):
当前:update 30 300--->还原数据存放记录:update 300 30 (9:01)
commit提交(9:02)。
事务B: (9:05)
查询select --->300(对当前数据块的查询操作)
select ...as of timestamp 时间点;--->(9:00)(查询指定时间点的数据)
undo段和事务的关系:
段知识回顾:
test表空间中:t1数据段(存放t1表的数据)、t10数据段(存放t10表的数据)。数据表以段的形式存在。
事务处理和还原数据:
image.png1、undo表空间中存在段,段和事务又相关,每个事务都会分配一个undo段来使用。段的数量取决于当前的事务数量。
2、一个undo段可以同时被多个事务使用。
3、事务最终对应的是段中的数据块,最终要将还原数据保存在数据块中。
存储还原信息:
image.png还原表空间包含还原段,还原段又包含还原数据。
1、undo表空间有特殊的恢复注意事项。
比如备份恢复、非sys表空间可以在线恢复数据,而undo表空间不可以。
2、只能与单个实例相关联。
在单实例场景中:
可以存在多个undo表空间,但是数据库实例同时只能使用一个undo表空间。
在临时表空间中存在组的概念,数据库实例可以同时使用多个临时表空间文件,以组的方式。undo中没有组的概念,所以一个Oracle数据库实例只能使用一个undo表空间。
在多实例场景中:
每个实例都可以使用独立的undo表空间。
在多实例的RAC集群中,不同服务器上的数据库实例,使用的undo表空间、redo log group都不同。在多实例场景中,文件结构会变得复起来。
3、在任意给定时间,一个给定的实例只能有一个表空间是当前可写还原表空间。(在切换undo表空间时遇到的现象)
举例:
orcl实例正在使用undotbs1表空间。
DML操作,还原数据保存undotbs1表空间中。
创建undo表空间undotbs2。
修改参数:orcl实例把undotbs1表空间改为undotbs2表空间。
新的DML操作,还原数据保存在undotbs2表空间中。
总结:之前的DML操作的还原数据保存在undotbs1中,实例仍然需要这些还原数据保证事务特性,也会使用undotbs1(只读)来查询数据。但是后续的DML操作产生的还原数据仅保存在undotbs2(可读写)中。数据库实例在同一时间,只能对一个undo表空间进行读写操作。
还原数据与重做数据:
image.png前滚:应用redo恢复数据。
回滚:应用undo恢复数据。
场景:
1、执行事务A,已提交,同时创建了检查点AA。
2、执行事务B,已提交,没有触发检查点。
3、执行事务C:
事务C是个大事务,更新的数据量很大,事务C在数据更新期间,出现了数据库异常停机。
请思考:启动数据库SMON进程经过哪些数据恢复过程?
管理还原:
image.png查看undo相关参数:
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO /用于指定undo管理方法,自动模式
undo_retention integer 900
undo_tablespace string UNDOTBS1 /定义当前实例使用的undo表空间,一个实例只能使用一个undo表空间。
undo_retention:定义还原数据保留时间。一旦事务提交则还原数据失效,失效后开始计时,超过保留时间的还原数据可以被覆盖。注意是可以覆盖不是一定会被覆盖,当undo表空间充足就算超过900s,这个数据块依然会存在。
闪回查询,所能闪回的时间段取决于还原数据的保留时间。在这900s之内他是一定不会被覆盖,但是在900s之外需要根据业务而定,假如业务不忙还原数据只要不被覆盖,他依然能够闪回查询到这个指。
1、配置还原保留时间:
image.pngimage.png
2、将还原表空间改为固定大小:
image.png3、快照过旧:
3.1、事务A:
DML操作修改数据后并提交。
SQL> ! date +"%F %T"
2021-05-21 21:22:44
SQL> select count(*) from test;
COUNT(*)
----------
753900
SQL> delete from test where rownum<500000;
499999 rows deleted.
SQL> commit;
Commit complete.
3.2、事务B:
查看当前test表数据量:
SQL> select count(*) from test;
COUNT(*)
----------
253910
查看事务A执行delete前的数据量(此操作就叫做闪回查询):
闪回查询:查看到的是指定时间点的数据状态。
SQL> select count(*) from test as of timestamp to_date('2021-05-21 21:22:44','yyyy-mm-dd hh24:mi:ss');
COUNT(*)
----------
753900
3.3、事务B:
继续删除数据,再次进行查看,此时报错ORA-01555快照过旧。
总结:在进行闪回查询时,能够闪回的数据依赖于undo的数据量,undo足够的情况下可以完成闪回查询。如果undo中的还原数据已经被覆盖,则报错快照过旧。
SQL> delete from test where rownum<253910;
253910 rows deleted.
SQL> commit;
Commit complete.
SQL> select count(*) from test as of timestamp to_date('2021-05-21 21:22:44','yyyy-mm-dd hh24:mi:ss');
select count(*) from test as of timestamp to_date('2021-05-21 21:22:44','yyyy-mm-dd hh24:mi:ss');
*
ERROR at line 1:
ORA-01555: snapshot too old: rollback segment number 7 with name
"_SYSSMU7_4222772309$" too small /快照过旧,回滚段太小了
4、如何确定或调整undo表空间的大小,按照峰值计算需要的undo表空间的sql语句:
select
ur undo_retention,
dbs db_block_size,
((ur * (ups * dbs)) + (dbs * 24)) / 1024 / 1024 as "M_bytes"
from (select value as ur
from v$parameter
where name = 'undo_retention'),
(select (undoblks / ((end_time - begin_time) * 86400)) ups
from v$undostat where undoblks in (select max(undoblks) from v$undostat ) ),
(select value as dbs
from v$parameter
where name = 'db_block_size');
查看:
SQL> col undo_retention for a30
SQL> col db_block_size for a30
SQL> select
ur undo_retention,
2 3 dbs db_block_size,
4 ((ur * (ups * dbs)) + (dbs * 24)) / 1024 / 1024 as "M_bytes"
from (select value as ur
5 6 from v$parameter
where name = 'undo_retention'),
(select (undoblks / ((end_time - begin_time) * 86400)) ups
from v$undostat where undoblks in (select max(undoblks) from v$undostat ) ),
(select value as dbs
from v$parameter
where name = 'db_block_size'); 7 8 9 10 11 12
UNDO_RETENTION DB_BLOCK_SIZE M_bytes
------------------------------ ------------------------------ ----------
900 8192 689.8125
5、自动扩展打开的情况:
5.1、undo足够使用。
5.2、在undotbs中的数据文件扩展到最大值32G之前,不会发生rollback segment重用;
5.3、闪回操作可以查询到更早的数据。
5.4、缺点就是占用过多的磁盘空间。
6、自动扩展关闭的情况:
6.1、设置固定大小的undo表空间,大小取决于业务峰值的undo压力;
6.2、占用更少的磁盘空间;
6.3、突然执行的大事务可能会失败。
7、查看undo表空间使用状态:
SQL> SELECT tablespace_name, status, SUM (bytes)/1024/1024 "Bytes(M)" FROM dba_undo_extents GROUP BY tablespace_name, status;
TABLESPACE_NAME STATUS Bytes(M)
------------------------------ --------- ----------
UNDOTBS1 UNEXPIRED (未失效) 11.5
UNDOTBS1 EXPIRED (失效) 229
UNDOTBS1 ACTIVE 87.6875
自动覆盖:一个新事务开始的时候,如果undo 表空间已经被写满,则新事务的数据会自动覆盖已提交事务的数据,而不管这些数据是否已过期。
不自动覆盖:只有在一种情况下,undo 表空间能够确保 undo 中的数据在 undo_retention指定时间过期前一定有效,就是为 undo 表空间指定 Retention Guarantee,指定之后,oracle 对于 undo 表空间中未过期的 undo 数据不会覆盖。
给undo表空间添加强制保留还原数据选项,语法:
SQL> Alter tablespace undotbs2 retention guarantee;
给undo表空间添加不强制保留还原数据选项,语法:
SQL> Alter tablespace undotbs2 retention noguarantee;
查看是否是guarantee状态,数据库默认不强制保留:
SQL> SELECT tablespace_name, retention FROM dba_tablespaces;
TABLESPACE_NAME RETENTION
------------------------------ -----------
SYSTEM NOT APPLY
SYSAUX NOT APPLY
UNDOTBS1 NOGUARANTEE
TEMP NOT APPLY
USERS NOT APPLY
EXAMPLE NOT APPLY
TBS1 NOT APPLY
TBS3 NOT APPLY
TBS4 NOT APPLY
TBS5 NOT APPLY
TBS2 NOT APPLY
TABLESPACE_NAME RETENTION
------------------------------ -----------
TEST NOT APPLY
注意:要总体考虑到系统负载较重和较正常的情形,同时要考虑到表空间是否是自动扩展的。
当undo表空间增长较快时,要从以下角度考虑进行控制:
- 如果undo表空间是自动扩展的,将自动扩展关闭。如果undo表空间自动扩展,即使有过期的undo段,它也不会重用,而是选择增大数据文件。
alter database datafile '<datafile path(undo表空间数据文件)>' autoextend off; - 对数据文件进行裁剪(临时调大);
alter database datafile '<datafile path(undo表空间数据文件)>' resize <new size>; - 减少UNDO_RETENTION参数值。
设定UNDO_RETENTION参数值时,参考VUNDOSTAT;
注意:在生产环境下,只要保证UNDO_RETENTION设置时间大于统计的事务最长时间即可。设置undo的保留时间时,undo的保留时间取决于最长查询时间。 - 创建新的 undo表空间:
SQL> create undo tablespace UNDO_TBS1 datafile 'undotbs1.dbf' size 100m;
SQL> alter system set undo_tablespace=undo_tbs1;
SQL> drop tablespace undo_rbs0 including contents.(删除undo表空间,前提是undo中保存的还原数据对应的事务都已提交。)
如果在删除以前undo表空间时出现ORA-30013错误,则需要等待所有事务提交之后,才能删除以前undo表空间。
知识点回顾:
undo作用:
1、回滚
2、一致性读
3、闪回查询
事务结束标志:
rollback:意味着事务回滚,回滚操作需要使用还原数据。
commit:意味着事务提交,不能回滚,undo失效。
delete、truncate、drop区别:
1、delete属于DML操作,具有事务特性。
truncate和drop属于DDL操作,不被事务管理。
2、delete被事务管理,如果执行delete操作,会产生undo信息。还原数据,记录还原数据要保存在undo表空间的数据文件中。
delete操作会涉及到大量的物理IO(记录undo落盘)。
3、delete执行的速度很慢。
truncate/drop这两个操作不被事务管理,删除数据不产生undo信息。删除速度很快。
从事务角度来考虑数据安全问题:
delete更安全,truncate和drop更危险。
从操作速度角度来考虑:
truncate和drop性能更好,delete性能更差。
4、操作对象不同:
delete:针对行记录操作。delete from table_name where id=10;
truncate和drop针对表操作。truncate/drop table table_name;
举例:
delete from test;--->test所有行记录被删除,但是保留表结构。delete和高水位线无关(表结构和表数据的数据块还存在)。delete只删除段中数据块中的行记录。
truncate table test;--->test所有行记录被删除,但是保留表结构。truncate会回收数据表的高水位线(也就是只保留与表结构相关数据块,其他数据块被删除)。truncate不仅删除段中数据块中的行记录,还会释放段中数据块。
drop table test;--->test表被删除,表数据和表结构都被删除。但是他会把删除的表放在回收站中。
注意:11g中引入了回收站机制。删除表时,并没有真的删除表,而是进行了重命名。
举例:
SQL> create table test as select * from dba_objects;
Table created.
SQL> select count(*) from test;
COUNT(*)
----------
75431
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
TEST TABLE
SQL> drop table test;
Table dropped.
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BIN$wuAnRHemonrgUwUAAAoVZA==$0(test表回收站中的表名) TABLE
SQL> select count(*) from "BIN$wuAnRHemonrgUwUAAAoVZA==$0"; /拿回收站中test表的名称查询
COUNT(*)
----------
75431
查看回收站中的内容,并回收被删除的表。
SQL> show recyclebin; /查看回收站中的详细内容
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
TEST BIN$wuAnRHemonrgUwUAAAoVZA==$0 TABLE 2021-05-22:07:11:15
SQL> flashback table "BIN$wuAnRHemonrgUwUAAAoVZA==$0" to before drop; /回收站中数据表的恢复。
Flashback complete.
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
TEST TABLE
SQL> select count(*) from test;
COUNT(*)
----------
75431
清空回收站:
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
TEST BIN$wuAnRHelonrgUwUAAAoVZA==$0 TABLE 2021-05-22:07:09:35
SQL> purge recyclebin; /清空回收站
Recyclebin purged.
SQL> show recyclebin;
truncate删除表:
备注:truncate删除表其实是最危险的操作,一旦删除就无法恢复。
SQL> select count(*) from test;
COUNT(*)
----------
75431
SQL> truncate table test;
Table truncated.
SQL> select count(*) from test;
COUNT(*)
----------
0
总结:delete删除表可以rollback回滚,drop删除表可以用回收站还原找回,truncate删除表无法恢复,他也是最危险的删除表操作。
他们的安全性排序,delete安全性最高:
truncate<drop<delete。
网友评论