2016-04-07 34 views
0

當試圖存儲從RPostgreSQL的行時,我遇到stack depth limit exceeded。爲了解決散裝upserts我一直在使用這樣的查詢:通過hstore查詢超出PostgreSQL堆棧深度限制,儘管查詢小於2 MB

sql_query_data <- sprintf("BEGIN; 
         CREATE TEMPORARY TABLE 
          ts_updates(ts_key varchar, ts_data hstore, ts_frequency integer) ON COMMIT DROP; 
          INSERT INTO ts_updates(ts_key, ts_data) VALUES %s; 
          LOCK TABLE %s.timeseries_main IN EXCLUSIVE MODE; 

          UPDATE %s.timeseries_main 
          SET ts_data = ts_updates.ts_data, 
          ts_frequency = ts_updates.ts_frequency 
          FROM ts_updates 
          WHERE ts_updates.ts_key = %s.timeseries_main.ts_key; 

          INSERT INTO %s.timeseries_main 
          SELECT ts_updates.ts_key, ts_updates.ts_data, ts_updates.ts_frequency 
          FROM ts_updates 
          LEFT OUTER JOIN %s.timeseries_main ON (%s.timeseries_main.ts_key = ts_updates.ts_key) 
          WHERE %s.timeseries_main.ts_key IS NULL; 
          COMMIT;", 
          values, schema, schema, schema, schema, schema, schema, schema) 

}

到目前爲止,這個查詢工作得很好,同時保持較低的插入的數目更新數百萬條記錄。每當我遇到堆棧大小問題時,我都會簡單地將我的記錄分成多個塊並從那裏繼續。

但是,這種策略現在面臨一些麻煩。我沒有很多記錄了,但少數幾個,其中hstore有點大。但是,這不是非常「大」。我閱讀了@Craig Ringer的建議,他建議不要接近1GB的限制。所以我假定hstore本身的大小是沒有問題的,但我收到此消息:

Error in postgresqlExecStatement(conn, statement, ...) : RS-DBI driver: (could not Retrieve the result : ERROR: stack depth limit exceeded HINT: Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate. )

編輯:我沒有增加限制到7 MB,跑進了同樣的錯誤,說明7 MB不足夠。這對我來說真的很奇怪,因爲我的查詢本身只有1.7 MB(通過粘貼到文本文件來檢查它)。任何人都可以對此有所瞭解嗎?

回答

1

按照提示建議增加max_stack_depth。 [從官方文檔】 (http://www.postgresql.org/docs/9.1/static/runtime-config-resource.html):

此參數的理想的設置是由內核執行(如通過設置的ulimit -s或局部等效)的實際堆棧大小的限制,以下的安全餘量一個兆字節左右。

默認設置爲兩兆字節(2MB),這是保守的小,不太可能崩潰的風險。

超級用戶可以通過postgresql.conf文件(需要postgres服務器重啓)爲每個連接更改此設置,也可以爲所有用戶設置此設置。

+0

Thx! hstore在這裏相當不錯,因爲它有助於保持記錄數量,並且我幾乎不需要子集。我只有大約700k的ulimit -s基本上在10MB,所以我可以輕鬆地從最初的2MB上升一點。分貝和應用程序在不同的服務器上。注意:freq在不規則時爲空。 –

+0

很高興它的工作。在旁註中,我想指出,你可以寫'ts_frequency = NULL'而不是'ts_frequency = ts_updates.ts_frequency'。它只是更短的代碼,就是這樣。現在編輯答案。謝謝。 –

+0

要永久增加max_stack_depth,您需要編輯配置,對吧?不能僅以超級用戶身份執行所有其他用戶和會話。有沒有辦法填充更大的hstores。我的意思是我沒有接近最大尺寸,堆棧似乎是限制。複製和csv導入獲得適度的100k對的唯一方法?會是相同/ w json我想... –