Backup and Recovery, Security, and Operations

Operations are key to MongoDB production deployments—mastering backups, security, and monitoring can prevent 90% of production incidents.

1. What You'll Learn


100%
graph TB
    subgraph "Backup Strategy"
        A1[Daily Full Backup<br/>mongodump] --> S3[(S3/OSS<br/>Object Storage)]
        A2[oplog Continuous<br/>Incremental] --> S3
        A3[Atlas PITR<br/>Point-in-Time Recovery] --> S3
    end

    subgraph "Restore Scene"
        R1[Accidental Data Deletion] --> R2[mongorestore]
        R3[Entire database lost] --> R2
        R4[A specific point in time] --> R5[oplogReplay]
        R2 --> R6[✅ Data Recovery]
        R5 --> R6
    end

    style R6 fill:#d4edda

2. mongodump Logical Backup

Concept Explanation: mongodump is MongoDB’s official logical backup tool—it reads collection data and exports it to BSON/JSON files. A logical backup “exports data” rather than “copying files,” so it can be restored across versions and platforms, but backing up large databases is relatively slow.

How It Works: mongodump connects to MongoDB, reads data collection by collection and document by document, serializes it into BSON format, and writes it to disk. It supports gzip compression, conditional filtering, and including the oplog (for PITR). Collections are not locked during the backup (hot backup), but backing up large collections may impact performance.

Logical Backup vs. Physical Backup:

Dimension Logical Backup (mongodump) Physical Backup (File Copy)
Implementation Read data → Serialize → Write to file Copy the data file directly
Speed Slow (requires reading + serialization) Fast (file-level copy)
Cross-version ✅ Supported ❌ Tied to a specific engine version
Selectivity ✅ By database/collection/conditions ❌ Full
Size Small (compressed) Large (original file)
Consistency Single-set consistency Requires locks or replica set snapshots
Recovery Granularity Flexible (database/collection/document) Entire database

RPO/RTO Concepts:

Concept Meaning Example
RPO (Recovery Point Objective) Maximum acceptable data loss RPO=1h = Up to 1 hour of data loss
RTO (Recovery Time Objective) Maximum acceptable recovery time RTO=4h = Service must be restored within 4 hours
BASH
# === Back up the entire database ===
mongodump --uri="mongodb://localhost:27017/shopdb" --out=/backup/2026-07-01

# === Back Up a Specified Set ===
mongodump --uri="mongodb://localhost:27017/shopdb" --collection=users --out=/backup/users

# === Compressed Backup ===
mongodump --uri="mongodb://localhost:27017" --gzip --archive=/backup/shopdb.gz

# === Back up metadata only ===
mongodump --uri="mongodb://localhost:27017" --db=shopdb --collection=users --query='{"role":"admin"}'

Key mongodump Parameters:

Parameter Description Example
--uri Connection String mongodb://user:pass@host:port/db
--out Output Directory /backup/2026-07-01
--gzip gzip compression Reduces file size by 60–80%
--archive Single-file archive --archive=backup.gz
--oplog Includes oplog (PITR required) --oplog
--collection Specified Set --collection=users
--query Condition Filter --query='{"role":"admin"}'

3. mongorestore Recovery

Concept Overview: mongorestore is the counterpart to mongodump—it imports BSON/JSON backup files into MongoDB. It supports full restore, selective restore, PITR (point-in-time restore), and other modes.

How It Works: mongorestore reads from a backup directory or archive file and inserts documents one collection at a time. The --drop option first deletes existing collections and then restores them (overwrite mode). When used in conjunction with --oplogReplay, it replays the oplog to perform point-in-time recovery.

Recovery Mode Comparison:

Mode Command Options Use Cases
Full Restore mongorestore /backup/db Restore the entire database to the backup point in time
Overwrite and Restore --drop Restore After Clearing (Test Environment)
Selective Recovery --nsInclude Recover Only Specific Sets
PITR Recovery --oplogReplay Restore to a Specific Point in Time
Restore from Compressed Archive --gzip --archive=file.gz Restore from Compressed Archive
BASH
# === Restore the entire backup ===
mongorestore --uri="mongodb://localhost:27017" /backup/2026-07-01

# === Restore a Specified Database ===
mongorestore --uri="mongodb://localhost:27017" /backup/2026-07-01/shopdb

