Mastodon
  • 什么是 Mastodon?
  • 使用 Mastodon
    • 注册帐户
    • 设置你的个人资料
    • 在你的账户发布内容
    • 使用网络功能
    • 处理不想看到的内容
    • 推广你和他人
    • 进行偏好设置
    • 更多设置
    • 在站点外使用 Mastodon
    • 迁移或离开账户
    • 运行你自己的站点
  • 运营 Mastodon
    • 准备你的服务器
    • 从源代码安装
    • 配置你的环境
    • 安装可选功能
      • 对象存储
      • 洋葱服务
      • 验证码
      • 单点登录
    • 配置全文搜索
    • 设置你的新实例
    • 使用管理 CLI
    • 升级到新版本
    • 备份你的服务器
    • 迁移到新机器
    • 扩大你的站点规模
    • 审核操作
    • 故障排除
      • 数据库索引损坏
    • 用户组
  • 开发 Mastodon 应用
    • API 入门指南
    • 使用公开数据
    • 获取客户端应用访问权限
    • 使用帐户登录
    • 库与实现
  • 向 Mastodon 项目做贡献
    • 技术概览
    • 设置开发环境
    • 代码结构
    • 路由
    • 漏洞赏金与责任披露
  • 遵循的标准
    • ActivityPub
    • WebFinger
    • 安全性
    • Microformats
    • OAuth
    • Bearcaps
  • REST API
    • Datetime 格式
    • 指南与最佳实践
    • OAuth 令牌
    • OAuth 作用域
    • 速率限制
  • API 方法
    • apps
      • oauth
      • emails
    • accounts
      • bookmarks
      • favourites
      • mutes
      • blocks
      • domain_blocks
      • filters
      • reports
      • follow_requests
      • endorsements
      • featured_tags
      • preferences
      • followed_tags
      • suggestions
      • tags
    • profile
    • statuses
      • media
      • polls
      • scheduled_statuses
    • timelines
      • conversations
      • lists
      • markers
      • streaming
    • grouped notifications
    • notifications
      • push
    • search
    • instance
      • trends
      • directory
      • custom_emojis
      • announcements
    • admin
      • accounts
      • canonical_email_blocks
      • dimensions
      • domain_allows
      • domain_blocks
      • email_domain_blocks
      • ip_blocks
      • measures
      • reports
      • retention
      • trends
    • proofs
    • oembed
  • API 实体
    • Account
    • AccountWarning
    • Admin::Account
    • Admin::CanonicalEmailBlock
    • Admin::Cohort
    • Admin::Dimension
    • Admin::DomainAllow
    • Admin::DomainBlock
    • Admin::EmailDomainBlock
    • Admin::Ip
    • Admin::IpBlock
    • Admin::Measure
    • Admin::Report
    • Announcement
    • Appeal
    • Application
    • Context
    • Conversation
    • CustomEmoji
    • DomainBlock
    • Error
    • ExtendedDescription
    • FamiliarFollowers
    • FeaturedTag
    • Filter
    • FilterKeyword
    • FilterResult
    • FilterStatus
    • IdentityProof
    • Instance
    • List
    • Marker
    • MediaAttachment
    • Notification
    • NotificationPolicy
    • NotificationRequest
    • Poll
    • Preferences
    • PreviewCard
    • PreviewCardAuthor
    • PrivacyPolicy
    • Reaction
    • Relationship
    • RelationshipSeveranceEvent
    • Report
    • Role
    • Rule
    • ScheduledStatus
    • Search
    • Status
    • StatusEdit
    • StatusSource
    • Suggestion
    • Tag
    • TermsOfService
    • Token
    • Translation
    • V1::Filter
    • V1::Instance
    • V1::NotificationPolicy
    • WebPushSubscription

数据库索引损坏

如何从数据库索引损坏中恢复。

    • 语言数据与排序规则
    • 我是否受到这个问题的影响?
    • 修复问题
    • 避免问题

一个比较常见的配置问题可能导致整个数据库的索引损坏。本页尝试解释为什么会发生这种情况以及如何修复它。

语言数据与排序规则

数据库中的文本值,如用户名或状态标识符,使用所谓的排序规则进行比较,这些规则定义了字符的排序方式和大小写转换方式。 在设置数据库时,Mastodon 会使用数据库服务器的默认语言设置,包括默认排序规则,这通常由操作系统的设置决定。

不幸的是,在2018年末,一次 glibc 更新改变了许多区域设置的排序规则,这意味着使用受影响的语言设置的数据库现在会以不同方式排序文本值。 由于数据库索引依赖于它们所索引的值的排序的算法结构,一些索引可能会变得不一致。

更多信息:https://wiki.postgresql.org/wiki/Locale_data_changes https://postgresql.verite.pro/blog/2018/08/27/glibc-upgrade.html

我是否受到这个问题的影响?

如果你的数据库未使用 C 或 POSIX 作为其排序规则(你可以通过 SELECT datcollate FROM pg_database WHERE datname = current_database(); 检查), 并且你曾经使用过 glibc 2.28 之前的版本,并且在更新到 glibc 2.28 或更新版本后没有立即重新索引你的数据库,那么你的索引可能不一致。

