2011-09-02 53 views
5

我有一個名爲sales_observation_daily_summary的表,它是sales_observation_daily_summary_view的物化視圖。存儲過程名爲sync_daily_summary_view_with_table,它將刷新物化視圖,從功能上講,它的工作原理與我的想法完全相同,但是在同一連接上調用存儲過程兩次時(使用連接池時可能出現的情況)出現在我的Java集成測試中,但是我可以很容易地在MySQL Workbench上重現它,所以它不應該與JDBC或Spring或任何中間任何事情有關。MySQL存儲過程在第二次調用時出現「SELECT命令被拒絕給用戶'用戶'@'localhost'表'view_name'的同一連接失敗

call sync_daily_summary_view_with_table(); 
call sync_daily_summary_view_with_table(); 

在第一次調用時,它執行它應該執行的操作並正常返回。在第二個電話,我得到:

Error Code: 1142 
SELECT command denied to user 'test'@'localhost' for table 'one_pg_someone_sales_observation_daily_summary_view' 

one_pg_someone_sales_observation_daily_summary_view在sales_observation_daily_summary_view,這是在存儲過程中引用的參考。首先,存儲過程在第一次運行時並不反對,因此該錯誤消息毫無意義,其次,該用戶有足夠的權利在該視圖上進行選擇。

我不會讓所有的參與,因爲它是非常複雜的意見,但sales_observation_daily_summary_view被定義爲其他若干意見工會這樣的:

CREATE ALGORITHM=UNDEFINED DEFINER=`test`@`localhost` 
SQL SECURITY DEFINER 
VIEW `sales_observation_daily_summary_view` AS 
     /* Specific Stage and Observer */ 
     SELECT zone, 
       session_date, 
       session_year, 
       session_month, 
       session_week, 
       phenomenon_group_id, 
       phenomenon_group_name, 
       stage_id, 
       stage_name, 
       observer_id, 
       series_name, 
       benchmark_id, 
       session_count, 
       session_value, 
       benchmark_value 
     FROM one_pg_someone_sales_observation_daily_summary_view 
     UNION ALL /* All Stages */ 
     SELECT zone, 
       session_date, 
       session_year, 
       session_month, 
       session_week, 
       phenomenon_group_id, 
       phenomenon_group_name, 
       stage_id, 
       stage_name, 
       observer_id, 
       series_name, 
       benchmark_id, 
       session_count, 
       session_value, 
       benchmark_value 
     FROM all_stages_someone_sales_observation_daily_summary_view 
     UNION ALL /* All Activities */ 
     SELECT zone, 
       session_date, 
       session_year, 
       session_month, 
       session_week, 
       phenomenon_group_id, 
       phenomenon_group_name, 
       stage_id, 
       stage_name, 
       observer_id, 
       series_name, 
       benchmark_id, 
       session_count, 
       session_value, 
       benchmark_value 
     FROM all_activities_someone_sales_observation_daily_summary_view 
     UNION ALL /* All Observers */ 
     SELECT zone, 
       session_date, 
       session_year, 
       session_month, 
       session_week, 
       phenomenon_group_id, 
       phenomenon_group_name, 
       stage_id, 
       stage_name, 
       observer_id, 
       series_name, 
       benchmark_id, 
       session_count, 
       session_value, 
       benchmark_value 
     FROM one_pg_everyone_sales_observation_daily_summary_view 
     UNION ALL /* Everyone over All Stages */ 
     SELECT zone, 
       session_date, 
       session_year, 
       session_month, 
       session_week, 
       phenomenon_group_id, 
       phenomenon_group_name, 
       stage_id, 
       stage_name, 
       observer_id, 
       series_name, 
       benchmark_id, 
       session_count, 
       session_value, 
       benchmark_value 
     FROM all_stages_everyone_sales_observation_daily_summary_view 
     UNION ALL /* Everyone over All Activities */ 
     SELECT zone, 
       session_date, 
       session_year, 
       session_month, 
       session_week, 
       phenomenon_group_id, 
       phenomenon_group_name, 
       stage_id, 
       stage_name, 
       observer_id, 
       series_name, 
       benchmark_id, 
       session_count, 
       session_value, 
       benchmark_value 
     FROM all_activities_everyone_sales_observation_daily_summary_view 
     UNION ALL /* Benchmark */ 
     SELECT zone, 
       session_date, 
       session_year, 
       session_month, 
       session_week, 
       phenomenon_group_id, 
       phenomenon_group_name, 
       stage_id, 
       stage_name, 
       observer_id, 
       series_name, 
       benchmark_id, 
       session_count, 
       session_value, 
       benchmark_value 
     FROM benchmark_sales_observation_daily_summary_view 

的存儲過程是這樣定義的:

DELIMITER $$ 

CREATE DEFINER=`test`@`localhost` PROCEDURE `sync_daily_summary_view_with_table`() 
BEGIN 

       /* Update any values that may have changed */ 
       UPDATE sales_observation_daily_summary tb, 
         sales_observation_daily_summary_view vw 
       SET tb.session_count = vw.session_count, 
         tb.session_value = vw.session_count, 
         tb.benchmark_value = vw.benchmark_value, 
         tb.series_name = vw.series_name 
       WHERE vw.zone = tb.zone 
         AND vw.session_date = tb.session_date 
         AND Coalesce(vw.phenomenon_group_id, 0) = 
          Coalesce(tb.phenomenon_group_id, 0) 
         AND Coalesce(vw.stage_id, 0) = Coalesce(tb.stage_id, 0) 
         AND Coalesce(vw.observer_id, 0) = Coalesce(tb.observer_id, 0) 
         AND Coalesce(vw.benchmark_id, 0) = Coalesce(tb.benchmark_id, 0) 
         AND (Coalesce(tb.session_count, -1) <> Coalesce(vw.session_count, -1) 
           OR Coalesce(tb.session_value, -1) <> 
           Coalesce(vw.session_value, -1) 
           OR Coalesce(tb.benchmark_value, -1) <> 
           Coalesce(vw.benchmark_value, -1) 
           OR tb.series_name <> vw.series_name); 
END 

我在本地開發框中使用5.1.56版本的日誌。
UPDATE 1 我也在Amazon RDS服務器版本5.1.57-log上重現了錯誤。

