fix: 优化 MySQL 重试机制,增加可重试错误类型并改进日志记录
This commit is contained in:
parent
6c49ef042e
commit
0e7804451b
40
DB.py
40
DB.py
@ -92,34 +92,44 @@ video_author = Table(
|
||||
)
|
||||
|
||||
|
||||
def mysql_retry(max_retries: int = 3, base_delay: float = 2.0):
|
||||
"""
|
||||
装饰器:捕获断线异常(InterfaceError 或 OperationalError: 2013)后尝试重连,指数回退重试。
|
||||
"""
|
||||
def mysql_retry(max_retries: int = 3, base_delay: float = 1.0):
|
||||
RETRIABLE_ERRORS = {2013, 1213, 2006}
|
||||
|
||||
def decorator(fn):
|
||||
@functools.wraps(fn)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
for attempt in range(1, max_retries + 1):
|
||||
try:
|
||||
# 确保连接仍存活,失败自动 reconnect
|
||||
self.conn.ping(reconnect=True)
|
||||
return fn(self, *args, **kwargs)
|
||||
except (pymysql.InterfaceError, pymysql.OperationalError) as e:
|
||||
if isinstance(e, pymysql.OperationalError) and e.args[0] != 2013:
|
||||
raise # 只处理 2013,其他 OperationalError 抛出
|
||||
wait = base_delay * (2 ** (attempt - 1))
|
||||
logger.warning(f"[MySQL][{fn.__name__}] 第{attempt}次重试(断开连接:{e}),等待 {wait:.1f}s 后重连…")
|
||||
time.sleep(wait)
|
||||
self._reconnect_mysql()
|
||||
if attempt == max_retries:
|
||||
logger.error("[MySQL] 重试多次仍失败,抛出异常")
|
||||
|
||||
except pymysql.OperationalError as e:
|
||||
errno = e.args[0]
|
||||
if errno not in RETRIABLE_ERRORS:
|
||||
raise
|
||||
|
||||
reason = {
|
||||
2013: "连接断开",
|
||||
1213: "死锁冲突",
|
||||
2006: "连接失效",
|
||||
}.get(errno, f"MySQL错误{errno}")
|
||||
|
||||
wait = base_delay * (2 ** (attempt - 1))
|
||||
logger.warning(f"[MySQL][{fn.__name__}] 第{attempt}次重试({errno} {reason}):{e},等待 {wait:.1f}s...")
|
||||
|
||||
# 仅对断连类错误尝试重连
|
||||
if errno in {2013, 2006}:
|
||||
self._reconnect_mysql()
|
||||
|
||||
time.sleep(wait)
|
||||
|
||||
logger.error(f"[MySQL] 函数 `{fn.__name__}` 重试 {max_retries} 次仍失败,最终异常:{e}")
|
||||
raise
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def redis_retry(max_retries: int = 3):
|
||||
"""
|
||||
装饰器工厂:指定最大重试次数。
|
||||
|
Loading…
x
Reference in New Issue
Block a user