表空间的状态(二) - read/write

Oracle只读表空间管理
本文介绍了Oracle数据库中只读表空间的管理和使用方法。详细解释了只读表空间的特点,如无需频繁备份、禁止数据修改等,并给出了设置只读和读写状态的具体步骤及注意事项。

表空间状态-READ ONLY、READ WRITE


1. 只读表空间的主要用途就是为了消除对数据库大部分静态数据的备份和恢复的需要。Oracle不会更新只读表空间爱你的文件,因此这部分文件可以存储于只读介质中,例如CD-ROM或WORM drives。
2. 只读表空间并不是为了满足归档的要求。只读表空间不能修改。如果需要修改只读表空间中的记录,则需要先将表空间置为read/write。更新表空间后,可以重置为只读。
3. 由于只读表空间不能修改,所以只要没有置为read/write,就不需要重复地进行备份。而且,如果需要恢复数据库时,也不需要恢复只读表空间,原因就是他们未曾修改过。
4. 能从只读表空间中删除对象,例如表或索引,但不能创建或修改对象。可以执行修改数据字典中文件描述的语句,例如ALTER TABLE ... ADD或ALTER TABLE ... MODIFY,但不能添加任何新的描述信息,除非表空间置为read/write。
5. 只读表空间可以导出导入到其他数据库。既然只读表空间不能修改,他们就能存储于CD-ROM或WORM(一次写-多次读)这些设施中。
6. 所有表空间初始创建都是read/write。使用READ ONLY子句可以设置表空间为只读。前提是必须具有ALTER TABLESPACE或MANAGE TABLESPACE的系统权限。
使用ALTER TABLESPACE ... READ ONLY前,需要满足以下条件:
> 表空间处于online状态。这是为了确保不会有UNDO信息需要应用到表空间。注:如果处于offline,则会将UNDO信息存储于SYSTEM表空间,待恢复online时应用这些UNDO信息。
> 不能修改活动的UNDO表空间或SYSTEM表空间。
> 表空间不能处于当前正在进行的online备份中,因为备份结束时会更新表空间所有数据文件的头部信息。
> 为了让从只读表空间读取数据得到更好的性能,可以在置为read-only之前执行一次访问表空间的表中所有数据块的查询。一个像SELECT COUNT(*)这样简单的查询,就可以确保在表空间的数据块在接下来的访问中获得最佳的效率。因为这种做法就不需要数据库检查最近经常修改数据块的交易状态。
7. 可以在数据库正处理交易的时候执行ALTER TABLESPACE ... READ ONLY语句。执行语句后,表空间就处于交易只读状态。不会允许任何交易(DML操作)应用于表空间。如果尝试进行交易操作,那么此操作会被终止和回滚。然而,那些已经做了变更并不再进行进一步修改的交易,就允许执行commit或roll back操作。
如果ALTER TABLESPACE ... READ ONLY语句执行前,一个交易已经执行了,但是回滚到一个保存点,回滚了他对表空间的变更,那么ALTER TABLESPACE ... READ ONLY语句不会等待这个活动的交易。
8. 交易级只读状态仅仅当初始化参数COMPATIBLE是8.1.0或以上值时才能使用。如果参数值小于8.1.0,并且存在活动的交易,ALTER TABLESPACE ... READ ONLY语句会失败。
9. 如果ATLER TABLESPACE语句执行时间太长了,那么就需要找到阻止只读状态生效的那些交易。如下语句可以找出执行ALTER TABLESPACE ... RAED ONLY语句的交易入口和session地址(saddr):
SELECT SQL_TEXT, SADDR
FROM V$SQLAREA,V$SESSION
WHERE V$SQLAREA.ADDRESS = V$SESSION.SQL_ADDRESS AND SQL_TEXT LIKE 'alter tablespace%';
SQL_TEXT                                  SADDR
---------------------------------------- --------
alter tablespace tbs1 read only           80034AF0
每个活动交易的开始SCN会存储于V$TRANSACTION视图中。起始SCN越小,说明这步操作就越早。潜在地这条语句越可能阻止接下来只读状态的变更。
SELECT SES_ADDR, START_SCNB
FROM V$TRANSACTION
ORDER BY START_SCNB;
SES_ADDR START_SCNB
-------- ----------
800352A0 3621 --> waiting on this txn
80035A50 3623 --> waiting on this txn
80034AF0 3628 --> this is the ALTER TABLESPACE statement
80037910 3629 --> don't care about this txn
可以用如下语句找到阻塞交易的用户:
SELECT T.SES_ADDR, S.USERNAME, S.MACHINE
FROM V$SESSION S, V$TRANSACTION T
WHERE T.SES_ADDR = S.SADDR
ORDER BY T.SES_ADDR
SES_ADDR USERNAME              MACHINE
-------- -------------------- --------------------
800352A0 DAVIDB                DAVIDBLAP --> Contact this user
80035A50 MIKEL                 LAB61 --> Contact this user
80034AF0 DBA01                 STEVEFLAP
80037910 NICKD                 NICKDLAP
将表空间置为read-only后,建议立即备份。只要表空间一直处于只读状态,那就不需要再次地备份,因为不会有对表空间的更新。
10. 使用LATER TABLESPACE ... READ WRITE语句可以恢复只读表空间,前提是具有ALTER TABLESPACE或MANAGE TABLESPACE权限。
表空间置为read/write的前提条件还需要表空间中的所有数据文件以及表空间自身都处于online状态。可以使用ALTER DATABASE ... DATAFILE ... ONLINE语句将数据文件置为online状态。V$DATAFILE视图显示了数据文件当前的状态。
将表空间置为可写模式,需要更新控制文件,目的就是为了可以使用数据文件的只读版本作为恢复的起始点。
11. 在WORM设备中创建一个只读表空间。
(1) 创建一个可写表空间。创建对象、插入数据。
(2) 将表空间置为read-only只读模式。
(3) 使用操作系统命令将表空间的数据文件复制到WORM设备。
(4) 将表空间置为offline状态。
(5) 重命名数据文件以符合拷贝到WORM设备中的数据文件命名规范。使用ALTER TABLESPACE ... RENAME DATAFILE语句,重命名数据文件的操作会修改控制文件。
(6) 将表空间恢复为online状态。

