1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-02 17:22:27 +03:00

fix(memory leaks): MCOL-5791 - get rid of memory leaks in plugin code

There were numerous memory leaks in plugin's code and associated code.
During typical run of MTR tests it leaked around 65 megabytes of
objects. As a result they may severely affect long-lived connections.

This patch fixes (almost) all leaks found in the plugin. The exceptions
are two leaks associated with SHOW CREATE TABLE columnstore_table and
getting information of columns of columnstore-handled table. These
should be fixed on the server side and work is on the way.
This commit is contained in:
Serguey Zefirov
2024-09-30 14:50:35 +03:00
committed by Sergey Zefirov
parent 6445f4dff3
commit 38fd96a663
31 changed files with 472 additions and 229 deletions

View File

@ -128,6 +128,7 @@ using namespace funcexp;
#include "ha_mcs_datatype.h"
#include "statistics.h"
#include "ha_mcs_logging.h"
#include "ha_subquery.h"
namespace cal_impl_if
{
@ -332,7 +333,7 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, long t
std::vector<CalpontSystemCatalog::ColType>& colTypes = ti.tpl_scan_ctx->ctp;
RowGroup* rowGroup = ti.tpl_scan_ctx->rowGroup;
std::shared_ptr<RowGroup> rowGroup = ti.tpl_scan_ctx->rowGroup;
// table mode mysql expects all columns of the table. mapping between columnoid and position in rowgroup
// set coltype.position to be the position in rowgroup. only set once.
@ -656,7 +657,7 @@ vector<string> getOnUpdateTimestampColumns(string& schema, string& tableName, in
rowgroup::RGData rgData;
ByteStream::quadbyte qb = 4;
msg << qb;
rowgroup::RowGroup* rowGroup = 0;
std::unique_ptr<rowgroup::RowGroup> rowGroup;
uint32_t rowCount;
exemgrClient->write(msg);
@ -709,7 +710,7 @@ vector<string> getOnUpdateTimestampColumns(string& schema, string& tableName, in
if (!rowGroup)
{
// This is mete data
rowGroup = new rowgroup::RowGroup();
rowGroup.reset(new rowgroup::RowGroup());
rowGroup->deserialize(msg);
qb = 100;
msg.restart();
@ -888,7 +889,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
//@Bug 2753. the memory already freed by destructor of UpdateSqlStatement
if (ha_mcs_common::isUpdateStatement(thd->lex->sql_command))
{
ColumnAssignment* columnAssignmentPtr;
ColumnAssignment* columnAssignmentPtr = nullptr;
Item_field* item;
List_iterator_fast<Item> field_it(thd->lex->first_select_lex()->item_list);
List_iterator_fast<Item> value_it(thd->lex->value_list);
@ -919,6 +920,8 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
}
else if (strcmp(tableName.c_str(), tmpTableName.c_str()) != 0)
{
delete colAssignmentListPtr;
delete columnAssignmentPtr;
//@ Bug3326 error out for multi table update
string emsg(IDBErrorInfo::instance()->errorMsg(ERR_UPDATE_NOT_SUPPORT_FEATURE));
thd->raise_error_printf(ER_CHECK_NOT_IMPLEMENTED, emsg.c_str());
@ -929,6 +932,8 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
if (!item->db_name.str)
{
delete colAssignmentListPtr;
delete columnAssignmentPtr;
//@Bug 5312. if subselect, wait until the schema info is available.
if (thd->derived_tables_processing)
return 0;
@ -1003,7 +1008,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
// sysdate() etc.
if (!hasNonSupportItem && !cal_impl_if::nonConstFunc(ifp) && tmpVec.size() == 0)
{
gp_walk_info gwi2(gwi.timeZone);
gp_walk_info gwi2(gwi.timeZone, gwi.subQueriesChain);
gwi2.thd = thd;
SRCP srcp(buildReturnedColumn(value, gwi2, gwi2.fatalParseError));
ConstantColumn* constCol = dynamic_cast<ConstantColumn*>(srcp.get());
@ -1114,6 +1119,8 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
}
else if (value->type() == Item::WINDOW_FUNC_ITEM)
{
delete colAssignmentListPtr;
delete columnAssignmentPtr;
setError(thd, ER_INTERNAL_ERROR, logging::IDBErrorInfo::instance()->errorMsg(ERR_WF_UPDATE));
return ER_CHECK_NOT_IMPLEMENTED;
}
@ -1178,6 +1185,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
if (colAssignmentListPtr->empty() && ha_mcs_common::isUpdateStatement(thd->lex->sql_command))
{
ci->affectedRows = 0;
delete colAssignmentListPtr;
return 0;
}
@ -1205,7 +1213,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
boost::algorithm::to_lower(aTableName.table);
}
CalpontDMLPackage* pDMLPackage = 0;
std::shared_ptr<CalpontDMLPackage> pDMLPackage;
// dmlStmt += ";";
IDEBUG(cout << "STMT: " << dmlStmt << " and sessionID " << thd->thread_id << endl);
VendorDMLStatement dmlStatement(dmlStmt, sessionID);
@ -1215,7 +1223,6 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
else
dmlStatement.set_DMLStatementType(DML_DELETE);
TableName* qualifiedTablName = new TableName();
UpdateSqlStatement updateStmt;
//@Bug 2753. To make sure the momory is freed.
@ -1223,10 +1230,11 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
if (ha_mcs_common::isUpdateStatement(thd->lex->sql_command))
{
TableName* qualifiedTablName = new TableName();
qualifiedTablName->fName = tableName;
qualifiedTablName->fSchema = schemaName;
updateStmt.fNamePtr = qualifiedTablName;
pDMLPackage = CalpontDMLFactory::makeCalpontUpdatePackageFromMysqlBuffer(dmlStatement, updateStmt);
pDMLPackage.reset(CalpontDMLFactory::makeCalpontUpdatePackageFromMysqlBuffer(dmlStatement, updateStmt));
}
else if ((thd->lex)->sql_command == SQLCOM_DELETE_MULTI) //@Bug 6121 error out on multi tables delete.
{
@ -1246,9 +1254,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
boost::algorithm::to_lower(tableName);
boost::algorithm::to_lower(aliasName);
}
qualifiedTablName->fName = tableName;
qualifiedTablName->fSchema = schemaName;
pDMLPackage = CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(dmlStatement);
pDMLPackage.reset(CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(dmlStatement));
}
else
{
@ -1271,9 +1277,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
boost::algorithm::to_lower(tableName);
boost::algorithm::to_lower(aliasName);
}
qualifiedTablName->fName = tableName;
qualifiedTablName->fSchema = schemaName;
pDMLPackage = CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(dmlStatement);
pDMLPackage.reset(CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(dmlStatement));
}
}
else
@ -1288,9 +1292,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
boost::algorithm::to_lower(tableName);
boost::algorithm::to_lower(aliasName);
}
qualifiedTablName->fName = tableName;
qualifiedTablName->fSchema = schemaName;
pDMLPackage = CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(dmlStatement);
pDMLPackage.reset(CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(dmlStatement));
}
if (!pDMLPackage)
@ -1549,7 +1551,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
updateCP->serialize(*plan);
pDMLPackage->write(bytestream);
delete pDMLPackage;
pDMLPackage.reset();
ByteStream::byte b = 0;
ByteStream::octbyte rows = 0;
@ -1633,12 +1635,12 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
// cout << "doUpdateDelete start new DMLProc client for ctrl-c " << " for session " << sessionID
// << endl;
VendorDMLStatement cmdStmt("CTRL+C", DML_COMMAND, sessionID);
CalpontDMLPackage* pDMLPackage = CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(cmdStmt);
std::shared_ptr<CalpontDMLPackage> pDMLPackage(CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(cmdStmt));
pDMLPackage->set_TimeZone(timeZoneOffset);
ByteStream bytestream;
bytestream << static_cast<uint32_t>(sessionID);
pDMLPackage->write(bytestream);
delete pDMLPackage;
pDMLPackage.reset();
b = 1;
retry = maxRetries;
errorMsg = "Command canceled by user";
@ -1756,13 +1758,13 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
if (command != "")
{
VendorDMLStatement cmdStmt(command, DML_COMMAND, sessionID);
CalpontDMLPackage* pDMLPackage = CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(cmdStmt);
std::shared_ptr<CalpontDMLPackage> pDMLPackage(CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(cmdStmt));
pDMLPackage->set_TimeZone(timeZoneOffset);
pDMLPackage->setTableOid(ci->tableOid);
ByteStream bytestream;
bytestream << static_cast<uint32_t>(sessionID);
pDMLPackage->write(bytestream);
delete pDMLPackage;
pDMLPackage.reset();
ByteStream::byte bc;
std::string errMsg;
@ -2145,7 +2147,8 @@ int ha_mcs_impl_direct_update_delete_rows(bool execute, ha_rows* affected_rows,
const char* timeZone = thd->variables.time_zone->get_name()->ptr();
long timeZoneOffset;
dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset);
cal_impl_if::gp_walk_info gwi(timeZoneOffset);
SubQueryChainHolder chainHolder;
cal_impl_if::gp_walk_info gwi(timeZoneOffset, &chainHolder.chain);
gwi.thd = thd;
int rc = 0;
@ -2168,6 +2171,7 @@ int ha_mcs_impl_direct_update_delete_rows(bool execute, ha_rows* affected_rows,
*affected_rows = ci->affectedRows;
}
return rc;
}
@ -2178,7 +2182,8 @@ int ha_mcs::impl_rnd_init(TABLE* table, const std::vector<COND*>& condStack)
const char* timeZone = thd->variables.time_zone->get_name()->ptr();
long timeZoneOffset;
dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset);
gp_walk_info gwi(timeZoneOffset);
SubQueryChainHolder chainHolder;
gp_walk_info gwi(timeZoneOffset, &chainHolder.chain);
gwi.thd = thd;
if (thd->slave_thread && !get_replication_slave(thd) &&
@ -2452,9 +2457,9 @@ int ha_mcs::impl_rnd_init(TABLE* table, const std::vector<COND*>& condStack)
ti = ci->tableMap[table];
ti.msTablePtr = table;
if (ti.tpl_ctx == nullptr)
if (!ti.tpl_ctx)
{
ti.tpl_ctx = new sm::cpsm_tplh_t();
ti.tpl_ctx.reset(new sm::cpsm_tplh_t());
ti.tpl_scan_ctx = sm::sp_cpsm_tplsch_t(new sm::cpsm_tplsch_t());
}
@ -2729,7 +2734,6 @@ int ha_mcs_impl_rnd_end(TABLE* table, bool is_pushdown_hand)
else
ci->cal_conn_hndl = hndl;
ti.tpl_ctx = 0;
}
catch (IDBExcept& e)
{
@ -3737,6 +3741,13 @@ int ha_mcs_impl_delete_row(const uchar* buf)
return 0;
}
// this place is as good as any.
ext_cond_info::ext_cond_info(long timeZone)
: chainHolder(new SubQueryChainHolder())
, gwi(timeZone, &chainHolder->chain)
{
}
COND* ha_mcs_impl_cond_push(COND* cond, TABLE* table, std::vector<COND*>& condStack)
{
THD* thd = current_thd;
@ -3766,7 +3777,8 @@ COND* ha_mcs_impl_cond_push(COND* cond, TABLE* table, std::vector<COND*>& condSt
const char* timeZone = thd->variables.time_zone->get_name()->ptr();
long timeZoneOffset;
dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset);
gp_walk_info gwi(timeZoneOffset);
SubQueryChainHolder chainHolder;
gp_walk_info gwi(timeZoneOffset, &chainHolder.chain);
gwi.condPush = true;
gwi.sessionid = tid2sid(thd->thread_id);
cout << "------------------ cond push -----------------------" << endl;
@ -3782,16 +3794,17 @@ COND* ha_mcs_impl_cond_push(COND* cond, TABLE* table, std::vector<COND*>& condSt
const char* timeZone = thd->variables.time_zone->get_name()->ptr();
long timeZoneOffset;
dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset);
ti.condInfo = new gp_walk_info(timeZoneOffset);
ti.condInfo = new ext_cond_info(timeZoneOffset); //new gp_walk_info(timeZoneOffset);
}
gp_walk_info* gwi = ti.condInfo;
gp_walk_info* gwi = &ti.condInfo->gwi;
gwi->dropCond = false;
gwi->fatalParseError = false;
gwi->condPush = true;
gwi->thd = thd;
gwi->sessionid = tid2sid(thd->thread_id);
cond->traverse_cond(gp_walk, gwi, Item::POSTFIX);
clearDeleteStacks(*gwi);
ci->tableMap[table] = ti;
if (gwi->fatalParseError)
@ -4153,12 +4166,12 @@ int ha_mcs_impl_group_by_init(mcs_handler_info* handler_info, TABLE* table)
mapiter = ci->tableMap.find(tl->table);
if (mapiter != ci->tableMap.end() && mapiter->second.condInfo != NULL &&
mapiter->second.condInfo->condPush)
mapiter->second.condInfo->gwi.condPush)
{
while (!mapiter->second.condInfo->ptWorkStack.empty())
while (!mapiter->second.condInfo->gwi.ptWorkStack.empty())
{
ptIt = mapiter->second.condInfo->ptWorkStack.top();
mapiter->second.condInfo->ptWorkStack.pop();
ptIt = mapiter->second.condInfo->gwi.ptWorkStack.top();
mapiter->second.condInfo->gwi.ptWorkStack.pop();
gi.pushedPts.push_back(ptIt);
}
}
@ -4338,7 +4351,7 @@ int ha_mcs_impl_group_by_init(mcs_handler_info* handler_info, TABLE* table)
{
// MCOL-1601 Using stacks of ExeMgr conn hndls, table and scan contexts.
ti.tpl_ctx = new sm::cpsm_tplh_t();
ti.tpl_ctx.reset(new sm::cpsm_tplh_t());
ti.tpl_ctx_st.push(ti.tpl_ctx);
ti.tpl_scan_ctx = sm::sp_cpsm_tplsch_t(new sm::cpsm_tplsch_t());
ti.tpl_scan_ctx_st.push(ti.tpl_scan_ctx);
@ -4593,6 +4606,7 @@ int ha_mcs_impl_group_by_end(TABLE* table)
{
bool ask_4_stats = (ci->traceFlags) ? true : false;
sm::tpl_close(ti.tpl_ctx, &hndl, ci->stats, ask_4_stats, clearScanCtx);
ti.tpl_ctx = 0;
}
// Normaly stats variables are set in external_lock method but we set it here
// since they we pretend we are in vtable_disabled mode and the stats vars won't be set.
@ -4608,10 +4622,13 @@ int ha_mcs_impl_group_by_end(TABLE* table)
ci->miniStats += hndl->miniStats;
}
}
else
{
ti.tpl_ctx.reset();
}
ci->cal_conn_hndl = hndl;
ti.tpl_ctx = 0;
}
catch (IDBExcept& e)
{
@ -4684,6 +4701,8 @@ int ha_mcs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table, bool
IDEBUG(cout << "pushdown_init for table " << endl);
THD* thd = current_thd;
SubQueryChainHolder chainHolder;
if (thd->slave_thread && !get_replication_slave(thd) &&
ha_mcs_common::isDMLStatement(thd->lex->sql_command))
return 0;
@ -4691,7 +4710,7 @@ int ha_mcs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table, bool
const char* timeZone = thd->variables.time_zone->get_name()->ptr();
long timeZoneOffset;
dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset);
gp_walk_info gwi(timeZoneOffset);
gp_walk_info gwi(timeZoneOffset, &chainHolder.chain);
gwi.thd = thd;
bool err = false;
@ -5049,7 +5068,7 @@ int ha_mcs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table, bool
{
if (ti.tpl_ctx == 0)
{
ti.tpl_ctx = new sm::cpsm_tplh_t();
ti.tpl_ctx.reset(new sm::cpsm_tplh_t());
ti.tpl_scan_ctx = sm::sp_cpsm_tplsch_t(new sm::cpsm_tplsch_t());
}
@ -5174,7 +5193,7 @@ int ha_mcs_impl_select_next(uchar* buf, TABLE* table, long timeZone)
{
if (ti.tpl_ctx == 0)
{
ti.tpl_ctx = new sm::cpsm_tplh_t();
ti.tpl_ctx.reset(new sm::cpsm_tplh_t());
ti.tpl_scan_ctx = sm::sp_cpsm_tplsch_t(new sm::cpsm_tplsch_t());
}