
好的,我们将深入、详细地介绍 Oracle 透明数据加密(TDE)与重做日志保护的内部原理、管理机制、性能争用及排查方法。
第一部分:官方技术详解
一、透明数据加密 (TDE) 深入原理
1. 核心目标与类型
TDE 的核心目标是保护静态数据(Data-at-Rest),即在存储介质(如磁盘、备份磁带)上的数据文件。它提供“透明”加密,意味着应用程序无需修改即可使用,加解密过程在数据库引擎的 SQL 层和存储层之间完成。
TDE 主要提供两种类型的加密:
- 表空间加密 (TDE Tablespace Encryption):加密整个表空间。在此表空间中创建的所有对象(表、索引等)都将被自动加密。这是 Oracle 推荐的方式。
- 列级加密 (TDE Column Encryption):加密表中的特定列。由于灵活性较差且管理开销大,通常仅用于遗留系统或特定合规需求。
2. 核心组件与加密层次结构 (The Encryption Hierarchy)
TDE 采用一个分层密钥管理系统来平衡安全性和性能。这是理解其内部原理的关键。
-
主密钥 (Master Encryption Key):
- 作用:用于加密或解密表密钥(Table Keys/Tablespace Keys)。它是整个 TDE 密钥体系的根。
- 存储:绝不存储在数据库中。它存储在一个外部安全模块中,称为 Oracle Wallet 或 OKV (Oracle Key Vault)。数据库实例启动后,需要首先“打开”钱包,将主密钥读取到数据库实例的 SGA 中,以供后续加解密操作使用。
- 管理:可定期或按需重新生成(Rekey),以增强安全性。旧的主密钥仍会保留在钱包中,因为它需要解密那些用旧主密钥加密的表密钥。
-
表/表空间密钥 (Table/Tablespace Encryption Key):
- 作用:用于实际加密和解密表或表空间中的数据。
- 生成:当您为表(列加密)或表空间(表空间加密)启用加密时,数据库会为每个对象生成一个唯一的对称密钥(通常是 AES256)。
- 存储:安全地存储在数据库本身的数据字典(头文件)中。但存储的不是明文,而是用主密钥加密后的密文。
-
数据加密:
- 实际的数据块(Data Block)使用表/表空间密钥进行加密。
- 加密单元:对于表空间加密,默认的加密单元自 Oracle 19c 起是
PER_BLOCK,这允许在 Exadata 上进行智能扫描(Smart Scan)下推。传统选项是PER_TABLESPACE。
3. 加解密过程详解
- 写入(加密):
- 服务器进程将数据块写入磁盘时。
- 在数据块进入缓冲区缓存(Buffer Cache)后、写入磁盘前,数据库会从数据字典中获取加密的表密钥(密文)。
- 使用 SGA 中的主密钥解密该表密钥,得到明文表密钥。
- 使用明文表密钥加密数据块。
- 将加密后的数据块写入数据文件。
- 读取(解密):
- 服务器进程从磁盘读取加密的数据块到缓冲区缓存。
- 数据库从数据字典中获取加密的表密钥。
- 使用 SGA 中的主密钥解密表密钥。
- 使用明文表密钥解密缓冲区缓存中的数据块。
- 将明文数据提供给用户会话。
关键点:主密钥仅在实例启动后、钱包打开时被读取到 SGA 一次。后续大量的数据块加解密操作只涉及表密钥,而表密钥的解密(使用主密钥)是非常快速的操作,因此性能开销主要来自数据块本身的 AES 加密/解密。
二、重做日志保护 (Redo Log Protection)
1. 作用与必要性
重做日志记录了所有对数据库的更改,用于恢复和备用数据库(Data Guard)同步。如果重做日志包含明文数据,即使数据文件被 TDE 加密,攻击者也可能从重做日志中窃取敏感信息。
2. 保护机制
Oracle 通过两种方式保护重做日志中的敏感数据:
-
在数据库启用 TDE 的情况下:
- 在将重做记录(Redo Records)写入重做日志缓冲区(Redo Log Buffer)之前,数据库会实时地加密其中的敏感数据。
- 这个过程是同步的,由生成重做记录的用户进程(Server Process)本身完成。它使用与加密数据文件相同的 TDE 表密钥和主密钥体系。
- 影响:由于是同步加密,它会增加生成重做记录的 CPU 开销 和少量延迟。
-
REDO_TRANSPORT_ENCRYPT参数 (用于 Data Guard):- 这个参数用于加密通过网络传输到备用数据库的重做日志流(Log Shipping)。
- 它不加密本地磁盘上的联机重做日志文件,只加密传输过程。
- 它可以使用与 TDE 无关的独立加密密钥(SSL/TLS 证书),或者集成 TDE 钱包。
- 作用是防止网络嗅探(Sniffing)。
重要区别:TDE 对重做日志的保护是对日志内容中敏感字段的加密,而 REDO_TRANSPORT_ENCRYPT 是对整个网络传输流的加密。
三、管理机制与SQL操作
1. Wallet 管理
- 创建 Wallet:
ADMINISTER KEY MANAGEMENT CREATE KEYSTORE '/wallet/location' IDENTIFIED BY "wallet_password"; - 打开 Wallet:
ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY "wallet_password" [CONTAINER=ALL]; - 关闭 Wallet:
ADMINISTER KEY MANAGEMENT SET KEYSTORE CLOSE IDENTIFIED BY "wallet_password"; - 创建主密钥:
ADMINISTER KEY MANAGEMENT SET KEY IDENTIFIED BY "wallet_password" [WITH BACKUP ...]; - 备份 Wallet:必须手动将
ewallet.p12文件复制到安全位置。丢失钱包和密码将导致数据永久丢失。
2. TDE 管理
- 创建加密表空间:
CREATE TABLESPACE encrypted_ts DATAFILE 'encrypted_ts.dbf' SIZE 100M ENCRYPTION USING 'AES256' DEFAULT STORAGE (ENCRYPT); - 加密现有表空间:
ALTER TABLESPACE users ENCRYPTION ONLINE USING 'AES256' ENCRYPT;(需要ALTER TABLESPACE和SQL*Loader权限) - 检查加密状态:
SELECT t.name, e.encryptionalg algorithm FROM v$tablespace t, v$encrypted_tablespaces e WHERE t.ts# = e.ts#;
3. 重做日志传输加密管理
- 启用传输加密:
(通常还需要配置 Oracle Net 和 Wallet)ALTER SYSTEM SET REDO_TRANSPORT_ENCRYPT = TRUE SCOPE=SPFILE; ALTER SYSTEM SET SSL_VERSION = '1.2' SCOPE=SPFILE; -- 示例配置
第二部分:场景、争用、排查与解决
四、性能争用与排查
1. CPU 争用
- 场景:在高 DML(INSERT/UPDATE/DELETE)负载的系统上启用 TDE 后。
- 原理:每个被修改的数据块在写入磁盘前都需要加密,每个被读取的加密块都需要解密。重做日志中敏感记录的加密也是同步的。这些操作都会消耗额外的 CPU 周期。
- 影响:系统整体 CPU 使用率上升,可能成为瓶颈,导致事务吞吐量下降和响应时间变长。
- 等待事件:通常不直接表现为特定的等待事件,而是体现在
CPU used by this session的高等待时间。如果 CPU 资源耗尽,会话可能会排队等待 CPU 资源,表现为resmgr:cpu quantum(如果启用了资源管理器) 或简单的SGA: allocation forcing component growth(因为更多操作在 SGA 中完成)。 - 排查:
- 使用 AWR/ASH 报告,比较启用 TDE 前后的性能数据。
- 查看
LOAD PROFILE部分,观察CPU per Second和CPU per Transaction的增长。 - 在
TOP 5 TIMED EVENTS中,如果CPU time排名第一,且绝对值很高,很可能与 TDE 相关。 - 使用 OS 工具(如
top,vmstat)确认数据库服务器CPU使用率是否饱和。
- 解决:
- 硬件升级:增加更多或更快的 CPU 核心。
- 优化 SQL:减少逻辑读/物理读(索引、SQL调优),间接减少加解密次数。
- 调整加密算法:AES256 比 AES128 更安全但稍慢,评估是否可用 AES128。但通常不推荐为此降低安全级别。
2. Wallet 争用与 ENCRYPT_TABLESPACE 等待事件
- 场景:在大规模并行操作中,例如同时为多个表空间启用加密,或大量会话首次访问加密数据时。
- 原理:当数据库需要访问一个加密的表空间,但对应的表密钥尚未缓存在 SGA 中时,进程需要从数据字典中读取加密的表密钥,并用主密钥解密它。访问主密钥和加解密表密钥的操作是串行化的(需要通过一个锁机制来保护对钱包和主密钥的访问),以防止密钥在内存中被损坏。
- 影响:会话会等待获取访问密钥所需的锁,从而出现等待事件
ENCRYPT_TABLESPACE。这会导致并发性能下降。 - 排查:
- 查询
v$session_wait或v$active_session_history,查找等待事件为enq: TX - encrypt_tablespace或简写为ENCRYPT_TABLESPACE的会话。 - 使用 AWR 报告,在
ENQUEUE ACTIVITY部分查看TX-ENCRYPT_TABLESPACE的获取次数和等待时间。
- 查询
- 解决:
- 预热缓存:在业务高峰期前,通过全表扫描等方式预先访问加密表,将表密钥加载到 SGA 中并缓存起来。例如:
SELECT COUNT(*) FROM encrypted_table; - 避免大规模并行初始化:避免在业务高峰期为大量表空间同时启用加密。
- 预热缓存:在业务高峰期前,通过全表扫描等方式预先访问加密表,将表密钥加载到 SGA 中并缓存起来。例如:
3. I/O 争用与间接影响
- 场景:所有场景。
- 原理:TDE 加密后的数据几乎是不可压缩的。如果之前使用了存储级或 Oracle 高级压缩(Advanced Compression),启用 TDE 后压缩率会大幅下降,导致数据文件体积膨胀,增加 I/O 负载和缓存压力。
- 影响:物理读(
db file sequential read,db file scattered read)和物理写(db file parallel write,log file parallel write)可能会增加,因为需要读写更多数据块。 - 排查:监控 AWR 报告中的
I/O Profile部分,观察Physical Reads和Physical Writes的变化趋势。 - 解决:评估存储性能,确保 I/O 子系统有能力处理增加的负载。
第三部分:通俗易懂的解释
想象一下Oracle数据库是一个巨大的、非常安全的银行金库。
1. TDE 是如何工作的?
- 数据:就是金库里的现金和珠宝(你的客户信息、订单数据)。
- 表/表空间密钥:是每个保险箱(每个表或表空间)自己独有的钥匙。这把钥匙直接用来锁上或打开这个保险箱。
- 主密钥:是银行金库的总钥匙。但这个总钥匙不放在金库里,而是放在一个单独的、更安全的 “总管保险盒”(Oracle Wallet) 里。银行经理每天早上来上班,首先要用密码打开这个“总管保险盒”,取出总钥匙。
- 过程:当一个员工(服务器进程)要往一个保险箱里放钱时,他不能直接拿保险箱的钥匙,因为钥匙也被锁着。他需要:
- 用总钥匙打开一个“钥匙柜”(数据字典),取出那个保险箱的钥匙(但这把钥匙也是被锁着的)。
- 再用总钥匙把保险箱的钥匙解开(用主密钥解密表密钥)。
- 最后用解开的保险箱钥匙,去锁上保险箱(用表密钥加密数据)。
“透明”的意思是,来存钱取钱的客户(应用程序)根本看不到这些用钥匙开锁的过程,他们觉得和金库打交道和以前一样方便。
2. 重做日志保护是什么?
银行里有一个监控录像(重做日志),记录了每个员工每天对保险箱做的所有操作。如果录像带里清晰地录下了保险箱的密码,那即使保险箱再安全,密码也泄露了。
- TDE的重做日志保护:就是在录像的时候,实时地给录像画面里出现的密码和敏感信息打上马赛克。这样即使有人偷走了录像带,也看不到敏感信息。这个“打马赛克”的动作(加密)需要额外的人力(CPU),所以可能会让记录员(服务器进程)稍微慢一点点。
3. 会出现什么问题?
- CPU 争用(员工累坏了):打马赛克是个精细活,很费脑子(CPU)。如果一天的业务特别繁忙(高DML),记录员们都在疯狂打马赛克,整个银行(数据库)的脑子就不够用了,处理速度就会变慢。
- 钥匙争用(排队等总钥匙):早上刚开门,一大堆员工同时要开各自的保险箱。但总钥匙只有一把,一次只能一个人用。其他员工就只能排队(
ENCRYPT_TABLESPACE等待事件)等着用总钥匙去取自己保险箱的钥匙。解决的办法就是,让一个老员工提前开门,把所有常用保险箱的钥匙都先取出来放在手边(预热缓存),这样高峰期大家就不用都去抢总钥匙了。
总结:
TDE 是一个非常优雅的安全解决方案,它通过分层密钥管理实现了安全与性能的平衡。其主要开销在于 CPU 和潜在的密钥访问争用。DBA 在实施 TDE 前,必须进行充分的性能测试,并理解其底层原理,才能有效地进行故障排查和性能优化。对于重做日志,TDE 提供了字段级的同步加密,而网络传输加密则需单独配置,两者共同构成了全面的redo数据保护策略。
欢迎关注我的公众号《IT小Chen》
1423

被折叠的 条评论
为什么被折叠?



