Uploaded image for project: 'Kylin'
  1. Kylin
  2. KYLIN-958

update cube data model may fail and leave metadata in inconsistent state

VotersWatch issueWatchersLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Fixed
    • v0.7.2
    • v1.1
    • Metadata
    • None

    Description

      When user updates cube data model, say drop one lookup table and related dimensions, the operation will fail with message "Failed to deal with the request: null". What's worse is that metadata is corrupted, data model is in post-update state where cube desc is in pre-update state.

      Reproduction Steps:
      1. Define a cube "test_cube" with two lookup tables, EDW.TEST_SITES and EDW.TEST_SELLER_TYPE_DIM. Define a derived dimension SITE_NAME from EDW.TEST_SITES.
      2. Edit the cube, drop one lookup table EDW.TEST_SITES. The system will automatically drop dimensions from EDW.TEST_SITES.
      3. Save the new cube. The error message may occur. (race condition)

      From logs
      -------------

      java.lang.IllegalStateException: Derived can only be defined on lookup table, cube CubeDesc [name=test_cube], DimensionDesc [name=SITE_NAME, join=null, hierarchy=null, table=EDW.TEST_SITES, column=null, derived=[SITE_NAME]]
          at org.apache.kylin.cube.model.DimensionDesc.init(DimensionDesc.java:113)
          at org.apache.kylin.cube.model.CubeDesc.init(CubeDesc.java:446)
          at org.apache.kylin.cube.CubeDescManager.loadCubeDesc(CubeDescManager.java:129)
          at org.apache.kylin.cube.CubeDescManager.reloadAllCubeDesc(CubeDescManager.java:200)
          at org.apache.kylin.cube.CubeDescManager.<init>(CubeDescManager.java:93)
          at org.apache.kylin.cube.CubeDescManager.getInstance(CubeDescManager.java:73)
          at org.apache.kylin.cube.CubeInstance.getDescriptor(CubeInstance.java:121)
          at org.apache.kylin.rest.service.CubeService.updateCubeAndDesc(CubeService.java:237)
          at org.apache.kylin.rest.service.CubeService$$FastClassByCGLIB$$17a07c0e.invoke(<generated>)
          at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
          at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
          at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
          at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
          at org.apache.kylin.rest.service.CubeService$$EnhancerByCGLIB$$57a9f12a.updateCubeAndDesc(<generated>)
          at org.apache.kylin.rest.controller.CubeController.updateCubeDesc(CubeController.java:385)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:606)
          at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
          at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
          at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
          at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
          at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
          at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
          at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
          at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
          at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
          at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:800)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:649)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
          at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
          at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
          at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
      .... // ommited
      

      The cause of the problem is in CubeController.updateCubeDesc, data model is first updated metaManager.updateDataModelDesc(modelDesc);, which will cause a BroadcastEvent type=data_model, name=test_cube, action=update to be sent. As a result CubeDesc cache will be cleared.

      CacheService.java
      rebuildCache
              case DATA_MODEL:
                      getMetadataManager().reloadDataModelDesc(cacheKey);
                      IIDescManager.clearCache();
                      CubeDescManager.clearCache();
                      break;
      

      Then when the cube is being updated through cubeService.updateCubeAndDesc(cube, desc, projectName);, all cube desc is reloaded in CubeDescManager and the old cube desc can't match the new data model.

      Attachments

        1. KYLIN-958.patch
          25 kB
          Dayue Gao
        2. KYLIN-958-0.7-staging.patch.2
          25 kB
          Dayue Gao
        3. KYLIN-958-0.7-staging-v2.patch
          25 kB
          Shao Feng Shi

        Issue Links

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            shaofengshi Shao Feng Shi
            gaodayue Dayue Gao
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment