我正在为Oracle数据库创build一个Docker镜像,并且将从同一图像生成许多不同的容器。
当我启动Oracle实例时,出于某种原因将几个字节写入所有活动的数据文件。 Docker将容器中的diff保存到基本映像中,diff是整个文件发生了更改,因此每次启动一个容器时,为了启动数据库而将大于6 GB的容器写入磁盘。
那么,为什么在启动数据库时Oracle会写入数据文件呢? 只有当数据被更改并提交时,大多数逻辑行为才会写入数据文件。 我能做些改变吗?
除了Oracle Linux(这是我的映像的基础)之外,我也尝试了在Windows上的行为是一样的,所有的数据文件都被写入。
我试图将表空间设置为只读。 这避免了写操作,但是当我将表空间设置为读写时,它立即写入文件,导致再次出现问题。
只是要清楚,我需要表空间是可写的,但只有当数据实际发生变化时。
没有办法避免这种情况。 除了用户数据之外,Oracle还包含许多元数据 – 这些也必须维护。 Oracle内部维护一个名为SCN(系统变更号码)的号码。 这个数字会随着数据库中“某些东西”的改变而增加。
这个SCN号码被写入到每个数据文件的头部,也被写入到每个控制文件中。 当打开(启动)数据库时,Oracle会检查这个数字在所有文件中是否相同。 然后它假定文件是一致的。
即使数据库没有负载,这个SCN也会增加。 还有像统计数据收集这样的背景工作会有一些负担 另外,用户可能会创build系统触发器ON DATABASE STARTUP ,它将在数据库启动时执行一些作业。
一般来说,Oracle数据库服务器不适合虚拟化。 Oracle日志logging的工作人员也在内部进行,因此您保留相同的数据两次(这些文件称为存档重做日志)。 因此,如果放弃容器差异(仅适用于数据文件),Oracle将能够继续存在,因为它能够重放重做日志中的事务。
PS:克隆数据库时,还应该考虑将数据库SID更改为唯一的。 或者至less你应该使用nid来更改数据库唯一编号DBID。 否则,恢复RMAN数据库备份时可能会遇到麻烦。