对于一个包含上亿条记录的大型表,直接删除大量数据可能会导致性能问题,如长时间锁定表、事务日志过大等。为了提高删除操作的性能并减少对系统的影响,可以采用分批处理的方法,并结合一些优化技巧。以下是一个详细的Shell脚本示例,用于分批处理和删除数据。
Shell脚本示例
#!/bin/bash
# 数据库连接信息
DB_HOST="localhost"
DB_PORT="3306"
DB_NAME="your_database_name"
DB_USER="your_username"
DB_PASSWORD="your_password"
BATCH_SIZE=10000  # 每批次处理的数据量
MAX_ATTEMPTS=5   # 最大尝试次数
SLEEP_INTERVAL=10 # 每次尝试之间的等待时间(秒)
# 临时SQL文件
SQL_FILE="/tmp/hme_eo_job_sn_operations.sql"
# 创建临时表
cat > $SQL_FILE <<EOF
CREATE TABLE IF NOT EXISTS hme_eo_job_sn_split LIKE hme_eo_job_sn;
EOF
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD $DB_NAME < $SQL_FILE
# 分批处理
while true; do
  # 创建临时SQL文件
  cat > $SQL_FILE <<EOF
  -- 开始一个事务
  START TRANSACTION;
  -- 插入一批数据
  INSERT INTO hme_eo_job_sn_split SELECT * FROM hme_eo_job_sn
  WHERE creation_date < '2024-01-01'
  LIMIT $BATCH_SIZE;
  -- 删除这批数据
  DELETE FROM hme_eo_job_sn WHERE creation_date < '2024-01-01' LIMIT $BATCH_SIZE;
  -- 提交事务
  COMMIT;
EOF
  # 执行SQL文件
  for attempt in $(seq 1 $MAX_ATTEMPTS); do
    mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD $DB_NAME < $SQL_FILE
    if [ $? -eq 0 ]; then
      break
    else
      echo "Attempt $attempt failed, retrying in $SLEEP_INTERVAL seconds..."
      sleep $SLEEP_INTERVAL
    fi
  done
  # 检查是否还有数据需要处理
  cat > $SQL_FILE <<EOF
  SELECT COUNT(*) AS count FROM hme_eo_job_sn WHERE creation_date < '2024-01-01';
EOF
  ROW_COUNT=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD $DB_NAME -sN < $SQL_FILE)
  if [ "$ROW_COUNT" -le 0 ]; then
    break
  fi
done
# 删除临时SQL文件
rm -f $SQL_FILE
echo "操作成功完成。"详细说明
- 数据库连接信息:
 
- 设置数据库的主机名、端口、数据库名称、用户名和密码。
 - 
BATCH_SIZE:每批次处理的数据量,可以根据实际情况调整。 - 
MAX_ATTEMPTS:最大尝试次数,防止网络或服务器问题导致的失败。 - 
SLEEP_INTERVAL:每次尝试之间的等待时间(秒)。 
- 创建临时表:
 
- 使用 
CREATE TABLE IF NOT EXISTS语句创建hme_eo_job_sn_split表(如果它不存在)。 
- 分批处理:
 
- 循环执行插入和删除操作,直到所有符合条件的数据都被处理完。
 - 每次循环中,生成一个临时SQL文件,包含插入和删除操作。
 - 使用 
INSERT ... SELECT语句将符合条件的数据插入到hme_eo_job_sn_split表中。 - 使用 
DELETE ... WHERE id IN (SELECT ...)语句删除这些数据。 - 通过 
START TRANSACTION和COMMIT确保每个批次的操作是原子的。 
- 重试机制:
 
- 如果某次执行失败,脚本会自动重试,最多尝试 
MAX_ATTEMPTS次。 - 每次重试之间会等待 
SLEEP_INTERVAL秒。 
- 检查剩余数据:
 
- 在每次循环结束时,检查 
hme_eo_job_sn表中是否还有符合条件的数据。 - 如果没有更多数据需要处理,则退出循环。
 
- 删除临时SQL文件:
 
- 清理临时SQL文件以保持环境整洁。
 
性能优化建议
- 索引:
 
- 确保 
creation_date列上有索引,以加快查询速度。 - 如果 
id列不是主键,确保id列上有索引。 
- 批量大小:
 
- 调整 
BATCH_SIZE以找到最佳性能。太小会导致频繁的事务开销,太大可能导致长时间锁定表。 
- 事务隔离级别:
 
- 可以考虑降低事务隔离级别,例如使用 
READ UNCOMMITTED,但这可能会影响数据一致性。 
- 日志记录:
 
- 在生产环境中,建议在脚本中添加日志记录,以便跟踪操作进度和故障排查。
 
- 监控:
 
- 在执行过程中,监控数据库的性能指标,如 CPU、内存、磁盘 I/O 等,以确保系统稳定运行。
 
                