实验:
1. 设置表空间为read only状态
SQL> alter tablespace dcsopen_tbs read only;
Tablespace altered.

2. 查看数据文件状态
SQL> select file#, name, status from v$datafile where file#=11;
FILE#  NAME                                                                    STATUS
----- ------------------------------------------------------- ------------------------
11      /oracle/oradata_petest/petest/dcsopen_tbs02.dbf   ONLINE

3. 登录到只读表空间
SQL> select * from test1;
      T1ID T1V
---------- ----------
         1 t1
         2 t2
         3 t3
可以读其中的表。
SQL> insert into test1 values(12, 't12');
insert into test1 values(12, 't12')
            *
ERROR at line 1:
ORA-00372: file 7 cannot be modified at this time
ORA-01110: data file 7: '/oracle/oradata_petest/petest/dcsopen_tbs01.dbf'
执行交易操作时提示7号数据文件此时不能修改。
<think>我们正在处理两个主要问题: 1. "docker build context error: Can't add file to tar: io: read/write on closed pipe" 2. "Cannot connect to Docker daemon" 根据引用内容,我们可能遇到多种情况。我们逐一分析解决。 问题1: 构建上下文错误(Can't add file to tar: io read/write on closed pipe) 这种错误通常发生在构建上下文(context)过大,或者Docker守护进程(daemon)在构建过程中出现异常时。可能的原因包括: - 构建上下文过大,导致传输过程中管道(pipe)关闭。 - 磁盘空间不足(引用[3]提到“no space left on device”)。 - Docker守护进程没有运行(导致无法连接)。 问题2: 无法连接到Docker守护进程(Cannot connect to Docker daemon) 引用[1]中提到了类似的错误:`Error response from daemon: open \\.\pipe\docker_engine_linux: The system cannot find the file`。这通常意味着Docker守护进程没有运行。 解决方案: 步骤1:检查Docker守护进程状态 在Linux上,使用: ```bash sudo systemctl status docker ``` 如果发现Docker没有运行,启动它: ```bash sudo systemctl start docker ``` 步骤2:检查磁盘空间(引用[3]) 使用`df -h`查看磁盘空间,特别是Docker存储目录(通过`docker info | grep "Docker Root Dir"`查看)所在的磁盘分区。 如果空间不足,可以清理空间或者更改Docker的存储位置(如引用[3]所示): - 编辑`/etc/docker/daemon.json`,添加: ```json { "data-root": "/new/path/to/docker" } ``` - 然后重启Docker: ```bash sudo systemctl daemon-reload sudo systemctl restart docker ``` 步骤3:检查构建上下文大小 使用`.dockerignore`文件忽略不必要的文件(如node_modules、.git等),以减少构建上下文大小。 例如,在Dockerfile所在目录创建`.dockerignore`文件,内容如下: ``` **/.git **/node_modules **/*.log **/.DS_Store ``` 步骤4:检查文件路径(引用[4]) 确保在Dockerfile中`ADD`或`COPY`的文件存在于构建上下文中,且没有被`.dockerignore`忽略。 例如,引用[4]中的错误是因为`run.sh`文件不存在于构建上下文中。 步骤5:尝试重新加载Docker守护进程 如果上述步骤无效,尝试重新加载并重启Docker: ```bash sudo systemctl daemon-reload sudo systemctl restart docker ``` 步骤6:检查Docker日志 查看Docker守护进程的日志,以获取更多信息: ```bash sudo journalctl -u docker.service ``` 步骤7:检查文件权限(引用[2]) 如果出现类似引用[2]中的错误(`no such file or directory`),确保Docker存储目录(如`/var/lib/docker`)存在且权限正确。 总结操作顺序: 1. 确保Docker守护进程正在运行。 2. 检查磁盘空间。 3. 优化构建上下文(使用.dockerignore)。 4. 检查Dockerfile中的文件路径是否正确。 5. 重启Docker服务。 如果问题仍然存在,请提供更多上下文信息。 相关问题: 1. 如何查看Docker守护进程的日志? 2. 如何清理Docker占用的磁盘空间? 3. 如何配置Docker使用新的存储位置? 4. Docker构建上下文的最佳实践是什么?</think>### 解决 Docker 构建上下文错误与守护进程连接问题 您遇到的两个核心问题需要分别处理: #### 🔧 问题 1: `docker build context error: Can't add file to tar: io read/write on closed pipe` **原因分析**: - 构建上下文过大导致管道超载 - Docker 守护进程资源不足(磁盘空间或内存) - 文件系统权限问题(如引用[3][^3]所示) - Dockerfile 中引用了不存在的文件(如引用[4][^4]所示) **解决方案**: 1. **检查磁盘空间**: ```bash df -h # 查看磁盘使用情况 docker system df # 查看Docker磁盘使用 ``` 如果空间不足(如引用[3][^3]),迁移Docker存储位置: ```bash sudo nano /etc/docker/daemon.json ``` 添加配置: ```json { "data-root": "/new/path/with/space" } ``` 重启Docker: ```bash sudo systemctl daemon-reload sudo systemctl restart docker ``` 2. **优化构建上下文**: - 创建 `.dockerignore` 文件忽略非必要文件: ```gitignore .git node_modules *.log .DS_Store ``` - 使用更小的基础镜像(如 `alpine` 版本) 3. **验证文件路径**: 确保 Dockerfile 中的 `ADD`/`COPY` 指令引用的文件存在(如引用[4][^4]): ```bash # 检查文件是否存在 ls -la path/to/file ``` 4. **分阶段构建**: ```dockerfile # 第一阶段:构建环境 FROM node:alpine AS builder WORKDIR /app COPY . . RUN npm install && npm run build # 第阶段:生产镜像 FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html ``` --- #### ⚙️ 问题 2: `Cannot connect to Docker daemon` **原因分析**: - Docker 服务未运行(如引用[1][^1]) - 用户权限不足 - 系统服务配置错误 **解决方案**: 1. **检查 Docker 服务状态**: ```bash sudo systemctl status docker ``` 如果未运行: ```bash sudo systemctl start docker sudo systemctl enable docker # 设置开机自启 ``` 2. **添加用户到 docker 组**: ```bash sudo usermod -aG docker $USER newgrp docker # 刷新组权限 ``` 3. **检查 UNIX 套接字权限**: ```bash ls -l /var/run/docker.sock sudo chmod 666 /var/run/docker.sock # 临时解决方案 ``` 4. **验证守护进程配置**: ```bash sudo dockerd --debug # 查看详细启动日志 ``` --- ### 完整解决流程 ```bash # 1. 检查Docker服务 sudo systemctl status docker || sudo systemctl start docker # 2. 检查磁盘空间 df -h /var/lib/docker docker system prune -a # 清理无用资源 # 3. 添加用户权限 sudo usermod -aG docker $USER newgrp docker # 4. 优化构建上下文 echo "node_modules" >> .dockerignore # 5. 重建镜像 docker build -t gateway:2.0 . ``` > **提示**:如果使用 Windows WSL2 出现管道错误(如引用[1][^1]),需在 PowerShell 执行: > ```powershell > wsl --shutdown > wsl -d docker-desktop > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值