(데이터)초사이언티스트의 기록

RDS의 Enable Auto Minor Upgrade 체크시 발생하는 일 본문

데이터엔지니어링

RDS의 Enable Auto Minor Upgrade 체크시 발생하는 일

(데이터)초사이언티스트 2024. 2. 16. 23:46

 

최근에 RDS(Database Service)를 관리하는 중에 겪은 문제 중 하나는 "Enable Auto Minor Upgrade"를 활성화했을 때 Glue Job이 정상적으로 실행되지 않는 상황이었습니다. 이 문제를 해결하기 위해 시도한 접근 방법과 해결책에 대해 공유드리겠습니다.

 

문제 발생 상황:

RDS에서 Enable Auto Minor Upgrade를 활성화하면 RDS 엔진 버전 업데이트가 자동으로 이루어집니다. 그러나 이 기능을 활성화한 후 Glue Job이 평소대로 동작하지 않았습니다. Glue Job은 RDS의 데이터를 추출하여 가공하고 다른 시스템에 전달하는 역할을 합니다. 그러나 엔진 업데이트 후 Glue Job이 예상대로 동작하지 않으면 데이터 처리 및 전달 과정에 문제가 발생할 수 있습니다.

 

해결 과정:

  1. 로그 분석: 먼저 Glue Job의 실행 로그를 확인하여 어떤 부분에서 문제가 발생하는지를 파악했습니다. 로그를 통해 RDS 연결 및 쿼리 수행 단계에서 문제가 발생하는 것으로 확인되었습니다.
  2. Glue 업데이트 확인: Glue의 업데이트된 내역이 있는지 확인했습니다. 이는 Glue Job의 동작에 영향을 줄 수 있는 요소 중 하나였습니다.
  3. RDS 설정 및 업데이트 확인: RDS의 설정을 다시 살펴보았습니다. Enable Auto Minor Upgrade가 체크되어 있었으며, 자동 업그레이드가 이루어졌는지를 확인했습니다. 로그 및 이벤트 탭에서는 정보를 얻을 수 없었지만, Maintenance & Backup 탭에서 preupgrade 단계의 스냅샷이 확인되어 자동 업그레이드가 이루어졌음을 확인했습니다.
  4. 마이너 업데이트 이전의 버전의 snapshot으로 restore: 문제가 발생하기 이전의 RDS 스냅샷을 사용하여 RDS를 복원했습니다.
  5. 정상동작하는지 확인 후 데이터 비교: 복원한 RDS에서 Glue Job을 실행하여 정상적으로 작동하는지 확인한 후, 데이터를 비교하여 일관성을 검증했습니다.
  6. 기존의 RDS와 복원한 RDS의 이름 교환: 복원한 RDS를 기존 RDS와 이름을 교환하고 기존 RDS를 삭제했습니다.
  7. 복원한 RDS에서 Auto Minor Upgrade 비활성화: 데이터 파이프라인의 안정성을 고려하여 복원한 RDS에서 Auto Minor Upgrade를 비활성화했습니다.

결론:

RDS의 Enable Auto Minor Upgrade를 활성화하면서 Glue Job 실행에 문제가 발생할 수 있습니다. 이러한 상황에서는 엔진 업데이트 관리 방안을 다시 고려해야 합니다. 보안 및 성능을 고려하여 엔진 업데이트를 수동으로 관리하고, Glue Job과 같은 중요한 프로세스에 영향을 최소화할 수 있는 방법을 찾아야 합니다.

이러한 경험을 통해 우리는 데이터 파이프라인의 안정성을 유지하기 위해 시스템 간의 연관성을 고려하는 것이 중요하다는 점을 배웠습니다. 자동화된 기능이 편리할 수 있지만, 어떤 경우에는 수동 관리가 더 안정적일 수 있음을 명심해야 합니다.

이상으로 RDS의 Enable Auto Minor Upgrade로 인한 Glue Job 실행 문제에 대한 해결 방법에 대해 공유드렸습니다. 도움이 되셨기를 바랍니다.

 

발생한 오류 로그:

