cx_ Oracle DatabaseError: ORA-01652: невозможно увеличить временный сегмент на 128 в табличном пространстве TEMP - PullRequest
0 голосов
/ 21 января 2020

Я использую python версия 3.6.8. Недавно используя код, который я использовал в течение нескольких месяцев на ноутбуке Jupyter, я начал получать вышеуказанную ошибку. Код использует cx_ Oracle для подключения запуска нескольких запросов. Я никогда не получал эту ошибку раньше, когда выполнял эти запросы, и запросы обычно выполнялись в течение 1 минуты.

Код создает строку запроса sql в следующей форме (здесь я использую ***, чтобы обозначить, что запрос на самом деле намного длиннее, но я сократил его до основ):

def function(d1,d2):
conn=cx_Oracle.connect(dsn="connection")
sqlstr=f"""select *** from table 
          where date between {d1} and {d2}
       """

query1=pd.read_sql(f"""
select * from 
({sqlstr})
""",conn)


*several similar queries**

conn.close()

return [(query1,query2...)]

Я думаю, что ошибка, скорее всего, связана с форматированием строки, которое я делаю на основе проведенного мною тестирования, но я не уверен, почему это стало проблемой сейчас / случайно, когда код снова работал довольно долго сейчас же. sql, если я удаляю форматирование даты, работает отлично и очень быстро в других местах, поэтому форматирование кажется проблемой *.

РЕДАКТИРОВАТЬ *

Даже после редактирования форматирования строки у меня все еще были проблемы, но я смог изолировать его до одного запроса на самом деле - который на самом деле ** не может работать на прямом sql запросе, так что это скорее всего, это не проблема с питоном / строкой, а проблема с БД (мои извинения за неуместное заверение),

запрос:

select column1,column2,sum(column3)
from
(select several variables,Case When ... as column2
from table1 inner join table2 inner join table3
where several conditions
UNION ALL
select several variables, Case When ... as column2
from table1 inner join table2 inner join table3
where several conditions)
group by column1, column2
having (ABS(sum(column3))>=10000 and column1 in ('a','b','c'))
                or (column1 not in ('a','b','c'))
                order by column1, sum(column3) desc

Я предполагаю, что в некоторых изменениях Конец БД, из-за которого выполнение этого довольно сложного запроса в настоящее время не может быть выполнено, чтобы вызвать вышеуказанную ошибку? Дальнейшая его изоляция - похоже, она потенциально связана с группировкой по CASE, когда переменная колонка 2

1 Ответ

0 голосов
/ 23 января 2020

Как прокомментировали другие, эта ошибка связана с определением размера табличного пространства TEMP и рабочей нагрузкой на БД в данный момент. Кроме того, когда вы получаете «выбросы» TEMP, возможно, что конкретное выполнение SQL становится «жертвой», а не причиной высокотемпературного использования. К сожалению, нет никакого способа предсказать заранее, сколько табличного пространства TEMP потребует конкретная рабочая нагрузка, поэтому выбор правильных настроек - это процесс, включающий постепенное увеличение TEMP согласно вашим лучшим оценкам; TEMP должен быть достаточно большим, чтобы выдерживать пиковые нагрузки. Сказав, что вы можете использовать Active Session History [требуется пакет диагностики], чтобы найти высокий TEMP, потребляющий SQL и, возможно, настроить его на использование меньшего TEMP. Кроме того, вы можете использовать / instrument v $ sort_usage, чтобы определить, какие SQL используют больше всего TEMP. Следующий запрос можно использовать для изучения текущего использования табличного пространства TEMP:

with sort as 
(
SELECT username, sqladdr, sqlhash, sql_id, tablespace, session_addr
       , sum(blocks) sum_blocks
FROM v$sort_usage
GROUP BY username, sqladdr, sqlhash, sql_id, tablespace, session_addr
)
, temp as
(
SELECT A.tablespace_name tablespace, D.mb_total,
SUM (A.used_blocks * D.block_size) / 1024 / 1024 mb_used,
D.mb_total - SUM (A.used_blocks * D.block_size) / 1024 / 1024 mb_free
FROM v$sort_segment A,
(
SELECT B.name, C.block_size, SUM (C.bytes) / 1024 / 1024 mb_total
FROM v$tablespace B, v$tempfile C
WHERE B.ts#= C.ts#
GROUP BY B.name, C.block_size
) D
WHERE A.tablespace_name = D.name
GROUP by A.tablespace_name, D.mb_total
)
SELECT to_char(sysdate, 'DD-MON-YYYY HH24:MI:SS') sample_time
, sess.sql_id
, CASE WHEN elapsed_time > 2*86399*1000000
THEN '2 ' || to_char(to_date(round((elapsed_time-(2*86399*1000000))/decode(executions, 0, 1, executions)/1000000) ,'SSSSS'), 'HH24:MI:SS') 
WHEN elapsed_time > 86399*1000000
THEN '1 ' || to_char(to_date(round((elapsed_time-(86399*1000000))/decode(executions, 0, 1, executions)/1000000) ,'SSSSS'), 'HH24:MI:SS') 
WHEN elapsed_time <= 86399*1000000
THEN to_char(to_date(round(elapsed_time/decode(executions, 0, 1, executions)/1000000) ,'SSSSS'), 'HH24:MI:SS') 
END  as time_per_execution
, sum_blocks*dt.block_size/1024/1024 usage_mb, sort.tablespace
, temp.mb_used, temp.mb_free, temp.mb_total
, sort.username, sess.sid, sess.serial#
, p.spid, sess.osuser, sess.module, sess.machine, p.program
, vst.sql_text
FROM sort,
     v$sqlarea vst,
     v$session sess,
     v$process p,
     dba_tablespaces dt
     , temp
WHERE sess.sql_id = vst.sql_id (+) 
  AND sort.session_addr = sess.saddr (+)
  AND sess.paddr = p.addr (+)
  AND sort.tablespace = dt.tablespace_name (+)
  AND sort.tablespace = temp.tablespace
order by 4 desc
;

Когда я использую термин «инструмент», я имею в виду, вы можете периодически сохранять результаты выполнения этого запроса, чтобы вы могли посмотреть на позже, чтобы увидеть, что происходило, когда вы получили выброс TEMP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...