你可能是因为 PgHero 警告"重复索引"而找到此页面的。虽然这类警告有时可能表明部署或更新 Mastodon 时出现问题,但它们与数据库索引损坏无关,也不表明数据库存在任何功能问题。

你可以使用 PostgreSQL 的 amcheck 模块检查你的索引是否一致:作为数据库服务器的超级用户,连接到你的 Mastodon 数据库并执行以下命令(这可能需要一段时间):

CREATE EXTENSION IF NOT EXISTS amcheck;
SELECT bt_index_check(c.oid)
FROM pg_index i
JOIN pg_class c ON i.indexrelid = c.oid
WHERE c.relname IN ('index_account_domain_blocks_on_account_id_and_domain',
  'index_account_proofs_on_account_and_provider_and_username',
  'index_accounts_on_username_and_domain_lower', 'index_accounts_on_uri',
  'index_accounts_on_url', 'index_conversations_on_uri',
  'index_custom_emoji_categories_on_name',
  'index_custom_emojis_on_shortcode_and_domain',
  'index_devices_on_access_token_id', 'index_domain_allows_on_domain',
  'index_domain_blocks_on_domain', 'index_email_domain_blocks_on_domain',
  'index_invites_on_code', 'index_markers_on_user_id_and_timeline',
  'index_media_attachments_on_shortcode', 'index_preview_cards_on_url',
  'index_statuses_on_uri', 'index_tags_on_name_lower',
  'index_tombstones_on_uri', 'index_unavailable_domains_on_domain',
  'index_users_on_email', 'index_webauthn_credentials_on_external_id'
);

如果出现错误,则你的数据库已损坏,需要修复。如果没有错误,你可能需要执行更复杂的检查以确保。 与之前的检查不同,这些更复杂的检查在运行时会锁表,从而影响实例的可用性。

CREATE EXTENSION IF NOT EXISTS amcheck;
SELECT bt_index_parent_check(c.oid)
FROM pg_index i
JOIN pg_class c ON i.indexrelid = c.oid
WHERE c.relname IN ('index_account_domain_blocks_on_account_id_and_domain',
  'index_account_proofs_on_account_and_provider_and_username',
  'index_accounts_on_username_and_domain_lower', 'index_accounts_on_uri',
  'index_accounts_on_url', 'index_conversations_on_uri',
  'index_custom_emoji_categories_on_name',
  'index_custom_emojis_on_shortcode_and_domain',
  'index_devices_on_access_token_id', 'index_domain_allows_on_domain',
  'index_domain_blocks_on_domain', 'index_email_domain_blocks_on_domain',
  'index_invites_on_code', 'index_markers_on_user_id_and_timeline',
  'index_media_attachments_on_shortcode', 'index_preview_cards_on_url',
  'index_statuses_on_uri', 'index_tags_on_name_lower',
  'index_tombstones_on_uri', 'index_unavailable_domains_on_domain',
  'index_users_on_email', 'index_webauthn_credentials_on_external_id'
);

如果执行成功,没有返回错误,你的数据库应该是一致的,你可以安全地忽略 Mastodon 在运行 db:migrate 时发出的警告。

修复问题

如果你受到影响但不采取行动,随着时间推移,你的数据库可能会变得越来越不一致。因此,尽快修复这个问题非常重要。

Mastodon 3.2.2 及更高版本附带了一个半交互式脚本,以尽可能良好的方式修复这些损坏。如果你使用的是早期版本,请先更新到 3.2.2。由于这些损坏的存在,可能在运行数据库迁移到 3.2.2 时会失败,但数据库应该会变成一个可以被 Mastodon 3.2.2 附带的维护工具恢复的状态。

在尝试修复数据库之前,停止 Mastodon 并备份你的数据库。然后,在Mastodon 仍处于停止状态的情况下,运行维护脚本:

RAILS_ENV=production bin/tootctl maintenance fix-duplicates

该脚本将遍历数据库以自动查找重复项并修复它们。在某些情况下,这些操作是破坏性的。在最具破坏性的情况下,你将被要求选择要保留的记录和要丢弃的记录。在所有情况下,搜索整个数据库中的重复项是一项极其耗时的操作。

在某些情况下,重复记录可能有无法调和的冲突(例如两个不同的本站用户共享相同的用户名)。在这些情况下,去重操作可能是部分破坏性的,你将被询问哪些记录保持不变,哪些记录将被更改。 因此,此脚本是半交互式的。在所有情况下,搜索整个数据库中的重复项是一项极其耗时的操作。
由于维护脚本将暂时移除索引, Mastodon 必须在整个过程中完全停止,以防止出现其他重复项。

避免问题

要避免这个问题,请在任何 libc 更新后立即重新索引你的数据库。 SQL 命令 REINDEX 或 reindexdb 命令行工具 可能对此有用。

翻译状态: 本文是英文页面 Database index corruption 的翻译,最后翻译时间:2025-04-21,点击这里可以查看翻译后页面的改动。

最后更新于 April 21, 2025 · 改进此页面
也可在此找到: English

赞助商

Dotcom-Monitor LoadView Stephen Tures Swayable SponsorMotion

加入Mastodon · 博客 ·

查看源代码 · CC BY-SA 4.0 · 版权信息