2024-02-15 18:01:32,348 ERROR [main] glue.ProcessLauncher (Logging.scala:logError(73)): Error from Python:Traceback (most recent call last):
  File "/tmp/ingestion.py", line 100, in <module>
    connection_options=connection_mysql5_options)
  File "/opt/amazon/lib/python3.6/site-packages/awsglue/dynamicframe.py", line 770, in from_options
    format_options, transformation_ctx, push_down_predicate, **kwargs)
  File "/opt/amazon/lib/python3.6/site-packages/awsglue/context.py", line 237, in create_dynamic_frame_from_options
    return source.getFrame(**kwargs)
  File "/opt/amazon/lib/python3.6/site-packages/awsglue/data_source.py", line 36, in getFrame
    jframe = self._jsource.getDynamicFrame()
  File "/opt/amazon/spark/python/lib/py4j-0.10.9-src.zip/py4j/java_gateway.py", line 1305, in __call__
    answer, self.gateway_client, self.target_id, self.name)
  File "/opt/amazon/spark/python/lib/pyspark.zip/pyspark/sql/utils.py", line 111, in deco
    return f(*a, **kw)
  File "/opt/amazon/spark/python/lib/py4j-0.10.9-src.zip/py4j/protocol.py", line 328, in get_return_value
    format(target_id, ".", name), value)
py4j.protocol.Py4JJavaError: An error occurred while calling o79.getDynamicFrame.
: cohttp://m.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at cohttp://m.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
at cohttp://m.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
at cohttp://m.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:833)
at cohttp://m.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:453)
at cohttp://m.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
at cohttp://m.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198)
at cohttp://m.amazonaws.services.glue.util.JDBCWrapper$.$anonfun$connectionProperties$5(JDBCUtils.scala:992)
at cohttp://m.amazonaws.services.glue.util.JDBCWrapper$.$anonfun$connectWithSSLAttempt$2(JDBCUtils.scala:944)
at scala.Option.getOrElse(Option.scala:121)
at cohttp://m.amazonaws.services.glue.util.JDBCWrapper$.$anonfun$connectWithSSLAttempt$1(JDBCUtils.scala:944)
at scala.Option.getOrElse(Option.scala:121)
at cohttp://m.amazonaws.services.glue.util.JDBCWrapper$.connectWithSSLAttempt(JDBCUtils.scala:944)
at cohttp://m.amazonaws.services.glue.util.JDBCWrapper$.connectionProperties(JDBCUtils.scala:988)
at cohttp://m.amazonaws.services.glue.util.JDBCWrapper.connectionProperties$lzycompute(JDBCUtils.scala:752)
at cohttp://m.amazonaws.services.glue.util.JDBCWrapper.connectionProperties(JDBCUtils.scala:752)
at cohttp://m.amazonaws.services.glue.util.JDBCWrapper.tableDF(JDBCUtils.scala:878)
at cohttp://m.amazonaws.services.glue.util.NoCondition$.tableDF(JDBCUtils.scala:88)
at cohttp://m.amazonaws.services.glue.util.NoJDBCPartitioner$.tableDF(JDBCUtils.scala:174)
at cohttp://m.amazonaws.services.glue.JDBCDataSource.getDynamicFrame(DataSource.scala:1014)
at cohttp://m.amazonaws.services.glue.DataSource.getDynamicFrame(DataSource.scala:101)
at cohttp://m.amazonaws.services.glue.DataSource.getDynamicFrame$(DataSource.scala:101)
at cohttp://m.amazonaws.services.glue.AbstractSparkSQLDataSource.getDynamicFrame(DataSource.scala:725)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
at py4j.Gateway.invoke(Gateway.java:282)
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
at py4j.commands.CallCommand.execute(CallCommand.java:79)
at py4j.GatewayConnection.run(GatewayConnection.java:238)
at java.lang.Thread.run(Thread.java:750)
Caused by: cohttp://m.mysql.cj.exceptions.CJCommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at cohttp://m.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
at cohttp://m.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
at cohttp://m.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
at cohttp://m.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
at cohttp://m.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:342)
at cohttp://m.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:167)
at cohttp://m.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1350)
at cohttp://m.mysql.cj.NativeSession.connect(NativeSession.java:157)
at cohttp://m.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:953)
at cohttp://m.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:823)
... 30 more
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: protocol_version
at sun.security.ssl.Alert.createSSLException(Alert.java:131)
at sun.security.ssl.Alert.createSSLException(Alert.java:117)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:318)
at sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
at sun.security.ssl.TransportContext.dispatch(TransportContext.java:185)
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:152)
at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1401)
at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1309)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at cohttp://m.mysql.cj.protocol.ExportControlled.performTlsHandshake(ExportControlled.java:317)
at cohttp://m.mysql.cj.protocol.StandardSocketFactory.performTlsHandshake(StandardSocketFactory.java:188)
at cohttp://m.mysql.cj.protocol.a.NativeSocketConnection.performTlsHandshake(NativeSocketConnection.java:97)
at cohttp://m.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:333)
... 35 more