【Java.异常】记一次一千三百万记录的表迁移时发生的异常Java.sql.SQLException,关闭的ResultSet;findColumn
在一次表迁移测试中,我遇到了如下异常:
Java.sql.SQLException,关闭的ResultSet;findColumn,at oracle.jdbc.driver.InsentiveScrollableResultSet.ensureOpen......
这个异常字面意思是Resultset已经关闭了...其结果是数据写入目标数据库出错,迁移失败。
但我清楚程序里是一定是没有在读取结束前就关闭连接而导致ResultSet提前关闭的处理的,因为程序里没有这样的逻辑。
于是我又执行了一次代码,发现第二次出现同样的错误,而且脱敏历经的时长都是在11分20秒左右,此时已经迁移的记录为353万条左右;
两次结果惊人的相似,一定有什么原因,于是我到目标数据库查看一下,发现表很多,因为迁移表名根据日期更替,今天脱敏只删除今天为后缀的表,之前的就残留了,这个测试表空间不多,很有可能是表空间不足导致的,从前也因为空间不足导致过错误,可惜当时没记录下来。事后回忆,应该是ORA-01652、ORA-01653这样的爆表空间不足的错误。
于是我将有效的表空间内无用的表删除了几个,再次执行,这回错误出现在了480万条处,时间也长了。这说明应对措施立竿见影,问题的根很可能就在这。
接下来我干脆把dmask_test库内表都删除了,腾出足够空间来测试。结果将一张1300万记录的表和7张50万记录的表迁移完,也没出现错误。
至此完全确认是表空间不足导致的。
这是独立思考和尝试的胜利,如果直接拿“关闭的ResultSet”去网上找,只怕空耗流量精力而徒劳无功。
当然,写入循环和线程是不可能携带回目标数据库表空间不足的信息的,目标端也无从告诉程序什么阻止了它继续接收数据,但程序运行错误时抛出了异常,至于异常为什么会是Java.sql.SQLException,关闭的ResultSet这样的,我就无从得知了。
我只能猜是写入线程因目标DB空间不足而等待,导致CountDownlatch不能及时去除,而导致ResultSet长时间未能关闭所致,看来我也许该在CountDownlatch处理前就主动关闭ResultSet,让其读取完成就不再等待。这时表空间不足导致的错误或许能更接近事实;又或许,程序意识到出错了,但又不知道真正的错误是什么,就把最接近的数据库组件错误抛了出来。这两种都是我的猜想,还有待日后深挖。
查询表空间请参考:https://www.cnblogs.com/heyang78/p/16377040.html
批量删除表空间中表请参考:https://www.cnblogs.com/heyang78/p/16446229.html
脱敏流程请参考:https://www.cnblogs.com/heyang78/p/16410831.html
END