# === Restore gzip Compressed Backup ===
mongorestore --uri="mongodb://localhost:27017" --gzip --archive=/backup/shopdb.gz

# === Restore and overwrite existing data ===
mongorestore --uri="mongodb://localhost:27017" --drop /backup/2026-07-01

Key Points Analysis:

  1. --drop This will first delete the collection and then restore it; use with caution in production environments (new data added after the backup may be lost).
  2. Inserting data into mongorestore triggers index rebuilding, which slows down the restoration of large collections.
  3. When restoring to an existing database, a _id conflict will cause duplicate documents to be skipped; use --drop to avoid this conflict.

4. Backup Strategy

Concept Explanation: Backup strategies are at the core of operations and maintenance—they determine the RPO (maximum data loss) and RTO (maximum recovery time). Different business scenarios require different backup frequencies, retention policies, and recovery plans.

Comparison of Backup Strategies:

Strategy Frequency Retention RPO RTO Applicability Cost
Full Daily Backup Early morning every day 7–30 days 24 hours Several hours Small databases Low
Incremental per hour Per hour 24–48 hours 1 hour Several hours Medium-sized database Medium
oplog Persistence Real-time 7 days < 1 s Minute-level Large databases High
Atlas PITR Automatic 35 days Seconds Minutes Atlas Cloud Service Pay-as-you-go
File Snapshots On-demand 7–30 days Snapshot frequency Minute-level LVM/EBS support Low

Backup Strategy Selection Process:

100%
graph TB
    A{Business Type?} -->|Non-critical<br/>Log/Cache| B[Daily Total<br/>RPO=24h]
    A -->|General Business<br/>User/Order| C{Data volume?}
    A -->|Core Business<br/>Finance/Payment| D[oplogContinuous<br/>RPO<1s]
    C -->|< 100GB| E[Daily Total+<br/>oplog PITR]
    C -->|> 100GB| F[File Snapshot+<br/>oplogContinuous]

    style D fill:#d4edda
    style B fill:#fff3cd

PITR (Point-In-Time Recovery) Principle: First, restore the full backup, then replay the oplog entries from the backup time to the target point in time, thereby achieving point-in-time recovery accurate to the second.

100%
sequenceDiagram
    participant Full as Full Backup
    participant Oplog as oplog Incremental
    participant Target as Target Date

    Note over Full: Backup Time T0
    Full->>Oplog: RestoreT0Full Data Set

    Note over Oplog: T0 → T1 betweenoplog

    loop Replayoplog
        Oplog->>Target: Replay write operations one by one
    end

    Note over Target: Restore to a Specific Point in Time T1
Strategy Frequency Retention Applicability
Daily Full Backup Every morning 7–30 days Small databases
Hourly Increment Per hour 24–48 hours Medium-sized database
Oplog Persistence Real-time 7 days Large databases (based on replica set oplog)
Atlas PITR Automatic 35 days Atlas Cloud Service

▶ Example 1: Hands-On PITR Point-in-Time Recovery

BASH
# ShopHub Accidentally deleted 2026-07-01 10:00-10:30 Order Data,Need to revert to 10:00 Status

# 1. Restore the full backup from the previous day
mongorestore --uri="mongodb://localhost:27017/shopdb_recovery" --drop /backup/2026-06-30/shopdb

# 2. Replay oplog By the target date
mongorestore --uri="mongodb://localhost:27017/shopdb_recovery" --oplogReplay --oplogLimit=1750604400 /backup/2026-06-30/oplog.bson

# 3. Verify the restored data
mongosh --port 27017 shopdb_recovery --eval 'db.orders.count()'

# 4. Export the recovered data and import it into the production environment
mongodump --uri="mongodb://localhost:27017/shopdb_recovery" --collection=orders --query='{"createdAt":{"$gte":{"$date":"2026-07-01T10:00:00Z"},"$lt":{"$date":"2026-07-01T10:30:00Z"}}}' --out=/recovery/orders
mongorestore --uri="mongodb://localhost:27017/shopdb" /recovery/orders

5. Users and Authentication

