Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Improvement] Improve time precision of deleteAt to reduce possible bugs #3926

Open
yuqi1129 opened this issue Jun 20, 2024 · 9 comments
Open
Assignees
Labels
improvement Improvements on everything

Comments

@yuqi1129
Copy link
Contributor

What would you like to be improved?

When we switch default entity store to embedded JDBC database and try to drop a entity, the following errors occur:

java.lang.RuntimeException: Failed to operate object [mysql_it_schema_d163bcc4] operation [DROP] under [mysql_it_catalog_ab4808c3], reason [Unique index or primary key violation: "PUBLIC.UK_CID_SN_DEL_INDEX_4 ON PUBLIC.SCHEMA_META(CATALOG_ID, SCHEMA_NAME, DELETED_AT) VALUES 573259166732862349"; SQL statement:
UPDATE schema_meta SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0 WHERE schema_id = ? AND deleted_at = 0 [23505-200]]
java.lang.RuntimeException: org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.UK_CID_SN_DEL_INDEX_4 ON PUBLIC.SCHEMA_META(CATALOG_ID, SCHEMA_NAME, DELETED_AT) VALUES 573259166732862349"; SQL statement:
UPDATE schema_meta SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0 WHERE schema_id = ? AND deleted_at = 0 [23505-200]
### The error may exist in com/datastrato/gravitino/storage/relational/mapper/SchemaMetaMapper.java (best guess)
### The error may involve com.datastrato.gravitino.storage.relational.mapper.SchemaMetaMapper.softDeleteSchemaMetasBySchemaId-Inline
### The error occurred while setting parameters
### SQL: UPDATE schema_meta SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0 WHERE schema_id = ? AND deleted_at = 0
### Cause: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.UK_CID_SN_DEL_INDEX_4 ON PUBLIC.SCHEMA_META(CATALOG_ID, SCHEMA_NAME, DELETED_AT) VALUES 573259166732862349"; SQL statement:
UPDATE schema_meta SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0 WHERE schema_id = ? AND deleted_at = 0 [23505-200]
	at com.datastrato.gravitino.catalog.SchemaOperationDispatcher.dropSchema(SchemaOperationDispatcher.java:303)
	at com.datastrato.gravitino.catalog.SchemaNormalizeDispatcher.dropSchema(SchemaNormalizeDispatcher.java:68)
	at com.datastrato.gravitino.listener.SchemaEventDispatcher.dropSchema(SchemaEventDispatcher.java:123)
	at com.datastrato.gravitino.server.web.rest.SchemaOperations.lambda$dropSchema$8(SchemaOperations.java:203)
	at com.datastrato.gravitino.lock.TreeLockUtils.doWithTreeLock(TreeLockUtils.java:35)
	at com.datastrato.gravitino.server.web.rest.SchemaOperations.lambda$dropSchema$9(SchemaOperations.java:200)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:422)
	at com.datastrato.gravitino.utils.PrincipalUtils.doAs(PrincipalUtils.java:25)
	at com.datastrato.gravitino.server.web.Utils.doAs(Utils.java:121)
	at com.datastrato.gravitino.server.web.rest.SchemaOperations.dropSchema(SchemaOperations.java:195)
	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 org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:146)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:189)
	at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:93)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:478)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:400)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
	at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:256)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
	at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656)
	at com.datastrato.gravitino.server.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:59)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
	at com.datastrato.gravitino.server.web.VersioningFilter.doFilter(VersioningFilter.java:97)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:552)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
	at java.lang.Thread.run(Thread.java:750)
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.UK_CID_SN_DEL_INDEX_4 ON PUBLIC.SCHEMA_META(CATALOG_ID, SCHEMA_NAME, DELETED_AT) VALUES 573259166732862349"; SQL statement:
UPDATE schema_meta SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0 WHERE schema_id = ? AND deleted_at = 0 [23505-200]
### The error may exist in com/datastrato/gravitino/storage/relational/mapper/SchemaMetaMapper.java (best guess)
### The error may involve com.datastrato.gravitino.storage.relational.mapper.SchemaMetaMapper.softDeleteSchemaMetasBySchemaId-Inline
### The error occurred while setting parameters
### SQL: UPDATE schema_meta SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0 WHERE schema_id = ? AND deleted_at = 0
### Cause: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.UK_CID_SN_DEL_INDEX_4 ON PUBLIC.SCHEMA_META(CATALOG_ID, SCHEMA_NAME, DELETED_AT) VALUES 573259166732862349"; SQL statement:
UPDATE schema_meta SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0 WHERE schema_id = ? AND deleted_at = 0 [23505-200]
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:199)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:67)
	at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:152)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85)
	at com.sun.proxy.$Proxy130.softDeleteSchemaMetasBySchemaId(Unknown Source)
	at com.datastrato.gravitino.storage.relational.service.SchemaMetaService.lambda$deleteSchema$16(SchemaMetaService.java:220)
	at com.datastrato.gravitino.storage.relational.utils.SessionUtils.doWithCommit(SessionUtils.java:33)
	at com.datastrato.gravitino.storage.relational.service.SchemaMetaService.deleteSchema(SchemaMetaService.java:219)
	at com.datastrato.gravitino.storage.relational.JDBCBackend.delete(JDBCBackend.java:181)
	at com.datastrato.gravitino.storage.relational.RelationalEntityStore.delete(RelationalEntityStore.java:110)
	at com.datastrato.gravitino.catalog.SchemaOperationDispatcher.dropSchema(SchemaOperationDispatcher.java:299)
	... 76 more
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.UK_CID_SN_DEL_INDEX_4 ON PUBLIC.SCHEMA_META(CATALOG_ID, SCHEMA_NAME, DELETED_AT) VALUES 573259166732862349"; SQL statement:
UPDATE schema_meta SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0 WHERE schema_id = ? AND deleted_at = 0 [23505-200]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:459)
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
	at org.h2.message.DbException.get(DbException.java:205)
	at org.h2.message.DbException.get(DbException.java:181)
	at org.h2.index.BaseIndex.getDuplicateKeyException(BaseIndex.java:103)
	at org.h2.mvstore.db.MVSecondaryIndex.checkUnique(MVSecondaryIndex.java:221)
	at org.h2.mvstore.db.MVSecondaryIndex.add(MVSecondaryIndex.java:196)
	at org.h2.mvstore.db.MVTable.addRow(MVTable.java:531)
	at org.h2.table.Table.updateRows(Table.java:523)
	at org.h2.command.dml.Update.update(Update.java:225)
	at org.h2.command.CommandContainer.update(CommandContainer.java:198)
	at org.h2.command.Command.executeUpdate(Command.java:251)
	at org.h2.jdbc.JdbcPreparedStatement.execute(JdbcPreparedStatement.java:240)
	at org.apache.commons.dbcp2.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:95)
	at org.apache.commons.dbcp2.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:95)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:47)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74)
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197)
	... 86 more
	at com.datastrato.gravitino.client.ErrorHandlers$SchemaErrorHandler.accept(ErrorHandlers.java:308)
	at com.datastrato.gravitino.client.ErrorHandlers$SchemaErrorHandler.accept(ErrorHandlers.java:277)
	at com.datastrato.gravitino.client.HTTPClient.throwFailure(HTTPClient.java:225)
	at com.datastrato.gravitino.client.HTTPClient.execute(HTTPClient.java:378)
	at com.datastrato.gravitino.client.HTTPClient.execute(HTTPClient.java:286)
	at com.datastrato.gravitino.client.HTTPClient.delete(HTTPClient.java:610)
	at com.datastrato.gravitino.client.BaseSchemaCatalog.dropSchema(BaseSchemaCatalog.java:183)
	at com.datastrato.gravitino.client.RelationalCatalog.dropSchema(RelationalCatalog.java:48)
	at com.datastrato.gravitino.catalog.mysql.integration.test.CatalogMysqlIT.clearTableAndSchema(CatalogMysqlIT.java:160)
	at com.datastrato.gravitino.catalog.mysql.integration.test.CatalogMysqlIT.stop(CatalogMysqlIT.java:131)
	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 org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptAfterAllMethod(TimeoutExtension.java:116)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllMethods$13(ClassBasedTestDescriptor.java:425)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllMethods$14(ClassBasedTestDescriptor.java:423)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1082)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeAfterAllMethods(ClassBasedTestDescriptor.java:423)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:225)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:80)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:161)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:161)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
	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 org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

