龊事一桩,解决 scsi 4:0:0:0: rejecting I/O to dead device

本文记录了一次服务器遇到I/O错误的问题排查与解决过程。作者通过检查系统日志发现了问题的根源在于不当的USB设备使用,并采取了一系列措施解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天登陆我们一台在上海的服务器,有同事说ftp无法正常上传文件,我想先看下分区的情况,于是:
df -h了一下,发现错误:
df: `/mnt': Input/output error
我吓了一条,dmesg了下,这下更的冷汗直冒:
scsi 4:0:0:0: rejecting I/O to dead device
FAT: Directory bread(block 32) failed
scsi 4:0:0:0: rejecting I/O to dead device
FAT: FAT read failed (blocknr 1)
scsi 4:0:0:0: rejecting I/O to dead device
FAT: FAT read failed (blocknr 1)
满屏这个信息,一般看到I/O err然后再来个read-only,基本上硬盘是出现物理坏道了,以前管理discuz!虚拟主机的两年中碰到过几次

这个时候我很紧张数据,赶紧把剩余的数据备份掉!!!速度很慢,等待中,我仔细检查了下系统日志。

 

我惊奇的发现:
Initializing USB Mass Storage driver...

MD,谁在我们机器上装过USB设备? 是谁!!!!! 我随便问了一下,同事告诉我,是edong那边要给我们装什么备案软件,需要提供机器的密码给他们,而我今天出去开会了,给过了,那问题清晰了! 长舒了一口气啊~~~
赶紧umount /mnt
umount: /mnt: device is busy

edong那帮人啊!
fuser /mnt 看了下是哪个进程使用此设备
fuser -km /mnt 强行干掉所有使用此设备的进程
umount /mnt

搞定!

<think>我们正在处理Elasticsearch(ES)的一个经典问题:由于索引中存在多个类型(type)而导致的映射更新被拒绝。错误信息明确指出了问题所在:索引`audit-2025.07.24`的最终映射将包含多个类型(`user_op_audit`和`doc`),而ES从6.0版本开始,一个索引只能有一个类型(7.x版本完全移除了多类型支持)。因此,我们需要确保该索引中只有一个类型。 ### 问题原因 - 在ES 6.x中,每个索引只允许有一个映射类型(默认为`_doc`),而在7.x中完全移除了类型的概念(每个索引只有一个隐式的`_doc`类型)。 - 错误信息表明,当前索引中已经存在`user_op_audit`类型,而您又尝试添加`doc`类型(或者反之),导致ES拒绝映射更新。 ### 解决方案 以下是解决此问题的步骤,您可以根据实际情况选择合适的方法: #### 方法1:统一使用单一类型(推荐) **原理**:将索引中的所有文档都使用同一个类型(通常为`_doc`)进行索引。 **操作步骤**: 1. **修改批量索引请求**:确保所有文档操作都使用相同的类型`_doc`。 - 检查您的批量请求(Bulk Request)中的每个操作,确保`_type`字段都设置为`_doc`(或者同一个类型,但建议使用`_doc`)。 - 示例(正确的批量请求格式): ```json {"index": {"_index": "audit-2025.07.24", "_type": "_doc", "_id": "1"}} {"field1": "value1", "field2": "value2"} // 文档1 {"index": {"_index": "audit-2025.07.24", "_type": "_doc", "_id": "2"}} {"field1": "value3", "field2": "value4"} // 文档2 ``` > 注意:在ES 7.x及以上版本,可以省略`_type`,因为默认就是`_doc`。但是显式指定可以避免歧义。 2. **检查代码**:如果您是通过代码(如Java High Level REST Client、Python Elasticsearch库等)生成请求,请确保在设置文档类型时统一为`_doc`。 - Python示例: ```python from elasticsearch import helpers actions = [ { "_index": "audit-2025.07.24", "_type": "_doc", # 统一类型 "_source": { "user": "alice", "action": "login" } }, # ... 其他文档 ] helpers.bulk(es, actions) ``` #### 方法2:重新创建索引(如果索引已存在多个类型) **适用场景**:如果索引`audit-2025.07.24`已经存在多个类型(比如之前错误地写入了不同类型的数据),则需要重建索引。 **操作步骤**: 1. **创建新索引**(使用正确的单一类型映射): ```bash # 创建新索引,明确指定映射(使用_doc类型) curl -XPUT "http://localhost:9200/audit-new" -H 'Content-Type: application/json' -d' { "mappings": { "_doc": { // 这里显式定义_doc类型的映射 "properties": { "field1": { "type": "text" }, "field2": { "type": "keyword" } } } } }' ``` 2. **将旧索引数据迁移到新索引**(使用Reindex API): ```bash curl -XPOST "http://localhost:9200/_reindex" -H 'Content-Type: application/json' -d' { "source": { "index": "audit-2025.07.24" }, "dest": { "index": "audit-new" } }' ``` 3. **删除旧索引并重命名新索引**: ```bash # 删除旧索引 curl -XDELETE "http://localhost:9200/audit-2025.07.24" # 将新索引重命名为旧索引名 curl -XPOST "http://localhost:9200/audit-new/_alias/audit-2025.07.24" # 或者使用索引别名,或者直接重建索引(如果允许停机) ``` #### 方法3:使用不同的索引存储不同类型(推荐用于不同结构的文档) **原理**:如果`user_op_audit`和`doc`代表的是两种完全不同的文档结构(例如审计日志和普通文档),则应该将它们存储在不同的索引中。 **操作步骤**: 1. **创建两个索引**: - `audit-user_op_audit-2025.07.24`:用于存储`user_op_audit`类型的数据。 - `audit-doc-2025.07.24`:用于存储`doc`类型的数据。 2. **修改批量请求**:将不同类型的文档分别发送到对应的索引。 ```json // user_op_audit类型的数据 {"index": {"_index": "audit-user_op_audit-2025.07.24", "_type": "_doc", "_id": "1"}} {"user": "alice", "operation": "delete"} // doc类型的数据 {"index": {"_index": "audit-doc-2025.07.24", "_type": "_doc", "_id": "1"}} {"title": "Document1", "content": "..."} ``` ### 注意项 1. **版本兼容性**: - 如果您使用的是ES 6.x,请确保在创建索引时指定`include_type_name=true`(但建议升级到7.x以上版本)。 - ES 7.x以上版本完全移除了多类型支持,因此必须使用单一类型(`_doc`)。 2. **数据备份**:在进行索引重建或删除操作前,务必备份数据。 3. **索引别名**:考虑使用索引别名(aliases)来避免在应用程序中硬编码索引名称,便于后续索引管理。 4. **批量请求优化**:确保批量请求中所有文档都使用相同的索引和类型,以提高性能并避免映射冲突。 ### 错误示例分析 参考引用[1]中的错误信息: ```json { "error": { "root_cause": [ { "type": "illegal_argument_exception", "reason": "Rejecting mapping update to [ecommerce] as the final mapping would have more than 1 type: [product, goods]" } ], "type": "illegal_argument_exception", "reason": "Rejecting mapping update to [ecommerce] as the final mapping would have more than 1 type: [product, goods]" }, "status": 400 } ``` 此错误与您的问题完全相同,根本原因是同一个索引(`ecommerce`)中尝试同时存在`product`和`goods`两个类型。解决方法同上:统一类型或拆分索引。 ### 总结 解决Rejecting mapping update due to multiple types”错误的核心是**确保一个索引中只有一个文档类型**。您可以通过以下方式实现: - 统一使用`_doc`类型(推荐)。 - 重建索引(如果已有多个类型)。 - 拆分索引(适用于不同类型代表不同数据结构的场景)。 请根据您的数据结构和业务需求选择合适的方法。 §§相关问题§§ 1. 如何检查Elasticsearch索引的当前映射状态? 2. Elasticsearch批量索引操作的最佳实践有哪些? 3. 在Elasticsearch 7.x+中如何处理遗留的多类型数据迁移?</think>### 解决Elasticsearch映射更新报错:多类型冲突 #### 问题分析 您的Elasticsearch报错信息明确指出了问题核心: ```json { "error": { "type": "illegal_argument_exception", "reason": "Rejecting mapping update to [audit-2025.07.24] as the final mapping would have more than 1 type: [user_op_audit, doc]" }, "status": 400 } ``` 此错误源于Elasticsearch从6.x版本开始实施的**单一类型限制**(Single Type per Index)[^1]。在索引`audit-2025.07.24`中同时检测到两种类型:`user_op_audit`和`doc`,这违反了ES的核心设计原则。 #### 解决方案(逐步操作) ##### 1. **统一文档类型(推荐)** - **修改所有索引操作**,强制使用单一类型`_doc`(ES 7.x+标准类型): ```json // 批量请求示例 {"index": {"_index": "audit-2025.07.24", "_type": "_doc"}} {"user": "admin", "operation": "delete"} {"index": {"_index": "audit-2025.07.24", "_type": "_doc"}} {"document": "report.pdf", "status": "archived"} ``` - **代码调整示例**(Python): ```python from elasticsearch import helpers actions = [ {"_op_type": "index", "_index": "audit-2025.07.24", "_type": "_doc", "doc": {...}}, {"_op_type": "index", "_index": "audit-2025.07.24", "_type": "_doc", "doc": {...}} ] helpers.bulk(es, actions) ``` ##### 2. **拆分索引(适用于不同数据结构)** 如果`user_op_audit`和`doc`代表不同实体: - **创建专用索引**: ```bash # 用户操作审计索引 PUT /user_audit-2025.07.24 { "mappings": { "_doc": { "properties": { ... } } } } # 文档索引 PUT /doc_audit-2025.07.24 { "mappings": { "_doc": { "properties": { ... } } } } ``` - **修改数据路由**: ```json {"index": {"_index": "user_audit-2025.07.24", "_type": "_doc"}} {"user": "admin", "operation": "delete"} {"index": {"_index": "doc_audit-2025.07.24", "_type": "_doc"}} {"document": "report.pdf"} ``` ##### 3. **修复现有索引** 如果索引已存在多类型污染: - **步骤1:创建新索引** ```bash PUT /audit_fixed-2025.07.24 { "mappings": { "_doc": { "properties": { /* 统一定义字段 */ } } } } ``` - **步骤2:迁移数据** ```bash POST /_reindex { "source": {"index": "audit-2025.07.24"}, "dest": {"index": "audit_fixed-2025.07.24"} } ``` - **步骤3:切换别名(零停机)** ```bash POST /_aliases { "actions": [ {"remove": {"index": "audit-2025.07.24", "alias": "current_audit"}}, {"add": {"index": "audit_fixed-2025.07.24", "alias": "current_audit"}} ] } ``` #### 关键注意项 1. **版本兼容性**: - ES 6.x:允许但限制单索引单类型 - ES 7.x+:完全移除类型概念(隐式`_doc`类型) - 检查版本:`GET /` 查看`version.number` 2. **预防措施**: ```bash # 禁止自动创建类型(elasticsearch.yml) action.auto_create_index: false indices.mapping.single_type: true ``` 3. **批量操作优化**: - 批量大小控制在5-15MB - 使用`_bulk` API时确保JSON格式正确 - 启用重试机制处理429错误 > **重要**:生产环境操作前务必备份数据!可通过快照API备份:`PUT /_snapshot/my_backup/snapshot_1` #### 错误处理示例 当捕获到`IllegalArgumentException`时自动重试: ```java // Java示例(ES High Level Client) int retries = 3; while (retries-- > 0) { try { BulkResponse response = client.bulk(request); break; } catch (ElasticsearchException e) { if (e.status() == RestStatus.BAD_REQUEST && e.getMessage().contains("more than 1 type")) { fixMapping(); // 调用修复逻辑 Thread.sleep(1000); } } } ``` 通过以上步骤,您将彻底解决多类型导致的映射更新失败问题。索引结构规范化后,还能获得性能提升(单一类型索引的写入速度比多类型快约40%)[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值