Concept Overview: Security is the first line of defense for MongoDB in production deployments. SCRAM (Salted Challenge Response Authentication Mechanism) is MongoDB’s default authentication mechanism, while RBAC (Role-Based Access Control) controls permissions based on roles. The principle of least privilege is central to security—each user is granted only the minimum privileges necessary to perform their tasks.

How SCRAM Authentication Works: The client sends a username, and the server returns a random salt and the number of iterations. The client performs multiple hash operations using the password and the salt to generate a proof, and the server verifies whether the proof matches the stored hash. The password is never transmitted in plain text over the network.

100%
sequenceDiagram
    participant C as Client
    participant S as MongoDBServer

    C->>S: 1. Username
    S-->>C: 2. salt + iterationCount + storedKey
    C->>C: 3. password + salt → PBKDF2 → clientKey → storedKey
    C->>S: 4. clientProof(Digital Signature)
    S->>S: 5. Verification clientProof
    S-->>C: 6. Authentication Successful ✅ / Failure ❌

    Note over C,S: Passwords are never transmitted over the network

RBAC Permission Model:

Level Description
User An authenticated entity that holds one or more roles
Role A set of permissions that can inherit from other roles
Privilege Combination of Resource and Action
Resource Database/Collection/Cluster Level

(1) SCRAM Certification

JAVASCRIPT
// === Create an Administrator User ===
db.createUser({
  user: 'admin',
  pwd: 'SecurePass123!',
  roles: [
    { role: 'userAdminAnyDatabase', db: 'admin' },
    { role: 'readWriteAnyDatabase', db: 'admin' }
  ]
});

// === Create an Application User ===
db.createUser({
  user: 'app_user',
  pwd: 'AppPass456!',
  roles: [{ role: 'readWrite', db: 'shopdb' }]
});

// === Enable Authentication(mongod Startup Parameters)===
mongod --auth --bind_ip_all

(2) RBAC Roles

Built-in Role Permissions Applicable Users
read Read All Collections Analyst
readWrite Read and write all sets Application
dbAdmin Database Administration DBA
userAdmin User Management DBA
dbOwner All of the above permissions Person in Charge
readAnyDatabase Read All Databases Cross-Database Analyst
readWriteAnyDatabase Read and write to all databases Cross-database applications
userAdminAnyDatabase Manage all database users Super DBA
dbAdminAnyDatabase Manage All Databases Super DBA
backup Backup Permissions Backup Scripts
restore Restore Permissions Restore Script
root Superuser Emergency Maintenance

Principle of Least Privilege:

User Recommended Role Description
Application User readWrite (Single Database) Read/write access to the business database only
Backup User backup + readAnyDatabase Minimum Permissions Required for Backup
User Analysis read (Single Database) Read-Only Permissions
DBA userAdmin + dbAdmin Administrative privileges, not superuser
JAVASCRIPT
// === Custom Characters ===
db.createRole({
  role: 'orderManager',
  privileges: [
    { resource: { db: 'shopdb', collection: 'orders' }, actions: ['find', 'insert', 'update'] },
    { resource: { db: 'shopdb', collection: 'products' }, actions: ['find'] }
  ],
  roles: []
});

// === Authorization ===
db.grantRolesToUser('app_user', [{ role: 'orderManager', db: 'shopdb' }]);

▶ Example 2: Least Privilege RBAC Configuration

JAVASCRIPT
// TechCorp:Assign the minimum necessary permissions to different teams
// 1. Application Service Account(Read-write only shopdb)
db.createUser({
  user: 'app_service',
  pwd: 'AppSecurePass!',
  roles: [{ role: 'readWrite', db: 'shopdb' }]
});

// 2. Backup Service Account(Backup-only permissions)
db.createUser({
  user: 'backup_service',
  pwd: 'BackupSecurePass!',
  roles: [
    { role: 'backup', db: 'admin' },
    { role: 'readAnyDatabase', db: 'admin' }
  ]
});

// 3. Data Analytics Team(Read-only + Specific Set)
db.createRole({
  role: 'analyticsReader',
  privileges: [
    { resource: { db: 'shopdb', collection: 'orders' }, actions: ['find'] },
    { resource: { db: 'shopdb', collection: 'products' }, actions: ['find'] }
  ],
  roles: []
});
db.createUser({
  user: 'analyst',
  pwd: 'AnalystPass!',
  roles: [{ role: 'analyticsReader', db: 'shopdb' }]
});

