文章内容

2020/11/17 17:22:56,作 者: 黄兵

保存IP地址Bug的总结

最近在使用MySQL保存IP地址,但是在写代码的时候由于IP地址非常多,逻辑上的错误在运行的时候没有被发现,直到所有IP地址增加完成之后,统计总数之后才发现IP地址没有预期的多。

仔细分析了以下代码,将错误代码做一个分析,避免以后再出现类似错误。

错误代码如下:

ip_range_start = IPint('0.0.0.0').int()
ip_range_end = IPint('1.0.0.0').int()
temp_list = []
# 计数
i = 0
# 计算差值
ip_diff = ip_range_end - ip_range_start
for item in range(ip_range_start, ip_range_end):
i += 1
insert_sql = f"UPDATE ip_address SET ip_type_id = 1, ip_description_id = %s, ip_version_id = 1, time_updated = '{datetime.now()}' WHERE ip = {item};"
# 执行SQL语句
temp_list.append((str(1), str(item)))
if len(temp_list) >= 1000:
print(item)
if ip_diff >= 1000 and len(temp_list) >= 1000:
# 差值 >=1000
# 每次更新1000IP地址
try:
cur.executemany(insert_sql, temp_list)
except (MySQLdb.Error, MySQLdb.Warning) as e:
self._logger.error(f'更新IP地址出现错误,具体错误内容: {e}IP地址:{item}')
mysql_conn.commit()
else:
continue

经过修改之后保存IP地址代码:

ip_range_start = IPint('0.0.0.0').int()
ip_range_end = IPint('1.0.0.0').int()
temp_list = []
# 计数
i = 0
# 计算差值
ip_diff = ip_range_end - ip_range_start
for item in range(ip_range_start, ip_range_end):
i += 1
insert_sql = f"UPDATE ip_address SET ip_type_id = 1, ip_description_id = %s, ip_version_id = 1, time_updated = '{datetime.now()}' WHERE ip = {item};"
# 执行SQL语句
temp_list.append((str(1), str(item)))
if len(temp_list) >= 1000:
print(item)
if ip_diff >= 1000 and len(temp_list) >= 1000:
# 差值 >=1000
# 每次更新1000IP地址
try:
cur.executemany(insert_sql, temp_list)
except (MySQLdb.Error, MySQLdb.Warning) as e:
self._logger.error(f'更新IP地址出现错误,具体错误内容: {e}IP地址:{item}')
mysql_conn.commit()
elif i > math.floor(ip_diff / 1000) * 1000:
# 向下取整,之后计算几次之后开始单个更新IP地址,例如:15038/1000=15
# 15*1000=15000,也就是说从15000IP地址之后,开始单个更新
insert_sql = f"UPDATE ip_address SET ip_type_id = 1, ip_description_id = 1, ip_version_id = 1, time_updated = '{datetime.now()}' WHERE ip = {item};"
try:
cur.execute(insert_sql)
except (MySQLdb.Error, MySQLdb.Warning) as e:
self._logger.error(f'更新IP地址出现错误,具体错误内容: {e}IP地址:{item}')
mysql_conn.commit()

这里更新‘0.0.0.0/8’的IP地址,总共是:16,777,216个,需要运行很久。

程序每次修改1000条数据,这里如果循环了16777次之后,还有后面的216个数据,需要注意这个地方,如果没有考虑这216个,直接会遗漏。

当然上面也可以直接写SQL语句执行也没有问题。

例如:

UPDATE ip_address SET ip_type_id = 1, ip_description_id = 2, ip_version_id = 1 WHERE ip>=167772160 and ip < 184549376;

但是这里没有采用此方法。


总结:如果数据非常多,程序需要运行很长时间,其中有一些逻辑错误可能会没有被发现,在运行完程序之后,需要再次检查数据量是否正确,以确保程序按照想法正确运行,如果数量不够,需要检查数据的连贯性,看看哪里出现了问题,再根据遗漏的地方重新增加。


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 - 保存IP地址Bug的总结

分享到:

发表评论

评论列表