UPDATE 2 如果我定義存儲過程是SQL SECURITY INVOKER並執行它作爲根,它工作正常。這不是一個可接受的解決方法,但它可能是某種線索。 (例如,它不是一個表鎖定問題。

更新3 涉及的表是InnoDB表,我不知道這是否是一個線索,但是當我添加了一個開始事務的開始和一個在提交最後,花了更長的時間才能完成,但隨後上了第二次調用同樣的錯誤。

UPDATE 4 我已經簡化了存儲過程,仍然重現的問題,它曾經有過的INSERT語句後跟通過更新語句。事實證明,更新語句足以重現錯誤,因此我從存儲過程ab中刪除了插入語句OVE。

+0

你可以在另一臺服務器上重現它嗎? – Devart

+0

是的,我編輯了我的描述以反映這一點。本地盒子上的5.1.56和Amazon RDS上的5.1.57都有這個問題。 – jhericks

+0

你是唯一使用視圖/存儲過程的人嗎?這聽起來像是視圖中的一個表可以被鎖定。 – Mindfulgeek

回答

0

這可能是一個交易問題。嘗試在UPDATE和INSERT語句後添加COMMIT。如果你還沒有使用InnoDB,你可能也想嘗試。

你應該嘗試的功能,這樣就看你得到同樣的結果:

DELIMITER $$ 

CREATE DEFINER=`test`@`localhost` PROCEDURE `sync_daily_summary_view_with_table`() 
BEGIN 

      /* Update any values that may have changed */ 
      UPDATE sales_observation_daily_summary tb, 
        sales_observation_daily_summary_view vw 
      SET tb.session_count = vw.session_count, 
        tb.session_value = vw.session_count, 
        tb.benchmark_value = vw.benchmark_value, 
        tb.series_name = vw.series_name 
      WHERE vw.zone = tb.zone 
        AND vw.session_date = tb.session_date 
        AND Coalesce(vw.phenomenon_group_id, 0) = 
         Coalesce(tb.phenomenon_group_id, 0) 
        AND Coalesce(vw.stage_id, 0) = Coalesce(tb.stage_id, 0) 
        AND Coalesce(vw.observer_id, 0) = Coalesce(tb.observer_id, 0) 
        AND Coalesce(vw.benchmark_id, 0) = Coalesce(tb.benchmark_id, 0) 
        AND (Coalesce(tb.session_count, -1) <> Coalesce(vw.session_count, -1) 
          OR Coalesce(tb.session_value, -1) <> 
          Coalesce(vw.session_value, -1) 
          OR Coalesce(tb.benchmark_value, -1) <> 
          Coalesce(vw.benchmark_value, -1) 
          OR tb.series_name <> vw.series_name); 
      COMMIT; 
END 
+0

這些是InnoDB表。我不確定這是否是一條線索,但是當我在開始時添加了一個Start Transaction並且在最後添加了一個Commit時,它似乎掛起了。它只是跑,跑,跑,永不回來。 – jhericks

+0

糾正,它沒有掛,它只是花了很長時間才能運行。然而,我在第二次執行時遇到了同樣的錯誤。 – jhericks

+0

如果它花費更長的時間運行,它會讓我認爲該函數正在更新大量的行。 – Hunter

2

什麼是自動提交的價值? select @@ autocommit;

如果該值爲0,嘗試在兩個調用之間添加一個提交,因爲您可能以某種方式打開了事務 調用sync_daily_summary_view_with_table(); 承諾; 調用sync_daily_summary_view_with_table();

是任何視圖的物化表部分嗎?

+0

autocommit是'1'。該表格不是任何視圖的一部分,儘管我的計劃是在'zone'列中使用非常簡單的過濾器創建一些視圖。 – jhericks

0

這看起來可能與允許多條語句在一個查詢問題

這個(http://dev.mysql.com/doc/refman/5.0/en/mysql-set-server-option.html)可能是一種選擇:

mysql_set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_ON) 

或更好的連接過程:

mysql_real_connect (
    mysql, 
    host_name, 
    user_name, 
    password, 
    db_name, 
    port_num, 
    socket_name, 
    CLIENT_MULTI_STATEMENTS) 

你也應該看看這裏更好的解釋: http://dev.mysql.com/doc/refman/5.0/en/c-api-multiple-queries.html

+0

這不是問題。通過MySQL Workbench,我經常執行由';'分隔的多個語句我可以在Workbench中重現這個問題。此外,我不需要'調用sync_daily_summary_view_with_table(); 調用sync_daily_summary_view_with_table();'一氣呵成。我也可以通過執行一次'調用sync_daily_summary_view_with_table()'來重現問題,等待它完成,然後再次在同一個連接上執行它。它只在每個連接上工作一次,而不是每個請求一次。 – jhericks

0

我不知道你們是否找到了解決這個問題的方法。我遇到了同樣的問題,並且能夠修復它!

當我試圖通過過程在視圖中進行選擇時,我剛剛發生了這個問題。 Ar第一次工作正常,但是從第二次開始,它正在爲我的用戶發出拒絕命令消息。

解決方案是使用「管理員」用戶創建視圖,使其與過程相同(使用「管理員」用戶創建它),並將這些過程運行!

問題是,我不知道MySQL究竟如何使用另一個用戶通過視圖進行選擇,它不使用您的定義者或登錄的會話用戶,並且在第二次,這個「內部」用戶從視圖中獲取comamnd被拒絕。

我希望能幫助你們解決這個問題!

相關問題