// 4. Verify Permissions
db.auth('analyst', 'AnalystPass!');
db.orders.find({}); // ✅ Can be read
db.orders.insertOne({}); // ❌ Insufficient permissions

  1. TLS/SSL Encryption

Concept Explanation: TLS/SSL encryption secures MongoDB network communications—preventing man-in-the-middle attacks, data eavesdropping, and tampering. TLS must be enabled in production environments, especially for cross-datacenter or cross-cloud communications.

How It Works: TLS verifies the server's identity using certificates and establishes an encrypted connection. MongoDB supports X.509 certificate authentication (as an alternative to SCRAM), and mutual TLS (mTLS) verifies the identities of both the client and the server.

Encryption Levels:

Level Encryption Method Scope of Protection
Transport Layer TLS/SSL Network Communication (Client ↔ Server, Between Nodes)
Storage Layer WiredTiger Encryption Data Files (Static Encryption)
Field Level Application-Level Encryption Sensitive Fields (e.g., passwords, ID numbers)
BASH
# === Start mongod with SSL ===
mongod --tlsMode requireTLS --tlsCertificateKeyFile /etc/ssl/mongodb.pem

# === Client Connection ===
mongosh "mongodb://localhost:27017/shopdb?ssl=true&sslCertificateKeyFile=/etc/ssl/client.pem"

TLS Configuration Parameters:

Parameter Description Recommended Value
--tlsMode TLS Mode requireTLS (Production)
--tlsCertificateKeyFile Server Certificate + Private Key PEM Format
--tlsCAFile CA Certificate Used to verify client certificates
--tlsAllowInvalidCertificates Allow invalid certificates ❌ Disabled in production

Key Points Analysis:

  1. Self-hosted clusters can use self-signed certificates; TLS is enabled by default in Atlas.
  2. mTLS (Mutual TLS) enables certificate-based authentication as an alternative to password-based authentication.
  3. TLS increases connection latency by about 5–10%, but it is essential for data security.

7. Operations and Monitoring

Concept Explanation: Operations monitoring serves as a "health dashboard" for MongoDB production deployments—using tools such as serverStatus, dbStats, and slow query analysis to monitor database health in real time and promptly detect and prevent issues.

Monitoring System:

Monitoring Level Tool Key Metrics
Instance Level serverStatus() Connection Count, Operation Count, Memory
Database Level db.stats() Data Volume, Number of Indexes, Number of Sets
Collection Level collStats() Number of Documents, Size, Indexing Efficiency
Query Level Profiler / Explain Slow Queries, Execution Plans
Index Level $indexStats Index Usage

(1) serverStatus

Key Metrics:

Metric Description Healthy Range Alert Threshold
connections.current Current number of connections < 1000 > 8000
connections.available Number of available connections > 50,000 < 1,000
opcounters.query Queries per Second Baseline 10x Spike
opcounters.insert Operations per Second Baseline 10x Increase
mem.resident Memory in Use (MB) < 80% of Total Memory > 95% of Total Memory
uptime Runtime (seconds) > 86,400 < 3,600 (frequent restarts)
JAVASCRIPT
db.serverStatus();
// {
//   host: 'mongo1',
//   version: '7.0.5',
//   process: 'mongod',
//   uptime: 864000,
//   connections: { current: 150, available: 83860 },
//   opcounters: {
//     insert: 1234567,
//     query: 9876543,
//     update: 234567,
//     delete: 12345
//   },
//   mem: { resident: 1024, virtual: 4096 },
//   ...
// }

(2) Database Statistics

JAVASCRIPT
db.stats();
// {
//   db: 'shopdb',
//   collections: 10,
//   objects: 1000000,
//   dataSize: 524288000,
//   storageSize: 268435456,
//   indexes: 20,
//   indexSize: 52428800
// }

(3) Slow Query Analysis

Concept Explanation: Slow queries are the primary indicator of MongoDB performance issues. The standard process for performance optimization involves using the Profiler to log queries that exceed a certain threshold and then analyzing their execution plans and index usage.

Profiling Level Description Performance Impact
0 Close None
1 Slow queries only Very low
2 Log all operations Medium (for debugging only)
JAVASCRIPT
// === Enable the slow query log(>100ms)===
db.setProfilingLevel(2, { slowms: 100 });