As the query response time(less that 1ms) is very fast compared to MySQL, the value of new deleteAt is the same as old one, then error occur.

How should we improve?

I believe we need to improve the precision or use other ways to solve it, or we can't use embedded JDBC database well.

@yuqi1129 yuqi1129 added the improvement Improvements on everything label Jun 20, 2024
@xloya
Copy link
Collaborator

xloya commented Jun 21, 2024

In H2, the UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) function does not seem to be able to retain data below seconds, and the results are all 0 after seconds, so conflicts may occur.

@yuqi1129 yuqi1129 changed the title [Improvement] Improve time precision of deleteAt to reduce possible [Improvement] Improve time precision of deleteAt to reduce possible bugs Jun 21, 2024
@yuqi1129
Copy link
Contributor Author

In H2, the CURRENT_TIMESTAMP(3) function does not seem to be able to retain data below milliseconds, and the results are all 0 after mills, so conflicts may occur.

I recall that we discussed this several months ago. Do you have any suggestions on how to solve it?

@xloya
Copy link
Collaborator

xloya commented Jun 21, 2024

In H2, the CURRENT_TIMESTAMP(3) function does not seem to be able to retain data below milliseconds, and the results are all 0 after mills, so conflicts may occur.

I recall that we discussed this several months ago. Do you have any suggestions on how to solve it?

