Как проверить, сохраняется ли подключение к MySql через RMySql или нет?

Я подключился к базе данных mysql через пакет RMySQL, используя этот оператор:

con<-dbConnect(drv=RMySQL::MySQL(max.con=1,fetch.default.rec=500),host="host",dbname="dbname",password="psswd",user="user"))

Пока никаких проблем. Когда я проверяю:

>class(con)
[1] "MySQLConnection"
attr(,"package")
[1] "RMySQL"

Через час я использовал следующее утверждение:

dbGetQuery(conn=con,"show tables") 

и я получил ошибку:

Error in .local(dbObj, ...) : 
internal error in RS_DBI_getConnection: corrupt connection handle

Однако, если я проверю это утверждение:

dbListConnections(drv=RMySQL::MySQL())

Это дает:

[[1]]
<MySQLConnection:0,21>

Когда я пытаюсь:

dbDisconnect(conn=con)

Я получаю ту же ошибку:

Error in .local(dbObj, ...) : 
internal error in RS_DBI_getConnection: corrupt connection handle

Затем я удалил объект подключения:

rm(con)

Когда я попытался снова подключиться с помощью dbConnect(), я получил эту ошибку:

con<-dbConnect(drv=RMySQL::MySQL(max.con=1,fetch.default.rec=500),host="host",dbname="dbname",password="psswd",user="user"))
Error in .local(drv, ...): Cannot allocate a new connection: 1 connections already opened

Я знаю, что вызов dbListConnections() возвращает пустой список, когда нет подключения к базе данных. Но в этом случае не возвращает пустой список.

Является ли поврежденный дескриптор соединения состоянием соединения, отличным от состояния отключения?

OR

Время соединения истекло?

Как лучше всего проверить, работает ли соединение с БД?


person tushaR    schedule 25.01.2017    source источник
comment
Держать соединение открытым так долго — очень, ОЧЕНЬ серьезная ошибка. Вы должны закрыть соединение, как только закончите его использовать. Причина в том, что любые транзакции и блокировки, полученные при открытом соединении, сохраняются до тех пор, пока оно не будет закрыто, что приводит к серьезному снижению производительности. Просто закройте соединение и откройте его ТОЛЬКО при необходимости.   -  person Panagiotis Kanavos    schedule 25.01.2017
comment
Иными словами, если вы сделаете это с базой данных, используемой другими, вы получите срочный телефонный звонок от администраторов баз данных.   -  person Panagiotis Kanavos    schedule 25.01.2017
comment
@PanagiotisKanavos Хорошо. Спасибо, что указали на ошибку. Итак, я должен предположить, что это ошибка реализации с моей стороны, а не проблема с пакетом?   -  person tushaR    schedule 25.01.2017
comment
Да. Фактически, удаление незанятых соединений является стандартным поведением, начиная с версии 6.2. Проверьте эту ссылку. С помощью пула соединений драйвер очищает и кэширует соединения, которые вы закрываете, чтобы они были доступны в следующий раз, когда вы захотите открыть соединение. Это означает, что стоимость открытия соединения минимальна при наличии доступных соединений в пуле.   -  person Panagiotis Kanavos    schedule 25.01.2017


Ответы (1)


Вам по-прежнему может потребоваться закрыть соединение с помощью dbDisconnect(con). вместо rm(con), чтобы освободить внутренний дескриптор соединения и разрешить новое соединение. Последний только удаляет «указатель» на объект подключения (так что вы больше не можете получить доступ к этому объекту через con), но он все еще существует физически до тех пор, пока сборка мусора.

Вы можете проверить, действительно ли соединение через dbIsValid(con), или использовать простой dbGetQuery(con, "SELECT 1"). Мне было бы интересно узнать, обнаружит ли первый отключение в вашей системе, есть обсуждение на GitHub по этой теме.

person krlmlr    schedule 26.01.2017
comment
Я попробовал dbDisconnect(con), как упоминалось в вопросе. Но он выдает ошибку дескриптора поврежденного соединения. Завтра я проверю команду dbIsValid(con). - person tushaR; 26.01.2017
comment
Я установил соединение, запросил БД, а затем отключил ее с помощью dbDisconnect(con). После этого, если я выполню dbIsValid(con) : я получу ошибку дескриптора поврежденного соединения. Но, используя тот же (con), я могу снова подключиться к БД. Я не проверял это для более длительного соединения, поскольку я изменил свой код в соответствии с предложениями @Panagiotis Kanavos. - person tushaR; 27.01.2017
comment
Вы заглядывали в pool? Вот репозиторий Github, а вот вступительная статья. Он делает всю эту шаблонную работу за вас ... По сути, это позволяет вам не беспокоиться о том, на что намекал @Panagiotis Kanavos, когда писал. Сохранение соединения открытым так долго - очень, ОЧЕНЬ серьезная ошибка. Это гарантирует, что вы этого не сделаете, и в то же время даст вам точно такую ​​же семантику. - person Bárbara Borges; 14.02.2017