// === View Slow Queries ===
db.system.profile.find({ millis: { $gt: 100 } })
  .sort({ ts: -1 })
  .limit(10);

(4) Index Usage Statistics

JAVASCRIPT
db.products.aggregate([{ $indexStats: {} }]);
// Identify unused indexes

Recommendations for Monitoring Alert Configuration:

Alert Item Threshold Notification Method
Number of connections > 80% of maximum current > 64,000 Email + SMS
Slow queries > 10/min Lasting 5 minutes Slack
Memory > 90% Resident > 90% of total memory Email
Disk > 85% storageSize > 85% Disk Email + Text Messages
Copy delay > 10s optimeDate deviation Email

8. Common Operations and Maintenance Commands

Concept Overview: Daily operations and maintenance involve handling current operations, long-running transactions, index maintenance, collection compaction, and other issues. MongoDB provides a set of operational commands to help DBAs quickly diagnose and resolve production issues.

Quick Reference for Operations and Maintenance Commands:

Scenario Command Description
View Current Operations db.currentOp() Find Long Queries/Deadlocks
Kill Operation db.killOp(opId) Terminate Problem Operation
Compress Set db.runCommand({compact:'col'}) Reclaim Fragmented Space
Rebuild Index db.col.reIndex() Fix Index Fragmentation
View Connections db.serverStatus().connections Connection Count
Switch Logs db.adminCommand({logRotate:1}) Log Rotation
Force Sync rs.syncFrom('host:port') Specify Sync Source
JAVASCRIPT
// === Current Operation ===
db.currentOp({ "op": "query" });

// === Kill a process ===
db.killOp(opId);

// === Compressed Sets ===
db.runCommand({ compact: 'products' });

// === Rebuild Index ===
db.products.reIndex();

// === View Link ===
db.serverStatus().connections;

Operations and Maintenance Guidelines:

Operation Lock Type Risk of Blocking Recommendation
compact Exclusive Lock High Execute During Maintenance Window
reIndex Exclusive Lock High Execute During Maintenance Window
killOp Unlocked None Can be executed at any time
currentOp Unlocked None Can be executed at any time
logRotate Unlocked None Can be executed at any time

Emergency Troubleshooting Procedure:

  1. db.currentOp() Found a long operation
  2. db.killOp(opId) Kill the problematic operation
  3. db.serverStatus().connections Check the number of connections
  4. If the number of connections reaches capacity, consider temporarily reducing the application's connection pool size.
  5. Use Profiler to analyze the root cause afterward, and add indexes or optimize queries

▶ Example: Complete Backup Policy + RBAC Security Configuration

BASH
# === 1. Daily Automatic Backup Script(backup-daily.sh)===
#!/bin/bash
set -e

DATE=$(date +%Y%m%d)
BACKUP_DIR=/backup/mongodb/$DATE
RETENTION_DAYS=7

# 1.1 Full Backup(gzip Compression)
mongodump   --uri="mongodb://backup_user:SecurePass@mongo1:27017,mongo2:27017,mongo3:27017/shopdb?replicaSet=rs0"   --gzip   --archive=$BACKUP_DIR.gz   --oplog  # Includes oplog,Support PITR

# 1.2 Upload to S3
aws s3 cp $BACKUP_DIR.gz s3://my-bucket/mongodb-backups/$DATE/

# 1.3 Cleanup 7 Local backup from X days ago
find /backup/mongodb/ -name "*.gz" -mtime +$RETENTION_DAYS -delete

# 1.4 Record Backup Logs
echo "[$(date)] Backup completed: $BACKUP_DIR.gz ($(du -h $BACKUP_DIR.gz | cut -f1))" >> /var/log/mongodb-backup.log

# 1.5 Add to crontab (Daily at 2 AM)
# 0 2 * * * /usr/local/bin/backup-daily.sh

# === 2. Recovery Drill ===
# 2.1 View Available Backups
ls -lh /backup/mongodb/

# 2.2 Restore to the test environment
mongorestore   --uri="mongodb://localhost:27017/shopdb_test"   --gzip   --archive=/backup/mongodb/20260701.gz   --drop  # Overwrite existing data