The current method works well in our production environment, but I think the following research can be done:

  1. Is this method universal enough in most RDBMSs
  2. Is there an embedded RDBMS that supports the current method
  3. Is there a way to get millisecond time in H2
  4. Optimize the current function to support millisecond or even higher precision timestamps in a more general way. But this may affect some code logic.

@yuqi1129
Copy link
Contributor Author

From my observation, most RDBMSs cannot support time precision less than one millisecond. Using the built-in function to get the current time is far from ideal in terms of precision.

Is there a way to get millisecond time in H2

We don't need to limit our system to H2. We have left the interface to support other embedded databases like derby, sqlite, though it's not so necessary now or in the near future.

Optimize the current function to support millisecond or even higher precision timestamps in a more general way. But this may affect some code logic.

Yeah, I'm focusing on this point and will provide a TSO that is strongly related to current time but provides higher precision time. In this way, it can be database independent. I'm not entirely sure if the complexity is acceptable.

@xloya
Copy link
Collaborator

xloya commented Jun 21, 2024

From my observation, most RDBMSs cannot support time precision less than one millisecond. Using the built-in function to get the current time is far from ideal in terms of precision.

Is there a way to get millisecond time in H2

We don't need to limit our system to H2. We have left the interface to support other embedded databases like derby, sqlite, though it's not so necessary now or in the near future.

Optimize the current function to support millisecond or even higher precision timestamps in a more general way. But this may affect some code logic.

Yeah, I'm focusing on this point and will provide a TSO that is strongly related to current time but provides higher precision time. In this way, it can be database independent. I'm not entirely sure if the complexity is acceptable.

My initial consideration was to calculate the time externally and save it to the database, but this means that the time may be client-dependent, which may lead to inaccurate time if the clocks of multiple clients are not synchronized.

@yuqi1129
Copy link
Contributor Author

My initial consideration was to calculate the time externally and save it to the database, but this means that the time may be client-dependent, which may lead to inaccurate time if the clocks of multiple clients are not synchronized.

I see, there could be a time-skew problem if we use the time generated by the Gravitino server. let me think if it can be addressed.

@yuqi1129
Copy link
Contributor Author

Resolved by #3954

@yuqi1129 yuqi1129 reopened this Aug 27, 2024
@yuqi1129 yuqi1129 self-assigned this Aug 27, 2024
@yuqi1129
Copy link
Contributor Author

@yuqi1129
Copy link
Contributor Author

Test code

    for (int i = 0; i < 10; i++) {
        try {
          ResultSet rs = statement.executeQuery("SELECT (UNIX_TIMESTAMP() * 1000.0), EXTRACT(MICROSECOND FROM CURRENT_TIMESTAMP(3)) / 1000");
          rs.next();
          String v1 = rs.getString(1);
          String v2 = rs.getString(2);
          LOG.info("Current timestamp-yq: {}, {}", v1, v2);

          statement.execute("update schema_meta set deleted_at = 1000 where schema_id = 1");
        } catch (Exception e) {
          LOG.error("Failed to connect to H2 database. Retrying...", e);
          Thread.sleep(1000);
        }
      }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement Improvements on everything
Projects
None yet
Development

No branches or pull requests

2 participants