[ 
https://issues.apache.org/jira/browse/KYLIN-958?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14717902#comment-14717902
 ] 

Luke Han commented on KYLIN-958:
--------------------------------

Hi there,
   Please hold on merge, since this is still temporary workaround, it will 
broken user experience for edit cube.

   The right way is to introduce Data Model Editor like 0.8 branch did. Each 
entity should be exposed and enable full CRUD.

   Let's double check and create relative JIRA for further implementation on 
0.7 (v1.x) branch.

   Thanks.

Luke

> update cube data model may fail and leave metadata in inconsistent state
> ------------------------------------------------------------------------
>
>                 Key: KYLIN-958
>                 URL: https://issues.apache.org/jira/browse/KYLIN-958
>             Project: Kylin
>          Issue Type: Bug
>          Components: Metadata
>    Affects Versions: v0.7.2
>            Reporter: Dayue Gao
>            Assignee: Shaofeng SHI
>            Priority: Critical
>             Fix For: v1.1
>
>         Attachments: KYLIN-958.patch
>
>
> 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
> -------------
> {noformat}
> 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
> {noformat}
> 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.
> {code:title=CacheService.java}
> rebuildCache
>         case DATA_MODEL:
>                 getMetadataManager().reloadDataModelDesc(cacheKey);
>                 IIDescManager.clearCache();
>                 CubeDescManager.clearCache();
>                 break;
> {code}
> 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.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to