# 2.3 PITR Restore to a Specific Point in Time
mongorestore   --uri="mongodb://localhost:27017"   --gzip   --archive=/backup/mongodb/20260701.gz   --oplogReplay   --pointInTime=2026-07-01T10:30:00
JAVASCRIPT
// === 3. Enable Authentication + Create RBAC User ===
// 3.1 Create an Administrator User(The first must)
db.createUser({
  user: 'root',
  pwd: 'RootSecurePass!',
  roles: [{ role: 'root', db: 'admin' }]
});

// 3.2 Create a User Dedicated to Backups(Least Privilege)
db.createUser({
  user: 'backup_user',
  pwd: 'BackupPass!',
  roles: [
    { role: 'backup', db: 'admin' },
    { role: 'readAnyDatabase', db: 'admin' }
  ]
});

// 3.3 Create an Application User(Reading and Writing shopdb)
db.createUser({
  user: 'app_user',
  pwd: 'AppPass!',
  roles: [{ role: 'readWrite', db: 'shopdb' }]
});

// 3.4 Create a read-only analysis user
db.createUser({
  user: 'analytics_user',
  pwd: 'AnalyticsPass!',
  roles: [{ role: 'read', db: 'shopdb' }]
});

// 3.5 Enable TLS/SSL(mongod Startup Parameters)
// mongod --tlsMode requireTLS --tlsCertificateKeyFile /etc/ssl/mongodb.pem --auth

// === 4. Monitoring Alerts ===
// Enable the slow query log
db.setProfilingLevel(2, { slowms: 100 });

// View Slow Queries Top 10
db.system.profile.find({ millis: { $gt: 100 } })
  .sort({ ts: -1 })
  .limit(10)
  .forEach(p => print(`[${p.ts}] ${p.command.find}: ${p.millis}ms`));

// Monitor Connection Count
const stats = db.serverStatus();
print(`Active connections: ${stats.connections.current}/${stats.connections.available}`);
// Alert Thresholds:current > 1000 → Email Alerts

// === 5. Automated Inspection Script ===
function dailyHealthCheck() {
  print('=== MongoDB Daily Health Check ===');

  // 5.1 Dungeon Collection Status
  const rsStatus = rs.status();
  const primary = rsStatus.members.find(m => m.stateStr === 'PRIMARY');
  print(`Primary: ${primary.name}`);

  // 5.2 oplog Window(Avoid Overwriting)
  const oplogWindow = primary.optimeDate ? (Date.now() - primary.optimeDate.getTime()) / 1000 : 0;
  print(`Oplog window: ${Math.floor(oplogWindow / 3600)} hours`);
  if (oplogWindow > 24 * 3600) print('⚠️  WARNING: oplog window > 24h');

  // 5.3 Index Usage Rate
  const indexes = db.products.aggregate([{ $indexStats: {} }]).toArray();
  const unused = indexes.filter(i => i.accesses.ops === 0);
  print(`Unused indexes: ${unused.length}`);
  if (unused.length > 0) {
    unused.forEach(i => print(`  - ${i.name}`));
  }
}

dailyHealthCheck();

Output: Automatic daily backups with 7-day retention; three-tier RBAC user access control; monitoring and alerts for timely detection of performance issues.

❓ FAQ

Q Is mongodump a hot backup?
A Yes, mongodump does not require service downtime. However, backing up large collections may impact performance, so it is recommended to run it during off-peak hours.
Q Does RBAC affect performance?
A There is virtually no impact. RBAC checks permissions in memory.
Q How is production monitored?
A Use MongoDB Atlas (which includes built-in monitoring) or Prometheus + mongo_exporter (self-hosted).

📖 Summary


📝 Exercises

  1. Basic Exercise (⭐): Back up the shopdb database using mongodump, then restore it using mongorestore.
  2. Basic Exercise (⭐): Create the admin and app_user users and grant them permissions.
  3. Advanced Exercise (⭐⭐): Implement a daily backup script (cron + mongodump + compression + delete data older than 7 days).
  4. Advanced Exercise (⭐⭐): Enable slow query analysis and identify the top 10 slow queries.
  5. Challenge (⭐⭐⭐): Complete operations and maintenance plan (backup script + user permissions + TLS + monitoring and alerts).
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